refactor: Optimize the context switch overhead
[lunaix-os.git] / lunaix-os / includes / hal / cpu.h
1 #ifndef __LUNAIX_CPU_H
2 #define __LUNAIX_CPU_H
3
4 #include <lunaix/types.h>
5
6 #define SEL_RPL(selector) ((selector)&0x3)
7
8 typedef unsigned int reg32;
9 typedef unsigned short reg16;
10
11 typedef struct
12 {
13     reg32 eax;
14     reg32 ebx;
15     reg32 ecx;
16     reg32 edx;
17     reg32 edi;
18     reg32 ebp;
19     reg32 esi;
20     reg32 esp;
21 } __attribute__((packed)) gp_regs;
22
23 typedef struct
24 {
25     reg16 ds;
26     reg16 es;
27     reg16 fs;
28     reg16 gs;
29 } __attribute__((packed)) sg_reg;
30
31 void
32 cpu_get_brand(char* brand_out);
33
34 int
35 cpu_has_apic();
36
37 #pragma GCC diagnostic push
38 #pragma GCC diagnostic ignored "-Wreturn-type"
39 static inline reg32
40 cpu_rcr0()
41 {
42     ptr_t val;
43     asm volatile("movl %%cr0,%0" : "=r"(val));
44     return val;
45 }
46
47 static inline reg32
48 cpu_rcr2()
49 {
50     ptr_t val;
51     asm volatile("movl %%cr2,%0" : "=r"(val));
52     return val;
53 }
54
55 static inline reg32
56 cpu_rcr3()
57 {
58     ptr_t val;
59     asm volatile("movl %%cr3,%0" : "=r"(val));
60     return val;
61 }
62
63 static inline reg32
64 cpu_rcr4()
65 {
66     ptr_t val;
67     asm volatile("movl %%cr4,%0" : "=r"(val));
68     return val;
69 }
70
71 static inline reg32
72 cpu_reflags()
73 {
74     ptr_t val;
75     asm volatile("pushf\n"
76                  "popl %0\n"
77                  : "=r"(val)::);
78     return val;
79 }
80 #pragma GCC diagnostic pop
81
82 static inline void
83 cpu_lcr0(reg32 v)
84 {
85     asm("mov %0, %%cr0" ::"r"(v));
86 }
87
88 static inline void
89 cpu_lcr2(reg32 v)
90 {
91     asm("mov %0, %%cr2" ::"r"(v));
92 }
93
94 static inline void
95 cpu_lcr3(reg32 v)
96 {
97     asm("mov %0, %%cr3" ::"r"(v));
98 }
99
100 static inline void
101 cpu_invplg(ptr_t va)
102 {
103     asm volatile("invlpg (%0)" ::"r"(va) : "memory");
104 }
105
106 static inline void
107 cpu_enable_interrupt()
108 {
109     asm volatile("sti");
110 }
111
112 static inline void
113 cpu_disable_interrupt()
114 {
115     asm volatile("cli");
116 }
117
118 static inline void
119 cpu_invtlb()
120 {
121     reg32 interm;
122     asm("movl %%cr3, %0\n"
123         "movl %0, %%cr3"
124         : "=r"(interm)
125         : "r"(interm));
126 }
127
128 static inline void
129 cpu_int(int vect)
130 {
131     asm("int %0" ::"i"(vect));
132 }
133
134 void
135 cpu_rdmsr(u32_t msr_idx, u32_t* reg_high, u32_t* reg_low);
136
137 void
138 cpu_wrmsr(u32_t msr_idx, u32_t reg_high, u32_t reg_low);
139
140 static inline void
141 cpu_ldvmspace(ptr_t vms)
142 {
143     cpu_lcr3(vms);
144 }
145
146 #endif