SYSENTER support and using SYSENTER as default syscall method.
authorDavid Zhu <yuzhu@cs.berkeley.edu>
Mon, 11 May 2009 23:37:49 +0000 (16:37 -0700)
committerDavid Zhu <yuzhu@cs.berkeley.edu>
Mon, 11 May 2009 23:37:49 +0000 (16:37 -0700)
GNUmakefile
kern/init.c
kern/syscall.c
kern/syscall.h
kern/trap.c
kern/trap.h
kern/trapentry.S
lib/syscall.c

index 66b2182..c763ae6 100644 (file)
@@ -71,7 +71,7 @@ PERL  := perl
 # Compiler flags
 # -fno-builtin is required to avoid refs to undefined functions in the kernel.
 # Only optimize to -O1 to discourage inlining, which complicates backtraces.
-CFLAGS := $(CFLAGS) $(DEFS) $(LABDEFS) -D$(ARCH) -O -fno-builtin -fno-stack-protector -I$(TOP) -MD -Wall -Wno-format -Wno-unused -gstabs
+CFLAGS := $(CFLAGS) $(DEFS) $(LABDEFS) -D$(ARCH) -O -fno-builtin -fno-stack-protector -I$(TOP) -MD -Wall -Wno-format -Wno-unused -gstabs #-save-temps
 
 # 64 Bit machines need these settings to compile and link
 UNAME=$(shell uname -m)
index 7efa471..9f9f8c7 100644 (file)
@@ -58,10 +58,10 @@ void kernel_init(multiboot_info_t *mboot_info)
 
        env_init();
        idt_init();
+       sysenter_init();
        timer_init();
        // this returns when all other cores are done and ready to receive IPIs
        smp_boot();
-
        /*
        test_smp_call_functions();
        test_checklists();
@@ -81,11 +81,16 @@ void kernel_init(multiboot_info_t *mboot_info)
        //ENV_CREATE(user_divzero);
        //ENV_CREATE(user_buggyhello);
        //ENV_CREATE(user_evilhello);
+       ENV_CREATE(user_hello);
        //ENV_CREATE(user_hello);
        //ENV_CREATE(user_hello);
        //ENV_CREATE(user_hello);
        //ENV_CREATE(user_null);
        //ENV_CREATE(user_null);
+       env_run(&envs[0]);
+       panic("Don't Panic");
+       // ENV_CREATE(user_null);
+       /*ENV_CREATE(user_null);
        ENV_CREATE(user_null);
 
        //env_run(&envs[0]);
@@ -103,6 +108,7 @@ void kernel_init(multiboot_info_t *mboot_info)
                cpu_relax();
        }
        panic("Don't Panic");
+       */
 }
 
 /*
index 496d906..5f99bdf 100644 (file)
 #include <kern/trap.h>
 #include <kern/syscall.h>
 #include <kern/console.h>
+#include <kern/apic.h>
+
+
+void syscall_wrapper(struct Trapframe *tf)
+{
+       env_t* curenv = curenvs[lapic_get_id()];
+    curenv->env_tf = *tf;
+    tf->tf_regs.reg_eax =
+        syscall(curenv,
+                               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,
+                               0);
+    return;
+}
 
 //Do absolutely nothing.  Used for profiling.
 static void sys_null(env_t* e)
@@ -95,7 +112,7 @@ sys_env_destroy(env_t* e, envid_t envid)
 }
 
 
-
+// TODO: Build a dispatch table instead of switching on the syscallno
 // Dispatches to the correct kernel function, passing the arguments.
 int32_t syscall(env_t* e, uint32_t syscallno, uint32_t a1, uint32_t a2,
                 uint32_t a3, uint32_t a4, uint32_t a5)
index d2fab8d..68f237f 100644 (file)
@@ -11,5 +11,5 @@ int32_t (SYNCHRONOUS syscall)(env_t* e, uint32_t num, uint32_t a1, uint32_t a2,
                               uint32_t a3, uint32_t a4, uint32_t a5);
 int32_t syscall_async(env_t* e, syscall_req_t *syscall);
 uint32_t process_generic_syscalls(env_t* e, uint32_t max);
-
+void syscall_wrapper(struct Trapframe *tf);
 #endif /* !ROS_KERN_SYSCALL_H */
index 291e135..cf80bbb 100644 (file)
@@ -15,7 +15,7 @@
 #include <kern/apic.h>
 #include <kern/smp.h>
 
-static taskstate_t ts;
+taskstate_t ts;
 
 /* Interrupt descriptor table.  (Must be built at run time because
  * shifted function addresses can't be represented in relocation records.)
@@ -316,4 +316,10 @@ page_fault_handler(trapframe_t *tf)
        print_trapframe(tf);
        env_destroy(curenv);
 }
-
+extern void sysenter_handler();
+void sysenter_init(void)
+{
+       write_msr(MSR_IA32_SYSENTER_CS, GD_KT);
+       write_msr(MSR_IA32_SYSENTER_ESP, ts.ts_esp0);
+       write_msr(MSR_IA32_SYSENTER_EIP, (uint32_t) &sysenter_handler);
+}
index dbdcdc1..5d4ceed 100644 (file)
@@ -6,6 +6,10 @@
 # error "This is an ROS kernel header; user programs should not #include it"
 #endif
 
+#define MSR_IA32_SYSENTER_CS 0x174
+#define MSR_IA32_SYSENTER_ESP 0x175
+#define MSR_IA32_SYSENTER_EIP 0x176
+
 #include <inc/trap.h>
 #include <inc/mmu.h>
 
@@ -18,6 +22,7 @@ typedef struct InterruptHandler {
 
 /* The kernel's interrupt descriptor table */
 extern gatedesc_t idt[];
+extern taskstate_t ts;
 
 void idt_init(void);
 void register_interrupt_handler(handler_t (COUNT(256)table)[], uint8_t int_num,
@@ -27,4 +32,6 @@ void (IN_HANDLER print_trapframe)(trapframe_t *tf);
 void (IN_HANDLER page_fault_handler)(trapframe_t *tf);
 void backtrace(trapframe_t *tf);
 
+void sysenter_init(void);
+
 #endif /* ROS_KERN_TRAP_H */
index a4cf9c9..ffefb58 100644 (file)
@@ -176,3 +176,24 @@ _allirqs:
        popl %ds
        addl $0x8, %esp                 # skip IRQ number and err (which is 0)
        iret
+
+.globl sysenter_handler;
+.type sysenter_handler, @function;
+sysenter_handler:
+    cld
+       pushl %ds
+    pushl %es
+    pushal
+    movw $GD_KD, %ax
+    movw %ax, %ds
+    movw %ax, %es
+    pushl %esp
+       movl $0, %ebp                   # so we can backtrace to this point
+    call syscall_wrapper
+    popl %esp
+    popal
+    popl %es
+    popl %ds
+    movl %ebp, %ecx
+    movl %esi, %edx
+    sysexit
index cb79749..61b4387 100644 (file)
@@ -7,6 +7,42 @@
 static inline uint32_t
 syscall(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
 {
+       #ifndef SYSCALL_TRAP
+       return syscall_sysenter(num, a1, a2, a3, a4, a5);
+       #else
+       return syscall_trap(num, a1, a2, a3, a4, a5);
+       #endif
+}
+// TODO: modify to take only four parameters
+static uint32_t
+syscall_sysenter(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
+{
+       uint32_t ret;
+    asm volatile(
+            //"pushl %%ecx\n\t"
+            //"pushl %%edx\n\t"
+            "pushl %%ebp\n\t"
+                       "pushl %%esi\n\t"
+            "movl %%esp, %%ebp\n\t"
+            "leal after_sysenter, %%esi\n\t"
+            "sysenter\n\t"
+            "after_sysenter:\n\t"
+                       "popl %%esi\n\t"
+            "popl %%ebp\n\t"
+            //"popl %%edx\n\t"
+            //"popl %%ecx"
+            :"=a" (ret)
+            : "a" (num),
+                "d" (a1),
+                "c" (a2),
+                "b" (a3),
+                "D" (a4)
+        : "cc", "memory", "%esp");
+       return ret;
+}
+static inline uint32_t
+syscall_trap(int num, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
+{
        uint32_t ret;
 
        // Generic system call: pass system call number in AX,
@@ -120,7 +156,7 @@ void sys_null()
 void
 sys_cputs(const char *s, size_t len)
 {
-       syscall(SYS_cputs, (uint32_t) s, len, 0, 0, 0);
+       syscall(SYS_cputs, (uint32_t) s,  len, 0, 0, 0);
 }
 
 int