1#ifndef KERNEL_ARCH_I686_UTILS_CPU_OPS_H
2#define KERNEL_ARCH_I686_UTILS_CPU_OPS_H
4#include <kernel/types.h>
6#include <dailyrun/arch/i686/cpu.h>
9#include <utils/compiler.h>
12#define CPU_CACHE_ALIGN 64
14#define X86_FEATURE_WORDS 2
18 u32 features[X86_FEATURE_WORDS];
21extern struct x86_cpuinfo cpuinfo;
28#define READ_REGISTER_OPS(_reg) \
29 static ALWAYS_INLINE u32 read_##_reg() \
32 ASM("movl %%" #_reg ", %0" : "=r"(res)); \
37#define WRITE_REGISTER_OPS(_reg) \
38 static ALWAYS_INLINE void write_##_reg(u32 value) \
40 ASM("movl %0, %%" #_reg : : "r"(value)); \
43#define CPU_32BIT_REGISTERS \
44 cr0, cr1, cr2, cr3, cr4, esp, cs, ds, es, fs, gs, ss, eax
46MAP(READ_REGISTER_OPS, CPU_32BIT_REGISTERS)
47MAP(WRITE_REGISTER_OPS, CPU_32BIT_REGISTERS)
49#undef CPU_32BIT_REGISTERS
50#undef WRITE_REGISTER_OPS
51#undef READ_REGISTER_OPS
68static ALWAYS_INLINE
void outb(uint16_t port, uint8_t val)
70 ASM(
"out %0,%1" : :
"a"(val),
"Nd"(port) :
"memory");
74static ALWAYS_INLINE
void outw(uint16_t port, uint16_t val)
76 ASM(
"out %0,%1" : :
"a"(val),
"Nd"(port) :
"memory");
80static ALWAYS_INLINE
void outl(uint16_t port, uint32_t val)
82 ASM(
"out %0,%1" : :
"a"(val),
"Nd"(port) :
"memory");
86static ALWAYS_INLINE uint8_t inb(uint16_t port)
89 ASM(
"in %1, %0" :
"=a"(val) :
"Nd"(port) :
"memory");
94static ALWAYS_INLINE uint16_t inw(uint16_t port)
97 ASM(
"in %1, %0" :
"=a"(val) :
"Nd"(port) :
"memory");
102static ALWAYS_INLINE uint32_t inl(uint16_t port)
105 ASM(
"in %1,%0" :
"=a"(val) :
"Nd"(port) :
"memory");
109static ALWAYS_INLINE
void hlt(
void)
114static ALWAYS_INLINE
void insb(uint16_t port, uint8_t *buffer,
size_t size)
116 size_t count = size /
sizeof(*buffer);
118 asm volatile(
"cld; rep insb"
119 :
"+D"(buffer),
"+c"(count)
124static ALWAYS_INLINE
void insw(uint16_t port, uint16_t *buffer,
size_t size)
126 size_t count = size /
sizeof(*buffer);
128 asm volatile(
"cld; rep insw"
129 :
"+D"(buffer),
"+c"(count)
134static ALWAYS_INLINE
void insl(uint16_t port, uint32_t *buffer,
size_t size)
136 size_t count = size /
sizeof(*buffer);
138 asm volatile(
"cld; rep insl"
139 :
"+D"(buffer),
"+c"(count)
146#define cpuid(leaf, eax, ebx, ecx, edx) __get_cpuid(leaf, eax, ebx, ecx, edx)
152#define CPUID_FUNCTION(_reg) \
153 static inline uint32_t cpuid_##_reg(uint32_t leaf) \
160 cpuid(leaf, &eax, &ebx, &ecx, &edx); \
171#define CPUID_LEAF_GETVENDOR 0
172#define CPUID_LEAF_GETFEATURES 1
173#define CPUID_LEAF_GETFEATURES_EXT 7
176#define signature_QEMU_ebx 0x47435443
177#define signature_KVM_ebx 0x4D564B20
178#define signature_VMWARE_ebx 0x61774D56
179#define signature_VIRTUALBOX_ebx 0x786F4256
180#define signature_XEN_ebx 0x566E6558
181#define signature_HYPERV_ebx 0x7263694D
182#define signature_PARALLELS_ebx 0x6C727020
183#define signature_PARALLELS_ALT_ebx 0x6570726C
184#define signature_BHYVE_ebx 0x76796862
185#define signature_QNX_ebx 0x20584E51
187#define X86_FEATURES(F) \
202 F(CMPXCHG16B, 0, 13), \
212 F(TSCDeadline, 0, 24), \
229 F(CMPXCHG8B, 1, 8), \
251#define X86_FEATURE_NAME(_feature) X86_FEATURE_##_feature
252#define X86_FEATURE_VAL(_word, _bit) ((_word << X86_FEATURE_WORD_OFF) | (_bit & 0xff))
253#define X86_FEATURE_WORD_OFF 8
255enum x86_cpu_feature {
256#define DEFINE_X86_FEATURE(_name, _word, _bit) \
257 X86_FEATURE_NAME(_name) = X86_FEATURE_VAL(_word, _bit)
258X86_FEATURES(DEFINE_X86_FEATURE)
259#undef DEFINE_X86_FEATURE
262static inline bool cpu_test_feature(
enum x86_cpu_feature feature)
264 int leaf = (feature >> X86_FEATURE_WORD_OFF);
265 int bit = feature & (
BIT(X86_FEATURE_WORD_OFF) - 1);
267 return BIT_READ(cpuinfo.features[leaf], bit);
270#define cpu_has_feature(_feature) cpu_test_feature(X86_FEATURE_NAME(_feature))
277static inline uint64_t rdmsr(uint32_t msr)
281 ASM(
"rdmsr" :
"=a"(eax),
"=d"(edx) :
"c"(msr));
282 return (((uint64_t)edx) << 32) | eax;
286static inline void wrmsr(uint32_t msr, uint64_t val)
289 uint32_t edx = val >> 32;
290 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