summaryrefslogtreecommitdiff
path: root/sys/include/arch/amd64/gdt.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/include/arch/amd64/gdt.h')
-rw-r--r--sys/include/arch/amd64/gdt.h50
1 files changed, 50 insertions, 0 deletions
diff --git a/sys/include/arch/amd64/gdt.h b/sys/include/arch/amd64/gdt.h
new file mode 100644
index 0000000..f87416f
--- /dev/null
+++ b/sys/include/arch/amd64/gdt.h
@@ -0,0 +1,50 @@
+#ifndef _AMD64_GDT_H_
+#define _AMD64_GDT_H_
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+#define KERNEL_CS 0x08
+#define KERNEL_DS 0x10
+#define USER_CS 0x18
+#define USER_DS 0x20
+#define GDT_TSS 5
+
+struct __packed gdt_entry {
+ uint16_t limit;
+ uint16_t base_low;
+ uint8_t base_mid;
+ uint8_t access;
+ uint8_t granularity;
+ uint8_t base_hi;
+};
+
+struct __packed gdtr {
+ uint16_t limit;
+ uintptr_t offset;
+};
+
+__always_inline static inline void
+gdt_load(struct gdtr *gdtr)
+{
+ __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 */
+ "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"
+ :
+ : "m" (*gdtr)
+ : "rax", "memory"
+ );
+}
+
+extern struct gdt_entry g_gdt_data[256];
+
+#endif /* !AMD64_GDT_H_ */