summaryrefslogtreecommitdiff
path: root/kernel/gdt.c
blob: 92d3d4cb50b374c4a1c358529bc61ce4a7209a68 (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
#include "gdt.h"

tss_entry tss = tss_entry_init(0xfffff800, 0x10, 0x0b, 0x13);

gdt_entry gdt[] = {
	gdt_entry_init(0, 0, 0),
	gdt_entry_init(0, 0xfffff, 0xc09a), // Code segment.
	gdt_entry_init(0, 0xfffff, 0xc092), // Data segment.
	gdt_entry_init(0, 0xfffff, 0xc0fa), // User mode code segment.
	gdt_entry_init(0, 0xfffff, 0xc0f2), // User mode data segment.
	gdt_entry_init(0, sizeof(tss_entry), 0x00e9), // TSS.
};

gdt_ptr gdtr = {
	.base = gdt,
	.limit = sizeof(gdt) - 1
};

void gdt_init() {
	gdt[5].base_low = (uint32_t)&tss & 0xffff;
	gdt[5].base_mid = (uint32_t)&tss >> 16 & 0xff;
	gdt[5].base_high = (uint32_t)&tss >> 24 & 0xff;
	
	asm volatile(
		"lgdt (%0)\n"
		"mov %w1, %%ds\n"
		"mov %w1, %%es\n"
		"mov %w1, %%fs\n"
		"mov %w1, %%gs\n"
		"mov %w1, %%ss\n"
		"ljmp $0x08, $.flush\n"
		".flush:\n"
		"ltr %w2\n"
		: : "r" (&gdtr), "r" (0x10), "r" (0x28)
	);
}