summaryrefslogtreecommitdiff
path: root/sys/include/arch/amd64
diff options
context:
space:
mode:
authorQuinn Stephens <quinn@osmora.org>2025-05-22 15:11:35 -0400
committerIan Moffett <ian@osmora.org>2025-05-22 15:18:45 -0400
commit92e385d64d9883896b4cf55e7e0d5e110621cb0c (patch)
tree3e65b693c4179d326736a4e0d31839f9f32cda3b /sys/include/arch/amd64
parent6dfbc839f81f757b5e9635508fa4f31800807f2b (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')
-rw-r--r--sys/include/arch/amd64/gdt.h69
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_ */