summaryrefslogtreecommitdiff
path: root/kernel/cpu.c
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2021-04-02 18:04:26 +0000
committerAda Christine <adachristine18@gmail.com>2021-04-02 18:04:26 +0000
commit167481f8988a860ea6d7ea8bbdb7155e4eb7abeb (patch)
treec348e1ea1bec525039decf6f15477d381f2d0bd7 /kernel/cpu.c
parenta41f11851c23390510a8cf9d0a932b9d08636fb0 (diff)
kernel has gdt now and loads segment register and we can allocate pages
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r--kernel/cpu.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
new file mode 100644
index 0000000..0d3a404
--- /dev/null
+++ b/kernel/cpu.c
@@ -0,0 +1,48 @@
+#include "cpu.h"
+
+#include <stdint.h>
+
+#define KERNEL_CODE_DESC 0x00af9a000000ffff
+#define KERNEL_DATA_DESC 0x00cf92000000ffff
+
+#define KERNEL_CODE_SEL 0x8
+#define KERNEL_DATA_SEL 0x10
+
+struct gdtr64
+{
+ uint16_t limit;
+ uint64_t base;
+} __attribute__((packed));
+
+static uint64_t gdt[16];
+
+void cpu_init(void)
+{
+ gdt[0] = 0;
+ gdt[1] = KERNEL_CODE_DESC;
+ gdt[2] = KERNEL_DATA_DESC;
+
+ struct gdtr64 gdtr = {sizeof(gdt) - 1, (uint64_t)&gdt};
+
+ __asm__ volatile
+ ( "pushf\n"
+ "mov %%rsp, %%rcx\n"
+ "cli\n"
+ "lgdt %0\n"
+ "movw %w2, %%ds\n"
+ "movw %w2, %%es\n"
+ "movw %w2, %%fs\n"
+ "movw %w2, %%gs\n"
+ "push %q2\n"
+ "push %%rcx\n"
+ "pushf\n"
+ "push %q1\n"
+ "lea .flush(%%rip), %%rax\n"
+ "push %%rax\n"
+ "iretq\n"
+ ".flush:\n"
+ "popf\n"
+ :: "m"(gdtr), "a"(KERNEL_CODE_SEL), "d"(KERNEL_DATA_SEL)
+ );
+}
+