1#ifndef KERNEL_ARCH_I686_UTILS_CPU_OPS_H
2#define KERNEL_ARCH_I686_UTILS_CPU_OPS_H
4#include <kernel/types.h>
7#include <utils/compiler.h>
10#define CPU_CACHE_ALIGN 64
12#define X86_FEATURE_WORDS 2
16 u32 features[X86_FEATURE_WORDS];
19extern struct x86_cpuinfo cpuinfo;
26#define READ_REGISTER_OPS(_reg) \
27 static ALWAYS_INLINE u32 read_##_reg() \
30 ASM("movl %%" #_reg ", %0" : "=r"(res)); \
35#define WRITE_REGISTER_OPS(_reg) \
36 static ALWAYS_INLINE void write_##_reg(u32 value) \
38 ASM("movl %0, %%" #_reg : : "r"(value)); \
41#define CPU_32BIT_REGISTERS \
42 cr0, cr1, cr2, cr3, cr4, esp, cs, ds, es, fs, gs, ss, eax
44MAP(READ_REGISTER_OPS, CPU_32BIT_REGISTERS)
45MAP(WRITE_REGISTER_OPS, CPU_32BIT_REGISTERS)
47#undef CPU_32BIT_REGISTERS
48#undef WRITE_REGISTER_OPS
49#undef READ_REGISTER_OPS
66static ALWAYS_INLINE
void outb(uint16_t port, uint8_t val)
68 ASM(
"out %0,%1" : :
"a"(val),
"Nd"(port) :
"memory");
72static ALWAYS_INLINE
void outw(uint16_t port, uint16_t val)
74 ASM(
"out %0,%1" : :
"a"(val),
"Nd"(port) :
"memory");
78static ALWAYS_INLINE
void outl(uint16_t port, uint32_t val)
80 ASM(
"out %0,%1" : :
"a"(val),
"Nd"(port) :
"memory");
84static ALWAYS_INLINE uint8_t inb(uint16_t port)
87 ASM(
"in %1, %0" :
"=a"(val) :
"Nd"(port) :
"memory");
92static ALWAYS_INLINE uint16_t inw(uint16_t port)
95 ASM(
"in %1, %0" :
"=a"(val) :
"Nd"(port) :
"memory");
100static ALWAYS_INLINE uint32_t inl(uint16_t port)
103 ASM(
"in %1,%0" :
"=a"(val) :
"Nd"(port) :
"memory");
107static ALWAYS_INLINE
void hlt(
void)
112static ALWAYS_INLINE
void insb(uint16_t port, uint8_t *buffer,
size_t size)
114 size_t count = size /
sizeof(*buffer);
116 asm volatile(
"cld; rep insb"
117 :
"+D"(buffer),
"+c"(count)
122static ALWAYS_INLINE
void insw(uint16_t port, uint16_t *buffer,
size_t size)
124 size_t count = size /
sizeof(*buffer);
126 asm volatile(
"cld; rep insw"
127 :
"+D"(buffer),
"+c"(count)
132static ALWAYS_INLINE
void insl(uint16_t port, uint32_t *buffer,
size_t size)
134 size_t count = size /
sizeof(*buffer);
136 asm volatile(
"cld; rep insl"
137 :
"+D"(buffer),
"+c"(count)
144#define cpuid(leaf, eax, ebx, ecx, edx) __get_cpuid(leaf, eax, ebx, ecx, edx)
150#define CPUID_FUNCTION(_reg) \
151 static inline uint32_t cpuid_##_reg(uint32_t leaf) \
158 cpuid(leaf, &eax, &ebx, &ecx, &edx); \
169#define CPUID_LEAF_GETVENDOR 0
170#define CPUID_LEAF_GETFEATURES 1
171#define CPUID_LEAF_GETFEATURES_EXT 7
174#define signature_QEMU_ebx 0x47435443
175#define signature_KVM_ebx 0x4D564B20
176#define signature_VMWARE_ebx 0x61774D56
177#define signature_VIRTUALBOX_ebx 0x786F4256
178#define signature_XEN_ebx 0x566E6558
179#define signature_HYPERV_ebx 0x7263694D
180#define signature_PARALLELS_ebx 0x6C727020
181#define signature_PARALLELS_ALT_ebx 0x6570726C
182#define signature_BHYVE_ebx 0x76796862
183#define signature_QNX_ebx 0x20584E51
185#define X86_FEATURES(F) \
200 F(CMPXCHG16B, 0, 13), \
210 F(TSCDeadline, 0, 24), \
227 F(CMPXCHG8B, 1, 8), \
249#define X86_FEATURE_NAME(_feature) X86_FEATURE_##_feature
250#define X86_FEATURE_VAL(_word, _bit) ((_word << X86_FEATURE_WORD_OFF) | (_bit & 0xff))
251#define X86_FEATURE_WORD_OFF 8
253enum x86_cpu_feature {
254#define DEFINE_X86_FEATURE(_name, _word, _bit) \
255 X86_FEATURE_NAME(_name) = X86_FEATURE_VAL(_word, _bit)
256X86_FEATURES(DEFINE_X86_FEATURE)
257#undef DEFINE_X86_FEATURE
260static inline bool cpu_test_feature(
enum x86_cpu_feature feature)
262 int leaf = (feature >> X86_FEATURE_WORD_OFF);
263 int bit = feature & (
BIT(X86_FEATURE_WORD_OFF) - 1);
265 return BIT_READ(cpuinfo.features[leaf], bit);
268#define cpu_has_feature(_feature) cpu_test_feature(X86_FEATURE_NAME(_feature))
275static inline uint64_t rdmsr(uint32_t msr)
279 ASM(
"rdmsr" :
"=a"(eax),
"=d"(edx) :
"c"(msr));
280 return (((uint64_t)edx) << 32) | eax;
284static inline void wrmsr(uint32_t msr, uint64_t val)
287 uint32_t edx = val >> 32;
288 ASM(
"wrmsr" : :
"a"(eax),
"d"(edx),
"c"(msr));
#define BIT(_n)
Generate the nth power of 2 (nth bit set)
Definition: bits.h:20
#define BIT_READ(_x, _n)
Read the nth bit.
Definition: bits.h:30
#define MAP(f,...)
Applies the function macro f to each of the remaining parameters.
Definition: map.h:60