示例#1
0
static int shutdown_process(void *__unused)
{
	static char *envp[] = { "HOME=/", "TERM=linux",
				"PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
	static char *poweroff_argv[] = { "/sbin/poweroff", NULL };

#ifdef CONFIG_XEN
	extern asmlinkage long sys_reboot(int magic1, int magic2,
					  unsigned int cmd, void *arg);
#endif

	if ((shutting_down == SHUTDOWN_POWEROFF) ||
	    (shutting_down == SHUTDOWN_HALT)) {
		if (call_usermodehelper("/sbin/poweroff", poweroff_argv,
					envp, 0) < 0) {
#ifdef CONFIG_XEN
			sys_reboot(LINUX_REBOOT_MAGIC1,
				   LINUX_REBOOT_MAGIC2,
				   LINUX_REBOOT_CMD_POWER_OFF,
				   NULL);
#endif /* CONFIG_XEN */
		}
	}

	shutting_down = SHUTDOWN_INVALID; /* could try again */

	return 0;
}
示例#2
0
void
// do_upgrade_cgi(char *url, FILE *stream)
do_upgrade_cgi(struct mime_handler *handler, char *url, webs_t streamm, char *query)	// jimmy,
								// https,
								// 8/6/2003
{
#ifndef ANTI_FLASH
	fprintf(stderr, "do post\n");
	if (upgrade_ret)
		do_ej(handler, "Fail_u_s.asp", stream, NULL);
	else
		do_ej(handler, "Success_u_s.asp", stream, NULL);
	fprintf(stderr, "websdone\n");

	websDone(stream, 200);
	fprintf(stderr, "reboot\n");

	/*
	 * Reboot if successful 
	 */
	if (upgrade_ret == 0) {
		sleep(5);
		sys_reboot();
	}
#else
	do_ej(handler, "Fail_u_s.asp", stream, NULL);
	websDone(stream, 200);
#endif
}
void geo_check_master_reset( void )
{
    // Read reset messages from master
    can_fullcan_msg_t *can_rst_msg_ptr = NULL;
    can_fullcan_msg_t can_rst_msg;
    rst_msg *geo_rst_msg;

    can_rst_msg_ptr = CAN_fullcan_get_entry_ptr(can_id_rst);

    bool status = CAN_fullcan_read_msg_copy(can_rst_msg_ptr, &can_rst_msg);

    if( !status )
        return;         // There is no reset message

    LE.off(GEO_CAN_ERR_LED);

    geo_rst_msg = (rst_msg *)&(can_rst_msg.data.bytes[0]);

    if( geo_rst_msg->reset_geo == RESET )
    {

        LOG_ERROR("ERROR!!! Received a reset request from master\n");
        sys_reboot();
    }
}
示例#4
0
文件: glxgear.c 项目: s1mme/ChiffOS
void main()
{
	unsigned char *data;
	allocDoubleBuffer_vbe();
	
	sys_VBEstart();
	SCREEN =sys_giveSCREEN();
	
    allocDoubleBuffer_vbe();
   	memset(SCREEN, 10, 1024*768*4);
   		
    OSMesaContext gl_ctx = OSMesaCreateContext(OSMESA_BGRA, NULL);
	if(!OSMesaMakeCurrent(gl_ctx, DOUBLEBUFFER_vbe, GL_UNSIGNED_BYTE, 1024,768))
		sys_reboot();
		
	OSMesaPixelStore(OSMESA_Y_UP, 0);
	reshape(1024,768);
	
	init();
	
	int i;
	for(i = 0; i < 20000; i++)
	{
		angle += 6;
		draw();
		SwapBuffers_vbe();
	}
	fps(); 
}
示例#5
0
void vApplicationMallocFailedHook( void )
{
    u0_dbg_put("HALTING SYSTEM: Your system ran out of memory (RAM)!\n");

    delay_us(3000 * 1000);
    sys_reboot();
}
示例#6
0
/**
 * This is called from the HardFault_HandlerAsm with a pointer the Fault stack as the parameter.
 * We can then read the values from the stack and place them into local variables for ease of reading.
 * We then read the various Fault Status and Address Registers to help decode cause of the fault.
 * The function ends with a BKPT instruction to force control back into the debugger
 */
void isr_hard_fault_handler(unsigned long *hardfault_args)
{
    volatile unsigned int stacked_r0 ;
    volatile unsigned int stacked_r1 ;
    volatile unsigned int stacked_r2 ;
    volatile unsigned int stacked_r3 ;
    volatile unsigned int stacked_r12 ;
    volatile unsigned int stacked_lr ;
    volatile unsigned int stacked_pc ;
    volatile unsigned int stacked_psr ;

    stacked_r0 = ((unsigned long)hardfault_args[0]) ;
    stacked_r1 = ((unsigned long)hardfault_args[1]) ;
    stacked_r2 = ((unsigned long)hardfault_args[2]) ;
    stacked_r3 = ((unsigned long)hardfault_args[3]) ;
    stacked_r12 = ((unsigned long)hardfault_args[4]) ;
    stacked_lr = ((unsigned long)hardfault_args[5]) ;
    stacked_pc = ((unsigned long)hardfault_args[6]) ;
    stacked_psr = ((unsigned long)hardfault_args[7]) ;

    FAULT_EXISTS = FAULT_PRESENT_VAL;
    FAULT_PC = stacked_pc;
    FAULT_LR = stacked_lr - 1;
    FAULT_PSR = stacked_psr;

    sys_reboot();

    /* Prevent compiler warnings */
    (void) stacked_r0 ;
    (void) stacked_r1 ;
    (void) stacked_r2 ;
    (void) stacked_r3 ;
    (void) stacked_r12 ;
}
示例#7
0
int main(int argc, char *argv[])
{
  const char *cmd = "";
  if(argc > 1) {
    cmd = argv[1];
  }
  sys_reboot(cmd);

}
示例#8
0
void vApplicationStackOverflowHook( TaskHandle_t *pxTask, char *pcTaskName )
{
    u0_dbg_put("HALTING SYSTEM: Stack overflow by task: ");
    u0_dbg_put((char*)pcTaskName);
    u0_dbg_put("\nTry increasing stack memory of this task.\n");

	delay_us(3000 * 1000);
	sys_reboot();
}
示例#9
0
文件: menu.c 项目: krnprdp/os161-src
/*
 * Command for shutting down.
 */
static
int cmd_quit(int nargs, char **args) {
	(void) nargs;
	(void) args;

	vfs_sync();
	sys_reboot(RB_POWEROFF);
	thread_exit();
	return 0;
}
示例#10
0
/*
 * Command for shutting down.
 */
static
int
cmd_quit(int nargs, char **args)
{
	(void)nargs;
	(void)args;

	vfs_sync();
	sys_reboot(RB_POWEROFF);
	#if OPT_A2
	thread_exit(0);
	#endif /* OPT_A2 */
	return 0;
}
示例#11
0
void scheduler_start(bool register_internal_tlm)
{
    /* If no failure, start the FreeRTOS scheduler */
    if (!scheduler_init_all(register_internal_tlm)) {
        puts("Starting scheduler ...");
        vTaskStartScheduler();

        // vTaskStartScheduler() should not return
        puts("ERROR: Someone killed the scheduler");
    }
    else {
        puts("ERROR: Refusing to start OS scheduler due to error(s)");
        delay_ms(3000);
        sys_reboot();
    }
}
示例#12
0
static void wdog_cmsdk_apb_isr(void)
{
	/*
	 * Check if the watchdog was the reason of the NMI interrupt
	 * and if not, exit immediately
	 */
	if (!wdog_cmsdk_apb_has_fired()) {
		printk("NMI received! Rebooting...\n");
		/* In ARM implementation sys_reboot ignores the parameter */
		sys_reboot(0);
	} else {
		if (user_cb != NULL) {
			user_cb(wdog_r, 0);
		}
	}
}
示例#13
0
void start_sysinit(void)
{
	char buf[PATH_MAX];
	struct stat tmp_stat;
	time_t tm = 0;

	cprintf("sysinit() proc\n");
	/*
	 * /proc 
	 */

	mknod("/dev/mmc",S_IFBLK|0660,makedev(126,0));
	mknod("/dev/mmc0",S_IFBLK|0660,makedev(126,1));
	mknod("/dev/mmc1",S_IFBLK|0660,makedev(126,2));
	mknod("/dev/mmc2",S_IFBLK|0660,makedev(126,3));
	mknod("/dev/mmc3",S_IFBLK|0660,makedev(126,4));


	mkdir("/dev/mtd",0700);


	mknod("/dev/mtd/0",S_IFCHR|0644,makedev(90,0));
	mknod("/dev/mtd/0ro",S_IFCHR|0644,makedev(90,1));
	mknod("/dev/mtd/1",S_IFCHR|0644,makedev(90,2));
	mknod("/dev/mtd/1ro",S_IFCHR|0644,makedev(90,3));
	mknod("/dev/mtd/2",S_IFCHR|0644,makedev(90,4));
	mknod("/dev/mtd/2ro",S_IFCHR|0644,makedev(90,5));
	mknod("/dev/mtd/3",S_IFCHR|0644,makedev(90,6));
	mknod("/dev/mtd/3ro",S_IFCHR|0644,makedev(90,7));
	mknod("/dev/mtd/4",S_IFCHR|0644,makedev(90,8));
	mknod("/dev/mtd/4ro",S_IFCHR|0644,makedev(90,9));


	cprintf("sysinit() setup console\n");
	/*
	 * Setup console 
	 */

	cprintf("sysinit() klogctl\n");
	klogctl(8, NULL, atoi(nvram_safe_get("console_loglevel")));
	cprintf("sysinit() get router\n");

	/*
	 * load some netfilter stuff 
	 */
#ifndef HAVE_WP54G
#ifndef HAVE_NP28G
	insmod("nf_conntrack_ftp");
	insmod("nf_conntrack_irc");
	insmod("nf_conntrack_netbios_ns");
	insmod("nf_conntrack_pptp");
	insmod("nf_conntrack_proto_gre");
	insmod("nf_conntrack_proto_udplite");
	insmod("nf_conntrack_tftp");
	insmod("xt_CLASSIFY");
	insmod("xt_MARK");
	insmod("xt_TCPMSS");
	insmod("xt_length");
	insmod("xt_limit");
	insmod("xt_multiport");
	insmod("xt_pkttype");
	insmod("xt_state");
	insmod("xt_tcpmss");
	insmod("xt_u32");

	insmod("iptable_filter");
	insmod("iptable_mangle");
	insmod("nf_nat");
	insmod("iptable_nat");
	insmod("nf_nat_ftp");
	insmod("nf_nat_irc");
	insmod("nf_nat_pptp");
	insmod("nf_nat_proto_gre");
	insmod("nf_nat_tftp");
	insmod("ipt_LOG");
	insmod("ipt_MASQUERADE");
	insmod("ipt_REDIRECT");
	insmod("ipt_REJECT");
	insmod("ipt_ULOG");
	insmod("ipt_TRIGGER");
	insmod("ipt_iprange");
	insmod("ipt_ipp2p");
	insmod("ipt_layer7");
	insmod("ipt_webstr");

	// ppp drivers

	insmod("slhc");
	insmod("ppp_generic");
	insmod("ppp_async");
	insmod("ppp_synctty");
	insmod("ppp_mppe_mppc");
	insmod("pppox");
	insmod("pppoe");
#endif
#endif
	insmod("adm5120_wdt");
	insmod("adm5120sw");

	if (getRouterBrand() != ROUTER_BOARD_WP54G
	    && getRouterBrand() != ROUTER_BOARD_NP28G) {

		unsigned char mac[6];
		char eabuf[32];
		char mtdpath[32];

		memset(mac, 0, 6);
		FILE *fp;
		int mtd = getMTD("boot");
		int foundmac = 0;

		sprintf(mtdpath, "/dev/mtdblock/%d", mtd);
		fp = fopen(mtdpath, "rb");
		if (fp != NULL) {
			//check for osbridge
			fseek(fp, 0xff90 - 2, SEEK_SET);
			unsigned char os[32];

			fread(os, 32, 1, fp);
			if (strcmp(os, "OSBRiDGE 5XLi") == 0) {
				foundmac = 1;
				fprintf(stderr, "found OSBRiDGE 5XLi\n");
				nvram_set("DD_BOARD", "OSBRiDGE 5LXi");
				fseek(fp, 0xff82, SEEK_SET);
				fread(os, 12, 1, fp);
				int i;
				int count = 0;

				if (memcmp(os, "0050fc488130", 12) == 0) {
					//force change mac
					fclose(fp);
					start_change_mac();
					sys_reboot();

				}
				for (i = 0; i < 6; i++) {
					mac[i] = toNumeric(os[count++]) * 16;
					mac[i] |= toNumeric(os[count++]);
				}
				struct ifreq ifr;
				int s;

				if ((s =
				     socket(AF_INET, SOCK_RAW, IPPROTO_RAW))) {
					strncpy(ifr.ifr_name, "eth0", IFNAMSIZ);
					ioctl(s, SIOCGIFHWADDR, &ifr);
					memcpy((unsigned char *)ifr.ifr_hwaddr.
					       sa_data, mac, 6);
					ioctl(s, SIOCSIFHWADDR, &ifr);
					close(s);
				}
				if ((s =
				     socket(AF_INET, SOCK_RAW, IPPROTO_RAW))) {
					strncpy(ifr.ifr_name, "eth0", IFNAMSIZ);
					ioctl(s, SIOCGIFHWADDR, &ifr);
					nvram_set("et0macaddr_safe",
						  ether_etoa((unsigned char *)
							     ifr.
							     ifr_hwaddr.sa_data,
							     eabuf));
					nvram_set("et0macaddr",
						  ether_etoa((unsigned char *)
							     ifr.
							     ifr_hwaddr.sa_data,
							     eabuf));
					close(s);
				}
			}
			if (!foundmac) {
				int s = searchfor(fp, "mgmc", 0x20000 - 5);

				if (s != -1) {
					fread(mac, 6, 1, fp);
					struct ifreq ifr;
					int s;

					foundmac = 1;
					fprintf(stderr, "found Tonze-AP120\n");
					if ((s =
					     socket(AF_INET, SOCK_RAW,
						    IPPROTO_RAW))) {
						strncpy(ifr.ifr_name, "eth0",
							IFNAMSIZ);
						ioctl(s, SIOCGIFHWADDR, &ifr);
						memcpy((unsigned char *)
						       ifr.ifr_hwaddr.sa_data,
						       mac, 6);
						ioctl(s, SIOCSIFHWADDR, &ifr);
						close(s);
					}
					if ((s =
					     socket(AF_INET, SOCK_RAW,
						    IPPROTO_RAW))) {
						strncpy(ifr.ifr_name, "eth0",
							IFNAMSIZ);
						ioctl(s, SIOCGIFHWADDR, &ifr);
						nvram_set("et0macaddr_safe",
							  ether_etoa((unsigned
								      char *)
								     ifr.ifr_hwaddr.sa_data, eabuf));
						nvram_set("et0macaddr",
							  ether_etoa((unsigned
								      char *)
								     ifr.ifr_hwaddr.sa_data, eabuf));
						close(s);
					}
				}
			}

			if (foundmac == 0) {
				fprintf(stderr,
					"error: no valid mac address found for eth0\n");
			}
			fclose(fp);
		}
	} else {
		struct mylo_board_params params;
		char mtdpath[32];
		FILE *fp;
		int mtd = getMTD("boot");
		int foundmac = 0;
		struct ifreq ifr;
		int s;
		char eabuf[32];

		sprintf(mtdpath, "/dev/mtdblock/%d", mtd);
		fp = fopen(mtdpath, "rb");
		if (fp != NULL) {
			fseek(fp, 0xf800, SEEK_SET);
			fread(&params, sizeof(params), 1, fp);
			fclose(fp);
			if (params.magic == 0x20021103) {
				fprintf(stderr, "Found compex board magic!\n");
				if ((s =
				     socket(AF_INET, SOCK_RAW, IPPROTO_RAW))) {
					strncpy(ifr.ifr_name, "eth0", IFNAMSIZ);
					ioctl(s, SIOCGIFHWADDR, &ifr);
					memcpy((unsigned char *)ifr.ifr_hwaddr.
					       sa_data, params.addr[0].mac, 6);
					ioctl(s, SIOCSIFHWADDR, &ifr);
					close(s);
				}
				if ((s =
				     socket(AF_INET, SOCK_RAW, IPPROTO_RAW))) {
					strncpy(ifr.ifr_name, "eth1", IFNAMSIZ);
					ioctl(s, SIOCGIFHWADDR, &ifr);
					memcpy((unsigned char *)ifr.ifr_hwaddr.
					       sa_data, params.addr[1].mac, 6);
					ioctl(s, SIOCSIFHWADDR, &ifr);
					close(s);
				}
				if ((s =
				     socket(AF_INET, SOCK_RAW, IPPROTO_RAW))) {
					strncpy(ifr.ifr_name, "eth0", IFNAMSIZ);
					ioctl(s, SIOCGIFHWADDR, &ifr);
					nvram_set("et0macaddr_safe",
						  ether_etoa((unsigned char *)
							     ifr.
							     ifr_hwaddr.sa_data,
							     eabuf));
					nvram_set("et0macaddr",
						  ether_etoa((unsigned char *)
							     ifr.
							     ifr_hwaddr.sa_data,
							     eabuf));
					close(s);
				}

			}
		}
	}
	/*
	 * network drivers 
	 */
	detect_wireless_devices();

	if (!nvram_match("disable_watchdog", "1"))
		eval("watchdog");

#ifdef HAVE_WP54G
	writeproc("/proc/sys/dev/wifi0/ledpin","6");
	writeproc("/proc/sys/dev/wifi0/softled","1");
#endif
	/*
	 * Set a sane date 
	 */

	stime(&tm);
	nvram_set("wl0_ifname", "ath0");

	return;
}
示例#14
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);
}
示例#15
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");
}
示例#16
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___time:
		    err = sys___time((userptr_t)tf->tf_a0,
				     (userptr_t)tf->tf_a1);


		    break;

            /* ASST2: These implementations of read and write only work for
             * console I/O (stdin, stdout and stderr file descriptors)
             */
            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;

            /* process calls */
            case SYS__exit:
            	thread_exit(_MKWAIT_EXIT(tf->tf_a0));
            	panic("Returning from exit\n");
	
            case SYS_fork:
            	err = sys_fork(tf, &retval);
            	break;

            /* ASST2 - You need to fill in the code for each of these cases */
            case SYS_getpid:
            	err = sys_getpid(&retval);
                break;

            case SYS_waitpid:
                if(sys_waitpid(tf->tf_a0, \
                		(userptr_t)tf->tf_a1, tf->tf_a2, &retval) == -1)
                {
                  err=retval;
                }
                else{
                err=0;
                }
                break;

            case SYS_kill:
            	err = sys_kill(tf->tf_a0, tf->tf_a1);
            	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);
}
示例#17
0
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;
 	DEBUG(DB_SYSCALL, "The syscall number is %d\n", callno);

	switch (callno) {
	    case SYS_reboot:
		err = sys_reboot(tf->tf_a0);
		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);
}
示例#18
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);


}
示例#19
0
/***********************************************************************
F* Function:     static int process_mon_chains(void) P*A*Z*
 *
P* Parameters:   none
P*
P* Returnvalue:  int
P*                - 0 if the function returns at all
 *
Z* Intention:    This is the core function of the chain functionality.
Z*               The list with the monitored chain is processed and
Z*               expired entries handled appropriately by stepping up
Z*               the escalation ladder.  The escalation actions are
Z*               triggered from here.
 *
D* Design:       [email protected]
C* Coding:       [email protected]
V* Verification: [email protected]
 ***********************************************************************/
static int process_mon_chains(void)
{
	struct list_head *ptr;
	monitored_chain_t *entry;
	int sig;

	spin_lock(&mon_lock);

	for (ptr = mon_list.next; ptr != &mon_list; ptr = ptr->next) {
		entry = list_entry(ptr, monitored_chain_t, list);
		if (time_after_eq(jiffies, entry->expires)) {
			debugk("%s: WD monitor expired for id %d\n",
				__FUNCTION__, entry->chainid);
			switch (entry->action[entry->escalation]) {
			case WD_ACTION_SIGNAL:
				debugk("WD: sending user signal for key "
					"%d...\n", entry->chainid);
				sig = (entry->signal) ? entry->signal : SIGTERM;
				if (entry->pid)
					kill_proc_info(sig, SEND_SIG_PRIV, entry->pid);
				break;
			case WD_ACTION_KILL:
				debugk("WD: sending KILL signal for key "
					"%d...\n", entry->chainid);
				if (entry->pid)
					kill_proc_info(SIGKILL, SEND_SIG_PRIV, entry->pid);
				break;
			case WD_ACTION_REBOOT:
				spin_unlock(&mon_lock);
				wd_unregister_mon_chain(entry->chainid);
				printk("WD: Rebooting system for key "
					"%d...\n", entry->chainid);
				flush_cache_all();
				/*
				 * XXX This is not safe to call in interrupt
				 * context.
				 */
				sys_reboot(LINUX_REBOOT_MAGIC1,
					LINUX_REBOOT_MAGIC2,
					LINUX_REBOOT_CMD_RESTART,
					NULL);
				break;
			case WD_ACTION_RESET:
				printk("WD: Resetting system for key "
					"%d...\n", entry->chainid);
				BUG_ON(wd_hw_functions.wd_machine_restart
					== NULL);
				wd_hw_functions.wd_machine_restart();
				break;

			default:
				debugk("WD: undefined action %d\n",
					entry->action[entry->escalation]);
				break;
			}
			entry->escalation++;
			entry->expires = jiffies + HZ * 
				entry->timer_count[entry->escalation];
			list_del(&entry->list);
			insert_mon_chain(entry);
		} else
			/* The list is sorted, so we can stop here */
			break;
	}

	spin_unlock(&mon_lock);

	return 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;


	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;
	}
示例#21
0
/***********************************************************************
F* Function:     static int process_mon_chains(void) P*A*Z*
 *
P* Parameters:   none
P*
P* Returnvalue:  int
P*                - 0 if the function returns at all
 *
Z* Intention:    This is the core function of the chain functionality.
Z*               The list with the monitored chain is processed and
Z*               expired entries handled appropriately by stepping up
Z*               the escalation ladder.  The escalation actions are
Z*               triggered from here.
 *
D* Design:       [email protected]
C* Coding:       [email protected]
V* Verification: [email protected]
 ***********************************************************************/
static int process_mon_chains(void)
{
	struct list_head *ptr;
	monitored_chain_t *entry;
	int sig;

	spin_lock(&mon_lock);

	for (ptr=mon_list.next; ptr!=&mon_list; ptr=ptr->next) {
		entry=list_entry(ptr, monitored_chain_t, list);
		if (entry->expires<=jiffies) {
			debugk("%s: WDT8xx monitor expired for id %d\n", __FUNCTION__, entry->chainid);
			switch (entry->action[entry->escalation]) {
			case WDT_MPC8XX_ACTION_SIGNAL:
				debugk("WDT_8xx: sending user signal for key %d...\n", entry->chainid);
				sig=(entry->signal)?entry->signal:SIGTERM;
				if (entry->pid)
					kill_proc(entry->pid, sig, 1);
				break;

			case WDT_MPC8XX_ACTION_KILL:
				debugk("WDT_8xx: sending KILL signal for key %d...\n", entry->chainid);
				if (entry->pid)
					kill_proc(entry->pid, SIGKILL, 1);
				break;

			case WDT_MPC8XX_ACTION_REBOOT:
				spin_unlock(&mon_lock);
				wdt_mpc8xx_unregister_mon_chain(entry->chainid);
				printk("WDT_8xx: Rebooting system for key %d...\n", entry->chainid);
				sync();
				sys_reboot(LINUX_REBOOT_MAGIC1,
					   LINUX_REBOOT_MAGIC2,
					   LINUX_REBOOT_CMD_RESTART, NULL);
				break;

			case WDT_MPC8XX_ACTION_RESET:
				printk("WDT_8xx: Resetting system for key %d...\n", entry->chainid);
#ifdef CONFIG_8xx
				m8xx_restart (NULL);
#else
				machine_restart (NULL);
#endif
				break;
				
			default:
				debugk("WDT_8xx: undefined action %d\n", entry->action[entry->escalation]);
				break;
			}
			entry->escalation++;
			entry->expires=jiffies + HZ * 
				entry->timer_count[entry->escalation];
			list_del(&entry->list);
			insert_mon_chain(entry);
		} else
			/* The list is sorted, so we can stop here */
			break;
	}
			
	spin_unlock(&mon_lock);

	return(0);
}
示例#22
0
void
nas_reset_board()
{
	sys_reboot();
	return;
}
示例#23
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(void *trapframe, unsigned long junk)
{
  curproc->rt = (curproc->rt == BACKGROUND_U ?  BACKGROUND_K : INTERACTIVE_K);
  (void)junk;
  struct trapframe *tf = (struct trapframe*)trapframe;
  
  if(!curproc->context)
    curproc->context = kmalloc(sizeof(struct trapframe));
  
  memcpy(curproc->context, tf, sizeof(struct trapframe));
  
  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;
    
    /* Add stuff here */
    
  case SYS__exit:
    _exit((int)tf->tf_a0);
    break;
    
  case SYS_chdir:
    err = chdir((const char*)tf->tf_a0);
    break;

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

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

  case SYS_fork:
    err = fork(&retval);
    break;

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

  case SYS_getpid:
    err = getpid(&retval);//always return 0
    break;

  case SYS_lseek:
    err = lseek((int)tf->tf_a0,
		(off_t)(tf->tf_a1 | tf->tf_a2),
		(int)tf->tf_a3,
		(off_t*)&retval);
    break;

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

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

  case SYS_write:
    err = write((int)tf->tf_a0,
		(userptr_t)tf->tf_a1,
		(size_t)tf->tf_a2,
		&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);
	curproc->rt = (curproc->rt == BACKGROUND_K ?  BACKGROUND_U : INTERACTIVE_U);
}
示例#24
0
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;

		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_fork:
		err = sys_fork(tf, &retval);
		break;

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

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

		case SYS__exit:
		sys_exit(tf->tf_a0);
		break;
	    /* Add stuff here */

	    // case SYS_execv:
	    // sys_execv((char *) tf->tf_a0, (char **) tf->tf_a1, (int*) tf->tf_a2);
	    // 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 */
	}
		// kprintf("Here\/**/n");
	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);
}
示例#25
0
文件: syscall.c 项目: Hle14/ASST2
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;
		
	    case SYS_getpid:
			retval = ((int32_t)sys_getpid());
			err=retval;
			break;
			
		case SYS_waitpid:
			//just passing the the first arg from users waitpid
			err = (sys_waitpid(tf->tf_a0,&retval,0));
			break;
		
		case SYS__exit:
		
			retval = ((int32_t)sys__exit());
			err=retval;
			break;
			
		case SYS_fork:
			//http://jhshi.me/2012/03/21/os161-how-to-add-a-system-call/
			err = ((int32_t)sys_fork(tf));
			break;
		case SYS_execv:
			break;

		case SYS_read:
			//err = ((int32_t)sys_read(tf->tf_a0,(userptr_t)tf->tf_a1,tf->tf_a2)); //original
			err = ((int32_t)sys_read(tf->tf_a0,(char*)tf->tf_a1,tf->tf_a2));
			break;
		case SYS_write:
			err = ((int32_t)sys_write(tf->tf_a0,(char*)tf->tf_a1,tf->tf_a2));
			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 */
	assert(curspl==0);
}
示例#26
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;
	}
示例#27
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);
}
示例#28
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___time:
		err = sys___time((userptr_t)tf->tf_a0,
				 (userptr_t)tf->tf_a1);
		break;
        //F*****G A2
        case SYS_write:
           err=write(tf->tf_a0,(void*)tf->tf_a1,tf->tf_a2);
         break;
	    /* Add stuff here */
  	    case SYS_open:
  	      break;
  	     case SYS_close:
  	     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);
}
示例#29
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;
	}
示例#30
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);
}