xref: /haiku/headers/private/kernel/arch/x86/arch_cpuasm.h (revision fc7456e9b1ec38c941134ed6d01c438cf289381e)
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
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