/* * Determines if the specified arg is of a type (des, reg, etc.) */ void check (int arg, int type, int param) { /* Determine what type to check for */ switch (type) { case TYPE_SRC: if (!(arg >= 0 && arg < REGISTERS_LEN)) { printf ("Error: expected SRC for param %i.\n", param); sys_dump (0x0); sys_halt (0x0); } case TYPE_DES: if (!(arg >= 2 && arg < REGISTERS_LEN)) { printf ("Error: expected DES for param %i.\n", param); sys_dump (0x0); sys_halt (0x0); } case TYPE_REG: if (!(arg >= 0 && arg < REGISTERS_LEN)) { printf ("Error: expected REG for param %i.\n", param); sys_dump (0x0); sys_halt (0x0); } case TYPE_CONST8: break; case TYPE_CONST4: if (!(arg >= 0 && arg <= 15)) { printf ("Error: expected CONST4 for param %i.\n", param); sys_dump (0x0); sys_halt (0x0); } } }
static void decode_ersr() { if (mec_ersr & 0x01) { if (!(mec_mcr & 0x20)) { if (mec_mcr & 0x40) { sys_reset(); mec_ersr = 0x8000; if (sis_verbose) printf("Error manager reset - IU in error mode\n"); } else { sys_halt(); mec_ersr |= 0x2000; if (sis_verbose) printf("Error manager halt - IU in error mode\n"); } } else mec_irq(1); } if (mec_ersr & 0x04) { if (!(mec_mcr & 0x200)) { if (mec_mcr & 0x400) { sys_reset(); mec_ersr = 0x8000; if (sis_verbose) printf("Error manager reset - IU comparison error\n"); } else { sys_halt(); mec_ersr |= 0x2000; if (sis_verbose) printf("Error manager halt - IU comparison error\n"); } } else mec_irq(1); } if (mec_ersr & 0x20) { if (!(mec_mcr & 0x2000)) { if (mec_mcr & 0x4000) { sys_reset(); mec_ersr = 0x8000; if (sis_verbose) printf("Error manager reset - MEC hardware error\n"); } else { sys_halt(); mec_ersr |= 0x2000; if (sis_verbose) printf("Error manager halt - MEC hardware error\n"); } } else mec_irq(1); } }
void usbevt_vbusoff (){ /// Call sys_halt() first and mpipe_disconnect() last, because this guarantees /// that whatever happens in sys_halt() does not change the fact that we are /// certain MPipe must be disconnected. sys_halt() is not a sure-thing: some /// devices might have batteries, and the non-MPipe part of the application /// might not want or need to halt. sys_halt(HALT_nopower); //should set platform_ext.usb_wakeup ... or not mpipe_disconnect(NULL); }
/* * Executes a given instruction, or errors out * ins - instruction to run */ void execute (unsigned short int ins) { /* seperate instruction into parts */ short int a0 = (ins >> 12) % 16; short int a1 = (ins >> 8) % 16; short int a2 = (ins >> 4) % 16; short int a3 = (ins >> 0) % 16; /* Run associated instruction */ switch(a0) { case 0x0: _add (a1, a2, a3); break; case 0x1: _sub (a1, a2, a3); break; case 0x2: _mul (a1, a2, a3); break; case 0x3: _div (a1, a2, a3); break; case 0x6: _beq (a1, a2, a3); break; case 0x7: _bgt (a1, a2, a3); break; case 0x8: _ld (a1, a2, a3); break; case 0x9: _st (a1, a2, a3); break; case 0xa: _lc (a1, a3); break; case 0xb: _jmp (a1, a3); break; case 0xc: _inc (a1, a3); break; case 0xf: _sys (a1, a3); break; default: printf ("Error: invalid opcode %#x.\n", a0); sys_dump (0x0); sys_halt (0x0); } }
/* * Integer division * des - destination register * src1 - dividend * src2 - divisor */ void _div (int des, int src1, int src2) { check (des, TYPE_DES, 1); check (src1, TYPE_SRC, 2); check (src2, TYPE_SRC, 3); /* Check for divide-by-zero error, and divide if possible */ if (mem.registers[src2] == 0) { printf ("Error: division by zero.\n"); sys_dump (0x0); sys_halt (0x0); } else { reg_set (0x1, des, ((int)mem.registers[src1] / mem.registers[src2])); reg_set (0x0, 0x1, mem.registers[src1] % mem.registers[src2]); } }
void usbevt_suspend () { /// Call sys_halt() first and mpipe_close() & (mpipe.state = MPIPE_Null) last, /// because this guarantees that whatever happens in sys_halt() does not change /// the fact that we are certain MPipe must be suspended. sys_halt() is not a /// sure-thing: some devices might have batteries, and the non-MPipe part of /// the application might not want or need to halt. # if (MPIPE_USB_REMWAKE) if (mpipe.state >= MPIPE_Idle) { mpipe_close(); mpipe.state = MPIPE_Null; sys_halt(HALT_lowpower); //should set platform_ext.usb_wakeup ... or not } # else mpipe_close(); mpipe.state = MPIPE_Null; # endif }
/* * Saves a register into memory * reg - register to store * src1 - first part of addr * const4 - second part of addr * addr = src1 + const4 */ void _st (int reg, int src1, int const4) { check (reg, TYPE_REG, 1); check (src1, TYPE_SRC, 2); check (const4, TYPE_CONST4, 3); /* Store value of reg into memory */ int addr = mem.registers[src1] + const4; if (addr > 255) { printf ("Error: invalid address %#x.\n", addr); sys_dump (0x0); sys_halt (0x0); } else { mem_set (addr, mem.registers[reg]); } }
/* * Load a value from memory into a register * des - destination register * src1 - first part of addr * const4 - second part of addr * addr = src1 + const4 */ void _ld (int des, int src1, int const4) { check (des, TYPE_DES, 1); check (src1, TYPE_SRC, 2); check (const4, TYPE_CONST4, 3); /* Calculate address and store */ int addr = src1 + const4; if (addr > 255) { printf ("Error: invalid address %#x.\n", addr); sys_dump (0x0); sys_halt (0x0); } else { reg_set (0x1, des, mem.data[addr]); } }
static int syscall_dispatch(uint32_t sysnum, uint32_t args, regs_t *regs) { switch (sysnum) { case SYS_waitpid: return sys_waitpid((waitpid_args_t *)args); case SYS_exit: do_exit((int)args); panic("exit failed!\n"); return 0; case SYS_thr_exit: kthread_exit((void *)args); panic("thr_exit failed!\n"); return 0; case SYS_thr_yield: sched_make_runnable(curthr); sched_switch(); return 0; case SYS_fork: return sys_fork(regs); case SYS_getpid: return curproc->p_pid; case SYS_sync: sys_sync(); return 0; #ifdef __MOUNTING__ case SYS_mount: return sys_mount((mount_args_t *) args); case SYS_umount: return sys_umount((argstr_t *) args); #endif case SYS_mmap: return (int) sys_mmap((mmap_args_t *) args); case SYS_munmap: return sys_munmap((munmap_args_t *) args); case SYS_open: return sys_open((open_args_t *) args); case SYS_close: return sys_close((int)args); case SYS_read: return sys_read((read_args_t *)args); case SYS_write: return sys_write((write_args_t *)args); case SYS_dup: return sys_dup((int)args); case SYS_dup2: return sys_dup2((dup2_args_t *)args); case SYS_mkdir: return sys_mkdir((mkdir_args_t *)args); case SYS_rmdir: return sys_rmdir((argstr_t *)args); case SYS_unlink: return sys_unlink((argstr_t *)args); case SYS_link: return sys_link((link_args_t *)args); case SYS_rename: return sys_rename((rename_args_t *)args); case SYS_chdir: return sys_chdir((argstr_t *)args); case SYS_getdents: return sys_getdents((getdents_args_t *)args); case SYS_brk: return (int) sys_brk((void *)args); case SYS_lseek: return sys_lseek((lseek_args_t *)args); case SYS_halt: sys_halt(); return -1; case SYS_set_errno: curthr->kt_errno = (int)args; return 0; case SYS_errno: return curthr->kt_errno; case SYS_execve: return sys_execve((execve_args_t *)args, regs); case SYS_stat: return sys_stat((stat_args_t *)args); case SYS_uname: return sys_uname((struct utsname *)args); case SYS_debug: return sys_debug((argstr_t *)args); case SYS_kshell: return sys_kshell((int)args); default: dbg(DBG_ERROR, "ERROR: unknown system call: %d (args: %#08x)\n", sysnum, args); curthr->kt_errno = ENOSYS; return -1; } }
static void syscall_handler (struct intr_frame *f) { int syscall_number; ASSERT( sizeof(syscall_number) == 4 ); // assuming x86 // The system call number is in the 32-bit word at the caller's stack pointer. memread_user(f->esp, &syscall_number, sizeof(syscall_number)); _DEBUG_PRINTF ("[DEBUG] system call, number = %d!\n", syscall_number); // Store the esp, which is needed in the page fault handler. // refer to exception.c:page_fault() (see manual 4.3.3) thread_current()->current_esp = f->esp; // Dispatch w.r.t system call number // SYS_*** constants are defined in syscall-nr.h switch (syscall_number) { case SYS_HALT: // 0 { sys_halt(); NOT_REACHED(); break; } case SYS_EXIT: // 1 { int exitcode; memread_user(f->esp + 4, &exitcode, sizeof(exitcode)); sys_exit(exitcode); NOT_REACHED(); break; } case SYS_EXEC: // 2 { void* cmdline; memread_user(f->esp + 4, &cmdline, sizeof(cmdline)); int return_code = sys_exec((const char*) cmdline); f->eax = (uint32_t) return_code; break; } case SYS_WAIT: // 3 { pid_t pid; memread_user(f->esp + 4, &pid, sizeof(pid_t)); int ret = sys_wait(pid); f->eax = (uint32_t) ret; break; } case SYS_CREATE: // 4 { const char* filename; unsigned initial_size; bool return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); memread_user(f->esp + 8, &initial_size, sizeof(initial_size)); return_code = sys_create(filename, initial_size); f->eax = return_code; break; } case SYS_REMOVE: // 5 { const char* filename; bool return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_remove(filename); f->eax = return_code; break; } case SYS_OPEN: // 6 { const char* filename; int return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_open(filename); f->eax = return_code; break; } case SYS_FILESIZE: // 7 { int fd, return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_filesize(fd); f->eax = return_code; break; } case SYS_READ: // 8 { int fd, return_code; void *buffer; unsigned size; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &buffer, sizeof(buffer)); memread_user(f->esp + 12, &size, sizeof(size)); return_code = sys_read(fd, buffer, size); f->eax = (uint32_t) return_code; break; } case SYS_WRITE: // 9 { int fd, return_code; const void *buffer; unsigned size; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &buffer, sizeof(buffer)); memread_user(f->esp + 12, &size, sizeof(size)); return_code = sys_write(fd, buffer, size); f->eax = (uint32_t) return_code; break; } case SYS_SEEK: // 10 { int fd; unsigned position; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &position, sizeof(position)); sys_seek(fd, position); break; } case SYS_TELL: // 11 { int fd; unsigned return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_tell(fd); f->eax = (uint32_t) return_code; break; } case SYS_CLOSE: // 12 { int fd; memread_user(f->esp + 4, &fd, sizeof(fd)); sys_close(fd); break; } #ifdef VM case SYS_MMAP: // 13 { int fd; void *addr; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &addr, sizeof(addr)); mmapid_t ret = sys_mmap (fd, addr); f->eax = ret; break; } case SYS_MUNMAP: // 14 { mmapid_t mid; memread_user(f->esp + 4, &mid, sizeof(mid)); sys_munmap(mid); break; } #endif #ifdef FILESYS case SYS_CHDIR: // 15 { const char* filename; int return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_chdir(filename); f->eax = return_code; break; } case SYS_MKDIR: // 16 { const char* filename; int return_code; memread_user(f->esp + 4, &filename, sizeof(filename)); return_code = sys_mkdir(filename); f->eax = return_code; break; } case SYS_READDIR: // 17 { int fd; char *name; int return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); memread_user(f->esp + 8, &name, sizeof(name)); return_code = sys_readdir(fd, name); f->eax = return_code; break; } case SYS_ISDIR: // 18 { int fd; int return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_isdir(fd); f->eax = return_code; break; } case SYS_INUMBER: // 19 { int fd; int return_code; memread_user(f->esp + 4, &fd, sizeof(fd)); return_code = sys_inumber(fd); f->eax = return_code; break; } #endif /* unhandled case */ default: printf("[ERROR] system call %d is unimplemented!\n", syscall_number); // ensure that waiting (parent) process should wake up and terminate. sys_exit(-1); break; } }
static void syscall_handler (struct intr_frame *f) { int sys_vector; sys_vector=*(int *)(f->esp); switch(sys_vector) { case SYS_HALT: esp_under_phys_base(f, 0); sys_halt (); break; case SYS_EXIT: if ((void *)((int *)f->esp + 1) >= PHYS_BASE) sys_exit (-1); else sys_exit (*((int *)f->esp + 1)); break; case SYS_EXEC: esp_under_phys_base(f, 1); under_phys_base (*((int **)f->esp + 1)); sys_exec (*((int **)f->esp + 1), f); break; case SYS_WAIT: esp_under_phys_base(f, 1); sys_wait (*((int *)f->esp + 1), f); break; case SYS_CREATE: if ((void*)*((int **)f->esp + 1) == NULL) sys_exit(-1); esp_under_phys_base(f, 2); under_phys_base (*((int **)f->esp + 1)); sys_create (*((int **)f->esp + 1), *((int *)f->esp + 2), f); break; case SYS_REMOVE: esp_under_phys_base(f, 1); under_phys_base (*((int **)f->esp + 1)); sys_remove (*((int **)f->esp + 1), f); break; case SYS_OPEN: if ((void*)*((int **)f->esp + 1) == NULL) sys_exit(-1); esp_under_phys_base(f, 1); under_phys_base (*((int **)f->esp + 1)); sys_open (*((int **)f->esp + 1), f); break; case SYS_FILESIZE: esp_under_phys_base(f, 1); check_fd(*((int *)f->esp + 1), -1, f); sys_filesize (*((int *)f->esp + 1), f); break; case SYS_READ: esp_under_phys_base(f, 3); under_phys_base (*((int **)f->esp + 2)); check_fd(*((int *)f->esp + 1), -1, f) sys_read (*((int *)f->esp + 1), *((int **)f->esp + 2), *((int *)f->esp + 3), f); break; case SYS_WRITE: esp_under_phys_base(f, 3); under_phys_base (*((int **)f->esp + 2)); check_fd(*((int *)f->esp + 1), -1, f) sys_write (*((int *)f->esp + 1), *((int **)f->esp + 2), *((int *)f->esp + 3), f); break; case SYS_SEEK: esp_under_phys_base(f, 2); check_fd(*((int *)f->esp + 1), 0, f) sys_seek (*((int *)f->esp + 1), *((int *)f->esp + 2), f); break; case SYS_TELL: esp_under_phys_base(f, 1); check_fd(*((int *)f->esp + 1), 0, f) sys_tell (*((int *)f->esp + 1), f); break; case SYS_CLOSE: esp_under_phys_base(f, 1); check_fd(*((int *)f->esp + 1), 0, f) sys_close (*((int *)f->esp + 1), f); break; } }
/* Syscall handler calls the appropriate function. */ static void syscall_handler (struct intr_frame *f) { int ret = 0; int *syscall_nr = (int *) f->esp; void *arg1 = (int *) f->esp + 1; void *arg2 = (int *) f->esp + 2; void *arg3 = (int *) f->esp + 3; /* Check validate pointer. */ if (!is_user_vaddr (syscall_nr) || !is_user_vaddr (arg1) || !is_user_vaddr (arg2) || !is_user_vaddr (arg3)) sys_exit (-1); switch (*syscall_nr) { case SYS_HALT: sys_halt (); break; case SYS_EXIT: sys_exit (*(int *) arg1); break; case SYS_EXEC: ret = sys_exec (*(char **) arg1); break; case SYS_WAIT: ret = sys_wait (*(pid_t *) arg1); break; case SYS_CREATE: ret = sys_create (*(char **) arg1, *(unsigned *) arg2); break; case SYS_REMOVE: ret = sys_remove (*(char **) arg1); break; case SYS_OPEN: ret = sys_open (*(char **) arg1); break; case SYS_FILESIZE: ret = sys_filesize (*(int *) arg1); break; case SYS_READ: ret = sys_read (*(int *) arg1, *(void **) arg2, *(unsigned *) arg3); break; case SYS_WRITE: ret = sys_write (*(int *) arg1, *(void **) arg2, *(unsigned *) arg3); break; case SYS_SEEK: sys_seek (*(int *) arg1, *(unsigned *) arg2); break; case SYS_TELL: ret = sys_tell (*(int *) arg1); break; case SYS_CLOSE: sys_close (*(int *) arg1); break; default: printf (" (%s) system call! (%d)\n", thread_name (), *syscall_nr); sys_exit (-1); break; } f->eax = ret; }
static void syscall_handler (struct intr_frame *f) { /* Check to see that we can read supplied user memory pointer, using the check_mem_ptr helper() function, in get_word_from_stack(). If the check fails, the process is terminated. */ int syscall_number = (int)get_word_on_stack(f, 0); switch(syscall_number) { case SYS_HALT: { sys_halt(); break; } case SYS_EXIT: { int status = (int)get_word_on_stack(f, 1); sys_exit(status); /* Returns exit status to the kernel. */ f->eax = status; break; } case SYS_EXEC: { const char *cmd_line = (const char *)get_word_on_stack(f, 1); pid_t pid = sys_exec(cmd_line); /* Returns new processes pid. */ f->eax = pid; break; } case SYS_WAIT: { pid_t pid = (pid_t)get_word_on_stack(f, 1); /* Returns child's exit status (pid argument is pid of this child). */ f->eax = sys_wait(pid); break; } case SYS_CREATE: { const char *filename = (const char *)get_word_on_stack(f, 1); unsigned initial_size = (unsigned)get_word_on_stack(f, 2); /* Returns true to the kernel if creation is successful. */ f->eax = (int)sys_create(filename, initial_size); break; } case SYS_REMOVE: { const char *filename = (const char *)get_word_on_stack(f, 1); /* Returns true if successful, and false otherwise. */ f->eax = sys_remove(filename); break; } case SYS_OPEN: { const char *filename = (const char *)get_word_on_stack(f, 1); /* Returns file descriptor of opened file, or -1 if it could not be opened. */ f->eax = sys_open(filename); break; } case SYS_FILESIZE: { int fd = (int)get_word_on_stack(f, 1); /* Returns size of file in bytes. */ f->eax = sys_filesize(fd); break; } case SYS_READ: { int fd = (int)get_word_on_stack(f, 1); void *buffer = (void *)get_word_on_stack(f, 2); unsigned size = (unsigned)get_word_on_stack(f, 3); /* Returns number of bytes actually read, or -1 if it could not be read. */ f->eax = sys_read(fd, buffer, size, f); break; } case SYS_WRITE: { int fd = (int)get_word_on_stack(f, 1); void *buffer = (void *)get_word_on_stack(f, 2); unsigned size = (unsigned)get_word_on_stack(f, 3); /* Returns number of bytes written. */ f->eax = sys_write(fd, buffer, size); break; } case SYS_SEEK: { int fd = (int)get_word_on_stack(f, 1); unsigned position = (int)get_word_on_stack(f, 2); sys_seek(fd, position); break; } case SYS_TELL: { int fd = (int)get_word_on_stack(f, 1); /* Returns the position of the next byte to be read or written in open file 'fd' (in bytes, from start of file). */ f->eax = sys_tell(fd); break; } case SYS_CLOSE: { int fd = (int)get_word_on_stack(f, 1); sys_close(fd); break; } case SYS_MMAP: { int fd = (int)get_word_on_stack(f, 1); void *addr = (void *)get_word_on_stack(f, 2); f->eax = sys_mmap(fd, addr); break; } case SYS_MUNMAP: { mapid_t mapping = (mapid_t)get_word_on_stack(f, 1); sys_munmap(mapping); break; } default: { NOT_REACHED(); } } }
void halt() { sys_halt(); }
static void syscall_handler (struct intr_frame *f) { int *sys_call; int *status; int *fd; const char **buf; int *size; const char **file; tid_t *pid; const char **cmd_line; unsigned *initial_size; unsigned *position; void **buffer; sys_call = (int*) f->esp; check_ptr(sys_call); switch(*sys_call) { case SYS_HALT: sys_halt (); break; case SYS_EXIT: status = (int *) get_arg_ptr (f->esp, 1); sys_exit(*status); NOT_REACHED(); break; case SYS_EXEC: cmd_line = (const char **) get_arg_ptr (f->esp, 1); f->eax = sys_exec (*cmd_line); break; case SYS_WAIT: pid = (tid_t *) get_arg_ptr (f->esp, 1); f->eax = sys_wait (*pid); break; case SYS_CREATE: file = (const char **) get_arg_ptr (f->esp, 1); initial_size = (unsigned *) get_arg_ptr (f->esp, 2); f->eax = sys_create (*file, *initial_size); break; case SYS_REMOVE: file = (const char **) get_arg_ptr (f->esp, 1); f->eax = sys_remove (*file); break; case SYS_OPEN: file = (const char **) get_arg_ptr(f->esp, 1); f->eax = sys_open (*file); break; case SYS_FILESIZE: fd = (int *) get_arg_ptr (f->esp, 1); f->eax = sys_filesize (*fd); break; case SYS_READ: fd = (int *) get_arg_ptr (f->esp, 1); buffer = (void **) get_arg_ptr (f->esp, 2); size = (int *) get_arg_ptr (f->esp, 3); f->eax = sys_read (*fd, *buffer, *size); break; case SYS_WRITE: fd = (int *) get_arg_ptr (f->esp, 1); buf = (const void **) get_arg_ptr (f->esp, 2); size = (int *) get_arg_ptr (f->esp, 3); f->eax = sys_write (*fd, *buf, *size); break; case SYS_SEEK: fd = (int *) get_arg_ptr (f->esp, 1); position = (unsigned *) get_arg_ptr (f->esp, 2); sys_seek (*fd, *position); break; case SYS_TELL: fd = (int *) get_arg_ptr (f->esp, 1); f->eax = sys_tell (*fd); break; case SYS_CLOSE: fd = (int *) get_arg_ptr (f->esp, 1); sys_close (*fd); break; default: printf ("Unrecognized system call!\n"); thread_exit (); } }