17d36db35SAvi Kivity #ifndef LIBCFLAT_PROCESSOR_H 27d36db35SAvi Kivity #define LIBCFLAT_PROCESSOR_H 37d36db35SAvi Kivity 47d36db35SAvi Kivity #include "libcflat.h" 52b2d7aadSAvi Kivity #include <stdint.h> 67d36db35SAvi Kivity 77d36db35SAvi Kivity struct descriptor_table_ptr { 87d36db35SAvi Kivity u16 limit; 97d36db35SAvi Kivity ulong base; 107d36db35SAvi Kivity } __attribute__((packed)); 117d36db35SAvi Kivity 127d36db35SAvi Kivity static inline void barrier(void) 137d36db35SAvi Kivity { 147d36db35SAvi Kivity asm volatile ("" : : : "memory"); 157d36db35SAvi Kivity } 167d36db35SAvi Kivity 177d36db35SAvi Kivity static inline u16 read_cs(void) 187d36db35SAvi Kivity { 197d36db35SAvi Kivity unsigned val; 207d36db35SAvi Kivity 217d36db35SAvi Kivity asm ("mov %%cs, %0" : "=mr"(val)); 227d36db35SAvi Kivity return val; 237d36db35SAvi Kivity } 247d36db35SAvi Kivity 257d36db35SAvi Kivity static inline u16 read_ds(void) 267d36db35SAvi Kivity { 277d36db35SAvi Kivity unsigned val; 287d36db35SAvi Kivity 297d36db35SAvi Kivity asm ("mov %%ds, %0" : "=mr"(val)); 307d36db35SAvi Kivity return val; 317d36db35SAvi Kivity } 327d36db35SAvi Kivity 337d36db35SAvi Kivity static inline u16 read_es(void) 347d36db35SAvi Kivity { 357d36db35SAvi Kivity unsigned val; 367d36db35SAvi Kivity 377d36db35SAvi Kivity asm ("mov %%es, %0" : "=mr"(val)); 387d36db35SAvi Kivity return val; 397d36db35SAvi Kivity } 407d36db35SAvi Kivity 417d36db35SAvi Kivity static inline u16 read_ss(void) 427d36db35SAvi Kivity { 437d36db35SAvi Kivity unsigned val; 447d36db35SAvi Kivity 457d36db35SAvi Kivity asm ("mov %%ss, %0" : "=mr"(val)); 467d36db35SAvi Kivity return val; 477d36db35SAvi Kivity } 487d36db35SAvi Kivity 497d36db35SAvi Kivity static inline u16 read_fs(void) 507d36db35SAvi Kivity { 517d36db35SAvi Kivity unsigned val; 527d36db35SAvi Kivity 537d36db35SAvi Kivity asm ("mov %%fs, %0" : "=mr"(val)); 547d36db35SAvi Kivity return val; 557d36db35SAvi Kivity } 567d36db35SAvi Kivity 577d36db35SAvi Kivity static inline u16 read_gs(void) 587d36db35SAvi Kivity { 597d36db35SAvi Kivity unsigned val; 607d36db35SAvi Kivity 617d36db35SAvi Kivity asm ("mov %%gs, %0" : "=mr"(val)); 627d36db35SAvi Kivity return val; 637d36db35SAvi Kivity } 647d36db35SAvi Kivity 65*77e03b63SGleb Natapov static inline unsigned long read_rflags(void) 66*77e03b63SGleb Natapov { 67*77e03b63SGleb Natapov unsigned long f; 68*77e03b63SGleb Natapov asm ("pushf; pop %0\n\t" : "=rm"(f)); 69*77e03b63SGleb Natapov return f; 70*77e03b63SGleb Natapov } 71*77e03b63SGleb Natapov 727d36db35SAvi Kivity static inline void write_ds(unsigned val) 737d36db35SAvi Kivity { 747d36db35SAvi Kivity asm ("mov %0, %%ds" : : "rm"(val) : "memory"); 757d36db35SAvi Kivity } 767d36db35SAvi Kivity 777d36db35SAvi Kivity static inline void write_es(unsigned val) 787d36db35SAvi Kivity { 797d36db35SAvi Kivity asm ("mov %0, %%es" : : "rm"(val) : "memory"); 807d36db35SAvi Kivity } 817d36db35SAvi Kivity 827d36db35SAvi Kivity static inline void write_ss(unsigned val) 837d36db35SAvi Kivity { 847d36db35SAvi Kivity asm ("mov %0, %%ss" : : "rm"(val) : "memory"); 857d36db35SAvi Kivity } 867d36db35SAvi Kivity 877d36db35SAvi Kivity static inline void write_fs(unsigned val) 887d36db35SAvi Kivity { 897d36db35SAvi Kivity asm ("mov %0, %%fs" : : "rm"(val) : "memory"); 907d36db35SAvi Kivity } 917d36db35SAvi Kivity 927d36db35SAvi Kivity static inline void write_gs(unsigned val) 937d36db35SAvi Kivity { 947d36db35SAvi Kivity asm ("mov %0, %%gs" : : "rm"(val) : "memory"); 957d36db35SAvi Kivity } 967d36db35SAvi Kivity 977d36db35SAvi Kivity static inline u64 rdmsr(u32 index) 987d36db35SAvi Kivity { 997d36db35SAvi Kivity u32 a, d; 1007d36db35SAvi Kivity asm volatile ("rdmsr" : "=a"(a), "=d"(d) : "c"(index) : "memory"); 1017d36db35SAvi Kivity return a | ((u64)d << 32); 1027d36db35SAvi Kivity } 1037d36db35SAvi Kivity 1047d36db35SAvi Kivity static inline void wrmsr(u32 index, u64 val) 1057d36db35SAvi Kivity { 1067d36db35SAvi Kivity u32 a = val, d = val >> 32; 1077d36db35SAvi Kivity asm volatile ("wrmsr" : : "a"(a), "d"(d), "c"(index) : "memory"); 1087d36db35SAvi Kivity } 1097d36db35SAvi Kivity 1102b2d7aadSAvi Kivity static inline uint64_t rdpmc(uint32_t index) 1112b2d7aadSAvi Kivity { 1122b2d7aadSAvi Kivity uint32_t a, d; 1132b2d7aadSAvi Kivity asm volatile ("rdpmc" : "=a"(a), "=d"(d) : "c"(index)); 1142b2d7aadSAvi Kivity return a | ((uint64_t)d << 32); 1152b2d7aadSAvi Kivity } 1162b2d7aadSAvi Kivity 1177d36db35SAvi Kivity static inline void write_cr0(ulong val) 1187d36db35SAvi Kivity { 1197d36db35SAvi Kivity asm volatile ("mov %0, %%cr0" : : "r"(val) : "memory"); 1207d36db35SAvi Kivity } 1217d36db35SAvi Kivity 1227d36db35SAvi Kivity static inline ulong read_cr0(void) 1237d36db35SAvi Kivity { 1247d36db35SAvi Kivity ulong val; 1257d36db35SAvi Kivity asm volatile ("mov %%cr0, %0" : "=r"(val) : : "memory"); 1267d36db35SAvi Kivity return val; 1277d36db35SAvi Kivity } 1287d36db35SAvi Kivity 1297d36db35SAvi Kivity static inline void write_cr2(ulong val) 1307d36db35SAvi Kivity { 1317d36db35SAvi Kivity asm volatile ("mov %0, %%cr2" : : "r"(val) : "memory"); 1327d36db35SAvi Kivity } 1337d36db35SAvi Kivity 1347d36db35SAvi Kivity static inline ulong read_cr2(void) 1357d36db35SAvi Kivity { 1367d36db35SAvi Kivity ulong val; 1377d36db35SAvi Kivity asm volatile ("mov %%cr2, %0" : "=r"(val) : : "memory"); 1387d36db35SAvi Kivity return val; 1397d36db35SAvi Kivity } 1407d36db35SAvi Kivity 1417d36db35SAvi Kivity static inline void write_cr3(ulong val) 1427d36db35SAvi Kivity { 1437d36db35SAvi Kivity asm volatile ("mov %0, %%cr3" : : "r"(val) : "memory"); 1447d36db35SAvi Kivity } 1457d36db35SAvi Kivity 1467d36db35SAvi Kivity static inline ulong read_cr3(void) 1477d36db35SAvi Kivity { 1487d36db35SAvi Kivity ulong val; 1497d36db35SAvi Kivity asm volatile ("mov %%cr3, %0" : "=r"(val) : : "memory"); 1507d36db35SAvi Kivity return val; 1517d36db35SAvi Kivity } 1527d36db35SAvi Kivity 1537d36db35SAvi Kivity static inline void write_cr4(ulong val) 1547d36db35SAvi Kivity { 1557d36db35SAvi Kivity asm volatile ("mov %0, %%cr4" : : "r"(val) : "memory"); 1567d36db35SAvi Kivity } 1577d36db35SAvi Kivity 1587d36db35SAvi Kivity static inline ulong read_cr4(void) 1597d36db35SAvi Kivity { 1607d36db35SAvi Kivity ulong val; 1617d36db35SAvi Kivity asm volatile ("mov %%cr4, %0" : "=r"(val) : : "memory"); 1627d36db35SAvi Kivity return val; 1637d36db35SAvi Kivity } 1647d36db35SAvi Kivity 1657d36db35SAvi Kivity static inline void write_cr8(ulong val) 1667d36db35SAvi Kivity { 1677d36db35SAvi Kivity asm volatile ("mov %0, %%cr8" : : "r"(val) : "memory"); 1687d36db35SAvi Kivity } 1697d36db35SAvi Kivity 1707d36db35SAvi Kivity static inline ulong read_cr8(void) 1717d36db35SAvi Kivity { 1727d36db35SAvi Kivity ulong val; 1737d36db35SAvi Kivity asm volatile ("mov %%cr8, %0" : "=r"(val) : : "memory"); 1747d36db35SAvi Kivity return val; 1757d36db35SAvi Kivity } 1767d36db35SAvi Kivity 1777d36db35SAvi Kivity static inline void lgdt(const struct descriptor_table_ptr *ptr) 1787d36db35SAvi Kivity { 1797d36db35SAvi Kivity asm volatile ("lgdt %0" : : "m"(*ptr)); 1807d36db35SAvi Kivity } 1817d36db35SAvi Kivity 1827d36db35SAvi Kivity static inline void sgdt(struct descriptor_table_ptr *ptr) 1837d36db35SAvi Kivity { 1847d36db35SAvi Kivity asm volatile ("sgdt %0" : "=m"(*ptr)); 1857d36db35SAvi Kivity } 1867d36db35SAvi Kivity 1877d36db35SAvi Kivity static inline void lidt(const struct descriptor_table_ptr *ptr) 1887d36db35SAvi Kivity { 1897d36db35SAvi Kivity asm volatile ("lidt %0" : : "m"(*ptr)); 1907d36db35SAvi Kivity } 1917d36db35SAvi Kivity 1927d36db35SAvi Kivity static inline void sidt(struct descriptor_table_ptr *ptr) 1937d36db35SAvi Kivity { 1947d36db35SAvi Kivity asm volatile ("sidt %0" : "=m"(*ptr)); 1957d36db35SAvi Kivity } 1967d36db35SAvi Kivity 1977d36db35SAvi Kivity static inline void lldt(unsigned val) 1987d36db35SAvi Kivity { 1997d36db35SAvi Kivity asm volatile ("lldt %0" : : "rm"(val)); 2007d36db35SAvi Kivity } 2017d36db35SAvi Kivity 2027d36db35SAvi Kivity static inline u16 sldt(void) 2037d36db35SAvi Kivity { 2047d36db35SAvi Kivity u16 val; 2057d36db35SAvi Kivity asm volatile ("sldt %0" : "=rm"(val)); 2067d36db35SAvi Kivity return val; 2077d36db35SAvi Kivity } 2087d36db35SAvi Kivity 209fd5d3dc6SAvi Kivity static inline void ltr(u16 val) 2107d36db35SAvi Kivity { 2117d36db35SAvi Kivity asm volatile ("ltr %0" : : "rm"(val)); 2127d36db35SAvi Kivity } 2137d36db35SAvi Kivity 2147d36db35SAvi Kivity static inline u16 str(void) 2157d36db35SAvi Kivity { 2167d36db35SAvi Kivity u16 val; 2177d36db35SAvi Kivity asm volatile ("str %0" : "=rm"(val)); 2187d36db35SAvi Kivity return val; 2197d36db35SAvi Kivity } 2207d36db35SAvi Kivity 2217d36db35SAvi Kivity static inline void write_dr6(ulong val) 2227d36db35SAvi Kivity { 2237d36db35SAvi Kivity asm volatile ("mov %0, %%dr6" : : "r"(val) : "memory"); 2247d36db35SAvi Kivity } 2257d36db35SAvi Kivity 2267d36db35SAvi Kivity static inline ulong read_dr6(void) 2277d36db35SAvi Kivity { 2287d36db35SAvi Kivity ulong val; 2297d36db35SAvi Kivity asm volatile ("mov %%dr6, %0" : "=r"(val)); 2307d36db35SAvi Kivity return val; 2317d36db35SAvi Kivity } 2327d36db35SAvi Kivity 2337d36db35SAvi Kivity static inline void write_dr7(ulong val) 2347d36db35SAvi Kivity { 2357d36db35SAvi Kivity asm volatile ("mov %0, %%dr7" : : "r"(val) : "memory"); 2367d36db35SAvi Kivity } 2377d36db35SAvi Kivity 2387d36db35SAvi Kivity static inline ulong read_dr7(void) 2397d36db35SAvi Kivity { 2407d36db35SAvi Kivity ulong val; 2417d36db35SAvi Kivity asm volatile ("mov %%dr7, %0" : "=r"(val)); 2427d36db35SAvi Kivity return val; 2437d36db35SAvi Kivity } 2447d36db35SAvi Kivity 2457d36db35SAvi Kivity struct cpuid { u32 a, b, c, d; }; 2467d36db35SAvi Kivity 2477d36db35SAvi Kivity static inline struct cpuid cpuid_indexed(u32 function, u32 index) 2487d36db35SAvi Kivity { 2497d36db35SAvi Kivity struct cpuid r; 2507d36db35SAvi Kivity asm volatile ("cpuid" 2517d36db35SAvi Kivity : "=a"(r.a), "=b"(r.b), "=c"(r.c), "=d"(r.d) 2527d36db35SAvi Kivity : "0"(function), "2"(index)); 2537d36db35SAvi Kivity return r; 2547d36db35SAvi Kivity } 2557d36db35SAvi Kivity 2567d36db35SAvi Kivity static inline struct cpuid cpuid(u32 function) 2577d36db35SAvi Kivity { 2587d36db35SAvi Kivity return cpuid_indexed(function, 0); 2597d36db35SAvi Kivity } 2607d36db35SAvi Kivity 2617d36db35SAvi Kivity static inline void pause(void) 2627d36db35SAvi Kivity { 2637d36db35SAvi Kivity asm volatile ("pause"); 2647d36db35SAvi Kivity } 2657d36db35SAvi Kivity 2667d36db35SAvi Kivity static inline void cli(void) 2677d36db35SAvi Kivity { 2687d36db35SAvi Kivity asm volatile ("cli"); 2697d36db35SAvi Kivity } 2707d36db35SAvi Kivity 2717d36db35SAvi Kivity static inline void sti(void) 2727d36db35SAvi Kivity { 2737d36db35SAvi Kivity asm volatile ("sti"); 2747d36db35SAvi Kivity } 2757d36db35SAvi Kivity 2760d7251beSJason Wang static inline unsigned long long rdtsc() 2770d7251beSJason Wang { 2780d7251beSJason Wang long long r; 2790d7251beSJason Wang 2800d7251beSJason Wang #ifdef __x86_64__ 2810d7251beSJason Wang unsigned a, d; 2820d7251beSJason Wang 2830d7251beSJason Wang asm volatile ("rdtsc" : "=a"(a), "=d"(d)); 2840d7251beSJason Wang r = a | ((long long)d << 32); 2850d7251beSJason Wang #else 2860d7251beSJason Wang asm volatile ("rdtsc" : "=A"(r)); 2870d7251beSJason Wang #endif 2880d7251beSJason Wang return r; 2890d7251beSJason Wang } 2900d7251beSJason Wang 2910d7251beSJason Wang static inline void wrtsc(u64 tsc) 2920d7251beSJason Wang { 2930d7251beSJason Wang unsigned a = tsc, d = tsc >> 32; 2940d7251beSJason Wang 2950d7251beSJason Wang asm volatile("wrmsr" : : "a"(a), "d"(d), "c"(0x10)); 2960d7251beSJason Wang } 2970d7251beSJason Wang 298ae0a920bSGleb Natapov static inline void irq_disable(void) 299ae0a920bSGleb Natapov { 300ae0a920bSGleb Natapov asm volatile("cli"); 301ae0a920bSGleb Natapov } 302ae0a920bSGleb Natapov 303ae0a920bSGleb Natapov static inline void irq_enable(void) 304ae0a920bSGleb Natapov { 305ae0a920bSGleb Natapov asm volatile("sti"); 306ae0a920bSGleb Natapov } 307ae0a920bSGleb Natapov 3084029c34bSGleb Natapov static inline void invlpg(void *va) 3094029c34bSGleb Natapov { 3104029c34bSGleb Natapov asm volatile("invlpg (%0)" ::"r" (va) : "memory"); 3114029c34bSGleb Natapov } 312334cd2bfSGleb Natapov 313334cd2bfSGleb Natapov static inline void safe_halt(void) 314334cd2bfSGleb Natapov { 315334cd2bfSGleb Natapov asm volatile("sti; hlt"); 316334cd2bfSGleb Natapov } 3179d7eaa29SArthur Chunqi Li 3189d7eaa29SArthur Chunqi Li #ifdef __x86_64__ 3199d7eaa29SArthur Chunqi Li static inline u64 read_rflags(void) 3209d7eaa29SArthur Chunqi Li { 3219d7eaa29SArthur Chunqi Li u64 r; 3229d7eaa29SArthur Chunqi Li asm volatile("pushf; pop %0\n\t" : "=q"(r) : : "cc"); 3239d7eaa29SArthur Chunqi Li return r; 3249d7eaa29SArthur Chunqi Li } 3259d7eaa29SArthur Chunqi Li 3269d7eaa29SArthur Chunqi Li static inline void write_rflags(u64 r) 3279d7eaa29SArthur Chunqi Li { 3289d7eaa29SArthur Chunqi Li asm volatile("push %0; popf\n\t" : : "q"(r) : "cc"); 3299d7eaa29SArthur Chunqi Li } 3309d7eaa29SArthur Chunqi Li #endif 3319d7eaa29SArthur Chunqi Li 3327d36db35SAvi Kivity #endif 333