59 lines
1.4 KiB
D
59 lines
1.4 KiB
D
/**
|
|
* GDT (Global Descriptor Table) functionality.
|
|
*/
|
|
module hulk.gdt;
|
|
|
|
import ldc.llvmasm;
|
|
|
|
struct Gdt
|
|
{
|
|
struct gdtr_t
|
|
{
|
|
ushort limit;
|
|
align(2) ulong offset;
|
|
}
|
|
static assert(gdtr_t.sizeof == 10u);
|
|
|
|
public enum size_t SELECTOR_NULL = 0x00u;
|
|
public enum size_t SELECTOR_KERNEL_CODE = 0x08u;
|
|
public enum size_t SELECTOR_KERNEL_DATA = 0x10u;
|
|
public enum size_t SELECTOR_COUNT = 3u;
|
|
|
|
static __gshared ulong[SELECTOR_COUNT] gdt;
|
|
static __gshared gdtr_t gdtr;
|
|
|
|
public static void initialize()
|
|
{
|
|
gdt[SELECTOR_KERNEL_CODE / ulong.sizeof] = 0x00_A_F_9A_000000_0000u;
|
|
gdt[SELECTOR_KERNEL_DATA / ulong.sizeof] = 0x00_C_F_92_000000_0000u;
|
|
gdtr.limit = gdt.sizeof - 1u;
|
|
gdtr.offset = cast(ulong)&gdt;
|
|
lgdt(&gdtr);
|
|
load_data_selectors(SELECTOR_KERNEL_DATA);
|
|
load_code_selector(SELECTOR_KERNEL_CODE);
|
|
}
|
|
|
|
private static void lgdt(gdtr_t * gdtr)
|
|
{
|
|
__asm("lgdt $0", "*m", gdtr);
|
|
}
|
|
|
|
private static void load_data_selectors(ulong selector)
|
|
{
|
|
__asm(`mov %ax, %ds
|
|
mov %ax, %es
|
|
mov %ax, %fs
|
|
mov %ax, %gs
|
|
mov %ax, %ss`, "{rax}", selector);
|
|
}
|
|
|
|
private static void load_code_selector(ulong selector)
|
|
{
|
|
__asm(`push %rax
|
|
movabs $$1f, %rax
|
|
push %rax
|
|
lretq
|
|
1:`, "{rax}", selector);
|
|
}
|
|
}
|