My Project
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
23#ifndef UNREFERENCED_PARAMETER
24#define UNREFERENCED_PARAMETER(x) (void)(x)
25#endif
26
27#ifdef _MSC_VER
28#ifndef __asm__
29#define __asm__ __asm
30#endif
31#endif
32
33#include <stdbool.h>
35
36// Disable interrupts (cli)
38void __cli(void) {
39 __asm__ volatile ("cli");
40}
41
42// Enable interrupts (sti)
44void __sti(void) {
45 __asm__ volatile ("sti");
46}
47
48// Halt CPU until next interrupt (hlt)
50void __hlt(void) {
51 __asm__ volatile ("hlt");
52}
53
54// Read CR0 register
55FORCEINLINE unsigned long int __read_cr0(void) {
56 unsigned long int val;
57 __asm__ volatile ("mov %%cr0, %0" : "=r"(val));
58 return val;
59}
60
61// Write CR0 register
62FORCEINLINE void __write_cr0(unsigned long int val) {
63 __asm__ volatile ("mov %0, %%cr0" :: "r"(val));
64}
65
66// CR2 (Page fault linear address)
67FORCEINLINE unsigned long __read_cr2(void) {
68 unsigned long val;
69 __asm__ volatile("mov %%cr2, %0" : "=r"(val));
70 return val;
71}
72
73FORCEINLINE void __write_cr2(unsigned long val) {
74 __asm__ volatile("mov %0, %%cr2" :: "r"(val) : "memory");
75}
76
77// CR3 (Page table base address)
78FORCEINLINE uint64_t __read_cr3(void) {
79 uint64_t val;
80 __asm__ volatile("mov %%cr3, %0" : "=r"(val));
81 return val;
82}
83FORCEINLINE void __write_cr3(uint64_t val) {
84 __asm__ volatile("mov %0, %%cr3" :: "r"(val) : "memory");
85}
86
87// CR4 (Feature control)
88FORCEINLINE unsigned long __read_cr4(void) {
89 unsigned long val;
90 __asm__ volatile("mov %%cr4, %0" : "=r"(val));
91 return val;
92}
93FORCEINLINE void __write_cr4(unsigned long val) {
94 __asm__ volatile("mov %0, %%cr4" :: "r"(val) : "memory");
95}
96
97// CR8 (Task Priority Register, x86-64 only)
98FORCEINLINE unsigned long __read_cr8(void) {
99 unsigned long val;
100 __asm__ volatile("mov %%cr8, %0" : "=r"(val));
101 return val;
102}
103FORCEINLINE void __write_cr8(unsigned long val) {
104 __asm__ volatile("mov %0, %%cr8" :: "r"(val) : "memory");
105}
106
107
108// Read DRx register (dr0-dr7) (Usage __read_dr(3) = will return dr3.
109FORCEINLINE uint64_t __read_dr(int reg) {
110 unsigned long val = 0;
111 switch (reg) {
112 case 0: __asm__ volatile("mov %%dr0, %0" : "=r"(val)); break;
113 case 1: __asm__ volatile("mov %%dr1, %0" : "=r"(val)); break;
114 case 2: __asm__ volatile("mov %%dr2, %0" : "=r"(val)); break;
115 case 3: __asm__ volatile("mov %%dr3, %0" : "=r"(val)); break;
116 case 6: __asm__ volatile("mov %%dr6, %0" : "=r"(val)); break;
117 case 7: __asm__ volatile("mov %%dr7, %0" : "=r"(val)); break;
118 default: break;
119 }
120 return val;
121}
122
123// Write DRx register (dr0-dr7) (Usage __write_dr(3, 0x5000) = will write 0x5000 to dr3.
124FORCEINLINE void __write_dr(int reg, uint64_t val) {
125 switch (reg) {
126 case 0: __asm__ volatile("mov %0, %%dr0" :: "r"(val)); break;
127 case 1: __asm__ volatile("mov %0, %%dr1" :: "r"(val)); break;
128 case 2: __asm__ volatile("mov %0, %%dr2" :: "r"(val)); break;
129 case 3: __asm__ volatile("mov %0, %%dr3" :: "r"(val)); break;
130 case 6: __asm__ volatile("mov %0, %%dr6" :: "r"(val)); break;
131 case 7: __asm__ volatile("mov %0, %%dr7" :: "r"(val)); break;
132 default: break;
133 }
134}
135FORCEINLINE void __lidt(void* idt_ptr) {
136 __asm__ volatile ("lidt (%0)" :: "r"(idt_ptr));
137}
138
139// Read RFLAGS register
140FORCEINLINE unsigned long int __read_rflags(void) {
141 unsigned long int rflags;
142 __asm__ volatile (
143 "pushfl\n\t"
144 "pop %0"
145 : "=r"(rflags)
146 );
147 return rflags;
148}
149
150// Write RFLAGS register
151FORCEINLINE void __write_rflags(unsigned long int rflags) {
152 __asm__ volatile (
153 "push %0\n\t"
154 "popfl"
155 :: "r"(rflags)
156 );
157}
158
159// Read port (inw)
160FORCEINLINE unsigned short __inword(unsigned short port) {
161 unsigned short ret;
162 __asm__ volatile ("inw %1, %0" : "=a"(ret) : "Nd"(port));
163 return ret;
164}
165
166// Write port (outw)
167FORCEINLINE void __outword(unsigned short port, unsigned short val) {
168 __asm__ volatile ("outw %0, %1" : : "a"(val), "Nd"(port));
169}
170
171// Read port (inb)
172FORCEINLINE unsigned char __inbyte(unsigned short port) {
173 unsigned char ret;
174 __asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
175 return ret;
176}
177
178// Write port (outb)
179FORCEINLINE void __outbyte(unsigned short port, unsigned char val) {
180 __asm__ volatile ("outb %0, %1" :: "a"(val), "Nd"(port));
181}
182
183FORCEINLINE void send_eoi(unsigned char irq) {
184 if (irq >= 8) {
185 __outbyte(PIC2_COMMAND_SLAVE, PIC_EOI); // Slave PIC
186 }
187 __outbyte(PIC1_COMMAND_MASTER, PIC_EOI); // Master PIC
188}
189
190FORCEINLINE void invlpg(void* m) {
191 __asm__ volatile("invlpg (%0)" : : "b"(m) : "memory");
192}
193
194FORCEINLINE uint64_t __readmsr(uint32_t msr) {
195 uint32_t lo, hi;
196 __asm__ volatile ("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr));
197 return ((uint64_t)hi << 32) | lo;
198}
199
200FORCEINLINE void __writemsr(uint32_t msr, uint64_t value) {
201 uint32_t lo = value & 0xFFFFFFFF;
202 uint32_t hi = value >> 32;
203 __asm__ volatile ("wrmsr" : : "c"(msr), "a"(lo), "d"(hi));
204}
205
206FORCEINLINE uint64_t __read_rbp(void) {
207 uint64_t val;
208 __asm__ volatile ("mov %%rbp, %0" : "=r"(val));
209 return val;
210}
211
212FORCEINLINE uint64_t __read_rsp(void) {
213 uint64_t val;
214 __asm__ volatile ("mov %%rsp, %0" : "=r"(val));
215 return val;
216}
217
218FORCEINLINE uint64_t __read_rip(void) {
219 uint64_t rip;
220 __asm__ volatile ("leaq (%%rip), %0" : "=r"(rip));
221 return rip;
222}
223
225 __asm__ volatile("pause" ::: "memory");
226}
227
228FORCEINLINE uint64_t __readgsqword(uint64_t offset) {
229 uint64_t value;
230 __asm__ volatile (
231 "movq %%gs:(%1), %0"
232 : "=r"(value)
233 : "r"(offset)
234 : "memory"
235 );
236 return value;
237}
238
239FORCEINLINE uint64_t __readfsqword(uint64_t offset) {
240 uint64_t value;
241 __asm__ volatile (
242 "movq %%fs:(%1), %0"
243 : "=r"(value)
244 : "r"(offset)
245 : "memory"
246 );
247 return value;
248}
249
251 __asm__ volatile ("swapgs" ::: "memory");
252}
253
254FORCEINLINE bool __rdrand64(uint64_t* out) {
255 unsigned char ok;
256 uint64_t val;
257 __asm__ volatile("rdrand %0; setc %1"
258 : "=r"(val), "=qm"(ok));
259 *out = val;
260 return ok; // 1=success, 0=failure
261}
262
263FORCEINLINE uint64_t __rdtsc(void) {
264 uint32_t lo, hi;
265 __asm__ volatile ("rdtsc" : "=a"(lo), "=d"(hi));
266 return ((uint64_t)hi << 32) | lo;
267}
268
269#endif // X86_INTRINSICS_H
#define FORCEINLINE
Definition annotations.h:22
FORCEINLINE uint64_t __readmsr(uint32_t msr)
Definition intrin.h:194
FORCEINLINE void __writemsr(uint32_t msr, uint64_t value)
Definition intrin.h:200
#define PIC1_COMMAND_MASTER
Definition intrin.h:10
FORCEINLINE uint64_t __rdtsc(void)
Definition intrin.h:263
FORCEINLINE uint64_t __read_rip(void)
Definition intrin.h:218
#define PIC_EOI
Definition intrin.h:16
#define PIC2_COMMAND_SLAVE
Definition intrin.h:12
FORCEINLINE void __pause(void)
Definition intrin.h:224
FORCEINLINE uint64_t __readgsqword(uint64_t offset)
Definition intrin.h:228
FORCEINLINE uint64_t __read_rsp(void)
Definition intrin.h:212
FORCEINLINE bool __rdrand64(uint64_t *out)
Definition intrin.h:254
FORCEINLINE void __write_cr2(unsigned long val)
Definition intrin.h:73
FORCEINLINE uint64_t __read_dr(int reg)
Definition intrin.h:109
FORCEINLINE void invlpg(void *m)
Definition intrin.h:190
FORCEINLINE void __outword(unsigned short port, unsigned short val)
Definition intrin.h:167
FORCEINLINE void __hlt(void)
Definition intrin.h:50
FORCEINLINE unsigned long int __read_cr0(void)
Definition intrin.h:55
FORCEINLINE unsigned short __inword(unsigned short port)
Definition intrin.h:160
FORCEINLINE void __sti(void)
Definition intrin.h:44
FORCEINLINE uint64_t __read_rbp(void)
Definition intrin.h:206
FORCEINLINE void __write_cr0(unsigned long int val)
Definition intrin.h:62
FORCEINLINE void __write_cr4(unsigned long val)
Definition intrin.h:93
FORCEINLINE void __write_dr(int reg, uint64_t val)
Definition intrin.h:124
FORCEINLINE unsigned long __read_cr4(void)
Definition intrin.h:88
FORCEINLINE void __swapgs(void)
Definition intrin.h:250
FORCEINLINE void __outbyte(unsigned short port, unsigned char val)
Definition intrin.h:179
FORCEINLINE void __write_cr8(unsigned long val)
Definition intrin.h:103
FORCEINLINE void __cli(void)
Definition intrin.h:38
FORCEINLINE uint64_t __readfsqword(uint64_t offset)
Definition intrin.h:239
FORCEINLINE void __write_cr3(uint64_t val)
Definition intrin.h:83
FORCEINLINE unsigned long __read_cr2(void)
Definition intrin.h:67
FORCEINLINE unsigned long int __read_rflags(void)
Definition intrin.h:140
FORCEINLINE void __lidt(void *idt_ptr)
Definition intrin.h:135
FORCEINLINE void __write_rflags(unsigned long int rflags)
Definition intrin.h:151
FORCEINLINE unsigned char __inbyte(unsigned short port)
Definition intrin.h:172
FORCEINLINE unsigned long __read_cr8(void)
Definition intrin.h:98
FORCEINLINE void send_eoi(unsigned char irq)
Definition intrin.h:183
FORCEINLINE uint64_t __read_cr3(void)
Definition intrin.h:78