diff options
author | Quinn Stephens <quinn@osmora.org> | 2025-05-22 15:11:35 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-05-22 15:18:45 -0400 |
commit | 92e385d64d9883896b4cf55e7e0d5e110621cb0c (patch) | |
tree | 3e65b693c4179d326736a4e0d31839f9f32cda3b /sys/include/arch/amd64/gdt.h | |
parent | 6dfbc839f81f757b5e9635508fa4f31800807f2b (diff) |
kernel/amd64: Improve GDT implementation
* Switched to using macros for the GDT entry bits, to improve clarity
and make the code easier to modify. Also got rid of some junk values
in a few of the entries.
* Shrunk the GDT data array from 256 entries to 7 (GDT_ENTRY_COUNT)
since the GDT will only ever use 7 of the entries for now.
* Aligned the GDT using __cacheline_aligned, because the GDT entries
will be read every time a segment selector is loaded.
* Modified code dealing with the GDTR to just use `g_gdtr`, since the
same GDT/GDTR is always used.
* In `gdt_load()`, changed `eax` -> `ax`, since segment registers are
only 16 bits. Also replaced the `gdtr` to just use `g_gdtr`.
Additionally, used the inline assembly formatting to supply segment
selectors with KERNEL_CS/DS macros.
Signed-off-by: Quinn Stephens <quinn@osmora.org>
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/include/arch/amd64/gdt.h')
-rw-r--r-- | sys/include/arch/amd64/gdt.h | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/sys/include/arch/amd64/gdt.h b/sys/include/arch/amd64/gdt.h index 55666a7..0c5faf1 100644 --- a/sys/include/arch/amd64/gdt.h +++ b/sys/include/arch/amd64/gdt.h @@ -4,18 +4,48 @@ #include <sys/types.h> #include <sys/cdefs.h> +#define GDT_TSS_INDEX 5 +#define GDT_ENTRY_COUNT 7 + +/* Segment selectors */ #define KERNEL_CS 0x08 #define KERNEL_DS 0x10 -#define USER_CS 0x18 -#define USER_DS 0x20 -#define GDT_TSS 5 +#define USER_CS 0x18 +#define USER_DS 0x20 + +/* + * Bit definitions for regular segment descriptors + * + * See Intel SPG 3/25 Section 3.4.5 - Segment Descriptors + */ + +#define GDT_ATTRIBUTE_ACCESSED BIT(0) /* Accessed */ +#define GDT_ATTRIBUTE_EXECUTABLE BIT(3) /* Executable */ +#define GDT_ATTRIBUTE_NONSYSTEM BIT(4) /* Code/data */ +#define GDT_ATTRIBUTE_PRESENT BIT(7) /* Present */ +#define GDT_ATTRIBUTE_64BIT_CODE BIT(13) /* 64-bit code */ +#define GDT_ATTRIBUTE_32BIT BIT(14) /* 32-bit code/data */ +#define GDT_ATTRIBUTE_GRANULARITY BIT(15) /* 4KiB limit granularity */ + +/* Attributes for executable segments */ +#define GDT_ATTRIBUTE_READABLE BIT(1) /* Readable */ +#define GDT_ATTRIBUTE_CONFORMING BIT(2) /* Conforming */ + +/* Attributes for non-executable segments */ +#define GDT_ATTRIBUTE_WRITABLE BIT(1) /* Writable */ +#define GDT_ATTRIBUTE_EXPANDS_DOWN BIT(2) /* See SPG 3/25 Section 6.8.1 */ + +/* DPL (Descriptor Privilege Level) specifier */ +#define GDT_ATTRIBUTE_DPL0 0 +#define GDT_ATTRIBUTE_DPL1 (1 << 5) +#define GDT_ATTRIBUTE_DPL2 (2 << 5) +#define GDT_ATTRIBUTE_DPL3 (3 << 5) struct __packed gdt_entry { uint16_t limit; uint16_t base_low; uint8_t base_mid; - uint8_t access; - uint8_t granularity; + uint16_t attributes; uint8_t base_hi; }; @@ -24,27 +54,28 @@ struct __packed gdtr { uintptr_t offset; }; +extern struct gdt_entry g_gdt_data[GDT_ENTRY_COUNT]; +extern const struct gdtr g_gdtr; + __always_inline static inline void -gdt_load(struct gdtr *gdtr) +gdt_load(void) { __ASMV("lgdt %0\n" - "push $8\n" /* Push CS */ - "lea 1f(%%rip), %%rax\n" /* Load 1 label address into RAX */ - "push %%rax\n" /* Push the return address (label 1) */ - "lretq\n" /* Far return to update CS */ + "push %1\n" /* Push code segment selector */ + "lea 1f(%%rip), %%rax\n" /* Load label 1 address into RAX */ + "push %%rax\n" /* Push return address (label 1) */ + "lretq\n" /* Far return to update CS */ "1:\n" - " mov $0x10, %%eax\n" - " mov %%eax, %%ds\n" - " mov %%eax, %%es\n" - " mov %%eax, %%fs\n" - " mov %%eax, %%gs\n" - " mov %%eax, %%ss\n" + " mov %2, %%ax\n" /* Load data segment selectors */ + " mov %%ax, %%ds\n" + " mov %%ax, %%es\n" + " mov %%ax, %%fs\n" + " mov %%ax, %%gs\n" + " mov %%ax, %%ss\n" : - : "m" (*gdtr) + : "m" (g_gdtr), "i"(KERNEL_CS), "i"(KERNEL_DS) : "rax", "memory" ); } -extern struct gdt_entry g_gdt_data[256]; - #endif /* !AMD64_GDT_H_ */ |