xref: /haiku/headers/private/kernel/arch/x86/arch_cpuasm.h (revision 410ed2fbba58819ac21e27d3676739728416761d)
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 #define x86_write_cr3(value) \
38 	__asm__("mov    %0,%%cr3" : : "r" (value))
39 
40 #define x86_read_cr4() ({ \
41 	size_t _v; \
42 	__asm__("mov    %%cr4,%0" : "=r" (_v)); \
43 	_v; \
44 })
45 
46 #define x86_write_cr4(value) \
47 	__asm__("mov    %0,%%cr4" : : "r" (value))
48 
49 #define x86_read_dr3() ({ \
50 	size_t _v; \
51 	__asm__("mov    %%dr3,%0" : "=r" (_v)); \
52 	_v; \
53 })
54 
55 #define x86_write_dr3(value) \
56 	__asm__("mov    %0,%%dr3" : : "r" (value))
57 
58 #define invalidate_TLB(va) \
59 	__asm__("invlpg (%0)" : : "r" (va))
60 
61 #define wbinvd() \
62 	__asm__ volatile ("wbinvd" : : : "memory")
63 
64 #define set_ac() \
65 	__asm__ volatile (ASM_STAC : : : "memory")
66 
67 #define clear_ac() \
68 	__asm__ volatile (ASM_CLAC : : : "memory")
69 
70 #define xgetbv(reg) ({ \
71 	uint32 low, high; \
72 	__asm__ volatile ("xgetbv" : "=a" (low), "=d" (high), "c" (reg)); \
73 	(low | (uint64)high << 32); \
74 })
75 
76 #define xsetbv(reg, value) { \
77 	uint32 low = value; uint32 high = value >> 32; \
78 	__asm__ volatile ("xsetbv" : : "a" (low), "d" (high), "c" (reg)); }
79 
80 #define out8(value,port) \
81 	__asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
82 
83 #define out16(value,port) \
84 	__asm__ ("outw %%ax,%%dx" : : "a" (value), "d" (port))
85 
86 #define out32(value,port) \
87 	__asm__ ("outl %%eax,%%dx" : : "a" (value), "d" (port))
88 
89 #define in8(port) ({ \
90 	uint8 _v; \
91 	__asm__ volatile ("inb %%dx,%%al" : "=a" (_v) : "d" (port)); \
92 	_v; \
93 })
94 
95 #define in16(port) ({ \
96 	uint16 _v; \
97 	__asm__ volatile ("inw %%dx,%%ax":"=a" (_v) : "d" (port)); \
98 	_v; \
99 })
100 
101 #define in32(port) ({ \
102 	uint32 _v; \
103 	__asm__ volatile ("inl %%dx,%%eax":"=a" (_v) : "d" (port)); \
104 	_v; \
105 })
106 
107 #define out8_p(value,port) \
108 	__asm__ ("outb %%al,%%dx\n" \
109 			"\tjmp 1f\n" \
110 			"1:\tjmp 1f\n" \
111 			"1:" : : "a" (value), "d" (port))
112 
113 #define in8_p(port) ({ \
114 	uint8 _v; \
115 	__asm__ volatile ("inb %%dx,%%al\n" \
116 			"\tjmp 1f\n" \
117 			"1:\tjmp 1f\n" \
118 			"1:" : "=a" (_v) : "d" (port)); \
119 	_v; \
120 })
121 
122 
123 #endif /* _KERNEL_ARCH_x86_CPUASM_H */
124