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
|
#include "gdt.h"
#include "smp.h"
#include "lib/string.h"
static struct gdt_entry _gdt[GDT_TSS_HI+1] =
{
[GDT_KERNEL_NULL] = { 0 },
[GDT_KERNEL_CODE] = (struct gdt_entry) {
.limit_0_15 = 0xFFFF,
.base_0_15 = 0x0,
.base_16_23 = 0x0,
.type_flg = 0b10011010,
.limit_flg = 0b10101111,
.base_24_31 = 0x0
},
[GDT_KERNEL_DATA] = (struct gdt_entry) {
.limit_0_15 = 0xFFFF,
.base_0_15 = 0x0,
.base_16_23 = 0x0,
.type_flg = 0b10010010,
.limit_flg = 0b10101111,
.base_24_31 = 0x0
},
[GDT_USER_NULL] = { 0 },
[GDT_USER_DATA] = (struct gdt_entry) {
.limit_0_15 = 0xFFFF,
.base_0_15 = 0x0,
.base_16_23 = 0x0,
.type_flg = 0b11110010,
.limit_flg = 0b10101111,
.base_24_31 = 0x0
},
[GDT_USER_CODE] = (struct gdt_entry) {
.limit_0_15 = 0xFFFF,
.base_0_15 = 0x0,
.base_16_23 = 0x0,
.type_flg = 0b11111010,
.limit_flg = 0b10101111,
.base_24_31 = 0x0
},
[GDT_TSS_LO] = (struct gdt_entry) {
.limit_0_15 = 0x0,
.base_0_15 = 0x0,
.base_16_23 = 0x0,
.type_flg = 0x89,
.limit_flg = 0x0,
.base_24_31 = 0x0
},
[GDT_TSS_HI] = { 0 }
};
void
gdt_setup(processor_t *processor)
{
memcpy(processor->gdt, _gdt, sizeof(struct gdt_entry) * (GDT_TSS_HI+1));
memset(processor->iopb, 0, 0x2000);
struct gdt_descriptor gdtr;
gdtr.base = (uintptr_t)&processor->gdt;
gdtr.limit = sizeof(struct gdt_entry) * (GDT_TSS_HI+1) - 1;
extern void load_gdt(struct gdt_descriptor *gdtr);
load_gdt(&gdtr);
uintptr_t tss_base = (uintptr_t)&processor->tss;
size_t tss_limit = sizeof(struct tss);
struct gdt_entry *tss_lo = &processor->gdt[GDT_TSS_LO];
struct gdt_entry *tss_hi = &processor->gdt[GDT_TSS_HI];
tss_lo->base_0_15 = (uint16_t)(tss_base & 0xFFFF);
tss_lo->base_16_23 = (uint8_t)((tss_base >> 16) & 0xFF);
tss_lo->base_24_31 = (uint8_t)((tss_base >> 24) & 0xFF);
tss_hi->limit_0_15 = (uint16_t)((tss_base >> 32) & 0xFFFF);
tss_hi->base_0_15 = (uint16_t)((tss_base >> 48) & 0xFFFF);
tss_lo->limit_0_15 = (uint16_t)(tss_limit & 0xFFFF);
tss_lo->limit_flg |= (uint8_t)((tss_limit >> 16) & 0xF);
processor->tss.iopb = sizeof(struct tss);
extern void load_tss(void);
load_tss();
}
|