1 #ifndef LIBCFLAT_PROCESSOR_H 2 #define LIBCFLAT_PROCESSOR_H 3 4 #include "libcflat.h" 5 6 struct descriptor_table_ptr { 7 u16 limit; 8 ulong base; 9 } __attribute__((packed)); 10 11 static inline void barrier(void) 12 { 13 asm volatile ("" : : : "memory"); 14 } 15 16 static inline u16 read_cs(void) 17 { 18 unsigned val; 19 20 asm ("mov %%cs, %0" : "=mr"(val)); 21 return val; 22 } 23 24 static inline u16 read_ds(void) 25 { 26 unsigned val; 27 28 asm ("mov %%ds, %0" : "=mr"(val)); 29 return val; 30 } 31 32 static inline u16 read_es(void) 33 { 34 unsigned val; 35 36 asm ("mov %%es, %0" : "=mr"(val)); 37 return val; 38 } 39 40 static inline u16 read_ss(void) 41 { 42 unsigned val; 43 44 asm ("mov %%ss, %0" : "=mr"(val)); 45 return val; 46 } 47 48 static inline u16 read_fs(void) 49 { 50 unsigned val; 51 52 asm ("mov %%fs, %0" : "=mr"(val)); 53 return val; 54 } 55 56 static inline u16 read_gs(void) 57 { 58 unsigned val; 59 60 asm ("mov %%gs, %0" : "=mr"(val)); 61 return val; 62 } 63 64 static inline void write_ds(unsigned val) 65 { 66 asm ("mov %0, %%ds" : : "rm"(val) : "memory"); 67 } 68 69 static inline void write_es(unsigned val) 70 { 71 asm ("mov %0, %%es" : : "rm"(val) : "memory"); 72 } 73 74 static inline void write_ss(unsigned val) 75 { 76 asm ("mov %0, %%ss" : : "rm"(val) : "memory"); 77 } 78 79 static inline void write_fs(unsigned val) 80 { 81 asm ("mov %0, %%fs" : : "rm"(val) : "memory"); 82 } 83 84 static inline void write_gs(unsigned val) 85 { 86 asm ("mov %0, %%gs" : : "rm"(val) : "memory"); 87 } 88 89 static inline u64 rdmsr(u32 index) 90 { 91 u32 a, d; 92 asm volatile ("rdmsr" : "=a"(a), "=d"(d) : "c"(index) : "memory"); 93 return a | ((u64)d << 32); 94 } 95 96 static inline void wrmsr(u32 index, u64 val) 97 { 98 u32 a = val, d = val >> 32; 99 asm volatile ("wrmsr" : : "a"(a), "d"(d), "c"(index) : "memory"); 100 } 101 102 static inline void write_cr0(ulong val) 103 { 104 asm volatile ("mov %0, %%cr0" : : "r"(val) : "memory"); 105 } 106 107 static inline ulong read_cr0(void) 108 { 109 ulong val; 110 asm volatile ("mov %%cr0, %0" : "=r"(val) : : "memory"); 111 return val; 112 } 113 114 static inline void write_cr2(ulong val) 115 { 116 asm volatile ("mov %0, %%cr2" : : "r"(val) : "memory"); 117 } 118 119 static inline ulong read_cr2(void) 120 { 121 ulong val; 122 asm volatile ("mov %%cr2, %0" : "=r"(val) : : "memory"); 123 return val; 124 } 125 126 static inline void write_cr3(ulong val) 127 { 128 asm volatile ("mov %0, %%cr3" : : "r"(val) : "memory"); 129 } 130 131 static inline ulong read_cr3(void) 132 { 133 ulong val; 134 asm volatile ("mov %%cr3, %0" : "=r"(val) : : "memory"); 135 return val; 136 } 137 138 static inline void write_cr4(ulong val) 139 { 140 asm volatile ("mov %0, %%cr4" : : "r"(val) : "memory"); 141 } 142 143 static inline ulong read_cr4(void) 144 { 145 ulong val; 146 asm volatile ("mov %%cr4, %0" : "=r"(val) : : "memory"); 147 return val; 148 } 149 150 static inline void write_cr8(ulong val) 151 { 152 asm volatile ("mov %0, %%cr8" : : "r"(val) : "memory"); 153 } 154 155 static inline ulong read_cr8(void) 156 { 157 ulong val; 158 asm volatile ("mov %%cr8, %0" : "=r"(val) : : "memory"); 159 return val; 160 } 161 162 static inline void lgdt(const struct descriptor_table_ptr *ptr) 163 { 164 asm volatile ("lgdt %0" : : "m"(*ptr)); 165 } 166 167 static inline void sgdt(struct descriptor_table_ptr *ptr) 168 { 169 asm volatile ("sgdt %0" : "=m"(*ptr)); 170 } 171 172 static inline void lidt(const struct descriptor_table_ptr *ptr) 173 { 174 asm volatile ("lidt %0" : : "m"(*ptr)); 175 } 176 177 static inline void sidt(struct descriptor_table_ptr *ptr) 178 { 179 asm volatile ("sidt %0" : "=m"(*ptr)); 180 } 181 182 static inline void lldt(unsigned val) 183 { 184 asm volatile ("lldt %0" : : "rm"(val)); 185 } 186 187 static inline u16 sldt(void) 188 { 189 u16 val; 190 asm volatile ("sldt %0" : "=rm"(val)); 191 return val; 192 } 193 194 static inline void ltr(u16 val) 195 { 196 asm volatile ("ltr %0" : : "rm"(val)); 197 } 198 199 static inline u16 str(void) 200 { 201 u16 val; 202 asm volatile ("str %0" : "=rm"(val)); 203 return val; 204 } 205 206 static inline void write_dr6(ulong val) 207 { 208 asm volatile ("mov %0, %%dr6" : : "r"(val) : "memory"); 209 } 210 211 static inline ulong read_dr6(void) 212 { 213 ulong val; 214 asm volatile ("mov %%dr6, %0" : "=r"(val)); 215 return val; 216 } 217 218 static inline void write_dr7(ulong val) 219 { 220 asm volatile ("mov %0, %%dr7" : : "r"(val) : "memory"); 221 } 222 223 static inline ulong read_dr7(void) 224 { 225 ulong val; 226 asm volatile ("mov %%dr7, %0" : "=r"(val)); 227 return val; 228 } 229 230 struct cpuid { u32 a, b, c, d; }; 231 232 static inline struct cpuid cpuid_indexed(u32 function, u32 index) 233 { 234 struct cpuid r; 235 asm volatile ("cpuid" 236 : "=a"(r.a), "=b"(r.b), "=c"(r.c), "=d"(r.d) 237 : "0"(function), "2"(index)); 238 return r; 239 } 240 241 static inline struct cpuid cpuid(u32 function) 242 { 243 return cpuid_indexed(function, 0); 244 } 245 246 static inline void pause(void) 247 { 248 asm volatile ("pause"); 249 } 250 251 static inline void cli(void) 252 { 253 asm volatile ("cli"); 254 } 255 256 static inline void sti(void) 257 { 258 asm volatile ("sti"); 259 } 260 261 static inline unsigned long long rdtsc() 262 { 263 long long r; 264 265 #ifdef __x86_64__ 266 unsigned a, d; 267 268 asm volatile ("rdtsc" : "=a"(a), "=d"(d)); 269 r = a | ((long long)d << 32); 270 #else 271 asm volatile ("rdtsc" : "=A"(r)); 272 #endif 273 return r; 274 } 275 276 static inline void wrtsc(u64 tsc) 277 { 278 unsigned a = tsc, d = tsc >> 32; 279 280 asm volatile("wrmsr" : : "a"(a), "d"(d), "c"(0x10)); 281 } 282 283 static inline void irq_disable(void) 284 { 285 asm volatile("cli"); 286 } 287 288 static inline void irq_enable(void) 289 { 290 asm volatile("sti"); 291 } 292 293 static inline void invlpg(void *va) 294 { 295 asm volatile("invlpg (%0)" ::"r" (va) : "memory"); 296 } 297 #endif 298