#include #include #include #include #include static void init_entry(struct gdt_entry *entry, int access, int flags) { entry->ge_limit_low = 0xFFFF; entry->ge_base_low = 0x00; entry->ge_base_mid = 0x00; entry->ge_access = access; entry->ge_gran = flags; entry->ge_base_hi = 0x00; } int gdt_init(struct gdt *gdt, struct gdt_ptr *gdtp) { memset(&gdt->g_entries[0], 0x0, sizeof gdt->g_entries[0]); init_entry( &gdt->g_entries[1], GDT_A_PRESENT | GDT_A_CODEREAD | GDT_A_CODE, GDT_F_64BIT); init_entry( &gdt->g_entries[2], GDT_A_PRESENT | GDT_A_DATAWRITE | GDT_A_DATA, GDT_F_64BIT); init_entry( &gdt->g_entries[3], GDT_A_PRESENT | GDT_A_USER | GDT_A_DATAWRITE | GDT_A_DATA, GDT_F_64BIT); init_entry( &gdt->g_entries[4], GDT_A_PRESENT | GDT_A_USER | GDT_A_CODEREAD | GDT_A_CODE, GDT_F_64BIT); gdtp->g_ptr = (uint64_t)gdt; gdtp->g_limit = sizeof(*gdt) - 1; return 0; } void gdt_write_tss(struct gdt *gdt, struct tss *tss) { struct tss_gdt_entry *tss_entry = &gdt->g_tss; virt_addr_t base = (virt_addr_t)tss; size_t limit = sizeof *tss; tss_entry->ge_base_low = (base & 0xFFFF); tss_entry->ge_base_mid = (base >> 16) & 0xFF; tss_entry->ge_base_hi = (base >> 24) & 0xFF; tss_entry->ge_base_ext = (base >> 32) & 0xFFFFFFFF; tss_entry->ge_limit_low = (limit & 0xFFFF); tss_entry->ge_gran = (limit >> 16) & 0xF; tss_entry->ge_access = 0xE9; tss_entry->ge_reserved = 0; }