k-chow/k/gdt.c
Julien CLEMENT 02811acc2c feat(gdt): add macros for generic kernel segment descriptors
Signed-off-by: Julien CLEMENT <julien.clement@epita.fr>
2021-07-16 02:47:12 +02:00

117 lines
2.3 KiB
C

#include "gdt.h"
static struct gdt gdt = { 0 };
static void create_kernel_ds(void)
{
struct gdt_entry *entry = gdt.entries + KERNEL_DS_INDEX;
uint32_t limit = 0xfffff;
uint32_t base = 0x0;
entry->granularity = 1;
entry->db = 1;
entry->l = 0;
entry->available = 0;
entry->present = 1;
entry->desc_priv = 0;
entry->desc_type = 1;
entry->ex = 0;
entry->dc = 0;
entry->rw = 1;
entry->accessed = 0;
entry->limit_1 = limit & 0xffff;
entry->limit_2 = (limit >> 16) & 0xf;
entry->base_1 = base & 0xffff;
entry->base_2 = (base >> 16) & 0xff;
entry->base_3 = (base >> 24) & 0xff;
}
static void create_kernel_cs(void)
{
struct gdt_entry *entry = gdt.entries + KERNEL_CS_INDEX;
uint32_t limit = 0xfffff;
uint32_t base = 0x0;
entry->granularity = 1;
entry->db = 1;
entry->l = 0;
entry->available = 0;
entry->present = 1;
entry->desc_priv = 0;
entry->desc_type = 1;
entry->ex = 1;
entry->dc = 0;
entry->rw = 1;
entry->accessed = 0;
entry->limit_1 = limit & 0xffff;
entry->limit_2 = (limit >> 16) & 0xf;
entry->base_1 = base & 0xffff;
entry->base_2 = (base >> 16) & 0xff;
entry->base_3 = (base >> 24) & 0xff;
}
static void create_gdt(void)
{
create_kernel_ds();
create_kernel_cs();
}
static void load_gdt(void)
{
struct gdt_r gdtr;
gdtr.addr = (uint32_t)&gdt;
gdtr.limit = GDT_SIZE - 1;
asm volatile("lgdt %0\n"
:
: "m" (gdtr)
: "memory");
}
static void load_ds(void)
{
struct segment_selector selector = KERNEL_DS_SEGMENT_SELECTOR;
asm volatile("movw %0, %%ax\n"
"movw %%ax, %%ds\n"
"movw %%ax, %%fs\n"
"movw %%ax, %%gs\n"
"movw %%ax, %%ss\n"
:
: "m" (selector)
: "ax");
}
static void load_cs(void)
{
struct segment_selector selector = KERNEL_CS_SEGMENT_SELECTOR;
asm volatile("pushl %0\n"
"pushl $1f\n"
"lret\n"
"1:\n"
:
: "m" (selector));
}
static void reload_segment_selectors(void)
{
load_ds();
load_cs();
}
void init_gdt(void)
{
create_gdt();
load_gdt();
reload_segment_selectors();
}