1 /*
2 * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com.
3 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
4 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
5 * Distributed under the terms of the MIT License.
6 *
7 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
8 * Distributed under the terms of the NewOS License.
9 */
10 #ifndef _KERNEL_ARCH_x86_CPUASM_H
11 #define _KERNEL_ARCH_x86_CPUASM_H
12
13
14 #define nop() __asm__ ("nop"::)
15
16 #define x86_read_cr0() ({ \
17 size_t _v; \
18 __asm__("mov %%cr0,%0" : "=r" (_v)); \
19 _v; \
20 })
21
22 #define x86_write_cr0(value) \
23 __asm__("mov %0,%%cr0" : : "r" (value))
24
25 #define x86_read_cr2() ({ \
26 size_t _v; \
27 __asm__("mov %%cr2,%0" : "=r" (_v)); \
28 _v; \
29 })
30
31 #define x86_read_cr3() ({ \
32 size_t _v; \
33 __asm__("mov %%cr3,%0" : "=r" (_v)); \
34 _v; \
35 })
36
37 static inline void
x86_write_cr3(size_t value)38 x86_write_cr3(size_t value)
39 {
40 __asm__("mov %0,%%cr3" : : "r" (value) : "memory");
41 }
42
43 #define x86_read_cr4() ({ \
44 size_t _v; \
45 __asm__("mov %%cr4,%0" : "=r" (_v)); \
46 _v; \
47 })
48
49 #define x86_write_cr4(value) \
50 __asm__("mov %0,%%cr4" : : "r" (value))
51
52 #define x86_read_dr3() ({ \
53 size_t _v; \
54 __asm__("mov %%dr3,%0" : "=r" (_v)); \
55 _v; \
56 })
57
58 #define x86_write_dr3(value) \
59 __asm__("mov %0,%%dr3" : : "r" (value))
60
61 #define invalidate_TLB(va) \
62 __asm__("invlpg (%0)" : : "r" (va))
63
64 #define wbinvd() \
65 __asm__ volatile ("wbinvd" : : : "memory")
66
67 #define arch_cpu_enable_user_access() \
68 __asm__ volatile (ASM_STAC : : : "memory")
69
70 #define arch_cpu_disable_user_access() \
71 __asm__ volatile (ASM_CLAC : : : "memory")
72
73 #define xgetbv(reg) ({ \
74 uint32 low, high; \
75 __asm__ volatile ("xgetbv" : "=a" (low), "=d" (high), "c" (reg)); \
76 (low | (uint64)high << 32); \
77 })
78
79 #define xsetbv(reg, value) { \
80 uint32 low = value; uint32 high = value >> 32; \
81 __asm__ volatile ("xsetbv" : : "a" (low), "d" (high), "c" (reg)); }
82
83 #define out8(value,port) \
84 __asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
85
86 #define out16(value,port) \
87 __asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port))
88
89 #define out32(value,port) \
90 __asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port))
91
92 #define in8(port) ({ \
93 uint8 _v; \
94 __asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \
95 _v; \
96 })
97
98 #define in16(port) ({ \
99 uint16 _v; \
100 __asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \
101 _v; \
102 })
103
104 #define in32(port) ({ \
105 uint32 _v; \
106 __asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \
107 _v; \
108 })
109
110 #define out8_p(value,port) \
111 __asm__ ("outb %%al,%%dx\n" \
112 "\tjmp 1f\n" \
113 "1:\tjmp 1f\n" \
114 "1:" : : "a" (value), "d" (port))
115
116 #define in8_p(port) ({ \
117 uint8 _v; \
118 __asm__ volatile ("inb %%dx,%%al\n" \
119 "\tjmp 1f\n" \
120 "1:\tjmp 1f\n" \
121 "1:" : "=a" (_v) : "d" (port)); \
122 _v; \
123 })
124
125
126 #endif /* _KERNEL_ARCH_x86_CPUASM_H */
127