diff options
| author | Ada Christine <adachristine18@gmail.com> | 2021-12-19 22:41:15 +0000 |
|---|---|---|
| committer | Ada Christine <adachristine18@gmail.com> | 2021-12-19 22:41:15 +0000 |
| commit | e303a03e7c96bc5bf7fa93f7b46ce63196893d7a (patch) | |
| tree | f187b374feec85015d6df1f94db618a3f5cc893f /kernel/cpu.c | |
| parent | bff63a4337eb3388617d230970c5eb2684d6a215 (diff) | |
moving files around
Diffstat (limited to 'kernel/cpu.c')
| -rw-r--r-- | kernel/cpu.c | 225 |
1 files changed, 0 insertions, 225 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c deleted file mode 100644 index ed1a04e..0000000 --- a/kernel/cpu.c +++ /dev/null @@ -1,225 +0,0 @@ -#include "cpu.h" -#include "exceptions.h" - -#include <stdint.h> - -#define GDT_ENTRIES 16 -#define IDT_ENTRIES 256 - -#define CODE_SEG_INDEX 1 -#define DATA_SEG_INDEX 2 -#define TASK_SEG_INDEX 3 - -struct dtr64 -{ - uint16_t limit; - uint64_t base; -} __attribute__((packed)); - -struct segment_descriptor -{ - uint16_t limit0; - uint16_t base0; - uint8_t base16; - uint8_t access; - uint8_t flags_limit16; - uint8_t base24; -} __attribute__((packed)); - -enum segment_descriptor_type -{ - CODE64_SEG, - DATA_SEG, - TASK64_SEG, -}; - -struct gate_descriptor -{ - uint16_t offset0; - uint16_t selector; - uint8_t ist; - uint8_t access; - uint16_t offset16; - uint64_t offset32; -} __attribute__((packed)); - -enum gate_descriptor_type -{ - INT64_GATE, - TRAP64_GATE, -}; - -struct task64_segment -{ - uint32_t reserved0; - uint64_t rsp0; - uint64_t rsp1; - uint64_t rsp2; - uint64_t reserved1; - uint64_t ist[7]; - uint16_t reserved2; - uint16_t iomap_base; -}; - -static struct segment_descriptor gdt[GDT_ENTRIES]; -static struct gate_descriptor idt[IDT_ENTRIES]; -static struct task64_segment tss; - -static void set_gdt(int index, - uint64_t base, - uint64_t limit, - enum segment_descriptor_type type) -{ - gdt[index].limit0 = limit & 0xffff; - gdt[index].base0 = base & 0xffff; - gdt[index].base16 = (base >> 16) & 0xff; - gdt[index].flags_limit16 = (limit >> 16) & 0xf; - gdt[index].base24 = (base >> 24) & 0xff; - - switch (type) - { - case CODE64_SEG: - gdt[index].access = 0x9a; - gdt[index].flags_limit16 |= 0xa0; - break; - case DATA_SEG: - gdt[index].access = 0x92; - gdt[index].flags_limit16 |= 0xc0; - break; - case TASK64_SEG: - gdt[index].access = 0x89; - //TODO: make this cleaner i don't like it - gdt[index+1].limit0 = (base >> 32) & 0xffff; - gdt[index+1].base0 = (base >> 48) & 0xffff; - break; - }; -} - -static void set_idt(int vec, - uint16_t selector, - uint64_t offset, - enum gate_descriptor_type type) -{ - idt[vec].offset0 = offset & 0xffff; - idt[vec].selector = selector; - idt[vec].offset16 = (offset >> 16) & 0xffff; - idt[vec].offset32 = (offset >> 32) & 0xffffffff; - - switch (type) - { - case INT64_GATE: - idt[vec].access = 0x8e; - break; - case TRAP64_GATE: - idt[vec].access = 0x8f; - break; - } -} - -void set_ist(int vec, int ist_index) -{ - // non-destructively set the ist index. - idt[vec].access |= ist_index & 0x7; -} - -static void gdt_init(void) -{ - set_gdt(CODE_SEG_INDEX, 0, (uint64_t)-1, CODE64_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}; - - __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" - // make a far return frame on the stack - // [ss] @rsp+8 - // [rip] @rsp - "pushq %1\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" - "popf\n" - // dependency on pre-boot GDT is now gone - : - : "m"(gdtr), - "i"(CODE_SEG_INDEX << 3), - "r"(DATA_SEG_INDEX << 3), - "r"(TASK_SEG_INDEX << 3) - ); -} - -static void idt_init(void) -{ - struct dtr64 idtr = {sizeof(idt) - 1, (uint64_t)&idt}; - - __asm__ volatile - ( - // can't have interrupts enabled during IDT reload--obviously. - // as with GDT don't re-enable interrupts if they were already - // disabled. - "pushf\n" - "cli\n" - "lidt %0\n" - "popf\n" - // much more straightforward than the gdt code. - :: "m"(idtr) - ); -} - -void cpu_init(void) -{ - gdt_init(); - idt_init(); - exceptions_init(); -} - -void exceptions_init(void) -{ - isr_install(PAGE_FAULT_VECTOR, &page_fault_isr, 0, 0); -} - -void isr_install(int vec, void (*isr)(void), int trap, int ist) -{ - enum gate_descriptor_type type = INT64_GATE; - - if (trap) - { - type = TRAP64_GATE; - } - - set_idt(vec, CODE_SEG_INDEX << 3, (uint64_t)isr, type); - if (ist) - { - set_ist(vec, ist); - } -} - -void ist_install(int ist, void *stack) -{ - tss.ist[ist] = (uint64_t)stack; -} - -void int_enable(void) -{ - __asm__ ("sti"); -} - -void int_disable(void) -{ - __asm__ ("cli"); -} |
