MentOS  0.8.0
The Mentoring Operating System
proc_access.h
Go to the documentation of this file.
1 
6 #pragma once
7 
8 #include "stdint.h"
9 
10 #define CR0_PE 0x00000001u
11 #define CR0_MP 0x00000002u
12 #define CR0_EM 0x00000004u
13 #define CR0_TS 0x00000008u
14 #define CR0_ET 0x00000010u
15 #define CR0_PG 0x80000000u
16 
17 #define CR4_SEE 0x00008000u
18 #define CR4_SMAP 0x00200000u
19 #define CR4_SMEP 0x00100000u
20 #define CR4_OSXSAVE 0x00040000u
21 #define CR4_PCIDE 0x00020000u
22 #define CR4_RDWRFSGS 0x00010000u
23 #define CR4_SMXE 0x00004000u
24 #define CR4_VMXE 0x00002000u
25 #define CR4_OSXMM 0x00000400u
26 #define CR4_OSFXS 0x00000200u
27 #define CR4_PCE 0x00000100u
28 #define CR4_PGE 0x00000080u
29 #define CR4_MCE 0x00000040u
30 #define CR4_PAE 0x00000020u
31 #define CR4_PSE 0x00000010u
32 #define CR4_DE 0x00000008u
33 #define CR4_TSD 0x00000004u
34 #define CR4_PVI 0x00000002u
35 #define CR4_VME 0x00000001u
36 
39 static inline uint16_t get_es(void)
40 {
41  uint16_t es;
42  __asm__ __volatile__("mov %%es, %0"
43  : "=r"(es));
44  return es;
45 }
46 
49 static inline void set_es(uint16_t es)
50 {
51  __asm__ __volatile__("mov %0, %%es"
52  :
53  : "r"(es));
54 }
55 
58 static inline uint16_t get_ds(void)
59 {
60  uint16_t ds;
61  __asm__ __volatile__("mov %%ds, %0"
62  : "=r"(ds));
63  return ds;
64 }
65 
68 static inline void set_ds(uint16_t ds)
69 {
70  __asm__ __volatile__("mov %0, %%ds"
71  :
72  : "r"(ds));
73 }
74 
77 static inline uint16_t get_fs(void)
78 {
79  uint16_t fs;
80  __asm__ __volatile__("mov %%fs, %0"
81  : "=r"(fs));
82  return fs;
83 }
84 
87 static inline void set_fs(uint16_t fs)
88 {
89  __asm__ __volatile__("mov %0, %%fs"
90  :
91  : "r"(fs));
92 }
93 
96 static inline uint16_t get_gs(void)
97 {
98  uint16_t gs;
99  __asm__ __volatile__("mov %%gs, %0"
100  : "=r"(gs));
101  return gs;
102 }
103 
106 static inline void set_gs(uint16_t gs)
107 {
108  __asm__ __volatile__("mov %0, %%gs"
109  :
110  : "r"(gs));
111 }
112 
115 static inline uint16_t get_ss(void)
116 {
117  uint16_t ss;
118  __asm__ __volatile__("mov %%ss, %0"
119  : "=r"(ss));
120  return ss;
121 }
122 
125 static inline void set_ss(uint16_t ss)
126 {
127  __asm__ __volatile__("mov %0, %%ss"
128  :
129  : "r"(ss));
130 }
131 
134 static inline uintptr_t get_cr0(void)
135 {
136  uintptr_t cr0;
137  __asm__ __volatile__("mov %%cr0, %0"
138  : "=r"(cr0));
139  return (cr0);
140 }
141 
144 static inline void set_cr0(uintptr_t cr0)
145 {
146  __asm__ __volatile__("mov %0, %%cr0"
147  :
148  : "r"(cr0));
149 }
150 
151 
154 static inline uintptr_t get_cr2(void)
155 {
156  uintptr_t cr2;
157  __asm__ __volatile__("mov %%cr2, %0"
158  : "=r"(cr2));
159  return (cr2);
160 }
161 
164 static inline void set_cr2(uintptr_t cr2)
165 {
166  __asm__ __volatile__("mov %0, %%cr2"
167  :
168  : "r"(cr2));
169 }
170 
173 static inline uintptr_t get_cr3(void)
174 {
175  uintptr_t cr3;
176  __asm__ __volatile__("mov %%cr3, %0"
177  : "=r"(cr3));
178  return (cr3);
179 }
180 
183 static inline void set_cr3(uintptr_t cr3)
184 {
185  __asm__ __volatile__("mov %0, %%cr3"
186  :
187  : "r"(cr3));
188 }
189 
192 static inline uintptr_t get_cr4(void)
193 {
194  uintptr_t cr4;
195  __asm__ __volatile__("mov %%cr4, %0"
196  : "=r"(cr4));
197  return (cr4);
198 }
199 
202 static inline void set_cr4(uintptr_t cr4)
203 {
204  __asm__ __volatile__("mov %0, %%cr4"
205  :
206  : "r"(cr4)
207  : "memory");
208 }
209 
212 static inline uintptr_t get_eflags(void)
213 {
214  uintptr_t eflags;
215  // "=rm" is safe here, because "pop" adjusts the stack before
216  // it evaluates its effective address -- this is part of the
217  // documented behavior of the "pop" instruction.
218  __asm__ __volatile__("pushf; pop %0"
219  : "=rm"(eflags)
220  : // no input
221  : "memory");
222  return eflags;
223 }
224 
226 static inline void clear_ts(void)
227 {
228  __asm__ __volatile__("clts");
229 }
230 
233 static inline unsigned short get_tr(void)
234 {
235  unsigned short seg;
236  __asm__ __volatile__("str %0"
237  : "=rm"(seg));
238  return (seg);
239 }
240 
243 static inline void set_tr(unsigned short seg)
244 {
245  __asm__ __volatile__("ltr %0"
246  :
247  : "rm"(seg));
248 }
249 
252 static inline unsigned short sldt(void)
253 {
254  unsigned short seg;
255  __asm__ __volatile__("sldt %0"
256  : "=rm"(seg));
257  return (seg);
258 }
259 
262 static inline void lldt(unsigned short seg)
263 {
264  __asm__ __volatile__("lldt %0"
265  :
266  : "rm"(seg));
267 }
268 
272 static inline void lgdt(uintptr_t *desc)
273 {
274  __asm__ __volatile__("lgdt %0"
275  :
276  : "m"(*desc));
277 }
278 
282 static inline void lidt(uintptr_t *desc)
283 {
284  __asm__ __volatile__("lidt %0"
285  :
286  : "m"(*desc));
287 }
288 
291 static inline void sti(void)
292 {
293  __asm__ __volatile__("sti"
294  :
295  :
296  : "memory");
297 }
298 
301 static inline void cli(void)
302 {
303  __asm__ __volatile__("cli"
304  :
305  :
306  : "memory");
307 }
308 
311 static inline void swapgs(void)
312 {
313  __asm__ __volatile__("swapgs");
314 }
315 
317 static inline void hlt(void)
318 {
319  __asm__ __volatile__("hlt");
320 }
321 
323 static inline void pause(void)
324 {
325  __asm__ __volatile__("pause");
326 }
327 
328 // == Memory clobbers =========================================================
329 // Memory clobber implies a fence, and it also impacts how the compiler treats
330 // potential data aliases. A memory clobber says that the asm block modifies
331 // memory that is not otherwise mentioned in the asm instructions.
332 // So, for example, a correct use of memory clobbers would be when using an
333 // instruction that clears a cache line. The compiler will assume that
334 // virtually any data may be aliased with the memory changed by that
335 // instruction. As a result, all required data used after the asm block
336 // will be reloaded from memory after the asm completes. This is much more
337 // expensive than the simple fence implied by the "volatile" attribute.
338 
339 // == Volatile Block ==========================================================
340 // Making an inline asm block "volatile" as in this example, ensures that,
341 // as it optimizes, the compiler does not move any instructions above or
342 // below the block of asm statements.
343 // __asm__ __volatile__(" addic. %0,%1,%2\n" : "=r"(res): "=r"(a),"r"(a))
344 // This can be particularly important in cases when the code is accessing
345 // shared memory.
static uint16_t get_ss(void)
Reads the Stack Segment (SS).
Definition: proc_access.h:115
static void set_fs(uint16_t fs)
Sets FS.
Definition: proc_access.h:87
static uintptr_t get_cr0(void)
Reads the current cr0 value.
Definition: proc_access.h:134
static uint16_t get_es(void)
Reads the Extra Segment (DS).
Definition: proc_access.h:39
static void set_cr0(uintptr_t cr0)
Sets the cr0 value.
Definition: proc_access.h:144
static unsigned short sldt(void)
Reads the segment selector from the local descriptor table register (LDTR).
Definition: proc_access.h:252
static uintptr_t get_cr3(void)
Reads the current cr3 value.
Definition: proc_access.h:173
static void set_es(uint16_t es)
Sets the Extra Segment (DS).
Definition: proc_access.h:49
static uint16_t get_fs(void)
Reads FS.
Definition: proc_access.h:77
static uint16_t get_ds(void)
Reads the Data Segment (DS).
Definition: proc_access.h:58
static void set_cr3(uintptr_t cr3)
Sets the cr3 value.
Definition: proc_access.h:183
static void lgdt(uintptr_t *desc)
Loads the values in the source operand into the global descriptor table register (GDTR) or the interr...
Definition: proc_access.h:272
static uintptr_t get_eflags(void)
Reads entire contents of the EFLAGS register.
Definition: proc_access.h:212
static void swapgs(void)
Exchanges the current GS base register value with the value contained in MSR address C0000102H.
Definition: proc_access.h:311
static void lldt(unsigned short seg)
Loads the source operand into the segment selector field of the local descriptor table register (LDTR...
Definition: proc_access.h:262
static void set_ss(uint16_t ss)
Sets the Stack Segment (SS).
Definition: proc_access.h:125
static void lidt(uintptr_t *desc)
Loads the values in the source operand into the global descriptor table register (GDTR) or the interr...
Definition: proc_access.h:282
static void set_cr4(uintptr_t cr4)
Sets the cr4 value.
Definition: proc_access.h:202
static void cli(void)
Clear interrupt flag; interrupts disabled when interrupt flag cleared.
Definition: proc_access.h:301
static void set_cr2(uintptr_t cr2)
Sets the cr2 value.
Definition: proc_access.h:164
static void pause(void)
Gives hint to processor that improves performance of spin-wait loops.
Definition: proc_access.h:323
static uintptr_t get_cr4(void)
Reads the current cr4 value.
Definition: proc_access.h:192
static unsigned short get_tr(void)
Reads the segment selector from the task register (TR).
Definition: proc_access.h:233
static uint16_t get_gs(void)
Reads GS.
Definition: proc_access.h:96
static void set_tr(unsigned short seg)
Loads the source operand into the segment selector field of the task register.
Definition: proc_access.h:243
static void set_gs(uint16_t gs)
Sets GS.
Definition: proc_access.h:106
static void hlt(void)
Halts the CPU until the next external interrupt is fired.
Definition: proc_access.h:317
static void clear_ts(void)
Clears the task-switched (TS) flag in the CR0 register.
Definition: proc_access.h:226
static void set_ds(uint16_t ds)
Sets the Data Segment (DS).
Definition: proc_access.h:68
static void sti(void)
Set interrupt flag; external, maskable interrupts enabled at the end of the next instruction.
Definition: proc_access.h:291
static uintptr_t get_cr2(void)
Reads the current cr2 value.
Definition: proc_access.h:154
procfs_t fs
The procfs filesystem.
Definition: procfs.c:76
Standard integer data-types.
unsigned uintptr_t
Define the unsigned 32-bit pointer.
Definition: stdint.h:36
unsigned short uint16_t
Define the unsigned 16-bit integer.
Definition: stdint.h:24