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
37static inline void
38x86_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 set_ac() \
68	__asm__ volatile (ASM_STAC : : : "memory")
69
70#define clear_ac() \
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