1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
#ifndef FOOLOS_X86_H
#define FOOLOS_X86_H
/**
* @file
*
* X86 32-bit Basics
* =================
*
* **All the functions are very specific to the targeted x86 architecture.**
*
* This is the header of our basic **x86** function definitions.
* Most of the functions are implemented in assembler in the file _asm/x86.s_,
* however a few short helper functions are defined in this header itself:
*
* * x86_set_page_directory()
* * x86_paging_enable()
* * x86_paging_disable()
*
*
* Reading and Writing Ports
* -------------------------
*
* The functions of the form x86_outX() and x86_inX(), where the X
* indicates the value size allow reading and writing ports.
*
* * x86_outb() / x86_inb()
* * x86_outw() / x86_inw()
* * x86_outl() / x86_inl()
*
* The sizes are:
*
* * b - byte (8 bit)
* * w - word (16 bit)
* * l - double word (32 bit)
*
* Remember, that the port address is always 32 bits wide.
*
* Dependencies
* ------------
*
* All we need are uint32_t, uint16_t and uint8_t as provided by <stdint.h>
*
* References
* ----------
* * http://wiki.osdev.org/Interrupt_Service_Routines
* * https://wiki.osdev.org/CPU_Registers_x86
* * ...
*
*/
// we need uint32_t, uint16_t, uint8_t //
#include <stdint.h>
/** write byte to port */
void x86_outb (uint32_t port, uint8_t data);
/** read byte from port */
uint8_t x86_inb (uint32_t port);
/** write word to port */
void x86_outw (uint32_t port, uint16_t data);
/** read word from port */
uint16_t x86_inw (uint32_t port);
/** write double word to port */
void x86_outl (uint32_t port, uint32_t data);
/** read double word from port */
uint32_t x86_inl (uint32_t port);
/** disable interrupts */
void x86_cli ();
/** enable interrupts */
void x86_sti ();
/** xchg - this can be used for semaphors and simlar */
uint8_t x86_xchg (uint32_t addr, uint32_t val);
/** invlpg - invalidate translation lookaside buffer */
void x86_invlpg(uint32_t addr);
/** read value from control register specified by num */
uint32_t x86_get_cr(uint8_t num);
/** write given value to the control register specified by num */
void x86_set_cr(uint8_t num, uint32_t value);
/** Set the address of the page directory. This is required **before** enabling paging */
static inline void x86_set_page_directory(uint32_t pdir_addr) {x86_set_cr(3,pdir_addr);}
/** Get the address of the page directory. */
static inline uint32_t x86_get_page_directory() {return x86_get_cr(3);}
/** Enable paging */
static inline void x86_paging_enable() {x86_set_cr(0,x86_get_cr(0)| 0x80000000);}
/** Disable paging */
static inline void x86_paging_disable() {x86_set_cr(0,x86_get_cr(0)&~0x80000000);}
#endif
|