Initial syscall support
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 23 Feb 2009 06:44:02 +0000 (22:44 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 23 Feb 2009 06:44:02 +0000 (22:44 -0800)
'goodbye world' works, but needs actual testing.

kern/init.c
kern/syscall.c
kern/trap.c
user/hello.c

index 958390c..f95e590 100644 (file)
@@ -46,14 +46,14 @@ void kernel_init(multiboot_info_t *mboot_info)
        ENV_CREATE2(TEST, TESTSIZE);
 #else
        // Touch all you want.
-       ENV_CREATE(user_faultread);
+       //ENV_CREATE(user_faultread);
        //ENV_CREATE(user_faultreadkernel);
        //ENV_CREATE(user_faultwrite);
        //ENV_CREATE(user_faultwritekernel);
        //ENV_CREATE(user_breakpoint);
-       ENV_CREATE(user_badsegment);
+       //ENV_CREATE(user_badsegment);
        //ENV_CREATE(user_divzero);
-       //ENV_CREATE(user_hello);
+       ENV_CREATE(user_hello);
 #endif // TEST*
 
        // We only have one user environment for now, so just run it.
index 63a47ce..b0a332b 100644 (file)
@@ -20,7 +20,20 @@ sys_cputs(const char *s, size_t len)
        // Check that the user has permission to read memory [s, s+len).
        // Destroy the environment if not.
        
-       // LAB 3: Your code here.
+       void *start, *end;
+       size_t num_pages, i;
+       pte_t *pte;
+
+       start = ROUNDDOWN((void*)s, PGSIZE);
+       end = ROUNDUP((void*)s + len, PGSIZE);
+       if (start >= end)
+               env_destroy(curenv);
+       num_pages = PPN(end - start);
+       for (i = 0; i < num_pages; i++, start += PGSIZE) {
+               pte = pgdir_walk(curenv->env_pgdir, start, 0);
+               if ( !pte || !(*pte & PTE_P) || !(*pte & PTE_U) ) 
+                       env_destroy(curenv);
+       }
 
        // Print the string supplied by the user.
        cprintf("%.*s", len, s);
@@ -77,8 +90,25 @@ syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
 {
        // Call the function corresponding to the 'syscallno' parameter.
        // Return any appropriate return value.
-       // LAB 3: Your code here.
 
-       panic("syscall not implemented");
+       //cprintf("Incoming syscall number: %d\n    a1: %x\n    a2: %x\n    a3: %x\n    a4: %x\n    a5: %x\n", syscallno, a1, a2, a3, a4, a5);
+
+       if (syscallno >= NSYSCALLS)
+               return -E_INVAL;
+       
+       switch (syscallno) {
+               case 0:
+                       sys_cputs((void*)a1, a2);
+                       return 0;
+               case 1:
+                       return sys_cgetc();
+               case 2:
+                       return sys_getenvid();
+               case 3:
+                       return sys_env_destroy((envid_t)a1);
+               default:
+                       panic("invalid syscall number!");
+       }
+       return 0xdeadbeef;
 }
 
index c782df8..8a7187a 100644 (file)
@@ -135,26 +135,34 @@ trap_dispatch(struct Trapframe *tf)
        // Handle processor exceptions.
        
        switch(tf->tf_trapno) {
-               case (T_BRKPT):
+               case T_BRKPT:
                        while (1)
                                monitor(tf);
                        // never get to this
                        assert(0);
-               case (T_PGFLT):
+               case T_PGFLT:
                        page_fault_handler(tf);
                        break;
-               default:
+               case T_SYSCALL:
+                       // check for userspace, for now
+                       assert(tf->tf_cs != GD_KT);
+                       tf->tf_regs.reg_eax = 
+                               syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, 
+                                       tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, 
+                                       tf->tf_regs.reg_edi, tf->tf_regs.reg_esi);
+                       env_run(curenv);
                        break;
+               default:
+                       // Unexpected trap: The user process or the kernel has a bug.
+                       print_trapframe(tf);
+                       if (tf->tf_cs == GD_KT)
+                               panic("Damn Damn!  Unhandled trap in the kernel!");
+                       else {
+                               env_destroy(curenv);
+                               return;
+                       }
        }
-
-       // Unexpected trap: The user process or the kernel has a bug.
-       print_trapframe(tf);
-       if (tf->tf_cs == GD_KT)
-               panic("unhandled trap in kernel");
-       else {
-               env_destroy(curenv);
-               return;
-       }
+       return;
 }
 
 void
@@ -180,6 +188,8 @@ trap(struct Trapframe *tf)
        trap_dispatch(tf);
 
        // should this be if == 3?  Sort out later when we handle traps.
+       // so far we never get here
+       assert(0);
         // Return to the current environment, which should be runnable.
         assert(curenv && curenv->env_status == ENV_RUNNABLE);
         env_run(curenv);
index e2fdd68..9df9780 100644 (file)
@@ -4,6 +4,7 @@
 void
 umain(void)
 {
-       cprintf("hello, world\n");
+       cprintf("goodbye, world!\n");
+       // this is just their way of generating a pagefault...
        cprintf("i am environment %08x\n", env->env_id);
 }