refactor: decouple i386 specific instruction invocation
[lunaix-os.git] / lunaix-os / arch / i386 / cpu.c
1 #include <arch/i386/vectors.h>
2 #include <cpuid.h>
3 #include <hal/cpu.h>
4 #include <lunaix/types.h>
5
6 #define BRAND_LEAF 0x80000000UL
7
8 void
9 cpu_get_model(char* model_out)
10 {
11     u32_t* out = (u32_t*)model_out;
12     u32_t eax = 0, ebx = 0, edx = 0, ecx = 0;
13
14     __get_cpuid(0, &eax, &ebx, &ecx, &edx);
15
16     out[0] = ebx;
17     out[1] = edx;
18     out[2] = ecx;
19     model_out[12] = '\0';
20 }
21
22 int
23 cpu_brand_string_supported()
24 {
25     u32_t supported = __get_cpuid_max(BRAND_LEAF, 0);
26     return (supported >= 0x80000004UL);
27 }
28
29 void
30 cpu_get_id(char* id_out)
31 {
32     if (!cpu_brand_string_supported()) {
33         id_out[0] = '?';
34         id_out[1] = '\0';
35     }
36     u32_t* out = (u32_t*)id_out;
37     u32_t eax = 0, ebx = 0, edx = 0, ecx = 0;
38     for (u32_t i = 2, j = 0; i < 5; i++) {
39         __get_cpuid(BRAND_LEAF + i, &eax, &ebx, &ecx, &edx);
40         out[j] = eax;
41         out[j + 1] = ebx;
42         out[j + 2] = ecx;
43         out[j + 3] = edx;
44         j += 4;
45     }
46     id_out[48] = '\0';
47 }
48
49 u32_t
50 cpu_ldstate()
51 {
52     ptr_t val;
53     asm volatile("pushf\n"
54                  "popl %0\n"
55                  : "=r"(val)::);
56     return val;
57 }
58
59 u32_t
60 cpu_ldconfig()
61 {
62     ptr_t val;
63     asm volatile("movl %%cr0,%0" : "=r"(val));
64     return val;
65 }
66
67 void
68 cpu_chconfig(u32_t val)
69 {
70     asm("mov %0, %%cr0" ::"r"(val));
71 }
72
73 u32_t
74 cpu_ldvmspace()
75 {
76     ptr_t val;
77     asm volatile("movl %%cr3,%0" : "=r"(val));
78     return val;
79 }
80
81 void
82 cpu_chvmspace(u32_t val)
83 {
84     asm("mov %0, %%cr3" ::"r"(val));
85 }
86
87 void
88 cpu_flush_page(ptr_t va)
89 {
90     asm volatile("invlpg (%0)" ::"r"(va) : "memory");
91 }
92
93 void
94 cpu_flush_vmspace()
95 {
96     asm("movl %%cr3, %%eax\n"
97         "movl %%eax, %%cr3" ::
98           : "eax");
99 }
100
101 void
102 cpu_enable_interrupt()
103 {
104     asm volatile("sti");
105 }
106
107 void
108 cpu_disable_interrupt()
109 {
110     asm volatile("cli");
111 }
112
113 void
114 cpu_trap_sched()
115 {
116     asm("int %0" ::"i"(LUNAIX_SCHED));
117 }
118
119 void
120 cpu_trap_panic(char* message)
121 {
122     asm("int %0" ::"i"(LUNAIX_SYS_PANIC), "D"(message));
123 }
124
125 void
126 cpu_wait()
127 {
128     asm("hlt");
129 }
130
131 ptr_t
132 cpu_ldeaddr()
133 {
134     ptr_t val;
135     asm volatile("movl %%cr2,%0" : "=r"(val));
136     return val;
137 }
138
139 void
140 cpu_rdmsr(u32_t msr_idx, u32_t* reg_high, u32_t* reg_low)
141 {
142     u32_t h = 0, l = 0;
143     asm volatile("rdmsr" : "=d"(h), "=a"(l) : "c"(msr_idx));
144
145     *reg_high = h;
146     *reg_low = l;
147 }
148
149 void
150 cpu_wrmsr(u32_t msr_idx, u32_t reg_high, u32_t reg_low)
151 {
152     asm volatile("wrmsr" : : "d"(reg_high), "a"(reg_low), "c"(msr_idx));
153 }