diff options
Diffstat (limited to 'src/arch/i386')
-rw-r--r-- | src/arch/i386/boot.c | 33 | ||||
-rw-r--r-- | src/arch/i386/boot.s | 16 | ||||
-rw-r--r-- | src/arch/i386/gdt.h | 16 | ||||
-rw-r--r-- | src/arch/i386/gdt/farjump.s | 9 | ||||
-rw-r--r-- | src/arch/i386/gdt/gdt.c | 127 | ||||
-rw-r--r-- | src/arch/i386/interrupts/idt.c | 75 | ||||
-rw-r--r-- | src/arch/i386/interrupts/idt.h | 3 | ||||
-rw-r--r-- | src/arch/i386/interrupts/isr.c | 24 | ||||
-rw-r--r-- | src/arch/i386/interrupts/isr.h | 15 | ||||
-rw-r--r-- | src/arch/i386/log.c | 6 | ||||
-rw-r--r-- | src/arch/i386/multiboot.h | 31 | ||||
-rw-r--r-- | src/arch/i386/multiboot.s | 19 | ||||
-rw-r--r-- | src/arch/i386/sysenter.h | 2 | ||||
-rw-r--r-- | src/arch/i386/sysenter.s | 31 | ||||
-rw-r--r-- | src/arch/i386/tty.c | 36 | ||||
-rw-r--r-- | src/arch/i386/tty.h | 6 |
16 files changed, 0 insertions, 449 deletions
diff --git a/src/arch/i386/boot.c b/src/arch/i386/boot.c deleted file mode 100644 index 242d070..0000000 --- a/src/arch/i386/boot.c +++ /dev/null @@ -1,33 +0,0 @@ -#include <arch/generic.h> -#include <arch/i386/gdt.h> -#include <arch/i386/interrupts/idt.h> -#include <arch/i386/multiboot.h> -#include <arch/i386/sysenter.h> -#include <arch/i386/tty.h> -#include <kernel/main.h> -#include <kernel/panic.h> - -void kmain_early(struct multiboot_info *multiboot) { - struct kmain_info info; - - // setup some basic stuff - tty_clear(); - log_const("gdt..."); - gdt_init(); - log_const("idt..."); - idt_init(); - log_const("sysenter..."); - sysenter_setup(); - - { // find the init module - struct multiboot_mod *module = &multiboot->mods[0]; - if (multiboot->mods_count < 1) { - log_const("can't find init! "); - panic(); - } - info.init.at = module->start; - info.init.size = module->end - module->start; - } - - kmain(info); -} diff --git a/src/arch/i386/boot.s b/src/arch/i386/boot.s deleted file mode 100644 index 74de9b7..0000000 --- a/src/arch/i386/boot.s +++ /dev/null @@ -1,16 +0,0 @@ -.section .text -.global _start -.type _start, @function -_start: - mov $stack_top, %esp - push %ebx // address of the Multiboot struct - call kmain_early - -.global halt_cpu -.type halt_cpu, @function -halt_cpu: - cli -1: hlt - jmp 1b - -.size _start, . - _start diff --git a/src/arch/i386/gdt.h b/src/arch/i386/gdt.h deleted file mode 100644 index bcb9870..0000000 --- a/src/arch/i386/gdt.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -enum { - SEG_null, - // order dictated by SYSENTER - SEG_r0code, - SEG_r0data, - SEG_r3code, - SEG_r3data, - SEG_TSS, - - SEG_end -}; - -void gdt_init(); -void gdt_farjump(int segment); diff --git a/src/arch/i386/gdt/farjump.s b/src/arch/i386/gdt/farjump.s deleted file mode 100644 index 85d8ba5..0000000 --- a/src/arch/i386/gdt/farjump.s +++ /dev/null @@ -1,9 +0,0 @@ -.section .text -.global gdt_farjump -.type gdt_farjump, @function -gdt_farjump: - /* retf pops off the return address and code segment off the stack. - * it turns out that in the i386 cdecl calling convention they're in - * the correct place already. - */ - retf diff --git a/src/arch/i386/gdt/gdt.c b/src/arch/i386/gdt/gdt.c deleted file mode 100644 index c61002b..0000000 --- a/src/arch/i386/gdt/gdt.c +++ /dev/null @@ -1,127 +0,0 @@ -#include <arch/generic.h> -#include <arch/i386/gdt.h> -#include <kernel/util.h> -#include <stdbool.h> -#include <stdint.h> - - -struct gdt_entry { - uint64_t limit_low : 16; - uint64_t base_low : 24; - uint64_t accessed : 1; // set by the processor - // CODE | DATA - uint64_t rw : 1; // readable? | writeable? - uint64_t conforming : 1; // conforming? | expands down? - uint64_t code : 1; // 1 | 0 - - uint64_t codeordata : 1; // 1 for everything other than TSS and LDT - uint64_t ring : 2; - uint64_t present : 1; // always 1 - uint64_t limit_high : 4; - uint64_t available : 1; // ??? - uint64_t long_mode : 1; - uint64_t x32 : 1; - uint64_t gran : 1; // 1 - 4kb, 0 - 1b - uint64_t base_high : 8; -} __attribute__((packed)); - -struct tss_entry { - uint32_t _unused0; - uint32_t esp0; // kernel mode stack pointer - uint32_t ss0; // kernel mode stack segment - uint8_t _unused1[0x5c]; -} __attribute__((packed)); - -struct lgdt_arg { - uint16_t limit; - uint32_t base; -} __attribute__((packed)); - -static struct gdt_entry GDT[SEG_end]; -static struct tss_entry TSS; -static struct lgdt_arg lgdt_arg; // probably doesn't need to be global - -static void gdt_fillout(struct gdt_entry* entry, uint8_t ring, bool code); -static void gdt_prepare(); -static void gdt_load(); - - -static void gdt_fillout(struct gdt_entry* entry, uint8_t ring, bool code) { - *entry = (struct gdt_entry) { - // set up the identity mapping - .limit_low = 0xFFFF, - .limit_high = 0xF, - .gran = 1, // 4KB * 0xFFFFF = (almost) 4GB - .base_low = 0, - .base_high = 0, - - .ring = ring, - .code = code, - - .accessed = 0, - .rw = 1, - .conforming = 0, - .codeordata = 1, - .present = 1, - .long_mode = 0, // ??? - .available = 1, // ??? - .x32 = 1, - }; -} - -static void gdt_prepare() { - GDT[SEG_null].present = 0; - - gdt_fillout(&GDT[SEG_r0code], 0, true); - gdt_fillout(&GDT[SEG_r0data], 0, false); - gdt_fillout(&GDT[SEG_r3code], 3, true); - gdt_fillout(&GDT[SEG_r3data], 3, false); - - // tss - memset(&TSS, 0, sizeof(TSS)); - TSS.ss0 = SEG_r0data << 3; // kernel data segment - TSS.esp0 = (uintptr_t) &stack_top; - - GDT[SEG_TSS] = (struct gdt_entry) { - .limit_low = sizeof(TSS), - .limit_high = sizeof(TSS) >> 16, - .gran = 0, - .base_low = (uintptr_t) &TSS, - .base_high = ((uintptr_t) &TSS) >> 24, - - .accessed = 1, // 1 for TSS - .rw = 0, // 1 busy / 0 not busy - .conforming = 0, // 0 for TSS - .code = 1, // 32bit - .codeordata = 0, // is a system entry - .ring = 3, - .present = 1, - .available = 0, // 0 for TSS - .long_mode = 0, - .x32 = 0, // idk - }; -} - -static void gdt_load() { - lgdt_arg.limit = sizeof(GDT) - 1; - lgdt_arg.base = (uintptr_t) &GDT; - asm("lgdt (%0)" - : : "r" (&lgdt_arg) : "memory"); - - asm("ltr %%ax" - : : "a" (SEG_TSS << 3 | 3) : "memory"); - - // update all segment registers - gdt_farjump(SEG_r0code << 3); - asm("mov %0, %%ds;" - "mov %0, %%ss;" - "mov %0, %%es;" - "mov %0, %%fs;" - "mov %0, %%gs;" - : : "r" (SEG_r0data << 3) : "memory"); -} - -void gdt_init() { - gdt_prepare(); - gdt_load(); -} diff --git a/src/arch/i386/interrupts/idt.c b/src/arch/i386/interrupts/idt.c deleted file mode 100644 index 4e23118..0000000 --- a/src/arch/i386/interrupts/idt.c +++ /dev/null @@ -1,75 +0,0 @@ -#include <arch/i386/gdt.h> -#include <arch/i386/interrupts/idt.h> -#include <arch/i386/interrupts/isr.h> -#include <kernel/panic.h> -#include <stdbool.h> -#include <stdint.h> - -struct idt_entry { - uint16_t offset_low ; - uint16_t code_seg ; - uint8_t zero ; // unused, has to be 0 - uint8_t type : 4; // 16/32 bit, task/interrupt/task gate - uint8_t storage : 1; // 0 for interrupt/trap gates - uint8_t ring : 2; - uint8_t present : 1; - uint16_t offset_high ; -} __attribute__((packed)); - -// is exactly the same as lgdt_arg, i should combine them into a single struct -// later -struct lidt_arg { - uint16_t limit; - uint32_t base; -} __attribute__((packed)); - - -static struct idt_entry IDT[256]; -static struct lidt_arg lidt_arg; - -static inline void idt_add(uint8_t num, bool user, void (*isr)); -static void idt_prepare(); -static void idt_load(); -static void idt_test(); - - -static inline void idt_add(uint8_t num, bool user, void (*isr)) { - uintptr_t offset = (uintptr_t) isr; - - IDT[num] = (struct idt_entry) { - .offset_low = offset, - .offset_high = offset >> 16, - .code_seg = SEG_r0code << 3, - .zero = 0, - .present = 1, - .ring = user ? 3 : 0, - .storage = 0, - .type = 0xE, // 32-bit interrupt gate - }; -} - -static void idt_prepare() { - for (int i = 0; i < 256; i++) - IDT[i].present = 0; - - idt_add(0x08, false, isr_double_fault); - idt_add(0x0d, false, isr_general_protection_fault); - idt_add(0x34, false, isr_test_interrupt); -} - -static void idt_load() { - lidt_arg.limit = sizeof(IDT) - 1; - lidt_arg.base = (uintptr_t) &IDT; - asm("lidt (%0)" : : "r" (&lidt_arg) : "memory"); -} - -static void idt_test() { - asm("int $0x34" : : : "memory"); - if (!isr_test_interrupt_called) panic(); -} - -void idt_init() { - idt_prepare(); - idt_load(); - idt_test(); -} diff --git a/src/arch/i386/interrupts/idt.h b/src/arch/i386/interrupts/idt.h deleted file mode 100644 index 5627657..0000000 --- a/src/arch/i386/interrupts/idt.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void idt_init(); diff --git a/src/arch/i386/interrupts/isr.c b/src/arch/i386/interrupts/isr.c deleted file mode 100644 index 1603fba..0000000 --- a/src/arch/i386/interrupts/isr.c +++ /dev/null @@ -1,24 +0,0 @@ -#include <arch/i386/interrupts/isr.h> -#include <arch/log.h> -#include <kernel/panic.h> -#include <stdbool.h> -#include <stdint.h> - -bool isr_test_interrupt_called = false; - -__attribute__((interrupt)) -void isr_double_fault(struct interrupt_frame *frame) { - log_const("#DF"); - panic(); -} - -__attribute__((interrupt)) -void isr_general_protection_fault(struct interrupt_frame *frame) { - log_const("#GP"); - panic(); -} - -__attribute__((interrupt)) -void isr_test_interrupt(struct interrupt_frame *frame) { - isr_test_interrupt_called = true; -} diff --git a/src/arch/i386/interrupts/isr.h b/src/arch/i386/interrupts/isr.h deleted file mode 100644 index 150fc46..0000000 --- a/src/arch/i386/interrupts/isr.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include <stdbool.h> - -struct interrupt_frame; - -extern bool isr_test_interrupt_called; // used in the self-test in idt.c - -__attribute__((interrupt)) -void isr_double_fault(struct interrupt_frame *frame); - -__attribute__((interrupt)) -void isr_general_protection_fault(struct interrupt_frame *frame); - -__attribute__((interrupt)) -void isr_test_interrupt(struct interrupt_frame *frame); diff --git a/src/arch/i386/log.c b/src/arch/i386/log.c deleted file mode 100644 index fc82023..0000000 --- a/src/arch/i386/log.c +++ /dev/null @@ -1,6 +0,0 @@ -#include <arch/i386/tty.h> -#include <arch/log.h> - -void log_write(const char *buf, size_t len) { - tty_write(buf, len); -} diff --git a/src/arch/i386/multiboot.h b/src/arch/i386/multiboot.h deleted file mode 100644 index f030247..0000000 --- a/src/arch/i386/multiboot.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include <stdint.h> - -// TODO assert that pointers have 4 bytes. - -struct multiboot_mod { - void *start; - void *end; - const char *str; - uint32_t _reserved; -} __attribute__((packed)); - -struct multiboot_info { - uint32_t flag_mem : 1; - uint32_t flag_boot_device : 1; - uint32_t flag_cmdline : 1; - uint32_t flag_mods : 1; - uint32_t _flag_other : 28; // unimplemented - - uint32_t mem_lower; - uint32_t mem_upper; - - uint32_t boot_device; - - const char *cmdline; - - uint32_t mods_count; - struct multiboot_mod *mods; - - // [...] -} __attribute__((packed)); diff --git a/src/arch/i386/multiboot.s b/src/arch/i386/multiboot.s deleted file mode 100644 index db502cc..0000000 --- a/src/arch/i386/multiboot.s +++ /dev/null @@ -1,19 +0,0 @@ -.set MAGIC, 0x1BADB002 -/* TODO set bss_end_addr, so the init module doesn't get overriden by the stack */ - -/* 1<<0 - align modules on page boundaries. - 1<<16 - enable manual addressing */ -.set FLAGS, 1<<0 | 1<<16 -.set CHECKSUM, -(MAGIC + FLAGS) - -.section .multiboot -.align 4 -multiboot_header: - .long MAGIC - .long FLAGS - .long CHECKSUM - .long multiboot_header // header_addr - .long multiboot_header // load_addr - .long _data_end // load_end_addr - .long _bss_end // bss_end_addr - .long _start // entry_addr diff --git a/src/arch/i386/sysenter.h b/src/arch/i386/sysenter.h deleted file mode 100644 index b531fe8..0000000 --- a/src/arch/i386/sysenter.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -void sysenter_setup(); diff --git a/src/arch/i386/sysenter.s b/src/arch/i386/sysenter.s deleted file mode 100644 index 666c0f0..0000000 --- a/src/arch/i386/sysenter.s +++ /dev/null @@ -1,31 +0,0 @@ -/* arch/i386/gdt.c */ -.set SEG_r0code, 1 -.set SEG_r3code, 3 -.set SEG_r3data, 4 - -.set IA32_SYSENTER_CS, 0x174 - -.section .text -.global sysexit -.type sysexit, @function -sysexit: - pop %ecx - pop %edx - - mov $(SEG_r3data << 3 | 3), %ax - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - - sysexit - - -.global sysenter_setup -.type sysenter_setup, @function -sysenter_setup: - xor %edx, %edx - mov $(SEG_r0code << 3), %eax - mov $IA32_SYSENTER_CS, %ecx - wrmsr - ret diff --git a/src/arch/i386/tty.c b/src/arch/i386/tty.c deleted file mode 100644 index a7c74f5..0000000 --- a/src/arch/i386/tty.c +++ /dev/null @@ -1,36 +0,0 @@ -#include <arch/i386/tty.h> - -struct vga_cell { - unsigned char c; - unsigned char style; -} __attribute__((__packed__)); - -static const size_t vga_len = 80 * 25; -static struct vga_cell *vga = (void*) 0xB8000; -static size_t vga_pos = 0; - -static void tty_scroll() { - for (int i = 0; i < vga_len - 80; i++) { - vga[i] = vga[i + 80]; - } - vga_pos -= 80; -} - -void tty_putchar(char c) -{ - if (vga_pos >= vga_len - 80) tty_scroll(); - vga[vga_pos++].c = c; -} - -void tty_write(const char *buf, size_t len) -{ - for (size_t i = 0; i < len; i++) { - tty_putchar(buf[i]); - } -} - -void tty_clear() { - for (size_t i = 0; i < vga_len; i++) - vga[i].c = ' '; - vga_pos = 0; -} diff --git a/src/arch/i386/tty.h b/src/arch/i386/tty.h deleted file mode 100644 index cbb8efc..0000000 --- a/src/arch/i386/tty.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include <stddef.h> - -void tty_putchar(char c); -void tty_write(const char *buf, size_t len); -void tty_clear(); |