// Dispatches to the correct kernel function, passing the arguments. int64_t syscall(uint64_t syscallno, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. // panic("syscall not implemented"); switch (syscallno) { case SYS_cputs: sys_cputs((const char *)a1, (size_t)a2); return 0; case SYS_cgetc: return sys_cgetc(); case SYS_getenvid: return sys_getenvid(); case SYS_env_destroy: return sys_env_destroy(a1); case SYS_yield: sys_yield(); return 0; case SYS_page_alloc: return sys_page_alloc((envid_t)a1, (void *)a2,(int)a3); case SYS_page_map: return sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5); case SYS_page_unmap: return sys_page_unmap((envid_t)a1, (void *)a2); case SYS_exofork: return sys_exofork(); case SYS_env_set_status: return sys_env_set_status((envid_t)a1, a2); case SYS_env_set_pgfault_upcall: return sys_env_set_pgfault_upcall((envid_t)a1,(void *)a2); case SYS_ipc_try_send: return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, a4); case SYS_ipc_recv: return sys_ipc_recv((void *)a1); case SYS_env_set_trapframe: return sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2); case SYS_time_msec: return sys_time_msec(); case SYS_packet_transmit: return sys_packet_transmit((char*)a1,(size_t)a2); case SYS_packet_receive: return sys_packet_receive((char *)a1); //lab 7 code from here case SYS_insmod: return sys_insmod((char *)a1, (char *)a2,(char *)a3); case SYS_rmmod: return sys_rmmod((char *)a1); case SYS_lsmod: return sys_lsmod(); case SYS_depmod: return sys_depmod((char *)a1); //lab7 code ends here default: return -E_NO_SYS; } }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. curenv->env_syscalls++; switch(syscallno){ case SYS_cputs: sys_cputs((char *)a1, (size_t)a2);break; case SYS_cgetc: sys_cgetc();break; case SYS_getenvid: return sys_getenvid(); case SYS_env_destroy: return sys_env_destroy((envid_t)a1); case SYS_dump_env: sys_dump_env();break; case SYS_page_alloc: return sys_page_alloc((envid_t)a1, (void *)a2, (int)a3); case SYS_page_map: { return sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5); } case SYS_page_unmap: return sys_page_unmap((envid_t)a1, (void *)a2); case SYS_exofork: return sys_exofork(); case SYS_env_set_status: return sys_env_set_status((envid_t)a1,(int)a2); case SYS_env_set_trapframe: return sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2); case SYS_env_set_pgfault_upcall: return sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2); case SYS_yield: sys_yield();break;//new add syscall for lab4; case SYS_ipc_try_send: return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, (unsigned)a4); case SYS_ipc_recv: return sys_ipc_recv((void *)a1); case SYS_ide_read: sys_ide_read((uint32_t)a1, (void *)a2, (size_t)a3); break; case SYS_ide_write: sys_ide_write((uint32_t)a1, (void *)a2, (size_t)a3); break; case SYS_time_msec: return sys_time_msec(); case NSYSCALLS: break; default: return -E_INVAL; } return 0; //panic("syscall not implemented"); }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. // panic("syscall not implemented"); switch (syscallno) { case SYS_cputs: sys_cputs((char *)a1, a2); break; case SYS_cgetc: return sys_cgetc(); case SYS_env_destroy: return sys_env_destroy(a1); case SYS_getenvid: return sys_getenvid(); case SYS_yield: sys_yield(); break; case SYS_page_alloc: return sys_page_alloc(a1, (void *)a2, a3); case SYS_page_map: return sys_page_map(a1, (void *)a2, a3, (void *)a4, a5); case SYS_page_unmap: return sys_page_unmap(a1, (void *)a2); case SYS_env_set_status: return sys_env_set_status(a1, a2); case SYS_exofork: return sys_exofork(); case SYS_env_set_pgfault_upcall: return sys_env_set_pgfault_upcall(a1, (void *)a2); case SYS_ipc_try_send: return sys_ipc_try_send(a1, a2, (void*)a3, a4); case SYS_ipc_recv: return sys_ipc_recv((void*)a1); case SYS_env_set_trapframe: return sys_env_set_trapframe(a1, (struct Trapframe *)a2); case SYS_time_msec: return sys_time_msec(); case SYS_trans_pkt: return sys_trans_pkt((void*)a1, a2); case SYS_recv_pkt: return sys_recv_pkt((void *)a1, (size_t *)a2); default: return -E_INVAL; } return 0; }
// Dispatches to the correct kernel function, passing the arguments. int64_t syscall(uint64_t syscallno, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. uint64_t retval = 0; switch (syscallno) { case SYS_cputs: sys_cputs((char *) a1, (size_t) a2); return retval; case SYS_cgetc: return (int64_t) sys_cgetc(); case SYS_getenvid: return (int64_t) sys_getenvid(); case SYS_env_destroy: return (int64_t) sys_env_destroy((envid_t) a1); case SYS_yield: sys_yield(); return retval; case SYS_exofork: return (int64_t)sys_exofork(); case SYS_page_alloc: return (int64_t)sys_page_alloc((envid_t)a1, (void *)a2, (int)a3); case SYS_page_map: return (int64_t)sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5); case SYS_page_unmap: return (int64_t)sys_page_unmap((envid_t)a1, (void *)a2); case SYS_env_set_status: return (int64_t)sys_env_set_status((envid_t)a1, (int)a2); case SYS_env_set_pgfault_upcall: return (int64_t)sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2); case SYS_ipc_try_send: return (int64_t) sys_ipc_try_send((envid_t) a1, (uint32_t) a2, (void *) a3, (unsigned) a4); case SYS_ipc_recv: return (int64_t)sys_ipc_recv((void*)a1); case SYS_env_set_trapframe: return sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2); case SYS_time_msec: return sys_time_msec(); case SYS_net_try_send: return sys_net_try_send((char *) a1, (int) a2); case SYS_net_try_receive: return sys_net_try_receive((char *) a1, (int *) a2); default: return -E_INVAL; } panic("syscall not implemented"); }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. switch (syscallno){ case SYS_getenvid: return sys_getenvid(); case SYS_cputs: sys_cputs((const char*)a1, a2); return 0; case SYS_cgetc: return sys_cgetc(); case SYS_env_destroy: return sys_env_destroy(a1); case SYS_map_kernel_page: return sys_map_kernel_page((void*)a1, (void*)a2); case SYS_sbrk: return sys_sbrk(a1); case SYS_yield: sys_yield(); return 0; case SYS_exofork: return sys_exofork(); case SYS_env_set_status: return sys_env_set_status((envid_t)a1, (int)a2); case SYS_page_alloc: return sys_page_alloc((envid_t)a1, (void *)a2, (int)a3); case SYS_page_map: return sys_page_map((envid_t)*((uint32_t*)a1), (void*)*((uint32_t*)a1+1), (envid_t)*((uint32_t*)a1+2), (void*)*((uint32_t*)a1+3), (int)*((uint32_t*)a1+4)); case SYS_page_unmap: return sys_page_unmap((envid_t)a1, (void*)a2); case SYS_env_set_pgfault_upcall: return sys_env_set_pgfault_upcall((envid_t)a1, (void*)a2); case SYS_ipc_recv: return sys_ipc_recv((void*)a1); case SYS_ipc_try_send: return sys_ipc_try_send((envid_t)a1, a2, (void*)a3, (int)a4); case SYS_env_set_priority: return sys_env_set_priority((envid_t)a1, (int) a2); case SYS_env_set_trapframe: return sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2); default: return -E_INVAL; } // panic("syscall not implemented"); }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. switch (syscallno) { case (SYS_cputs): sys_cputs((const char *) a1, a2); return 0; case (SYS_cgetc): return sys_cgetc(); case (SYS_getenvid): return sys_getenvid(); case (SYS_env_destroy): return sys_env_destroy(a1, a2); case (SYS_yield): sys_yield(); return 0; case (SYS_exofork): return sys_exofork(); case (SYS_env_set_status): return sys_env_set_status(a1, a2); case (SYS_page_alloc): return sys_page_alloc(a1, (void *) a2, a3); case (SYS_page_map): return sys_page_map(a1, (void *) a2, a3, (void *) a4, a5); case (SYS_page_unmap): return sys_page_unmap(a1, (void *) a2); case (SYS_env_set_pgfault_upcall): return sys_env_set_pgfault_upcall(a1, (void *) a2); case (SYS_ipc_try_send): return sys_ipc_try_send(a1, a2, (void *) a3, a4); case (SYS_ipc_recv): return sys_ipc_recv((void *) a1); case (SYS_env_set_trapframe): return sys_env_set_trapframe(a1, (struct Trapframe *) a2); case (SYS_time_msec): return sys_time_msec(); case (SYS_e1000_transmit): return sys_e1000_transmit(a1, (char *) a2, a3); default: return -E_INVAL; } }
// Dispatches to the correct kernel function, passing the arguments. uint32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. switch (syscallno){ case SYS_cputs: sys_cputs( (const char *)a1, a2); return 0; case SYS_cgetc: return sys_cgetc(); case SYS_getenvid: return sys_getenvid(); case SYS_env_destroy: return sys_env_destroy(a1); case SYS_yield: sys_yield(); return 0; case SYS_exofork: return sys_exofork(); case SYS_env_set_status: return sys_env_set_status(a1, a2); case SYS_page_alloc: return sys_page_alloc(a1, (void *)a2, a3); case SYS_page_map: return sys_page_map(a1, (void *)a2, a3, (void *)a4, a5); case SYS_env_set_trapframe: return sys_env_set_trapframe(a1, (struct Trapframe *)a2); case SYS_page_unmap: return sys_page_unmap(a1, (void *)a2); case SYS_env_set_pgfault_upcall: return sys_env_set_pgfault_upcall(a1, (void *)a2); case SYS_ipc_try_send: return sys_ipc_try_send(a1, a2, (void *)a3, a4); case SYS_ipc_recv: return sys_ipc_recv((void *)a1); default: panic("this syscall ( %d )is not yet implemented", syscallno); } }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. // My code: gmenghani // An invalid system call if(syscallno >= NSYSCALLS) return -E_INVAL; switch(syscallno) { case SYS_cputs: sys_cputs((char *) a1, (size_t)a2); return 0; case SYS_cgetc: return sys_cgetc(); case SYS_getenvid: return sys_getenvid(); case SYS_env_destroy: return sys_env_destroy((envid_t)a1); case SYS_yield : sys_yield(); break; case SYS_exofork : return sys_exofork(); case SYS_env_set_status : return sys_env_set_status((envid_t)a1, (int)a2); case SYS_page_alloc : return sys_page_alloc((envid_t)a1, (void*)a2, (int)a3); case SYS_page_map : return sys_page_map((envid_t)a1, (void*)a2, (envid_t)a3, (void*)a5, (int)a4); case SYS_page_unmap : return sys_page_unmap((envid_t)a1, (void*)a2); // For Challenge problem 1 Lab 4a case SYS_env_set_nice: sys_env_set_nice(a1); return 0; case SYS_env_set_pgfault_upcall: sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2); return 0; case SYS_ipc_try_send: return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void*)a3, (unsigned)a5); case SYS_ipc_recv: return sys_ipc_recv((void*)a1); case SYS_env_set_trapframe: return sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2); case SYS_time_msec: return sys_time_msec(); case SYS_net_send: return sys_net_send((void*)a1, (uint32_t) a2); case SYS_net_recv: return sys_net_recv((void*)a1, (uint16_t*) a2); } return 0; }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. switch(syscallno){ case SYS_cputs: user_mem_assert(curenv, (void *)a1, a2, PTE_U); sys_cputs((char *)a1, a2); return 0; break; case SYS_cgetc: return sys_cgetc(); break; case SYS_getenvid: return sys_getenvid(); break; case SYS_getenv_parent_id: return sys_getenv_parent_id(a1); break; case SYS_env_destroy: return sys_env_destroy(a1); break; case SYS_page_alloc: return sys_page_alloc(a1, (void *)a2, a3); break; case SYS_page_map: return sys_page_map(a1, (void *)a2, a3, (void *)a4, a5); break; case SYS_page_unmap: return sys_page_unmap(a1, (void *)a2); break; case SYS_exofork: return sys_exofork(); break; case SYS_env_set_status: return sys_env_set_status(a1, a2); break; case SYS_env_set_trapframe: return sys_env_set_trapframe(a1, (struct Trapframe *)a2); break; case SYS_env_set_pgfault_upcall: return sys_env_set_pgfault_upcall(a1, (void *)a2); break; case SYS_env_get_curdir: return sys_env_get_curdir((envid_t)a1, (char *)a2); break; case SYS_env_set_curdir: return sys_env_set_curdir((envid_t)a1, (char *)a2); break; case SYS_yield: sys_yield(); break; case SYS_ipc_try_send: return sys_ipc_try_send(a1, a2, (void *)a3, a4); break; case SYS_ipc_recv: return sys_ipc_recv((void *)a1); break; case SYS_time_msec: return sys_time_msec(); break; case SYS_net_send: return sys_net_send((void *)a1, a2); break; case SYS_net_recv: return sys_net_recv((void *)a1, a2); break; case NSYSCALLS: default: return -E_INVAL; break; } return 0; }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. /*stone's solution for lab3-B*/ int32_t ret = -E_INVAL; switch (syscallno){ case SYS_cputs: sys_cputs((char*)a1, a2); ret = 0; break; case SYS_cgetc: ret = sys_cgetc(); break; case SYS_getenvid: ret = sys_getenvid(); break; case SYS_env_destroy: ret = sys_env_destroy(a1); break; case SYS_map_kernel_page: ret = sys_map_kernel_page((void*)a1, (void*)a2); break; case SYS_sbrk: ret = sys_sbrk(a1); break; /*stone's solution for lab4-A*/ case SYS_yield: sys_yield(); ret = 0; break; case SYS_exofork: ret = sys_exofork(); break; case SYS_env_set_status: ret = sys_env_set_status(a1, a2); break; case SYS_env_set_pgfault_upcall: ret = sys_env_set_pgfault_upcall((envid_t)a1, (void*)a2); break; case SYS_page_alloc: ret = sys_page_alloc((envid_t)a1, (void*)a2, (int)a3); break; case SYS_page_map: /*stone: see lib/syscall.c for modification details*/ ret = sys_page_map(*((uint32_t*)a1), (void*)*((uint32_t*)a1 + 1), *((uint32_t*)a1 + 2), (void*)*((uint32_t*)a1 + 3), *((uint32_t*)a1 + 4)); //ret = sys_page_map(a1, (void*)a2, a3, (void*)a4, a5); break; case SYS_page_unmap: ret = sys_page_unmap(a1, (void*)a2); break; case SYS_ipc_recv: ret = sys_ipc_recv((void*)a1); break; case SYS_ipc_try_send: ret = sys_ipc_try_send((envid_t)a1, a2, (void*)a3, (int)a4); break; case SYS_env_set_trapframe: ret = sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2); break; default: break; } return ret; //panic("syscall not implemented"); }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. // We need to lock the kernel for any calls we know use sysenter syscall_cond_lock(syscallno, 1); int32_t ret = 0; switch(syscallno) { case SYS_cputs: sys_cputs((char *)a1, a2); break; case SYS_cgetc: ret = sys_cgetc(); break; case SYS_env_destroy: ret = sys_env_destroy(a1); break; case SYS_env_set_pgfault_upcall: ret = sys_env_set_pgfault_upcall((envid_t)a1, (void*)a2); break; case SYS_getenvid: ret = sys_getenvid(); break; case SYS_yield: sys_yield(); break; case SYS_exofork: ret = sys_exofork(); break; case SYS_env_set_status: ret = sys_env_set_status((envid_t)a1, a2); break; case SYS_page_alloc: ret = sys_page_alloc((envid_t)a1, (void*)a2, a3); break; case SYS_page_map: ret = sys_page_map((envid_t)a1, (void*)a2, (envid_t)a3, (void*)a4, a5); break; case SYS_page_unmap: ret = sys_page_unmap((envid_t)a1, (void*)a2); break; case SYS_ipc_try_send: ret = sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void*)a3, (unsigned) a4); break; case SYS_ipc_recv: ret = sys_ipc_recv((void*)a1); break; case SYS_env_set_trapframe: ret = sys_env_set_trapframe((envid_t)a1, (struct Trapframe*)a2); break; default: ret = -E_INVAL; break; } syscall_cond_lock(syscallno, 0); return ret; }
// Spawn a child process from a program image loaded from the file system. // prog: the pathname of the program to run. // argv: pointer to null-terminated array of pointers to strings, // which will be passed to the child as its command-line arguments. // Returns child envid on success, < 0 on failure. int spawn(const char *prog, const char **argv) { unsigned char elf_buf[512]; struct Trapframe child_tf; envid_t child; int fd, i, r; struct Elf *elf; struct Proghdr *ph; int perm; // This code follows this procedure: // // - Open the program file. // // - Read the ELF header, as you have before, and sanity check its // magic number. (Check out your load_icode!) // // - Use sys_exofork() to create a new environment. // // - Set child_tf to an initial struct Trapframe for the child. // // - Call the init_stack() function above to set up // the initial stack page for the child environment. // // - Map all of the program's segments that are of p_type // ELF_PROG_LOAD into the new environment's address space. // Use the p_flags field in the Proghdr for each segment // to determine how to map the segment: // // * If the ELF flags do not include ELF_PROG_FLAG_WRITE, // then the segment contains text and read-only data. // Use read_map() to read the contents of this segment, // and map the pages it returns directly into the child // so that multiple instances of the same program // will share the same copy of the program text. // Be sure to map the program text read-only in the child. // Read_map is like read but returns a pointer to the data in // *blk rather than copying the data into another buffer. // // * If the ELF segment flags DO include ELF_PROG_FLAG_WRITE, // then the segment contains read/write data and bss. // As with load_icode() in Lab 3, such an ELF segment // occupies p_memsz bytes in memory, but only the FIRST // p_filesz bytes of the segment are actually loaded // from the executable file - you must clear the rest to zero. // For each page to be mapped for a read/write segment, // allocate a page in the parent temporarily at UTEMP, // read() the appropriate portion of the file into that page // and/or use memset() to zero non-loaded portions. // (You can avoid calling memset(), if you like, if // page_alloc() returns zeroed pages already.) // Then insert the page mapping into the child. // Look at init_stack() for inspiration. // Be sure you understand why you can't use read_map() here. // // Note: None of the segment addresses or lengths above // are guaranteed to be page-aligned, so you must deal with // these non-page-aligned values appropriately. // The ELF linker does, however, guarantee that no two segments // will overlap on the same page; and it guarantees that // PGOFF(ph->p_offset) == PGOFF(ph->p_va). // // - Call sys_env_set_trapframe(child, &child_tf) to set up the // correct initial eip and esp values in the child. // // - Start the child process running with sys_env_set_status(). if ((r = open(prog, O_RDONLY)) < 0) return r; fd = r; // Read elf header elf = (struct Elf*) elf_buf; if (readn(fd, elf_buf, sizeof(elf_buf)) != sizeof(elf_buf) || elf->e_magic != ELF_MAGIC) { close(fd); cprintf("elf magic %08x want %08x\n", elf->e_magic, ELF_MAGIC); return -E_NOT_EXEC; } // Create new child environment if ((r = sys_exofork()) < 0) return r; child = r; // Set up trap frame, including initial stack. child_tf = envs[ENVX(child)].env_tf; child_tf.tf_eip = elf->e_entry; if ((r = init_stack(child, argv, &child_tf.tf_esp)) < 0) return r; // Set up program segments as defined in ELF header. ph = (struct Proghdr*) (elf_buf + elf->e_phoff); for (i = 0; i < elf->e_phnum; i++, ph++) { if (ph->p_type != ELF_PROG_LOAD) continue; perm = PTE_P | PTE_U; if (ph->p_flags & ELF_PROG_FLAG_WRITE) perm |= PTE_W; if ((r = map_segment(child, ph->p_va, ph->p_memsz, fd, ph->p_filesz, ph->p_offset, perm)) < 0) goto error; } close(fd); fd = -1; // Copy shared library state. if ((r = copy_shared_pages(child)) < 0) panic("copy_shared_pages: %e", r); if ((r = sys_env_set_trapframe(child, &child_tf)) < 0) panic("sys_env_set_trapframe: %e", r); if ((r = sys_env_set_status(child, ENV_RUNNABLE)) < 0) panic("sys_env_set_status: %e", r); return child; error: sys_env_destroy(child); close(fd); return r; }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. uint32_t result = -E_INVAL; //cprintf("syscallno:%08x\n",syscallno); switch(syscallno) { case SYS_cputs: sys_cputs((char *)a1,(size_t)a2); result = SYS_cputs; break; case SYS_getenvid: result = sys_getenvid(); break; case SYS_cgetc: result = sys_cgetc(); break; case SYS_env_destroy: result = sys_env_destroy((envid_t)a1); break; case SYS_env_set_trapframe: result = sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2); break; case SYS_yield: sys_yield(); result = SYS_yield; break; case SYS_exofork: result = sys_exofork(); break; case SYS_env_set_status: result = sys_env_set_status((envid_t)a1,(int)a2); break; case SYS_page_alloc: result = sys_page_alloc((envid_t)a1,(void *)a2,(int)a3); break; case SYS_page_map: result = sys_page_map((envid_t)a1,(void *)a2,(envid_t)a3,(void *)a4,(int)a5); break; case SYS_page_unmap: result = sys_page_unmap((envid_t)a1,(void *)a2); break; case SYS_env_set_pgfault_upcall: result = sys_env_set_pgfault_upcall((envid_t)a1,(void*)a2); break; case SYS_ipc_recv: result = sys_ipc_recv((void*)a1); break; case SYS_ipc_try_send: result = sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, (unsigned)a4); break; case SYS_for_fork: result = sys_for_fork((envid_t)a1, (void *)a2, (int)a3); break; case SYS_set_shforkid: result = sys_set_shforkid((envid_t)a1); break; default: result = -E_INVAL; } return result; }
// Spawn a child process from a program image loaded from the file system. // prog: the pathname of the program to run. // argv: pointer to null-terminated array of pointers to strings, // which will be passed to the child as its command-line arguments. // Returns child envid on success, < 0 on failure. int spawn(const char *prog, const char **argv) { unsigned char elf_buf[512]; struct Trapframe child_tf; envid_t child; // Insert your code, following approximately this procedure: // // - Open the program file. // // - Read the ELF header, as you have before, and sanity check its // magic number. (Check out your load_icode!) // // - Use sys_exofork() to create a new environment. // // - Set child_tf to an initial struct Trapframe for the child. // Hint: The sys_exofork() system call has already created // a good basis, in envs[ENVX(child)].env_tf. // Hint: You must do something with the program's entry point. // What? (See load_icode!) // // - Call the init_stack() function above to set up // the initial stack page for the child environment. // // - Map all of the program's segments that are of p_type // ELF_PROG_LOAD into the new environment's address space. // Use the p_flags field in the Proghdr for each segment // to determine how to map the segment: // // * If the ELF flags do not include ELF_PROG_FLAG_WRITE, // then the segment contains text and read-only data. // Use read_map() to read the contents of this segment, // and map the pages it returns directly into the child // so that multiple instances of the same program // will share the same copy of the program text. // Be sure to map the program text read-only in the child. // Read_map is like read but returns a pointer to the data in // *blk rather than copying the data into another buffer. // // * If the ELF segment flags DO include ELF_PROG_FLAG_WRITE, // then the segment contains read/write data and bss. // As with load_icode() in Lab 3, such an ELF segment // occupies p_memsz bytes in memory, but only the FIRST // p_filesz bytes of the segment are actually loaded // from the executable file - you must clear the rest to zero. // For each page to be mapped for a read/write segment, // allocate a page in the parent temporarily at UTEMP, // read() the appropriate portion of the file into that page // and/or use memset() to zero non-loaded portions. // (You can avoid calling memset(), if you like, if // page_alloc() returns zeroed pages already.) // Then insert the page mapping into the child. // Look at init_stack() for inspiration. // Be sure you understand why you can't use read_map() here. // // Note: None of the segment addresses or lengths above // are guaranteed to be page-aligned, so you must deal with // these non-page-aligned values appropriately. // The ELF linker does, however, guarantee that no two segments // will overlap on the same page; and it guarantees that // PGOFF(ph->p_offset) == PGOFF(ph->p_va). // // - Call sys_env_set_trapframe(child, &child_tf) to set up the // correct initial eip and esp values in the child. // // - Start the child process running with sys_env_set_status(). // LAB 5: Your code here. int fdnum; struct Elf *elf; char elfbuf[512]; uintptr_t init_esp; int r; struct Proghdr *ph, *eph; uint32_t pageva,pageoff; void *blk; uint32_t i; uint32_t left; uint32_t pteno,pdeno; uint32_t pn = 0; uintptr_t addr; pte_t pte; //cprintf("spawn:%s\n",prog); if((fdnum = open(prog, O_RDWR)) < 0) return fdnum; read(fdnum, elfbuf, 512); elf = (struct Elf *) elfbuf; if(elf->e_magic != ELF_MAGIC) return -E_NOT_EXEC; if((child = sys_exofork()) < 0) return child; else if(child == 0) { //cprintf("child\n"); env = &envs[ENVX(sys_getenvid())]; return 0; } child_tf = envs[ENVX(child)].env_tf; child_tf.tf_eip = elf->e_entry; if((r = init_stack(child, argv, &init_esp)) < 0) return r; child_tf.tf_esp = init_esp; ph = (struct Proghdr *) ((uint8_t*)elf + elf->e_phoff); eph = ph + elf->e_phnum; for (; ph != eph; ph++) { if(ph->p_type == ELF_PROG_LOAD) { pageva = ROUNDDOWN(ph->p_va, PGSIZE); pageoff = ROUNDDOWN(ph->p_offset, PGSIZE); if(!(ph->p_flags & ELF_PROG_FLAG_WRITE)) { for(i = 0; i< ph->p_memsz; i += PGSIZE) { if((r = read_map(fdnum, pageoff + i,&blk)) < 0) return r; if((r = sys_page_map(0, blk, child, (void *)(pageva + i),PTE_U|PTE_P)) < 0) return r; } } else { for(i = 0; i < ph->p_memsz; i += PGSIZE) { sys_page_alloc(0, (void*)UTEMP, PTE_U|PTE_P|PTE_W); if( i < ph->p_filesz) { seek(fdnum, pageoff + i); left = ph->p_filesz - i; if(left > PGSIZE) read(fdnum, (void *)UTEMP, PGSIZE); else { read(fdnum,(void *)UTEMP, left); memset((void*)(UTEMP + left),0x0,PGSIZE - left); } } else memset((void*)UTEMP, 0x0,PGSIZE); sys_page_map(0, UTEMP, child,(void *)(pageva + i),PTE_U|PTE_W|PTE_P); sys_page_unmap(0,UTEMP); } } } } close(fdnum); if((r = sys_env_set_trapframe(child, &child_tf)) < 0) return r; for(pdeno = PDX(0);pdeno < PDX(UTOP);pdeno++) { if(!(vpd[pdeno] & (PTE_P))) continue; else { for(pteno = 0;pteno < NPTENTRIES;pteno++) { pn = (pdeno<<10) + pteno; if((vpt[pn] & PTE_P) && (vpt[pn] & PTE_SHARE)) { //remember not to modify vpt[pn] pte = vpt[pn] & PTE_USER; addr = (uintptr_t)PGADDR(pdeno, pteno, 0); sys_page_map(0,(void*)addr,child,(void*)addr,pte); } } } } if((r = sys_env_set_status(child, ENV_RUNNABLE)) < 0) return r; return child; //panic("spawn unimplemented!"); }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. switch(syscallno) { case SYS_cputs: sys_cputs((char *) a1, (size_t) a2); break; case SYS_cgetc: return sys_cgetc(); case SYS_getenvid: return sys_getenvid(); case SYS_env_destroy: return sys_env_destroy((envid_t) a1); case SYS_yield: sys_yield(); break; case SYS_exofork: return sys_exofork(); case SYS_env_set_status: return sys_env_set_status((envid_t) a1, (int) a2); case SYS_env_set_trapframe: return sys_env_set_trapframe((envid_t) a1, (struct Trapframe *) a2); case SYS_page_alloc: return sys_page_alloc((envid_t) a1, (void *) a2, (int) a3); case SYS_page_map: return sys_page_map((envid_t) a1, (void *) a2, (envid_t) a3, (void *) a4, (int) a5); case SYS_page_unmap: return sys_page_unmap((envid_t) a1, (void *) a2); case SYS_env_set_pgfault_upcall: return sys_env_set_pgfault_upcall((envid_t) a1, (void *) a2); case SYS_ipc_try_send: return sys_ipc_try_send((envid_t) a1, (uint32_t) a2, (void *) a3, (unsigned) a4); case SYS_ipc_recv: return sys_ipc_recv((void *) a1); case SYS_env_swap: return sys_env_swap((envid_t) a1); case SYS_time_msec: return sys_time_msec(); case SYS_net_try_send: return sys_net_try_send((char *) a1, (int) a2); case SYS_net_try_receive: return sys_net_try_receive((char *) a1, (int *) a2); case SYS_get_mac: return sys_get_mac((uint32_t *) a1, (uint32_t *) a2); case SYS_env_lease: return sys_env_lease((struct Env*) a1, (envid_t *) a2); case SYS_copy_mem: return sys_copy_mem((envid_t) a1, (void *) a2, (void *) a3, (int) a4, (bool) a5); case SYS_get_perms: return sys_get_perms((envid_t) a1, (void *) a2, (int *) a3); case SYS_env_unsuspend: return sys_env_unsuspend((envid_t) a1, (uint32_t) a2, (uint32_t) a3); case SYS_env_set_thisenv: return sys_env_set_thisenv((envid_t) a1, (void *) a2); case SYS_migrate: return sys_migrate((void *) a1); case SYS_lease_complete: return sys_lease_complete(); default: return -E_INVAL; } return 0; // for syscall that return void }
// Spawn a child process from a program image loaded from the file system. // prog: the pathname of the program to run. // argv: pointer to null-terminated array of pointers to strings, // which will be passed to the child as its command-line arguments. // Returns child envid on success, < 0 on failure. int spawn(const char *prog, const char **argv) { unsigned char elf_buf[512]; struct Trapframe child_tf; envid_t child; int fd, i, r; struct Elf *elf; struct Proghdr *ph; int perm; if ((r = open(prog, O_RDONLY)) < 0) return r; fd = r; // Read elf header elf = (struct Elf*) elf_buf; if (read(fd, elf_buf, sizeof(elf_buf)) != sizeof(elf_buf) || elf->e_magic != ELF_MAGIC) { close(fd); cprintf("elf magic %08x want %08x\n", elf->e_magic, ELF_MAGIC); return -E_NOT_EXEC; } // Create new child environment if ((r = sys_exofork()) < 0) return r; child = r; // Set up trap frame, including initial stack. child_tf = envs[ENVX(child)].env_tf; child_tf.tf_eip = elf->e_entry; if ((r = init_stack(child, argv, &child_tf.tf_esp)) < 0) return r; // Set up program segments as defined in ELF header. ph = (struct Proghdr*) (elf_buf + elf->e_phoff); for (i = 0; i < elf->e_phnum; i++, ph++) { if (ph->p_type != ELF_PROG_LOAD) continue; perm = PTE_P | PTE_U; if (ph->p_flags & ELF_PROG_FLAG_WRITE) perm |= PTE_W; if ((r = map_segment(child, ph->p_va, ph->p_memsz,fd, ph->p_filesz, ph->p_offset, perm)) < 0) goto error; //memset((void *)(ph->p_va+ph->p_filesz), 0, //(ph->p_memsz-ph->p_filesz)); } close(fd); fd = -1; if ((r = sys_env_set_trapframe(child, &child_tf)) < 0) panic("sys_env_set_trapframe: %e", r); if ((r = sys_env_set_status(child, ENV_RUNNABLE)) < 0) panic("sys_env_set_status: %e", r); return child; error: sys_env_destroy(child); close(fd); return r; }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. switch (syscallno) { case SYS_cputs : sys_cputs((const char*) a1, (size_t) a2); return 0; case SYS_env_set_trapframe: return sys_env_set_trapframe((envid_t)a1, (struct Trapframe*) a2); case SYS_cgetc : return sys_cgetc(); case SYS_getenvid: return sys_getenvid(); case SYS_env_destroy: return sys_env_destroy((envid_t) a1); case SYS_yield: sys_yield(); return 0; case SYS_exofork: return sys_exofork(); case SYS_env_set_status: return sys_env_set_status((envid_t)a1,(int)a2); case SYS_page_alloc: return sys_page_alloc((envid_t)a1, (void *)a2, (int)a3); case SYS_page_map: return sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5); case SYS_page_unmap: return sys_page_unmap((envid_t)a1, (void *)a2); case SYS_env_set_pgfault_upcall: return sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2); case SYS_ipc_try_send: //cprintf("Sending ipc..\n\n\n"); return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, (unsigned)a4); case SYS_ipc_recv: return sys_ipc_recv((void *)a1); case SYS_clear_block_access_bit: return sys_clear_block_access_bit((envid_t)a1, (void*) a2); case SYS_time_msec: return sys_time_msec(); case SYS_send_packet: return sys_send_packet((void *)a1, (unsigned)a2); case SYS_receive_packet: return sys_receive_packet((void *)a1); case SYS_get_mac_address: return sys_get_mac_address((uint8_t *) a1); case SYS_get_logged_user_name: return sys_get_logged_user_name((char *)a1); case SYS_get_current_path: return sys_get_current_path((char *)a1); case SYS_update_current_path: return sys_update_current_path((char *)a1); case SYS_get_home_dir: return sys_get_home_dir((char *)a1); default: return -E_INVAL; } //panic("syscall not implemented"); }
// Dispatches to the correct kernel function, passing the arguments. int64_t syscall(uint64_t syscallno, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. int64_t returnVal = -E_INVAL; if(syscallno == SYS_cputs){ sys_cputs((char *)a1,(size_t)a2); returnVal = 0; } if(syscallno == SYS_cgetc){ returnVal = (uint64_t)sys_cgetc(); } if(syscallno == SYS_getenvid){ returnVal = (uint64_t)sys_getenvid(); } if(syscallno == SYS_env_destroy){ returnVal = (uint64_t)sys_env_destroy((envid_t)a1); } if(syscallno == SYS_yield){ sys_yield(); returnVal = 0; } if(syscallno == SYS_exofork){ returnVal = (uint64_t)sys_exofork(); } if(syscallno == SYS_env_set_status){ returnVal = (uint64_t)sys_env_set_status((envid_t)a1,(uint64_t)a2); } if(syscallno == SYS_page_alloc){ returnVal = (uint64_t)sys_page_alloc((envid_t)a1,(uint64_t *)a2,(int)a3); } if(syscallno == SYS_page_map){ returnVal = (uint64_t)sys_page_map((envid_t)a1,(uint64_t *)a2,(envid_t)a3,(uint64_t *)a4,(int)a5); } if(syscallno == SYS_page_unmap){ returnVal = (uint64_t)sys_page_unmap((envid_t)a1,(uint64_t *)a2); } if(syscallno == SYS_env_set_pgfault_upcall){ returnVal = (uint64_t)sys_env_set_pgfault_upcall((envid_t)a1,(void *)a2); } if(syscallno == SYS_ipc_try_send){ returnVal = (uint64_t)sys_ipc_try_send((envid_t)a1,(uint32_t)a2,(void *)a3,(unsigned)a4); } if(syscallno == SYS_ipc_recv){ returnVal = (uint64_t)sys_ipc_recv((void *)a1); } if(syscallno == SYS_env_set_trapframe){ returnVal = (uint64_t)sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2); } if(syscallno == SYS_env_set_transaction){ returnVal = (uint64_t)sys_set_transaction((envid_t)a1,(void *)a2); } if(syscallno == SYS_init_journ){ returnVal = (uint64_t)sys_init_journ(); } return returnVal; }
// Spawn a child process from a program image. // In Lab 4, the image is loaded from the kernel. // In Lab 5, you will allow images to be loaded from the file system. // prog: the name of the program to run. // argv: pointer to null-terminated array of pointers to strings, // which will be passed to the child as its command-line arguments. // Returns child envid on success, < 0 on failure. envid_t spawn(const char* progname, const char** argv) { uint8_t elf_header_buf[512]; ssize_t elf_size; struct Trapframe child_tf; /* Hint!! */ // Insert your code, following approximately this procedure: // // - Look up the program using sys_program_lookup. // Return an error code if no such program exists. // envid_t child, envid; int pid, err; pid = sys_program_lookup(progname,sizeof(progname)); if(pid < 0) return pid; // - Set 'elf_size' to the program's ELF binary size using // sys_program_size. // elf_size = sys_program_size(pid); // - Map the program's first page at UTEMP using the map_page helper. // envid = sys_getenvid(); map_page(envid, pid, 0, (void *)UTEMP, PTE_U|PTE_P); // - Copy the 512-byte ELF header from UTEMP into elf_header_buf. // memcpy(elf_header_buf, (void *)UTEMP, 512); // - Read the ELF header, as you have before, and sanity check its // magic number. (Check out your load_elf for hints!) // struct Elf *elfbin = (struct Elf *)elf_header_buf; if (elfbin->e_magic != ELF_MAGIC) return -E_INVAL; // - Use sys_exofork() to create a new environment. // child = sys_exofork(); if (child < 0) panic("sys_exofork: %e", child); if (child == 0) { return 0; } // - Set child_tf to an initial struct Trapframe for the child. // Hint: The sys_exofork() system call has already created // a good starting point. It is accessible at // envs[ENVX(child)].env_tf. // Hint: You must do something with the program's entry point. // What? (See load_elf!) // child_tf = envs[ENVX(child)].env_tf; //child_tf.tf_regs = envs[ENVX(child)].env_tf.tf_regs; child_tf.tf_eip = elfbin->e_entry; //sys_env_set_trapframe(child, &child_tf); // - Call the init_stack() function to set up the initial stack // page for the child environment. // if((err = init_stack(child,argv,&(child_tf.tf_esp))) < 0){ sys_env_destroy(child); return err; } // - Map all of the program's segments that are of p_type // ELF_PROG_LOAD into the new environment's address space. // Use the load_segment() helper function below. // All the 'struct Proghdr' structures will be accessible // within the first 512 bytes of the ELF. // // load each program segment (ignores ph flags) struct Proghdr *ph, *eph; ph = (struct Proghdr *) ((uint8_t *) elfbin + elfbin->e_phoff); eph = ph + elfbin->e_phnum; for(; ph < eph; ph++){ if(ph->p_type != ELF_PROG_LOAD){ continue; } assert(ph->p_filesz <= ph->p_memsz); load_segment(child, pid, ph, elfbin, elf_size); } // - Call sys_env_set_trapframe(child, &child_tf) to set up the // correct initial eip and esp values in the child. // if((err = sys_env_set_trapframe(child, &child_tf)) < 0){ sys_env_destroy(child); return err; } // - Start the child process running with sys_env_set_status(). /// if((err = sys_env_set_status(child,ENV_RUNNABLE)) < 0){ sys_env_destroy(child); return err; } //panic("spawn unimplemented!"); return 0; }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. int32_t ret = 0; switch (syscallno) { case SYS_cputs: sys_cputs((char *)a1, (size_t)a2); break; case SYS_cgetc: ret = sys_cgetc(); break; case SYS_getenvid: ret = sys_getenvid(); break; case SYS_env_destroy: ret = sys_env_destroy((envid_t)a1); break; case SYS_yield: sys_yield(); break; case SYS_exofork: ret = sys_exofork(); break; case SYS_env_set_status: ret = sys_env_set_status((envid_t)a1, a2); break; case SYS_page_alloc: ret = sys_page_alloc((envid_t)a1, (void *)a2, a3); break; case SYS_page_map: ret = sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, a5); break; case SYS_page_unmap: ret = sys_page_unmap((envid_t)a1, (void *)a2); break; case SYS_env_set_pgfault_upcall: ret = sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2); break; case SYS_ipc_recv: ret = sys_ipc_recv((void *)a1); break; case SYS_ipc_try_send: ret = sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, (unsigned)a4); break; case SYS_env_set_trapframe: ret = sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2); break; case SYS_time_msec: ret = sys_time_msec(); break; case SYS_transmit_packet: ret = sys_transmit_packet((void *)a1, a2); break; case SYS_receive_packet: ret = sys_receive_packet((void *)a1); break; default: return -E_INVAL; } return ret; }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { // Call the function corresponding to the 'syscallno' parameter. // Return any appropriate return value. // LAB 3: Your code here. int32_t ret=0; /* if(syscallno==SYS_cputs||syscallno==SYS_getenvid||syscallno==SYS_env_destroy||syscallno==SYS_cgetc) { if(syscallno==SYS_cputs) sys_cputs((char *)a1,a2); if(syscallno==SYS_getenvid) return sys_getenvid(); if(syscallno==SYS_env_destroy) return sys_env_destroy(a1); if(syscallno==SYS_cgetc) return sys_cgetc(); return ret; }*/ //cprintf("\nNO----%d\n",syscallno); switch (syscallno) { case SYS_cputs: sys_cputs((const char *)a1, (size_t)a2); break; case SYS_cgetc: ret = sys_cgetc(); break; case SYS_getenvid: ret = sys_getenvid(); break; case SYS_env_destroy: ret = sys_env_destroy((envid_t)a1); break; case SYS_yield: sys_yield(); break; case SYS_exofork: ret=sys_exofork(); break; case SYS_env_set_status: ret = sys_env_set_status(a1,a2); break; case SYS_page_alloc: ret = sys_page_alloc(a1,(void *)a2,a3); break; case SYS_page_map: ret = sys_page_map(a1,(void *)a2,a3,(void *)a4,a5); break; case SYS_page_unmap: ret = sys_page_unmap(a1,(void *)a2); break; case SYS_env_set_pgfault_upcall: ret = sys_env_set_pgfault_upcall(a1,(void *)a2); case SYS_ipc_try_send: ret=sys_ipc_try_send(a1,a2,(void *)a3,a4); break; case SYS_ipc_recv: ret=sys_ipc_recv((void *)a1); break; case SYS_env_set_trapframe: ret=sys_env_set_trapframe(a1,(struct Trapframe *)a2); break; case SYS_time_msec: ret=sys_time_msec(); break; case SYS_call_packet_send: ret=sys_call_packet_send((void *)a1,a2); break; case SYS_call_receive_packet: ret=sys_call_receive_packet((void *)a1,(void *)a2); break; default: // NSYSCALLS ret = -E_INVAL; break; } return ret; }
// Dispatches to the correct kernel function, passing the arguments. int32_t syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) { switch (syscallno) { case SYS_cputs: sys_cputs((char *)a1, a2); return 0; /* Sys_cputs is of no interest in return-value */ case SYS_cgetc: return sys_cgetc(); case SYS_reboot: sys_reboot(); return 0; case SYS_env_destroy: return sys_env_destroy(a1); case SYS_getenvid: return sys_getenvid(); case SYS_yield: sys_yield(); /* Never return */ case SYS_page_alloc: return sys_page_alloc((envid_t)a1, (void *)a2, (int)a3); case SYS_page_map: return sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5); case SYS_page_unmap: return sys_page_unmap((envid_t)a1, (void *)a2); case SYS_exofork: return sys_exofork(); case SYS_env_set_status: return sys_env_set_status((envid_t)a1, (int)a2); case SYS_env_set_trapframe: return sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2); case SYS_env_set_pgfault_upcall: return sys_env_set_pgfault_upcall((envid_t)a1, (void *)a2); case SYS_ipc_try_send: return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, (unsigned)a4); case SYS_ipc_recv: return sys_ipc_recv((void *)a1); /* Never return */ case SYS_time_msec: return sys_time_msec(); case SYS_nic_send: return sys_nic_send((char *)a1, (int)a2); case SYS_nic_recv: return sys_nic_recv((char *)a1, (int *)a2); default: panic("Unknown system call!"); } }