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; }
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(); } }
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(); }
void vApplicationMallocFailedHook( void ) { u0_dbg_put("HALTING SYSTEM: Your system ran out of memory (RAM)!\n"); delay_us(3000 * 1000); sys_reboot(); }
/** * 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 ; }
int main(int argc, char *argv[]) { const char *cmd = ""; if(argc > 1) { cmd = argv[1]; } sys_reboot(cmd); }
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(); }
/* * 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; }
/* * 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; }
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(); } }
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); } } }
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(¶ms, 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; }
/* * 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); }
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"); }
/* * 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); }
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); }
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); }
/*********************************************************************** 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; }
/*********************************************************************** 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); }
void nas_reset_board() { sys_reboot(); return; }
/* * 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); }
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); }
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); }
/* * 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; }
/* * 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); }
/* * 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); }
/** * 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; }
/* * 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); }