blob: c352f3233577f00cc8e027b2629b53ecd199a925 (
plain)
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
|
#ifndef __X86_GDT_H
#define __X86_GDT_H
#include <stdint.h>
// Limit is 20-bit value
#define GDT_LIMIT_MAX (0x000FFFFF)
// Flags (4 bits)
#define GDT_GRAN_4KB (1 << 3)
#define GDT_GRAN_BYTE (0 << 3) /*
* Granularity. Indicates the size the
* limit value is scaled by.
*/
#define GDT_64BIT (1 << 1)
#define GDT_32BIT (1 << 2)
#define GDT_16BIT (0 << 2)
// Access flags (8 bits)
#define GDT_ACCESS_ACC (1 << 0) /*
* Accessed bit. The CPU sets 1 when
* the segment is accessed.
*/
#define GDT_ACCESS_RW (1 << 1) /*
* Readable/Writable bit.
*
* For code segments: readable bit.
* If set 1 read access is allowed.
* Write access is never allowed.
*
* For data segments: writable bit.
* If set 1 write access is allowed.
* Read access is always allowed.
*/
#define GDT_ACCESS_DC (1 << 2) /*
* Direction/Conforming bit.
*
*/
#define GDT_ACCESS_EX (1 << 3) /*
* Executable bit.
* 0 defines a data segment
* 1 defines a code segment
*/
#define GDT_ACCESS_S (1 << 4) /*
* Descriptor type bit.
* 0 defines a system segment (TSS, LDT)
* 1 defines a code/data segment
*/
#define GDT_ACCESS_PL0 (0 << 5) /* the highest privilege */
#define GDT_ACCESS_PL1 (1 << 5)
#define GDT_ACCESS_PL2 (2 << 5)
#define GDT_ACCESS_PL3 (3 << 5) /* the lowest privilege */
#define GDT_ACCESS_PRESENT (1 << 7) /* Must be set for any valid segments */
struct gdt_entry {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
union {
struct {
uint8_t type : 4; // EX + DC + RW + ACC
uint8_t s : 1; // 0 = system desc, 1 = regular desc
uint8_t dpl : 2; // desc privilege level
uint8_t p : 1; // present
};
uint8_t access;
};
union {
struct {
uint8_t limit_hi : 4;
uint8_t avl : 1; // available bit
uint8_t l : 1; // 64-bit segment
uint8_t d : 1; // default operation size. 0 = 16 bit, 1 = 32 bit
uint8_t g : 1; // granularity: 0 = byte, 1 = 4 KB
};
struct {
uint8_t limit_high : 4;
uint8_t flags : 4;
};
};
uint8_t base_high;
} __attribute__((packed));
void init_segmentation(void);
#endif /* __X86_GDT_H */
|