Пример #1
0
void
enter_process(void *tf,unsigned long addr)
{
	struct trapframe *childframe,child_tf;
	struct addrspace *childspace;
	if(tf!=NULL)
	{

		tf = (struct trapframe *) tf;
		childframe = tf;
		//copy the trapframe info now into the child_tf


	//	child_tf = *childframe;

		memcpy(&child_tf,tf,sizeof(struct trapframe));

		child_tf.tf_a3=0;
		child_tf.tf_v0=0;

		child_tf.tf_epc +=4;


		pid_t parentid = (pid_t)addr;
		if(process_array[curthread->t_pid]->parent_id!=parentid)
			process_array[curthread->t_pid]->parent_id=parentid;

		if(!(curthread->t_addrspace==NULL))
		{
			childspace = curthread->t_addrspace;
			as_activate(childspace);
		}
		mips_usermode(&child_tf);
	}
}
Пример #2
0
void md_forkentry(struct trapframe *tf,unsigned long addrspace_copy)
{
	/*
	 * This function is provided as a reminder. You need to write
	 * both it and the code that calls it.
	 *
	 * Thus, you can trash it and do things another way if you prefer.
	 */
	//(void)tf;
	//kprintf("\n md_forkentry");
	tf->tf_v0=0;
	tf->tf_a3=0;
	curthread->t_vmspace=(struct addrspace*)addrspace_copy;
	if(curthread->t_vmspace!=NULL){
		as_activate(curthread->t_vmspace);
	}

	//copy modified trap frame from kernel heap to stack
	struct trapframe tf_temp=*tf;//=kmalloc(sizeof(struct trapframe));
	tf_temp.tf_v0=tf->tf_v0;
	tf_temp.tf_a0=tf->tf_a0;
	tf_temp.tf_a1=tf->tf_a1;
	tf_temp.tf_a2=tf->tf_a2;
	tf_temp.tf_a3=tf->tf_a3; 
	tf->tf_epc+=4;
	mips_usermode(&tf_temp);
}
Пример #3
0
void
md_forkentry(struct trapframe *tf, unsigned int vmspace)
{

	struct trapframe child_kstack;

       /* copy trapframe of parent to chile procss*/
	memcpy(&child_kstack, tf, sizeof(struct trapframe));
       /* release trapframe when allocated at function process*/
	kfree(tf);

       /* activate addrspace*/
	as_activate((struct addrspace *)vmspace);

       /* increment pc*/
	child_kstack.tf_epc += 4;
	child_kstack.tf_v0 = 0;
	child_kstack.tf_a3 = 0;

       /* release lock so that other process can execute process_fork*/
//	lock_release(forklock);

       /* execute chile process*/
	mips_usermode(&child_kstack);



}
Пример #4
0
/* This is the entry point of the forked child process */
int
md_forkentry(void* tf, unsigned long vmspace)
{
	// int spl = splhigh();	
	//kprintf(" process %d is in enter md_forkentry\n",curthread->pID);
	struct trapframe child_tf;
	struct trapframe *tf_parent = (struct trapframe*) tf;
	assert(tf_parent != NULL);
	// memcpy(child_tf, tf, sizeof(struct trapframe));


	tf_parent->tf_epc += 4;
	//we set the return value to be 0.
	tf_parent->tf_v0 = 0;
	tf_parent->tf_a3 = 0;

	// Load Address Space of Child and Activate it.

	curthread->t_vmspace = (struct addrspace*)vmspace;
	assert(curthread->t_vmspace != NULL);
	as_activate(curthread->t_vmspace);

	child_tf = *tf_parent;
	mips_usermode(&child_tf);

	// we should never reach here
	panic("switching to user mode returned\n");
	return 0;
}
Пример #5
0
void
md_forkentry(struct trapframe *tf, unsigned long child_addr)
{
   /*
		this function is basically for the child thread, remember the threadfor in sys_fork, it calls the md_forkentry  and passed in new TF and addressspace and the child_thread.
	 */
	//kprintf("just enter forkentry\n");
	struct trapframe* modifiy_tf;
	struct trapframe dumbvalue;
	struct addrspace* new_addr = (struct addrspace*) child_addr;
	modifiy_tf= kmalloc(sizeof(struct trapframe));
	//kprintf("just enter memcpy modified tf and tf\n");
	memcpy(modifiy_tf, tf, sizeof(struct trapframe));
	//kprintf("just after memcpy modified tf and tf\n");
	//*modifiy_tf = *tf;

	modifiy_tf->tf_v0 = 0;
	modifiy_tf->tf_a3 = 0;
	modifiy_tf->tf_epc +=4;
	curthread->t_vmspace = new_addr;
	//activie the addressspace
	//kprintf("activate thread -- pid: %d\n", curthread->t_pid);
	as_activate(curthread->t_vmspace);
	//memcpy(dumbvalue, tf, sizeof(struct trapframe));
	//kprintf("just enter dumbvalue =*tf\n");
	dumbvalue = *modifiy_tf;
	//kprintf("just leave dumbvalue =*tf\n");
	mips_usermode(&dumbvalue);
}
Пример #6
0
	void
forkentry(void *tf, unsigned long child_addrs )
{
	(void)child_addrs;
	int *temp;
	struct trapframe my_tf;

	int s = splhigh();
	if((curthread->errflag)==1){
			splx(s);
			sysexit(temp,tf);
	}else{
		//DEBUG(1,"forkentry %d\n",curthread->ppid);

		memcpy(&my_tf, tf, sizeof(struct trapframe));

		my_tf.tf_a3 = 0;
		my_tf.tf_epc +=4;
		my_tf.tf_v0 = 0;
		splx(s);

		kfree(tf);
		mips_usermode(&my_tf);
	}
}
Пример #7
0
void 
md_forkentry(void * data1, unsigned long unused) {
	//(void)unused;
	struct fork_info * info = data1;
	struct addrspace * new_as;
	struct trapframe new_tf;
	/* copy address space */
	if (as_copy(info->parent->t_vmspace, &new_as)) {
		info->child_pid = ENOMEM; // Means no memory for process
		V(info->sem);	// child is done, parent should resume.
		thread_exit();
	}
	curthread->t_vmspace = new_as;
	as_activate(new_as);

	/* copy trap frame  */
	memcpy(&new_tf, info->tf, sizeof(struct trapframe));
	/* change tf's registers to return values for syscall */
	new_tf.tf_v0 = 0;
	new_tf.tf_a3 = 0;
	new_tf.tf_epc += 4;
	/* create process and get the pid */
	struct thread *new_process = kmalloc(sizeof(struct thread));
	 new_process->parent_pid = curthread->t_pid;
	proc_table++; 
	new_process->t_pid = create_tpid();
	proc_table++;
	

	V(info->sem);
	mips_usermode(&new_tf);
	/* mips_usermode does not return */
}
Пример #8
0
/*
 * Enter user mode for a newly forked process.
 *
 * This function is provided as a reminder. You need to write
 * both it and the code that calls it.
 *
 * Thus, you can trash it and do things another way if you prefer.
 */
void
enter_forked_process(struct trapframe *tf)
{
	KASSERT(tf);
	struct trapframe newtf=*tf;
        kfree(tf);
	newtf.tf_v0=0;
        newtf.tf_a0=0;
        newtf.tf_epc += 4;
	mips_usermode(&newtf);
	(void)tf;
}
Пример #9
0
Файл: trap.c Проект: dlyrikz/OS
/*
 * md_usermode: go to user mode after loading an executable.
 *
 * Works by creating an ersatz trapframe and jumping into the middle
 * of the exception return code.
 */
void
md_usermode(int argc, userptr_t argv, vaddr_t stack, vaddr_t entry)
{	struct trapframe tf;

	bzero(&tf, sizeof(tf));
	tf.tf_status = CST_IRQMASK | CST_IEp | CST_KUp;
	tf.tf_epc = entry;
	tf.tf_a0 = argc;
	tf.tf_a1 = (vaddr_t)argv;
	tf.tf_sp = stack;
	mips_usermode(&tf);
}
Пример #10
0
/*
 * Enter user mode for a newly forked process.
 *
 * Succeed and return 0 into userspace.
 */
void
enter_forked_process(struct trapframe *tf)
{
	tf->tf_v0 = 0;
	tf->tf_a3 = 0;

	/*
	 * Advance the PC.
	 */
	tf->tf_epc += 4;

	mips_usermode(tf);
}
/*
 * Enter user mode for a newly forked process.
 *
 * This function is provided as a reminder. You need to write
 * both it and the code that calls it.
 *
 * Thus, you can trash it and do things another way if you prefer.
 */
void
enter_forked_process(struct trapframe *tf)
{
	  #if OPT_A2
    struct trapframe temptrap;
  memcpy(&temptrap, (void *)tf, sizeof(struct trapframe));
  kfree(tf);
    temptrap.tf_v0 = 0;
  temptrap.tf_a3 = 0;
  temptrap.tf_epc += 4;
    mips_usermode(&temptrap); 
  #else
    (void)tf;
  #endif /* OPT_A2 */
}
Пример #12
0
//void entry_point(void* data1, unsigned long data2)
void enter_forked_process(void* data1, unsigned long data2)
{
	//(void)tf;
	//kprintf("hi1");
	struct trapframe tf = (*(struct trapframe*) data1);
	//struct trapframe new_tf;
 	//memcpy(&new_tf,tf, sizeof(struct trapframe));
	//new_tf = *tf;
	//(void) data2;
	tf.tf_a3 = 0;
	tf.tf_v0 = data2;
	tf.tf_epc += 4;
	//as_activate();
	mips_usermode(&tf); //Enter user mode for newly forked process
	//kprintf("hi2");
}
Пример #13
0
/*
 * Enter user mode for a newly forked process.
 *
 * This function is provided as a reminder. You need to write
 * both it and the code that calls it.
 *
 * Thus, you can trash it and do things another way if you prefer.
 */
void
enter_forked_process(struct trapframe *tf)
{
    //kprintf("enter_forked_process \n");
    #if OPT_A2
        struct trapframe thisTF = *tf; //create tf on stack
        thisTF.tf_v0 =0; //child returns with 0
        thisTF.tf_a3 =0; //error coding
        thisTF.tf_epc +=4; //counter
        as_activate();
        mips_usermode(&thisTF);
        panic("Should not return from mips usermode\n");
    #else
	    (void)tf;
	#endif
}
Пример #14
0
void child_process_entry(void *data1, unsigned long data2)
{
	struct trapframe *tf = (struct trapframe *)data1 ;

	curthread->t_addrspace = (struct addrspace *)data2 ;

	as_activate(curthread->t_addrspace) ;

	struct trapframe usertf ;
	usertf = *tf;
	//memcpy(&usertf,tf ,sizeof(struct trapframe ));
	usertf.tf_v0 = 0 ;
	usertf.tf_a3 = 0 ;
	usertf.tf_epc += 4 ;
	kfree(tf) ;
	mips_usermode(&usertf) ;
}
Пример #15
0
void child_fork_entry(void *data1, unsigned long data2)
{
	struct trapframe *ctf = (struct trapframe *)data1;
	struct addrspace *caddr = (struct addrspace *)data2;

	ctf->tf_a3= 0;
	ctf->tf_v0= 0;
	ctf->tf_epc = ctf->tf_epc+4;

	curthread->t_addrspace = caddr;
	as_activate(curthread->t_addrspace);

	struct trapframe tf;
	memcpy(&tf,ctf,sizeof(struct trapframe));
	mips_usermode(&tf);
	//KASSERT(SAME_STACK(cpustacks[curcpu->c_number]-1, (vaddr_t)tf_copy));
}
Пример #16
0
/*
 * Enter user mode for a newly forked process.
 *
 * This function is provided as a reminder. You need to write
 * both it and the code that calls it.
 *
 * Thus, you can trash it and do things another way if you prefer.
 */
void
enter_forked_process(struct trapframe *tf)
{
	#if OPT_A2
		struct trapframe forkTf = *tf;
		forkTf.tf_a3 = 0; //signal no error
		forkTf.tf_v0 = 0;
		forkTf.tf_epc += 4; //advance the PC, to avoid the syscall again

		as_activate();
		mips_usermode(&forkTf);

		panic("can't come here");
	#else
		(void)tf;
	#endif //OPT_A2
}
Пример #17
0
void
enter_forked_process(void *data1, unsigned long data2){
  struct trapframe *childtf = ((void **)data1)[0];
  struct addrspace *childas = ((void **)data1)[1];
// using local variable to put tf on stack
  struct trapframe local = *childtf;

// switch to childas
  curproc_setas(childas);
  as_activate();

// set register  
  local.tf_epc += 4;
  local.tf_v0 = 0;
  local.tf_a3 = 0;
  
  (void)data2;
  mips_usermode(&local);
}
Пример #18
0
/*
 * Enter user mode for a newly forked process.
 *
 * This function is provided as a reminder. You need to write
 * both it and the code that calls it.
 *
 * Thus, you can trash it and do things another way if you prefer.
 */
void
enter_forked_process(void* ptr, unsigned long args)
{
    //panic("test");
    //while(1) {}
	struct trapframe childtf;
    bzero(&childtf, sizeof(childtf));
    childtf = *(struct trapframe *) ptr;
    childtf.tf_v0 = 0;
    childtf.tf_a3 = 0;
    childtf.tf_epc += 4;
    kfree(ptr);
    // load and activate the address space
    struct addrspace* as = (struct addrspace *) args;
    proc_setas(as);
    as_activate();

    mips_usermode(&childtf);
}
Пример #19
0
void
child_forkentry(void *data1, unsigned long data2){

    struct trapframe st_trapframe;
    struct trapframe* childtf = (struct trapframe*) data1;
    struct addrspace* childaddr = (struct addrspace*) data2;

    childtf->tf_v0 = 0;
    childtf->tf_a3 = 0;
    childtf->tf_epc += 4;

    memcpy(&st_trapframe, childtf, sizeof(struct trapframe));
    kfree(childtf);
    childtf = NULL;

    curproc->p_addrspace = childaddr;
    as_activate();

    mips_usermode(&st_trapframe);
};
Пример #20
0
void
md_forkentry(struct fork_data *fd, unsigned long un)
{
	(void) un;
	struct trapframe local_tf;

	local_tf = *(fd->tf);
	
	curthread->t_vmspace = fd->addr;
	as_activate(curthread->t_vmspace);

	kfree(fd->tf);
	kfree(fd);

	local_tf.tf_epc += 4;
	local_tf.tf_a3 = 0;
	local_tf.tf_v0 = 0;

	mips_usermode(&local_tf);
}
Пример #21
0
/*
 * Enter user mode for a newly forked process.
 *
 * This function is provided as a reminder. You need to write
 * both it and the code that calls it.
 *
 * Thus, you can trash it and do things another way if you prefer.
 */
void
enter_forked_process(void *tf, unsigned long arg)
{
#if OPT_A2
	(void) arg;
	as_activate();   //activate the address space
	struct trapframe stacktf;
	stacktf = *(struct trapframe *) tf;  //copy the trapframe
	
	stacktf.tf_v0 = 0;
	stacktf.tf_a3 = 0;
	stacktf.tf_epc = stacktf.tf_epc + 4;

	kfree(tf);
	mips_usermode(&stacktf);
	return;
#else
	(void)tf;
	(void)arg;
#endif
}
Пример #22
0
void
md_forkentry(struct trapframe *tf,unsigned long as_data)
{
	struct trapframe tf_local;
       struct trapframe *newtf; 
       struct addrspace *newas = (struct addrspace*) as_data;
       tf_local = *tf;
       newtf = &tf_local;

       newtf->tf_v0 = 0;
       newtf->tf_a3 = 0;
       newtf->tf_epc += 4;
       kfree(tf);
       curthread->t_vmspace = newas;

       as_activate(curthread->t_vmspace);
       
  

mips_usermode(&tf_local);
}
void
md_forkentry(struct trapframe *tf)
{
	/*
	 * This function is used to copy the trap frame of the parent process into
	 * the the child's and return the child process to user mode
	 */
	//int spl;

	// disable interrupts
	//spl = splhigh();

	//new trap frame for the child
	struct trapframe newtf;

	// copy the trap frame
	memcpy (&newtf, tf, sizeof(struct trapframe));
	//newtf = *tf;
	newtf.tf_v0 = 0; 	// return value of the child process should be 0
	newtf.tf_epc += 4; 	// advance the PC to avoid redo of the syscall
	newtf.tf_a3 = 0; 	// indicate that there are no errors

	curthread->t_vmspace = (struct addrspace*)tf->tf_a0;
	//memcpy (curthread->t_vmspace, (struct addrspace*) tf->tf_a0, sizeof(struct addrspace*));
	//kprintf ("BEOFRE");
	//struct addrspace *temp = (struct addrspace*) tf->tf_a0;
    //int test = as_copy(curthread->t_vmspace, &temp);
    //kprintf ("as_copy: %d\n", test);
    //kprintf ("TESTING HERE");
	as_activate(curthread->t_vmspace);
	kfree (tf);
	V(curthread->t_sem_fork);

	//kprintf ("md_forkentry childpid: %d\n", curthread->t_pid);

	// re-enable interrupts
	//splx(spl);
	// Warp to user mode
	mips_usermode(&newtf);
}
Пример #24
0
/*
 * Enter user mode for a newly forked process.
 *
 * This function is provided as a reminder. You need to write
 * both it and the code that calls it.
 *
 * Thus, you can trash it and do things another way if you prefer.
 */
void
enter_forked_process(void *data1, unsigned long unused)
{
	struct trapframe local_tf;
	(void)unused;

	/* Copy the trapframe passed in onto the current thread's stack */
	local_tf = *(struct trapframe *)data1;

	/* And free the kernel memory from the trapframe passed in */
	kfree(data1);

	/*
	 * Advance the program counter, to avoid restarting
	 * the syscall over and over again in the child.
	 */
	local_tf.tf_epc += 4;
	local_tf.tf_a3 = 0; /* Success if the child gets here */
	local_tf.tf_v0 = 0; /* return 0 to the child */

	mips_usermode(&local_tf);
}
Пример #25
0
static
void md_forkentry(struct trapframe *tf, unsigned long vmspace)
{
    // disable interrupt
    struct addrspace *t_vmspace = (struct addrspace*)vmspace;
    splhigh();

    if (t_vmspace == NULL) {
        thread_exit();
    }
    assert(curthread->t_vmspace == NULL);
    curthread->t_vmspace = t_vmspace;


    // copy the trapframe to our own stack and free it
    struct trapframe mytf;
    memmove(&mytf, tf, sizeof(mytf));
    kfree(tf);

    // set the return value to 0
    mytf.tf_v0 = 0;
    mytf.tf_a3 = 0;

    // next instruction
    mytf.tf_epc += 4;

    /* Activate it. */
    // as_hold(curthread->t_vmspace);
    as_activate(curthread->t_vmspace);

    // kprintf("sw to user mode.\n");

    // switch to usermode
    mips_usermode(&mytf);

    // should not come here
    assert(0);
}
Пример #26
0
void
md_forkentry(struct trapframe *tf)
{
	/*
	 * This function is provided as a reminder. You need to write
	 * both it and the code that calls it.
	 *
	 * Thus, you can trash it and do things another way if you prefer.
	 */

	int s;
	s = splhigh();

	DEBUG(DB_SYSCALL,"forking thread");
	//(void)tf;

	//
	tf->tf_v0 = 0; //set return value to 0 for child process
	tf->tf_epc += 4; //advance pc to avoid restarting syscall
	tf->tf_a3 = 0; //a3 set to 0 to indicate success

	splx(s);
	mips_usermode(tf);
}
Пример #27
0
void entrypoint(void* data1, unsigned long data2) { 
	struct trapframe *tf, tfnew;
    struct addrspace * addr;

    tf = (struct trapframe *) data1;

    addr = (struct addrspace *) data2;

    tf->tf_a3 = 0;
    tf->tf_v0 = 0;
    tf->tf_epc += 4;
    //kprintf(" LMAO  ");
    curproc->p_addrspace = addr;
    //kprintf(" rekt  ");
    //memcpy(tfnew, tf, sizeof(struct trapframe));
    
    as_activate();
    //kprintf(" nips  ");
    tfnew = *tf;
    
    //kprintf(" nips  ");
    mips_usermode(&tfnew);
    //kprintf(" SWAG  ");
}
Пример #28
0
// The parent copies the appropriate data from itself to its child in this function
void start_child(void * data1, unsigned long unused) {
	(void)unused;
	struct fork_info * info = data1;
	struct addrspace * new_as;
	struct trapframe new_tf;

	/* copy address space */
	if (as_copy(info->parent->t_vmspace, &new_as)) {
		info->child_pid = ENOMEM; // Means no memory for process
		V(info->sem);	// child is done, parent should resume.
		thread_exit();
	}
	curthread->t_vmspace = new_as;
	as_activate(new_as);

	/* copy trap frame to new curkstack */
	memcpy(&new_tf, info->tf, sizeof(struct trapframe));
	/* change tf's registers to return values for syscall */
	new_tf.tf_v0 = 0;
	new_tf.tf_a3 = 0;
	new_tf.tf_epc += 4;

	/* create process and get the pid */
	struct process *new_process = proctable_add_child_process(curthread->t_process);
	if (new_process == NULL) {
		info->child_pid = EAGAIN; // Means no more processes available in process table
		V(info->sem);	// child is done, parent should resume.
		thread_exit();
	}
	info->child_pid = new_process->pid;
	new_process->parent = info->parent->t_process;

	// Attach new process to our thread
	curthread->t_process = new_process;

	// Initalize new file table
	int result = fdtable_create();
	if (result) 
	{
		// Error occured
		info->child_pid = result;
		result = proctable_remove_process(new_process->pid);
		// We're already exiting, so if there's an error with the line above, then it doesn't matter that much
		V(info->sem);	// child is done, parent should resume.
		thread_exit();
	}

	struct process * parent_process = info->parent->t_process;
	lock_acquire(parent_process->t_fdtable_lock);

	// Copy file table
	// This requires the filetable to be locked and the refcounts of each file to be increased.
	int i;
	for (i = 0; i < OPEN_MAX ; i++) {
		new_process->t_fdtable->entries[i] = parent_process->t_fdtable->entries[i];
		if (new_process->t_fdtable->entries[i] != NULL) new_process->t_fdtable->entries[i]->refcount++;	// Increases the number of references to a file
	}
	lock_release(parent_process->t_fdtable_lock);

	// child is done, parent should resume.
	V(info->sem);

	mips_usermode(&new_tf);

	/* mips_usermode does not return */
	panic("start_child returned\n");
}