示例#1
0
bool CrashReporting::Handler(const char* dump_path, const char* minidump_id,
                             void* context, bool succeeded) {
  Print("Clementine has crashed!  A crash report has been saved to:\n  ");
  Print(dump_path);
  Print("/");
  Print(minidump_id);
  Print(
      "\n\nPlease send this to the developers so they can fix the problem:\n"
      "  http://code.google.com/p/clementine-player/issues/entry\n\n");

  if (sPath) {
    // We know the path to clementine, so exec it again to prompt the user to
    // upload the report.
    const char* argv[] = {sPath, kSendCrashReportOption, dump_path, minidump_id,
                          nullptr};

    sys_execv(sPath, argv);
  }

  return true;
}
/*
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception-*.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void syscall(struct trapframe *tf) {
	int callno;
	int32_t retval;
	int err;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values,
	 * like write.
	 */

	retval = 0;


	off_t pos, new_pos;
	switch (callno) {
	case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;

	case SYS___time:
		err = sys___time((userptr_t) tf->tf_a0, (userptr_t) tf->tf_a1);
		break;

	case SYS_open:
		err = sys_open((userptr_t) tf->tf_a0, (int) tf->tf_a1,
				(int) tf->tf_a2, &retval);
		break;

	case SYS_read:
		err = sys_read((int) tf->tf_a0, (userptr_t) tf->tf_a1,
				(int) tf->tf_a2, &retval);
		break;

	case SYS_write:
		err = sys_write((int) tf->tf_a0, (userptr_t) tf->tf_a1,
				(int) tf->tf_a2, &retval);
		break;
	case SYS_lseek:

		pos = (((off_t)tf->tf_a2 << 32) | tf->tf_a3);
		err = sys_lseek((userptr_t) tf->tf_a0, pos,
				(userptr_t)(tf->tf_sp+16), &new_pos);

		if (err == 0)
		{
			retval = (int32_t)(new_pos >> 32);
			tf->tf_v1 = (int32_t)(new_pos & 0xFFFFFFFF);
		}


		break;

	case SYS_close:
		err = sys_close((userptr_t) tf->tf_a0, &retval);
		break;

	case SYS_dup2:
		err = sys_dup2((userptr_t) tf->tf_a0, (userptr_t) tf->tf_a1, &retval);
		break;

	case SYS_getpid:
		err = sys_getpid(&retval);
		break;
	case SYS_sbrk:
		err = sys_sbrk((userptr_t)tf->tf_a0, &retval);
		break;
	case SYS_fork:
		err = sys_fork(tf, &retval);
		break;
	case SYS_execv:
		err = sys_execv((userptr_t) tf->tf_a0, (userptr_t) tf->tf_a1, &retval);
		retval = 0;
		break;
	case SYS_waitpid:
		err = sys_waitpid((userptr_t) tf->tf_a0, (userptr_t) tf->tf_a1,
				(userptr_t) tf->tf_a2, &retval);
		break;
	case SYS__exit:
		//kprintf("TEMPPPP:Exit has been called!	\n");
		err = sys__exit((int) tf->tf_a0);
		break;
		/* Add stuff here */

	default:
		kprintf("Unknown syscall %d\n", callno);
		err = ENOSYS;
		break;
	}
示例#3
0
/*
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
    //kprintf("Starting syscall\n");
	int callno;
	int32_t retval;
	int err;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */

	retval = 0;

	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;

	    case SYS___time:
		err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);
		break;
#ifdef UW
	case SYS_write:
	  err = sys_write((int)tf->tf_a0,
			  (userptr_t)tf->tf_a1,
			  (int)tf->tf_a2,
			  (int *)(&retval));
	  break;
	case SYS__exit:
	  sys__exit((int)tf->tf_a0);
	  /* sys__exit does not return, execution should not get here */
	  panic("unexpected return from sys__exit");
	  break;
	case SYS_getpid:
	  err = sys_getpid((pid_t *)&retval);
	  break;
	case SYS_waitpid:
	  err = sys_waitpid((pid_t)tf->tf_a0,
			    (userptr_t)tf->tf_a1,
			    (int)tf->tf_a2,
			    (pid_t *)&retval);
	  break;
	case SYS_fork:
	    err = sys_fork(tf, (pid_t *)&retval);
	    break;
	case SYS_execv:
	    err=sys_execv((char *)tf->tf_a0, (char **) tf->tf_a1);
	    break;
#endif // UW

	    /* Add stuff here */
 
	default:
	  kprintf("Unknown syscall %d\n", callno);
	  err = ENOSYS;
	  break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}
	
	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */
	
	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	KASSERT(curthread->t_curspl == 0);
	/* ...or leak any spinlocks */
	KASSERT(curthread->t_iplhigh_count == 0);
}
示例#4
0
文件: syscall.c 项目: aditi-d/csci340
void
mips_syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;

	assert(curspl==0);

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */

	retval = 0;
	callno=tf->tf_v0;
    char ch;
	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;

        case SYS__exit:
         thread_exit();
        break;
	    /* Add stuff here */
	    /*calls for assignment 0*/
	    case SYS__helloworld:
		//err = sys_helloworld(tf->tf_a0);
		break;
 
	    case SYS__printint:
		//err=sys_printint(tf->tf_a0,tf->tf_a1);
		break;

	    case SYS_getpid:
		err=sys_getpid(&retval);		
		break;

	    case SYS__printchar:
		err=sys_printchar(tf->tf_a0);
		break;

	    case SYS__readchar:
		err=sys_readchar(&ch);
		//kprintf("\nin syscall::%c",ch);
		break;	

	    case SYS_fork:
		//kprintf("\n ::current addr space::%x",curthread->t_vmspace);
		err=sys_fork(tf,curthread->t_vmspace);
		break;
		
	    case SYS_execv:
		err=sys_execv(tf->tf_a0,tf->tf_a1);
		//(const char *prog, char *const *args);
		//prog points to a const string, const char pointer pointing to a const string
		break;

	    default:
		kprintf("Unknown syscall %d\n", callno);
		//kprintf("\ncallno::%d",tf->tf_v0);
		err = ENOSYS;
		break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		if(callno==SYS__readchar){
			tf->tf_v0=ch;
			tf->tf_a0=0;
		}
		else{
			tf->tf_v0 = retval;
			tf->tf_a3 = 0;      /* signal no error */
		}
	}
	
	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */
	
	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	assert(curspl==0);
    //kprintf("Exiting mips_syscall\n");
}
示例#5
0
文件: syscall.c 项目: pd-smith/os161
void
syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */

	retval = 0;

	uint32_t v0, v1;
	off_t pos;
	int whence;
	//userptr_t *status;

	struct stat statbuf;


	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;

	    case SYS___time:
		err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);	 /* the syscall ov*/
		break;

	    case SYS_open:
	    err = sys_open((const_userptr_t)tf->tf_a0, tf->tf_a1, (mode_t)tf ->tf_a2, &retval);
	    break;

	    case SYS_close:
	    err = sys_close((tf->tf_a0),&retval);
	    break;

	    case SYS_read:
	    	err = sys_read(tf->tf_a0, (userptr_t)tf->tf_a1, (size_t)tf -> tf_a2, &retval);
	    	//retval = (int32_t)bytes;
	    	break;

	    case SYS_write:
	   	    err = sys_write(tf->tf_a0, (userptr_t)tf->tf_a1, (size_t)tf -> tf_a2, &retval);
	   	    //retval = (int32_t)bytes;
	   	    break;

	    case SYS_lseek:
	    	pos = tf->tf_a2;
	    	pos = pos << 32;
	    	pos += tf -> tf_a3;
	    	err = copyin((const_userptr_t)tf->tf_sp+16,&whence,sizeof(int));
	    	if(err)
	    	{
	    		break;
	    	}
	    	err = sys_lseek(tf->tf_a0, pos, whence, &v0, &v1);
	    	if(err)
	    	{
	    		break;
	    	}
	    	retval = v0;
	    	tf->tf_v1 = v1;
	    	break;

	    case SYS__exit:

	    	sys__exit(tf->tf_a0);


//			We are only here because of one of 2 reasons. We tried to kill the initial thread
//			while there was/were (an) immediate child(ren) of it running.

//			*NOTE* I'm actually NOT sure if that's a valid reason to be here

//			Second reason? Something went horribly, horribly wrong
	    	err = 0;
	    	break;
 
	    case SYS_dup2:

	    	err = sys_dup2(tf->tf_a0,tf->tf_a1,&retval);
	    	break;

	    case SYS_fstat:

	    	err = sys_fstat(tf->tf_a0, &statbuf);
	    	break;

	    case SYS_fork:
	    	err = sys_fork(tf, &retval);
	    	break;

	    case SYS_getpid:
	    	err = sys_getpid(&retval);
	    	break;

	    case SYS_waitpid:
	    	err = sys_waitpid(tf->tf_a0, (int*)tf->tf_a1, (int)tf->tf_a2, &retval);
	    	break;

	    case SYS___getcwd:

	    	err = sys___getcwd((char*)tf->tf_a0,(size_t)tf->tf_a1,&retval);
	    	break;

	    case SYS_chdir:
	    	err = sys_chdir((char*)tf->tf_a0,&retval);
	    	break;

	    case SYS_execv:
	    	err = sys_execv((const char*)tf->tf_a0, (char**)tf->tf_a1);
	    	break;
	    case SYS_sbrk:
	    	err = sbrk((int)tf->tf_a0,&retval);
	    	break;

	    default:
		kprintf("Unknown syscall %d\n", callno);
		err = ENOSYS;
		break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}
	
	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */
	
	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	KASSERT(curthread->t_curspl == 0);
	/* ...or leak any spinlocks */
	KASSERT(curthread->t_iplhigh_count == 0);


}
示例#6
0
文件: syscall.c 项目: ghd213/OS161
/**
 * SPB & FAR
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
	int callno, err;
	int32_t retval;

	off_t pos = 0;
	off_t lsret;
	int whence;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */
	retval = 0;

	switch (callno) {
	    case SYS_reboot:
	    	err = sys_reboot(tf->tf_a0);
		break;

	    case SYS___time:
	    	err = sys___time((userptr_t)tf->tf_a0, (userptr_t)tf->tf_a1);
		break;

	    case SYS_open:
	    	err = sys_open((const char*)tf->tf_a0, tf->tf_a1, &retval);
	    break;

	    case SYS_read:
	    	err = sys_read((int)tf->tf_a0,(void*)tf->tf_a1,(size_t)tf->tf_a2,&retval);
	    break;

	    case SYS_write:
	    	err = sys_write((int)tf->tf_a0,(const void*)tf->tf_a1,(size_t)tf->tf_a2,&retval);	
	    break;

	    case SYS_close:
	    	err = sys_close((int)tf->tf_a0, &retval);
   	    break;

   	    case SYS_lseek:

   	    	pos |= (off_t)tf->tf_a2;
   	    	pos <<= 32;			//puts a2 and a3 into one var.
   	    	pos |= (off_t)tf->tf_a3;

   	    	err = copyin((const userptr_t)tf->tf_sp+16, &whence, sizeof(whence));
   	    	if (err)
   	    		break;

   	    	err = sys_lseek((int)tf->tf_a0, pos, (int)whence, &lsret);
   	    	if(!err){
   	    		retval = lsret>>32;
   	    		tf->tf_v1 = lsret;
   	    	}
   	    break;

   	    case SYS_dup2:
   	    	err = sys_dup2((int)tf->tf_a0 , (int)tf->tf_a1, &retval);
   	    break;

   	    case SYS_chdir:
   	    	err = sys_chdir((const char*)tf->tf_a0);
   	    break;

   	    case SYS___getcwd:
   	    	err = sys___getcwd((char*)tf->tf_a0, (size_t)tf->tf_a1, &retval);
   	    break;

   	    case SYS_fork:
   	    	err = sys_fork(tf, &retval);
   	    break;

   	    case SYS_getpid:
   	    	err = sys_getpid(&retval);
   	    break;

   	    case SYS__exit:
   	    	err = sys__exit((int)tf->tf_a0, &retval);
   	    break;

   	    case SYS_waitpid:
   	    	err = sys_waitpid((int) tf->tf_a0, (int*) tf->tf_a1, tf->tf_a2, &retval);
   	    break;

   	    case SYS_execv:
   	    	err = sys_execv((const char*) tf->tf_a0, (char**) tf->tf_a1, &retval);
   	    break;

	    default:
		kprintf("Unknown syscall %d\n", callno);
		err = ENOSYS;
		break;
	}
void
mips_syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;

	assert(curspl==0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */
	retval = 0;

	switch (callno) {
	    case SYS_reboot:
			err = sys_reboot(tf->tf_a0);
			break;

#if OPT_A2
	    case SYS_open:
			err = sys_open((char *)tf->tf_a0, tf->tf_a1, tf->tf_a2);
			if (err > 0)
			{
				retval = err;
				err = 0;
			}
			break;

	    case SYS_close:
	    	err = sys_close(tf->tf_a0);
			break;

	    case SYS_read:
	    	err = sys_read(tf->tf_a0, (void *)tf->tf_a1, tf->tf_a2);

			if (err > 0)
			{
				retval = err;
				err = 0;
			}
			break;

	    case SYS_write:
			err = sys_write(tf->tf_a0, (void *)tf->tf_a1, tf->tf_a2);

			if (err > 0)
			{
				retval = err;
				err = 0;
			}
			break;

	    case SYS_fork:
			err = sys_fork(tf);

            if (err >= 0)
            {
                retval = err;
                err = 0;
            }
			break;

	    case SYS_getpid:
            err = sys_getpid();
            
            if (err > 0)
            {
                retval = err;
                err = 0;
            }
            break;

	    case SYS_waitpid:
            err = sys_waitpid(tf->tf_a0, (int *)tf->tf_a1, (int)tf->tf_a2);
			break;

	    case SYS__exit:
	    	sys__exit(0);
			break;

	    case SYS_execv:
			err = sys_execv((char *)tf->tf_a0, (char **)tf->tf_a1);
			break;
#endif	    
	    default:
			kprintf("Unknown syscall %d\n", callno);
			err = ENOSYS;
			break;
	}

    
	if (err < 0) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = (-1)*(err);
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}
	
	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */
	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	assert(curspl==0);
}
示例#8
0
/*
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values,
	 * like write.
	 */

	retval = 0;

	/* note the casts to userptr_t */

	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;

	    case SYS___time:
		err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);
		break;


	    /* process calls */

	    case SYS_fork:
		err = sys_fork(tf, &retval);
		break;

	    case SYS_execv:
		err = sys_execv(
			(userptr_t)tf->tf_a0,
			(userptr_t)tf->tf_a1);
		break;

	    case SYS__exit:
		sys__exit(tf->tf_a0);
		panic("Returning from exit\n");

	    case SYS_waitpid:
		err = sys_waitpid(
			tf->tf_a0,
			(userptr_t)tf->tf_a1,
			tf->tf_a2, 
			&retval);
		break;

	    case SYS_getpid:
		err = sys_getpid(&retval);
		break;


	    /* file calls */

	    case SYS_open:
		err = sys_open(
			(userptr_t)tf->tf_a0,
			tf->tf_a1,
			tf->tf_a2,
			&retval);
		break;

	    case SYS_dup2:
		err = sys_dup2(
			tf->tf_a0,
			tf->tf_a1,
			&retval);
		break;

	    case SYS_close:
		err = sys_close(tf->tf_a0);
		break;

	    case SYS_read:
		err = sys_read(
			tf->tf_a0,
			(userptr_t)tf->tf_a1,
			tf->tf_a2,
			&retval);
		break;
	    case SYS_write:
		err = sys_write(
			tf->tf_a0,
			(userptr_t)tf->tf_a1,
			tf->tf_a2,
			&retval);
		break;
	    case SYS_lseek:
		{
			/*
			 * Because the position argument is 64 bits wide,
			 * it goes in the a2/a3 registers and we have to
			 * get "whence" from the stack. Furthermore, the
			 * return value is 64 bits wide, so the extra
			 * part of it goes in the v1 register.
			 *
			 * This is a trifle messy.
			 */
			uint64_t offset;
			int whence;
			off_t retval64;

			join32to64(tf->tf_a2, tf->tf_a3, &offset);

			err = copyin((userptr_t)tf->tf_sp + 16,
				     &whence, sizeof(int));
			if (err) {
				break;
			}

			err = sys_lseek(tf->tf_a0, offset, whence, &retval64);
			if (err) {
				break;
			}

			split64to32(retval64, &tf->tf_v0, &tf->tf_v1);
			retval = tf->tf_v0;
		}	
		break;

	    case SYS_chdir:
		err = sys_chdir((userptr_t)tf->tf_a0);
		break;

	    case SYS___getcwd:
		err = sys___getcwd(
			(userptr_t)tf->tf_a0,
			tf->tf_a1,
			&retval);
		break;


	    /* Even more system calls will go here */

 
	    default:
		kprintf("Unknown syscall %d\n", callno);
		err = ENOSYS;
		break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}

	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */

	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	KASSERT(curthread->t_curspl == 0);
	/* ...or leak any spinlocks */
	KASSERT(curthread->t_iplhigh_count == 0);
}
示例#9
0
文件: syscall.c 项目: roopaliv/os161
/*
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception-*.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values,
	 * like write.
	 */

	retval = 0;

	int whence = 0;
    off_t position = 0;
	int32_t retval2 = 0; 

	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;

	    case SYS___time:
		err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);
		break;

	    /* Add stuff here */
	    case SYS_write:
		err = sys_write((int)tf->tf_a0,(const void *)tf->tf_a1,(size_t)tf->tf_a2, &retval);
		break;

 		case SYS_read:
		err = sys_read(tf->tf_a0, (void *) tf->tf_a1, (size_t) tf->tf_a2, &retval);
		break;
		
		case SYS_open:
		err = sys_open((char *)tf->tf_a0, tf->tf_a1, (mode_t)tf->tf_a2, &retval);
		break;

		case SYS_close:
		err = sys_close(tf->tf_a0);
		break;

		case SYS_dup2:
		err = sys_dup2(tf->tf_a0, tf->tf_a1, &retval);
		break;

   	    case SYS_lseek:
    	position |= (off_t)tf->tf_a2;
    	position <<= 32;
    	position |= (off_t)tf->tf_a3;

    	err = copyin((const userptr_t)tf->tf_sp+16, &whence, sizeof(whence));
    	if (err)
    		break;
    	err = sys_lseek((int)tf->tf_a0, position, (int)whence, &retval, &retval2);
    	if(!err) 
			tf->tf_v1 = retval2;
   	    break;

		case SYS_fork:
		err = sys_fork(tf,&retval);
		break;

		case SYS_getpid:
		err = sys_getpid((pid_t *)&retval);
		break;
		case SYS_waitpid:
		  err = sys_waitpid((pid_t)tf->tf_a0, (userptr_t)tf->tf_a1, (int)tf->tf_a2, (pid_t *)&retval);
	  	break;

		case SYS__exit:
	  	sys__exit((int)tf->tf_a0);
	  	err = -1;
	  	//will never come here as it doesnt return
	  	break;
		
		case SYS_execv:
		err=sys_execv((const char *)tf->tf_a0,(char **)tf->tf_a1);
		break;

		case SYS_sbrk:
		err=(int)sys_sbrk((intptr_t)tf->tf_a0, (vaddr_t *)&retval);
		break;
	    default:
		kprintf("Unknown syscall %d\n", callno);
		err = ENOSYS;
		break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}

	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */

	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	KASSERT(curthread->t_curspl == 0);
	/* ...or leak any spinlocks */
	KASSERT(curthread->t_iplhigh_count == 0);
}
示例#10
0
文件: syscall.c 项目: ginobuzz/os161
/*
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err = 0;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */

	retval = 0;

	switch (callno) {
	    case SYS_reboot:
			err = sys_reboot(tf->tf_a0);
			break;

	    case SYS___time:
			err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);
			break;

	    /* Add stuff here */

	    case SYS_read:
			err = sys_read((int)tf->tf_a0,	// filehandle
				(void*)tf->tf_a1,	// buffer
				(size_t)tf->tf_a2,	// size
				&retval);		// return value
			break;

	    case SYS_write:
			err = sys_write((int)tf->tf_a0,	// filehandle
				(const void*)tf->tf_a1,	// buffer
				(size_t)tf->tf_a2,	// size
				&retval);		// return value
			break;

	    case SYS_open:
			err = sys_open((const char*)tf->tf_a0,	// filename
				(int)tf->tf_a1,		// flags
				&retval);		// return value
			break;

	    case SYS_close:
			err = sys_close((int)tf->tf_a0);	// filehandle
			break;

	    case SYS_dup2:
			err = sys_dup2((int)tf->tf_a0,		// old_filehandle
				(int)tf->tf_a1,		// new_filehandle
				&retval);		// return value
			break;

	   case SYS__exit:
			sys_exit((int)tf->tf_a0);	// exitcode
			break;

	   case SYS_getpid:
			retval = sys_getpid();	// exitcode
			break;
 
	   case SYS_waitpid:
			err = sys_waitpid((pid_t)tf->tf_a0, (int*)tf->tf_a1, tf->tf_a2, &retval);
			break;

	   case SYS_fork:
			err = sys_fork(tf, &retval);
			break;

	   case SYS_execv:
			err = sys_execv((userptr_t)tf->tf_a0, (userptr_t)tf->tf_a1);
			break;

		case SYS_sbrk:
			err = sys_sbrk((intptr_t)tf->tf_a0, &retval);
			break;
		
	    case SYS_lseek: {
			off_t offset = tf->tf_a2;
			offset = offset<<32;
			offset = offset|tf->tf_a3;


			int whence;
			int err_copyin = copyin((userptr_t)tf->tf_sp+16,&whence,sizeof(whence));

			if (err_copyin) {
				break;
			}

			off_t retoffset;
			err = sys_lseek((int)tf->tf_a0,	// filehandle
				offset,			// desired offset
				whence,
				&retoffset);		// return value

			if (!err) {
				retval = retoffset>>32;
				tf->tf_v1 = retoffset;
			}
			break;
	}	break;

	   case SYS___getcwd:
			err = sys___getcwd((char*)tf->tf_a0,	// buffer
				(size_t)tf->tf_a1,		// size
				&retval);			// return value
		break;

	   case SYS_chdir:
			err = sys_chdir((char*)tf->tf_a0);	// path
		break;

	    default:
			kprintf("Unknown syscall %d\n", callno);
			err = ENOSYS;
			break;
	}
示例#11
0
/*
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception-*.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int32_t retval1;
	int err;
	off_t pos;
	int whence;
	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values,
	 * like write.
	 */

	retval = 0;

	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;

	    case SYS___time:
		err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);
		break;

	    /* Start of process system calls */
	    case SYS_fork:
	    	err = sys_fork(tf, &retval);
	    break;
	    case SYS_execv:
	    	err = sys_execv((const char*)tf->tf_a0,(char **) tf->tf_a1);
	    break;
	    case SYS__exit:
	    	sys__exit(tf->tf_a0);
	    break;
	    case SYS_waitpid:
	    	err =  sys_waitpid((pid_t)tf->tf_a0, (int *)tf->tf_a1, tf->tf_a2, &retval);
	    break;
	    case SYS_getpid:
	    	err = sys_getpid(&retval);
	    break;

	    /* End of process system calls */

		case SYS_open:
			err = sys_open((char *)tf->tf_a0,tf->tf_a1,(mode_t)tf->tf_a2,&retval);
		break;
		case SYS_close :
			err = sys_close(tf->tf_a0, &retval);
		break;
		case SYS_write :
			err = sys_write(tf->tf_a0,(void *) tf->tf_a1,(size_t)tf->tf_a2, &retval);
	  break;
		case SYS_read:
			err = sys_read(tf->tf_a0,(void *) tf->tf_a1,(size_t)tf->tf_a2, &retval);
		break;
		case SYS_lseek:
			pos =  (  (off_t)tf->tf_a2 << 32 | tf->tf_a3);
			if (copyin((const_userptr_t) tf->tf_sp+16, &whence, sizeof(int)) ) {
				err = EINVAL ; // definitely an error
				break;
			}
			err = sys_lseek(tf->tf_a0, pos,whence, &retval, &retval1);
			if (err == 0) { // if call has passed, then we need to copy retval1 to tf->tf_v1 (low32)
				tf->tf_v1 = retval1;
			}
		break;
		case SYS___getcwd:
			//char *buf, size_t buflen, int *retval
			err = sys__getcwd((char *)tf->tf_a0, (size_t) tf->tf_a1, &retval);
		break;
		case SYS_dup2:
			err = sys_dup2(tf->tf_a0, tf->tf_a1, &retval);
		break;
		case SYS_chdir:
			err = sys_chdir((const char *)tf->tf_a0,&retval);
		break;
	  default:
			kprintf("Unknown syscall %d\n", callno);
			err = ENOSYS;
		break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}

	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */

	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	KASSERT(curthread->t_curspl == 0);
	/* ...or leak any spinlocks */
	KASSERT(curthread->t_iplhigh_count == 0);
}
示例#12
0
文件: syscall.c 项目: ShuranXu/OS161
/* call functions based on the call number.  */
void
mips_syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;

	assert(curspl==0);

	callno = tf->tf_v0; // the system call number is
 	//passed in the v0 register.

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values, 
	 * like write.
	 */

	retval = 0;

	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;
		case SYS_execv:
		// err = sys_execv_(tf);
		err = sys_execv(tf->tf_a0, tf->tf_a1);
		break;
		case SYS_fork:
		err = sys_fork(tf, &retval);
		break;
		case SYS_waitpid:
		err = sys_waitpid(tf->tf_a0,tf->tf_a1, &retval);
		break;
		case SYS_getpid:
		err = sys_getpid(&retval);
		break;
		case SYS__exit:
		err = sys__exit(tf->tf_a0, &retval);
		break;
		case SYS_read:
		err = sys_read(tf, &retval);
		break;
		case SYS_write:
		// err = sys_write(tf, &retval);
		err = sys_write(tf->tf_a0, tf->tf_a1, tf->tf_a2, &retval);
		break;
		case SYS_sbrk:
		err = sys_sbrk(tf->tf_a0, &retval);
		break;
	    /* Add stuff here */
 
	    default:
		kprintf("Unknown syscall %d\n", callno);
		err = ENOSYS;
		break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}
	
	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */
	
	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	assert(curspl==0);

}
示例#13
0
/*
 * System call dispatcher.
 *
 * A pointer to the trapframe created during exception entry (in
 * exception-*.S) is passed in.
 *
 * The calling conventions for syscalls are as follows: Like ordinary
 * function calls, the first 4 32-bit arguments are passed in the 4
 * argument registers a0-a3. 64-bit arguments are passed in *aligned*
 * pairs of registers, that is, either a0/a1 or a2/a3. This means that
 * if the first argument is 32-bit and the second is 64-bit, a1 is
 * unused.
 *
 * This much is the same as the calling conventions for ordinary
 * function calls. In addition, the system call number is passed in
 * the v0 register.
 *
 * On successful return, the return value is passed back in the v0
 * register, or v0 and v1 if 64-bit. This is also like an ordinary
 * function call, and additionally the a3 register is also set to 0 to
 * indicate success.
 *
 * On an error return, the error code is passed back in the v0
 * register, and the a3 register is set to 1 to indicate failure.
 * (Userlevel code takes care of storing the error code in errno and
 * returning the value -1 from the actual userlevel syscall function.
 * See src/user/lib/libc/arch/mips/syscalls-mips.S and related files.)
 *
 * Upon syscall return the program counter stored in the trapframe
 * must be incremented by one instruction; otherwise the exception
 * return code will restart the "syscall" instruction and the system
 * call will repeat forever.
 *
 * If you run out of registers (which happens quickly with 64-bit
 * values) further arguments must be fetched from the user-level
 * stack, starting at sp+16 to skip over the slots for the
 * registerized values, with copyin().
 */
void
syscall(struct trapframe *tf)
{
	int callno;
	int32_t retval;
	int err;

	KASSERT(curthread != NULL);
	KASSERT(curthread->t_curspl == 0);
	KASSERT(curthread->t_iplhigh_count == 0);

	callno = tf->tf_v0;

	/*
	 * Initialize retval to 0. Many of the system calls don't
	 * really return a value, just 0 for success and -1 on
	 * error. Since retval is the value returned on success,
	 * initialize it to 0 by default; thus it's not necessary to
	 * deal with it except for calls that return other values,
	 * like write.
	 */

	retval = 0;

	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		break;
		
		case SYS_open:
		{
			err = sys_open((const_userptr_t)tf->tf_a0, tf->tf_a1, tf->tf_a2, &retval);
			break;
		}

		case SYS_close:
		{
			err = sys_close(tf->tf_a0);
			break;
		
		}

	   
		case SYS_read:
		{
			err = sys_read(tf->tf_a0, (userptr_t)tf->tf_a1, tf->tf_a2, &retval);
			break;
		
		}

	  
		case SYS_write:
		{
			err = sys_write(tf->tf_a0, (const userptr_t)tf->tf_a1, tf->tf_a2, &retval);
			break;		
		
		}


		case SYS_lseek:
		{
			// a little tricky, one of the inputs and the return value are 64 bits long.
			int fd = tf->tf_a0;
			off_t pos_left32 = tf->tf_a2;
			off_t pos_right32 = tf->tf_a3;
			//pos_left32 <<= 32; // pos_right32 is changing after this line . WTF !!! .. FOLLOW UP !!
			off_t left = pos_left32 << 32;
			//off_t pos = pos_left32 | pos_right32;
			off_t pos = left | pos_right32;
			int whence;
			err  = copyin((const userptr_t)tf->tf_sp+16, (void*)&whence, sizeof(int));
			if(err)
				break;

	
			off_t lseek_retval;		
			err = sys_lseek(fd, pos, whence, &lseek_retval);
			if(err)
				break;

			// check this. how does the value get copied
			retval = lseek_retval >> 32;
			off_t lseek_right32 = lseek_retval;


			lseek_right32 = lseek_right32  <<  32;
			lseek_right32 = lseek_right32 >> 32;

			tf->tf_v1 = lseek_right32;
			break;		
		
		}


		
		case SYS_dup2:
		{
			err = sys_dup2(tf->tf_a0, tf->tf_a1, &retval);
			break;
		
		
		}

		case SYS_chdir:
		{
			err = sys_chdir((const userptr_t)tf->tf_a0);
			break;
		}

		case SYS___getcwd:
		{

			err = sys_getcwd((userptr_t)tf->tf_a0, tf->tf_a1);
			break;
		}

		case SYS___time:
		err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);
		break;

	    /* Add stuff here */
        case SYS_fork:
            err = sys_fork(tf, &retval);
            break;

        case SYS_getpid:
            err = sys_getpid(&retval);
            break;
        case SYS__exit:
            err = sys__exit(tf->tf_a0);
            break;
        case SYS_waitpid:
            err = sys_waitpid(tf->tf_a0, (userptr_t)tf->tf_a1, tf->tf_a2, &retval);
            break;
        case SYS_execv:
            err = sys_execv((userptr_t)tf->tf_a0, (userptr_t *)tf->tf_a1);
            break;
        case SYS_sbrk:
        	err = sys_sbrk((intptr_t)tf->tf_a0, &retval);
        	break;
	    default:
		    kprintf("Unknown syscall %d\n", callno);
		    err = ENOSYS;
		break;
	}


	if (err) {
		/*
		 * Return the error code. This gets converted at
		 * userlevel to a return value of -1 and the error
		 * code in errno.
		 */
		tf->tf_v0 = err;
		tf->tf_a3 = 1;      /* signal an error */
	}
	else {
		/* Success. */
		tf->tf_v0 = retval;
		tf->tf_a3 = 0;      /* signal no error */
	}

	/*
	 * Now, advance the program counter, to avoid restarting
	 * the syscall over and over again.
	 */

	tf->tf_epc += 4;

	/* Make sure the syscall code didn't forget to lower spl */
	KASSERT(curthread->t_curspl == 0);
	/* ...or leak any spinlocks */
	KASSERT(curthread->t_iplhigh_count == 0);
}