Added support for sysenter/sysexit for Intel processors. master
authorethereal <ethereal@ethv.net>
Tue, 17 Jun 2014 21:57:49 +0000 (14:57 -0700)
committerethereal <ethereal@ethv.net>
Tue, 17 Jun 2014 21:57:49 +0000 (14:57 -0700)
kernel/kmain.c
kernel/multiboot.s
kernel/syscall.s

index 1674000..7b62281 100644 (file)
@@ -8,17 +8,19 @@ uint64_t rdtsc_wrapper() {
     return low | ((uint64_t)high)<<32;
 }
 
-void update_with_value(uint64_t value) {
+void update_with_value(uint64_t value, int y) {
     const char *hex = "0123456789abcdef";
     for(int i = 15; i >= 0; i --) {
-        (PHY_MAP_BASE)[0xb8000 + (i*2)] = hex[value&0xf];
-        (PHY_MAP_BASE)[0xb8000 + (i*2) + 1] = 7;
+        (PHY_MAP_BASE)[0xb8000 + (i*2) + y*0xa0] = hex[value&0xf];
+        (PHY_MAP_BASE)[0xb8000 + (i*2) + y*0xa0 + 1] = 7;
 
         value >>= 4;
     }   
 }
 
 extern void syscall_entry();
+extern void sysenter_entry();
+extern void invoke_sysenter();
 extern void enter_userspace();
 
 void wrmsr_wrapper(uint32_t which, uint64_t val) {
@@ -27,10 +29,18 @@ void wrmsr_wrapper(uint32_t which, uint64_t val) {
 
 void userspace() {
     while(1) {
-        uint64_t before = rdtsc_wrapper();
-        for(int i = 0; i < 4096; i ++) __asm__("syscall");
-        uint64_t after = rdtsc_wrapper();
-        update_with_value(after-before);
+        {
+            uint64_t before = rdtsc_wrapper();
+            for(int i = 0; i < 4096; i ++) __asm__("syscall");
+            uint64_t after = rdtsc_wrapper();
+            update_with_value(after-before, 0);
+        }
+        {
+            uint64_t before = rdtsc_wrapper();
+            for(int i = 0; i < 4096; i ++) invoke_sysenter();
+            uint64_t after = rdtsc_wrapper();
+            update_with_value(after-before, 1);
+        }
     }
 }
 
@@ -43,6 +53,11 @@ void kmain(uint64_t __attribute__((unused)) *mem) {
     wrmsr_wrapper(0xc0000084, 0x200);
     wrmsr_wrapper(0xc0000081, ((uint64_t)(0x18+3) << 48) + ((uint64_t)0x08 << 32));
 
+    wrmsr_wrapper(0x174, 8);
+    uint64_t value;
+    wrmsr_wrapper(0x175, (uint64_t)&value - 0x100);
+    wrmsr_wrapper(0x176, (uint64_t)sysenter_entry);
+
     enter_userspace((uint64_t)userspace);
 
     while(1) {}
index acf69c3..ccc2b8f 100644 (file)
@@ -113,6 +113,20 @@ GDT:                               ; Global Descriptor Table (64-bit).
        db 11110010b            ; Access.
        db 00000000b            ; Granularity.
        db 0                    ; Base (high).
+       .ucode2: equ $ - GDT    ; The code descriptor.
+       dw 0                    ; Limit (low).
+       dw 0                    ; Base (low).
+       db 0                    ; Base (middle)
+       db 11111000b            ; Access.
+       db 00100000b            ; Granularity.
+       db 0                    ; Base (high).
+       .udata2: equ $ - GDT    ; The data descriptor.
+       dw 0                    ; Limit (low).
+       dw 0                    ; Base (low).
+       db 0                    ; Base (middle)
+       db 11110010b            ; Access.
+       db 00000000b            ; Granularity.
+       db 0                    ; Base (high).
        .pointer:               ; The GDT-pointer.
        dw $ - GDT - 1          ; Limit.
        dq GDT                  ; Base.
index cee25d6..2a37e43 100644 (file)
@@ -5,6 +5,21 @@ global syscall_entry
 syscall_entry:
        sysretq
 
+%idefine sysexitq o64 sysexit
+global sysenter_entry
+sysenter_entry:
+       sysexitq
+
+global invoke_sysenter
+invoke_sysenter:
+       mov     rcx, rsp
+       mov     rdx, .ret
+
+       sysenter
+
+       .ret:
+       ret
+
 global enter_userspace
 enter_userspace:
        mov     ax, 0x20 + 3