diff --git a/arch/x86/segment.c b/arch/x86/segment.c index 24ae3afc..4cad0566 100644 --- a/arch/x86/segment.c +++ b/arch/x86/segment.c @@ -56,6 +56,23 @@ idt_ptr_t boot_idt_ptr __data_init = { .addr = _ul(&boot_idt), }; + +gdt_desc_t __data_rmode rmode_gdt[NR_RMODE_GDT_ENTRIES] __aligned(16) = { + /* clang-format off */ + [GDT_NULL].desc = GDT_ENTRY(0x0, 0x0, 0x0), + [GDT_KERN_CS32].desc = GDT_ENTRY(DESC_FLAGS(GR, SZ, P, DPL0, S, CODE, R, A), 0x0, 0xfffff), + [GDT_KERN_DS32].desc = GDT_ENTRY(DESC_FLAGS(GR, SZ, P, DPL0, S, DATA, W, A), 0x0, 0xfffff), + [GDT_KERN_CS64].desc = GDT_ENTRY(DESC_FLAGS(GR, L, P, DPL0, S, CODE, R, A), 0x0, 0x00000), + [GDT_RMODE_CS16].desc = GDT_ENTRY(DESC_FLAGS(P, DPL0, S, CODE, R, A), 0x0, 0xfffff), + [GDT_RMODE_DS16].desc = GDT_ENTRY(DESC_FLAGS(P, DPL0, S, DATA, W, A), 0x0, 0xfffff), + /* clang-format on */ +}; + +gdt_ptr_t __data_rmode rmode_gdt_ptr = { + .size = sizeof(rmode_gdt) - 1, + .addr = _ul(&rmode_gdt), +}; + static void __text_init init_boot_tss(void) { #if defined(__i386__) boot_tss_df.iopb = sizeof(boot_tss_df); diff --git a/include/arch/x86/segment.h b/include/arch/x86/segment.h index 6afca0b9..c1e51dea 100644 --- a/include/arch/x86/segment.h +++ b/include/arch/x86/segment.h @@ -34,6 +34,9 @@ #define GDT_KERN_DS32 0x2 #define GDT_KERN_CS64 0x3 +#define GDT_RMODE_CS16 0x4 +#define GDT_RMODE_DS16 0x5 + #define GDT_BOOT_TSS 0x4 #define GDT_BOOT_TSS_DF 0x5 @@ -46,13 +49,17 @@ #define GDT_PERCPU 0x9 -#define NR_BOOT_GDT_ENTRIES 6 -#define NR_GDT_ENTRIES 10 +#define NR_BOOT_GDT_ENTRIES 6 +#define NR_RMODE_GDT_ENTRIES 8 +#define NR_GDT_ENTRIES 10 #define __KERN_CS32 (GDT_KERN_CS32 << 3) #define __KERN_DS32 (GDT_KERN_DS32 << 3) #define __KERN_CS64 (GDT_KERN_CS64 << 3) +#define __KERN_CS16 (GDT_RMODE_CS16 << 3) +#define __KERN_DS16 (GDT_RMODE_DS16 << 3) + #define __USER_CS32 ((GDT_USER_CS32 << 3) | 3) #define __USER_DS32 ((GDT_USER_DS32 << 3) | 3) #define __USER_CS64 ((GDT_USER_CS64 << 3) | 3)