kernel
Loading...
Searching...
No Matches
intrin.h
Go to the documentation of this file.
1/*
2 * PROJECT: MatanelOS Kernel
3 * LICENSE: NONE
4 * PURPOSE: Intrinsics for easy assembly use.
5 */
6#ifndef X86_INTRINSICS_H
7#define X86_INTRINSICS_H
8
9 // PIC Ports
10#define PIC1_COMMAND_MASTER 0x20
11#define PIC1_DATA 0x21
12#define PIC2_COMMAND_SLAVE 0xA0
13#define PIC2_DATA 0xA1
14
15// End of Interrupt command code
16#define PIC_EOI 0x20
17
18// MSRs
19#define IA32_KERNEL_GS_BASE 0xC0000102
20#define IA32_GS_BASE 0xC0000101 /* used both in kernel mode and user mode */
21#define IA32_FS_BASE 0xC0000100
22#define IA32_EFER 0xC0000080
23#define IA32_STAR 0xC0000081
24#define IA32_LSTAR 0xC0000082
25#define IA32_CSTAR 0xC0000083
26#define IA32_FMASK 0xC0000084
27
28#ifndef UNREFERENCED_PARAMETER
29#define UNREFERENCED_PARAMETER(x) (void)(x)
30#endif
31
32#ifdef _MSC_VER
33#ifndef __asm__
34#define __asm__ __asm
35#endif
36#endif
37
38#include <stdbool.h>
40
41// Disable interrupts (cli)
43void __cli(void) {
44 __asm__ volatile ("cli");
45}
46
47// Enable supervisor access to user memory (STAC)
48FORCEINLINE void __stac(void) {
49 __asm__ volatile("stac" ::: "memory");
50}
51
52// Disable supervisor access to user memory (CLAC)
53FORCEINLINE void __clac(void) {
54 __asm__ volatile("clac" ::: "memory");
55}
56
57// Enable interrupts (sti)
59void __sti(void) {
60 __asm__ volatile ("sti");
61}
62
63// Halt CPU until next interrupt (hlt)
65void __hlt(void) {
66 __asm__ volatile ("hlt");
67}
68
69// Read CR0 register
70FORCEINLINE unsigned long int __read_cr0(void) {
71 unsigned long int val;
72 __asm__ volatile ("mov %%cr0, %0" : "=r"(val));
73 return val;
74}
75
76// Write CR0 register
77FORCEINLINE void __write_cr0(unsigned long int val) {
78 __asm__ volatile ("mov %0, %%cr0" :: "r"(val));
79}
80
81// CR2 (Page fault linear address)
82FORCEINLINE unsigned long __read_cr2(void) {
83 unsigned long val;
84 __asm__ volatile("mov %%cr2, %0" : "=r"(val));
85 return val;
86}
87
88FORCEINLINE void __write_cr2(unsigned long val) {
89 __asm__ volatile("mov %0, %%cr2" :: "r"(val) : "memory");
90}
91
92// CR3 (Page table base address)
93FORCEINLINE uint64_t __read_cr3(void) {
94 uint64_t val;
95 __asm__ volatile("mov %%cr3, %0" : "=r"(val));
96 return val;
97}
98FORCEINLINE void __write_cr3(uint64_t val) {
99 __asm__ volatile("mov %0, %%cr3" :: "r"(val) : "memory");
100}
101
102// CR4 (Feature control)
103FORCEINLINE unsigned long __read_cr4(void) {
104 unsigned long val;
105 __asm__ volatile("mov %%cr4, %0" : "=r"(val));
106 return val;
107}
108FORCEINLINE void __write_cr4(unsigned long val) {
109 __asm__ volatile("mov %0, %%cr4" :: "r"(val) : "memory");
110}
111
112// CR8 (Task Priority Register, x86-64 only)
113FORCEINLINE unsigned long __read_cr8(void) {
114 unsigned long val;
115 __asm__ volatile("mov %%cr8, %0" : "=r"(val));
116 return val;
117}
118FORCEINLINE void __write_cr8(unsigned long val) {
119 __asm__ volatile("mov %0, %%cr8" :: "r"(val) : "memory");
120}
121
122
123// Read DRx register (dr0-dr7) (Usage __read_dr(3) = will return dr3.
124FORCEINLINE uint64_t __read_dr(int reg) {
125 unsigned long val = 0;
126 switch (reg) {
127 case 0: __asm__ volatile("mov %%dr0, %0" : "=r"(val)); break;
128 case 1: __asm__ volatile("mov %%dr1, %0" : "=r"(val)); break;
129 case 2: __asm__ volatile("mov %%dr2, %0" : "=r"(val)); break;
130 case 3: __asm__ volatile("mov %%dr3, %0" : "=r"(val)); break;
131 case 6: __asm__ volatile("mov %%dr6, %0" : "=r"(val)); break;
132 case 7: __asm__ volatile("mov %%dr7, %0" : "=r"(val)); break;
133 default: break;
134 }
135 return val;
136}
137
138// Write DRx register (dr0-dr7) (Usage __write_dr(3, 0x5000) = will write 0x5000 to dr3.
139FORCEINLINE void __write_dr(int reg, uint64_t val) {
140 switch (reg) {
141 case 0: __asm__ volatile("mov %0, %%dr0" :: "r"(val)); break;
142 case 1: __asm__ volatile("mov %0, %%dr1" :: "r"(val)); break;
143 case 2: __asm__ volatile("mov %0, %%dr2" :: "r"(val)); break;
144 case 3: __asm__ volatile("mov %0, %%dr3" :: "r"(val)); break;
145 case 6: __asm__ volatile("mov %0, %%dr6" :: "r"(val)); break;
146 case 7: __asm__ volatile("mov %0, %%dr7" :: "r"(val)); break;
147 default: break;
148 }
149}
150FORCEINLINE void __lidt(void* idt_ptr) {
151 __asm__ volatile ("lidt (%0)" :: "r"(idt_ptr));
152}
153
154// Read RFLAGS register
155FORCEINLINE unsigned long int __read_rflags(void) {
156 unsigned long int rflags;
157 __asm__ volatile (
158 "pushfl\n\t"
159 "pop %0"
160 : "=r"(rflags)
161 );
162 return rflags;
163}
164
165// Write RFLAGS register
166FORCEINLINE void __write_rflags(unsigned long int rflags) {
167 __asm__ volatile (
168 "push %0\n\t"
169 "popfl"
170 :: "r"(rflags)
171 );
172}
173
174// Read port (inw)
175FORCEINLINE unsigned short __inword(unsigned short port) {
176 unsigned short ret;
177 __asm__ volatile ("inw %1, %0" : "=a"(ret) : "Nd"(port));
178 return ret;
179}
180
181// Write port (outw)
182FORCEINLINE void __outword(unsigned short port, unsigned short val) {
183 __asm__ volatile ("outw %0, %1" : : "a"(val), "Nd"(port));
184}
185
186// Read port (inb)
187FORCEINLINE unsigned char __inbyte(unsigned short port) {
188 unsigned char ret;
189 __asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
190 return ret;
191}
192
193// Write port (outb)
194FORCEINLINE void __outbyte(unsigned short port, unsigned char val) {
195 __asm__ volatile ("outb %0, %1" :: "a"(val), "Nd"(port));
196}
197
198FORCEINLINE void send_eoi(unsigned char irq) {
199 if (irq >= 8) {
200 __outbyte(PIC2_COMMAND_SLAVE, PIC_EOI); // Slave PIC
201 }
202 __outbyte(PIC1_COMMAND_MASTER, PIC_EOI); // Master PIC
203}
204
205FORCEINLINE void invlpg(void* m) {
206 __asm__ volatile("invlpg (%0)" : : "b"(m) : "memory");
207}
208
209FORCEINLINE uint64_t __readmsr(uint32_t msr) {
210 uint32_t lo, hi;
211 __asm__ volatile ("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr));
212 return ((uint64_t)hi << 32) | lo;
213}
214
215FORCEINLINE void __writemsr(uint32_t msr, uint64_t value) {
216 uint32_t lo = value & 0xFFFFFFFF;
217 uint32_t hi = value >> 32;
218 __asm__ volatile ("wrmsr" : : "c"(msr), "a"(lo), "d"(hi));
219}
220
221FORCEINLINE uint64_t __read_rbp(void) {
222 uint64_t val;
223 __asm__ volatile ("mov %%rbp, %0" : "=r"(val));
224 return val;
225}
226
227FORCEINLINE uint64_t __read_rsp(void) {
228 uint64_t val;
229 __asm__ volatile ("mov %%rsp, %0" : "=r"(val));
230 return val;
231}
232
233FORCEINLINE uint64_t __read_rip(void) {
234 uint64_t rip;
235 __asm__ volatile ("leaq (%%rip), %0" : "=r"(rip));
236 return rip;
237}
238
240 __asm__ volatile("pause" ::: "memory");
241}
242
243FORCEINLINE uint64_t __readgsqword(uint64_t offset) {
244 uint64_t value;
245 __asm__ volatile (
246 "movq %%gs:(%1), %0"
247 : "=r"(value)
248 : "r"(offset)
249 : "memory"
250 );
251 return value;
252}
253
254FORCEINLINE uint64_t __readfsqword(uint64_t offset) {
255 uint64_t value;
256 __asm__ volatile (
257 "movq %%fs:(%1), %0"
258 : "=r"(value)
259 : "r"(offset)
260 : "memory"
261 );
262 return value;
263}
264
266 __asm__ volatile ("swapgs" ::: "memory");
267}
268
269FORCEINLINE bool __rdrand64(uint64_t* out) {
270 unsigned char ok;
271 uint64_t val;
272 __asm__ volatile("rdrand %0; setc %1"
273 : "=r"(val), "=qm"(ok));
274 *out = val;
275 return ok; // 1=success, 0=failure
276}
277
278FORCEINLINE uint64_t __rdtsc(void) {
279 uint32_t lo, hi;
280 __asm__ volatile ("rdtsc" : "=a"(lo), "=d"(hi));
281 return ((uint64_t)hi << 32) | lo;
282}
283
284#ifdef DEBUG
285
286// GDB Func to CLI and STI
287
288static void gcli(void) {
289 __cli();
290}
291
292static void gsti(void) {
293 __sti();
294}
295
296#endif
297
298#endif // X86_INTRINSICS_H
#define FORCEINLINE
Definition annotations.h:23
FORCEINLINE uint64_t __readmsr(uint32_t msr)
Definition intrin.h:209
FORCEINLINE void __writemsr(uint32_t msr, uint64_t value)
Definition intrin.h:215
#define PIC1_COMMAND_MASTER
Definition intrin.h:10
FORCEINLINE uint64_t __rdtsc(void)
Definition intrin.h:278
FORCEINLINE uint64_t __read_rip(void)
Definition intrin.h:233
#define PIC_EOI
Definition intrin.h:16
#define PIC2_COMMAND_SLAVE
Definition intrin.h:12
FORCEINLINE void __pause(void)
Definition intrin.h:239
FORCEINLINE uint64_t __readgsqword(uint64_t offset)
Definition intrin.h:243
FORCEINLINE uint64_t __read_rsp(void)
Definition intrin.h:227
FORCEINLINE bool __rdrand64(uint64_t *out)
Definition intrin.h:269
FORCEINLINE void __write_cr2(unsigned long val)
Definition intrin.h:88
FORCEINLINE uint64_t __read_dr(int reg)
Definition intrin.h:124
FORCEINLINE void invlpg(void *m)
Definition intrin.h:205
FORCEINLINE void __outword(unsigned short port, unsigned short val)
Definition intrin.h:182
FORCEINLINE void __hlt(void)
Definition intrin.h:65
FORCEINLINE unsigned long int __read_cr0(void)
Definition intrin.h:70
FORCEINLINE unsigned short __inword(unsigned short port)
Definition intrin.h:175
FORCEINLINE void __sti(void)
Definition intrin.h:59
FORCEINLINE uint64_t __read_rbp(void)
Definition intrin.h:221
FORCEINLINE void __write_cr0(unsigned long int val)
Definition intrin.h:77
FORCEINLINE void __write_cr4(unsigned long val)
Definition intrin.h:108
FORCEINLINE void __write_dr(int reg, uint64_t val)
Definition intrin.h:139
FORCEINLINE unsigned long __read_cr4(void)
Definition intrin.h:103
FORCEINLINE void __swapgs(void)
Definition intrin.h:265
FORCEINLINE void __outbyte(unsigned short port, unsigned char val)
Definition intrin.h:194
FORCEINLINE void __write_cr8(unsigned long val)
Definition intrin.h:118
FORCEINLINE void __cli(void)
Definition intrin.h:43
FORCEINLINE uint64_t __readfsqword(uint64_t offset)
Definition intrin.h:254
FORCEINLINE void __write_cr3(uint64_t val)
Definition intrin.h:98
FORCEINLINE unsigned long __read_cr2(void)
Definition intrin.h:82
FORCEINLINE unsigned long int __read_rflags(void)
Definition intrin.h:155
FORCEINLINE void __lidt(void *idt_ptr)
Definition intrin.h:150
FORCEINLINE void __write_rflags(unsigned long int rflags)
Definition intrin.h:166
FORCEINLINE unsigned char __inbyte(unsigned short port)
Definition intrin.h:187
FORCEINLINE void __stac(void)
Definition intrin.h:48
FORCEINLINE unsigned long __read_cr8(void)
Definition intrin.h:113
FORCEINLINE void send_eoi(unsigned char irq)
Definition intrin.h:198
FORCEINLINE uint64_t __read_cr3(void)
Definition intrin.h:93
FORCEINLINE void __clac(void)
Definition intrin.h:53