Added support for sysenter/sysexit for Intel processors.
[sliver.git] / kernel / kmain.c
1 #include <stdint.h>
2
3 #define PHY_MAP_BASE (uint8_t *)0xffffc00000000000ULL
4
5 uint64_t rdtsc_wrapper() {
6     uint32_t low, high;
7     __asm__("rdtsc" : "=a"(low), "=d"(high));
8     return low | ((uint64_t)high)<<32;
9 }
10
11 void update_with_value(uint64_t value, int y) {
12     const char *hex = "0123456789abcdef";
13     for(int i = 15; i >= 0; i --) {
14         (PHY_MAP_BASE)[0xb8000 + (i*2) + y*0xa0] = hex[value&0xf];
15         (PHY_MAP_BASE)[0xb8000 + (i*2) + y*0xa0 + 1] = 7;
16
17         value >>= 4;
18     }   
19 }
20
21 extern void syscall_entry();
22 extern void sysenter_entry();
23 extern void invoke_sysenter();
24 extern void enter_userspace();
25
26 void wrmsr_wrapper(uint32_t which, uint64_t val) {
27     __asm__("wrmsr" : : "c"(which), "a"(val & 0xffffffff), "d"(val >> 32));
28 }
29
30 void userspace() {
31     while(1) {
32         {
33             uint64_t before = rdtsc_wrapper();
34             for(int i = 0; i < 4096; i ++) __asm__("syscall");
35             uint64_t after = rdtsc_wrapper();
36             update_with_value(after-before, 0);
37         }
38         {
39             uint64_t before = rdtsc_wrapper();
40             for(int i = 0; i < 4096; i ++) invoke_sysenter();
41             uint64_t after = rdtsc_wrapper();
42             update_with_value(after-before, 1);
43         }
44     }
45 }
46
47 void kmain(uint64_t __attribute__((unused)) *mem) {
48     for(int i = 0; i < 80*24*2; i ++) (PHY_MAP_BASE) [0xb8000 + i] = 0;
49     (PHY_MAP_BASE) [0xb8000] = 'a';
50     (PHY_MAP_BASE) [0xb8001] = 7;
51
52     wrmsr_wrapper(0xc0000082, (uint64_t)syscall_entry);
53     wrmsr_wrapper(0xc0000084, 0x200);
54     wrmsr_wrapper(0xc0000081, ((uint64_t)(0x18+3) << 48) + ((uint64_t)0x08 << 32));
55
56     wrmsr_wrapper(0x174, 8);
57     uint64_t value;
58     wrmsr_wrapper(0x175, (uint64_t)&value - 0x100);
59     wrmsr_wrapper(0x176, (uint64_t)sysenter_entry);
60
61     enter_userspace((uint64_t)userspace);
62
63     while(1) {}
64 }