void Mem_space::poke_user (T *addr, T value) { // Check if we cross page boundaries if (((Address) addr & Config::PAGE_MASK) == (((Address) addr + sizeof (T) - 1) & Config::PAGE_MASK)) { Lock_guard <Cpu_lock> guard (&cpu_lock); *user_to_kernel (addr, true) = value; } else copy_to_user < T > (addr, &value, 1); }
T Mem_space::peek_user (T const *addr) { T value; // Check if we cross page boundaries if (((Address) addr & Config::PAGE_MASK) == (((Address) addr + sizeof (T) - 1) & Config::PAGE_MASK)) { Lock_guard <Cpu_lock> guard (&cpu_lock); value = *user_to_kernel (addr, false); } else copy_from_user < T > (&value, addr, 1); return value; }
void Mem_space::copy_to_user (T *udst, T const *ksrc, size_t n) { Lock_guard <Cpu_lock> guard (&cpu_lock); char *ptr = (char *) udst; char *src = (char *) ksrc; char *dst = 0; n *= sizeof (T); while (n--) { if (!dst || ((Address) ptr & ~Config::PAGE_MASK) == 0) dst = user_to_kernel (ptr, true); *dst++ = *src++; ptr++; } }
void Mem_space::copy_from_user (T *kdst, T const *usrc, size_t n) { Lock_guard <Cpu_lock> guard (&cpu_lock); char *ptr = (char *) usrc; char *dst = (char *) kdst; char *src = 0; n *= sizeof (T); while (n--) { if (!src || ((Address) ptr & ~Config::PAGE_MASK) == 0) src = user_to_kernel (ptr, false); *dst++ = *src++; ptr++; } }
void Mem_space::copy_user_to_user (Mem_space *dst, T *udst, T *usrc, size_t n) { Lock_guard <Cpu_lock> guard (&cpu_lock); char *src_uvirt = (char *) usrc; char *dst_uvirt = (char *) udst; char *src_kvirt = 0; char *dst_kvirt = 0; n *= sizeof (T); while (n--) { if (!src_kvirt || ((Address) src_uvirt & ~Config::PAGE_MASK) == 0) src_kvirt = user_to_kernel (src_uvirt, false); if (!dst_kvirt || ((Address) dst_uvirt & ~Config::PAGE_MASK) == 0) dst_kvirt = dst->user_to_kernel (dst_uvirt, true); *dst_kvirt++ = *src_kvirt++; src_uvirt++; dst_uvirt++; } }
static void syscall_handler (struct intr_frame *f) { uint32_t* args = ((uint32_t*) f->esp); // OUR CODE HERE verify_user_ptr(args); switch (args[0]) { case SYS_EXIT: { verify_args(args, 1); f->eax = args[1]; exit(args[1]); break; } case SYS_NULL: { verify_args(args, 1); f->eax = args[1] + 1; break; } case SYS_WRITE: { verify_args(args, 3); lock_acquire(&file_lock); f->eax = write(args[1], user_to_kernel((void *) args[2]), args[3]); lock_release(&file_lock); break; } case SYS_HALT: { shutdown_power_off(); break; } case SYS_WAIT: { verify_args(args, 1); f->eax = wait((tid_t) args[1]); break; } case SYS_EXEC: { verify_args(args, 1); f->eax = exec(user_to_kernel((void *) args[1])); break; } case SYS_CREATE: { verify_args(args, 2); f->eax = create(user_to_kernel((void *) args[1]), args[2]); break; } case SYS_REMOVE: { verify_args(args, 1); f->eax = remove(user_to_kernel((void *) args[1])); break; } case SYS_OPEN: { verify_args(args, 1); f->eax = open(user_to_kernel((void *) args[1])); break; } case SYS_FILESIZE: { verify_args(args, 1); f->eax = filesize(args[1]); break; } case SYS_READ: { verify_args(args, 3); f->eax = read(args[1], user_to_kernel((void *) args[2]), args[3]); break; } case SYS_SEEK: { verify_args(args, 2); seek(args[1], args[2]); break; } case SYS_TELL: { verify_args(args, 1); f->eax = tell(args[1]); break; } case SYS_CLOSE: { verify_args(args, 1); close(args[1]); break; } } }