summaryrefslogtreecommitdiff
path: root/kc/core/cpu/cpu.c
diff options
context:
space:
mode:
authorAda Christine <adachristine18@gmail.com>2023-02-14 15:14:35 +0000
committerAda Christine <adachristine18@gmail.com>2023-02-14 15:14:35 +0000
commit9fd358e9395aae73622bdcf58ebe43f12671c990 (patch)
treeb9bd20fba6ee4a7da84d54d2208e17a49c0305d5 /kc/core/cpu/cpu.c
parentf59e168c504f50de7b2ff77af0c1b1cfe0483e7b (diff)
refactors
Diffstat (limited to 'kc/core/cpu/cpu.c')
-rw-r--r--kc/core/cpu/cpu.c68
1 files changed, 43 insertions, 25 deletions
diff --git a/kc/core/cpu/cpu.c b/kc/core/cpu/cpu.c
index a979336..e3cff39 100644
--- a/kc/core/cpu/cpu.c
+++ b/kc/core/cpu/cpu.c
@@ -113,48 +113,66 @@ void set_ist(int vec, int ist_index)
idt[vec].access |= ist_index & 0x7;
}
-static void gdt_init(void)
-{
- set_gdt(CODE_SUPER_SEG_INDEX, 0, (uint64_t)-1, CODE64_SUPER_SEG);
- set_gdt(CODE_USER_SEG_INDEX, 0, (uint64_t)-1, CODE64_USER_SEG);
- set_gdt(DATA_SEG_INDEX, 0, (uint64_t)-1, DATA_SEG);
- set_gdt(TASK_SEG_INDEX, (uint64_t)&tss, sizeof(tss) - 1, TASK64_SEG);
-
- struct dtr64 gdtr = {sizeof(gdt) - 1, (uint64_t)&gdt};
-
+static void gdt_flush(uint16_t code_seg, uint16_t data_seg, uint16_t task_seg)
+{
__asm__ volatile
- (
- // can't have interrupts during GDT reload
- // but don't re-enable interrupts if they were already disabled
+ (
"pushf\n"
"cli\n"
- "lgdt %0\n"
- "mov %w2, %%ds\n"
- "mov %w2, %%es\n"
- "mov %w2, %%fs\n"
- "mov %w2, %%gs\n"
- "mov %w2, %%ss\n"
+ "mov %w1, %%ds\n"
+ "mov %w1, %%es\n"
+ "mov %w1, %%fs\n"
+ "mov %w1, %%gs\n"
+ "mov %w1, %%ss\n"
// make a far return frame on the stack
// [ss] @rsp+8
// [rip] @rsp
- "pushq %1\n"
+ "push %q0\n"
"lea .Lflush(%%rip), %%rax\n"
"push %%rax\n"
// far return, now we're in the code segment
// defined here.
"lretq\n"
".Lflush:\n"
- "ltr %w3\n"
+ "ltr %w2\n"
+ "popf\n"
+ :
+ :
+ "r"(code_seg << 3),
+ "r"(data_seg << 3),
+ "r"(task_seg << 3)
+ );
+}
+
+static void gdt_load(struct dtr64 gdtr)
+{
+ __asm__ volatile
+ (
+ // can't have interrupts during GDT reload
+ // but don't re-enable interrupts if they were already disabled
+ "pushf\n"
+ "cli\n"
+ "lgdt %0\n"
"popf\n"
// dependency on pre-boot GDT is now gone
:
- : "m"(gdtr),
- "i"(CODE_SUPER_SEG_INDEX << 3),
- "r"(DATA_SEG_INDEX << 3),
- "r"(TASK_SEG_INDEX << 3)
- );
+ : "m"(gdtr)
+ );
+}
+
+static void gdt_init(void)
+{
+ set_gdt(CODE_SUPER_SEG_INDEX, 0, (uint64_t)-1, CODE64_SUPER_SEG);
+ set_gdt(CODE_USER_SEG_INDEX, 0, (uint64_t)-1, CODE64_USER_SEG);
+ set_gdt(DATA_SEG_INDEX, 0, (uint64_t)-1, DATA_SEG);
+ set_gdt(TASK_SEG_INDEX, (uint64_t)&tss, sizeof(tss) - 1, TASK64_SEG);
+
+ struct dtr64 gdtr = {sizeof(gdt) - 1, (uint64_t)&gdt};
+ gdt_load(gdtr);
+ gdt_flush(CODE_SUPER_SEG_INDEX, DATA_SEG_INDEX, TASK_SEG_INDEX);
}
+
static void idt_init(void)
{
struct dtr64 idtr = {sizeof(idt) - 1, (uint64_t)&idt};