summaryrefslogtreecommitdiff
path: root/src/kernel/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/arch/i386')
-rw-r--r--src/kernel/arch/i386/ata.c151
-rw-r--r--src/kernel/arch/i386/ata.h7
-rw-r--r--src/kernel/arch/i386/boot.c53
-rw-r--r--src/kernel/arch/i386/boot.h4
-rw-r--r--src/kernel/arch/i386/boot.s34
-rw-r--r--src/kernel/arch/i386/debug.c18
-rw-r--r--src/kernel/arch/i386/driver/fsroot.c146
-rw-r--r--src/kernel/arch/i386/driver/fsroot.h2
-rw-r--r--src/kernel/arch/i386/driver/ps2.c61
-rw-r--r--src/kernel/arch/i386/driver/ps2.h5
-rw-r--r--src/kernel/arch/i386/driver/serial.c114
-rw-r--r--src/kernel/arch/i386/driver/serial.h10
-rw-r--r--src/kernel/arch/i386/gdt.h16
-rw-r--r--src/kernel/arch/i386/gdt/farjump.s8
-rw-r--r--src/kernel/arch/i386/gdt/gdt.c130
-rw-r--r--src/kernel/arch/i386/interrupts/idt.c68
-rw-r--r--src/kernel/arch/i386/interrupts/idt.h3
-rw-r--r--src/kernel/arch/i386/interrupts/irq.c33
-rw-r--r--src/kernel/arch/i386/interrupts/irq.h6
-rw-r--r--src/kernel/arch/i386/interrupts/isr.c38
-rw-r--r--src/kernel/arch/i386/interrupts/isr.h7
-rw-r--r--src/kernel/arch/i386/interrupts/isr_stub.s64
-rw-r--r--src/kernel/arch/i386/multiboot.h34
-rw-r--r--src/kernel/arch/i386/multiboot.s12
-rw-r--r--src/kernel/arch/i386/pagedir.c206
-rw-r--r--src/kernel/arch/i386/port_io.h22
-rw-r--r--src/kernel/arch/i386/registers.h21
-rw-r--r--src/kernel/arch/i386/sysenter.c26
-rw-r--r--src/kernel/arch/i386/sysenter.h8
-rw-r--r--src/kernel/arch/i386/sysenter.s89
-rw-r--r--src/kernel/arch/i386/tty/tty.c26
-rw-r--r--src/kernel/arch/i386/tty/tty.h7
-rw-r--r--src/kernel/arch/i386/tty/vga.c33
33 files changed, 0 insertions, 1462 deletions
diff --git a/src/kernel/arch/i386/ata.c b/src/kernel/arch/i386/ata.c
deleted file mode 100644
index 56344e4..0000000
--- a/src/kernel/arch/i386/ata.c
+++ /dev/null
@@ -1,151 +0,0 @@
-#include <kernel/arch/i386/ata.h>
-#include <kernel/arch/i386/port_io.h>
-#include <kernel/panic.h>
-#include <stdbool.h>
-
-static struct {
- enum {
- DEV_UNKNOWN,
- DEV_PATA,
- DEV_PATAPI,
- } type;
- uint32_t sectors;
-} ata_drives[4];
-
-enum {
- DATA = 0,
- FEAT = 1,
- SCNT = 2,
- LBAlo = 3,
- LBAmid = 4,
- LBAhi = 5,
- DRV = 6,
- CMD = 7,
- STATUS = 7,
-
- /* note: the OSDev wiki uses a different base port for the control port
- * however i can just use this offset and stuff will just work tm */
- CTRL = 0x206,
-}; // offsets
-
-// get I/O port base for drive
-static uint16_t ata_iobase(int drive) {
- bool secondary = drive&2;
- return secondary ? 0x170 : 0x1F0;
-}
-
-static void ata_400ns(void) {
- uint16_t base = ata_iobase(0); // doesn't matter
- for (int i = 0; i < 4; i++)
- port_in8(base + STATUS);
-}
-
-static void ata_driveselect(int drive, int block) {
- uint8_t v = 0xE0;
- if (drive&1) // slave?
- v |= 0x10; // set drive number bit
- // TODO account for block
- port_out8(ata_iobase(drive) + DRV, v);
-}
-
-static void ata_softreset(int drive) {
- uint16_t iobase = ata_iobase(drive);
- port_out8(iobase + CTRL, 4);
- port_out8(iobase + CTRL, 0);
- ata_400ns();
-
- uint16_t timeout = 10000;
- while (--timeout) { // TODO separate polling function
- uint8_t v = port_in8(iobase + STATUS);
- if (v & 0x80) continue; // still BSY, continue
- if (v & 0x40) break; // RDY, break
- // TODO check for ERR
- }
-}
-
-static void ata_detecttype(int drive) {
- ata_softreset(drive);
- ata_driveselect(drive, 0);
- ata_400ns();
- switch (port_in8(ata_iobase(drive) + LBAmid)) {
- case 0:
- ata_drives[drive].type = DEV_PATA;
- break;
- case 0x14:
- ata_drives[drive].type = DEV_PATAPI;
- break;
- default:
- ata_drives[drive].type = DEV_UNKNOWN;
- break;
- }
-}
-
-static bool ata_identify(int drive) {
- uint16_t iobase = ata_iobase(drive);
- uint16_t data[256];
- uint8_t v;
-
- ata_driveselect(drive, 0);
- for (int i = 2; i < 6; i++)
- port_out8(iobase + i, 0);
- switch (ata_drives[drive].type) {
- case DEV_PATA:
- port_out8(iobase + CMD, 0xEC); // IDENTIFY
- break;
- case DEV_PATAPI:
- port_out8(iobase + CMD, 0xA1); // IDENTIFY PACKET DEVICE
- break;
- default: panic_invalid_state();
- }
-
- v = port_in8(iobase + STATUS);
- if (v == 0) return false; // nonexistent drive
- while (port_in8(iobase + STATUS) & 0x80);
-
- /* pool until bit 3 (DRQ) or 0 (ERR) is set */
- while (!((v = port_in8(iobase + STATUS) & 0x9)));
- if (v & 1) return false; /* ERR was set, bail */
-
- for (int i = 0; i < 256; i++)
- data[i] = port_in16(iobase);
- ata_drives[drive].sectors = data[60] | (data[61] << 16);
- return true;
-}
-
-void ata_init(void) {
- for (int i = 0; i < 4; i++) {
- ata_detecttype(i);
- if (ata_drives[i].type == DEV_PATA)
- ata_identify(i);
- }
-}
-
-bool ata_available(int drive) {
- return ata_drives[drive].type != DEV_UNKNOWN;
-}
-
-int ata_read(int drive, uint32_t lba, void *buf) {
- assert(ata_drives[drive].type == DEV_PATA);
- int iobase = ata_iobase(drive);
-
- ata_driveselect(drive, lba);
- port_out8(iobase + FEAT, 0); // supposedly pointless
- port_out8(iobase + SCNT, 1); // sector count
- port_out8(iobase + LBAlo, lba);
- port_out8(iobase + LBAmid, lba >> 8);
- port_out8(iobase + LBAhi, lba >> 16);
- port_out8(iobase + CMD, 0x20); // READ SECTORS
-
- for (;;) { // TODO separate polling function
- uint8_t v = port_in8(iobase + STATUS);
- if (v & 0x80) continue; // still BSY, continue
- if (v & 0x40) break; // RDY, break
- // TODO check for ERR
- }
-
- uint16_t *b = buf;
- for (int i = 0; i < 256; i++)
- b[i] = port_in16(iobase);
-
- return 512;
-}
diff --git a/src/kernel/arch/i386/ata.h b/src/kernel/arch/i386/ata.h
deleted file mode 100644
index 82f4f81..0000000
--- a/src/kernel/arch/i386/ata.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-#include <stdbool.h>
-#include <stdint.h>
-
-void ata_init(void);
-bool ata_available(int drive);
-int ata_read(int drive, uint32_t lba, void *buf);
diff --git a/src/kernel/arch/i386/boot.c b/src/kernel/arch/i386/boot.c
deleted file mode 100644
index 754a327..0000000
--- a/src/kernel/arch/i386/boot.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <kernel/arch/generic.h>
-#include <kernel/arch/i386/ata.h>
-#include <kernel/arch/i386/boot.h>
-#include <kernel/arch/i386/driver/fsroot.h>
-#include <kernel/arch/i386/driver/ps2.h>
-#include <kernel/arch/i386/driver/serial.h>
-#include <kernel/arch/i386/gdt.h>
-#include <kernel/arch/i386/interrupts/idt.h>
-#include <kernel/arch/i386/interrupts/irq.h>
-#include <kernel/arch/i386/multiboot.h>
-#include <kernel/arch/i386/tty/tty.h>
-#include <kernel/main.h>
-#include <kernel/mem/alloc.h>
-#include <kernel/panic.h>
-
-static void find_init(struct multiboot_info *multiboot, struct kmain_info *info)
-{
- struct multiboot_mod *module = &multiboot->mods[0];
- if (multiboot->mods_count < 1) {
- kprintf("can't find init! ");
- panic_invalid_state();
- }
- info->init.at = module->start;
- info->init.size = module->end - module->start;
-
-}
-
-void kmain_early(struct multiboot_info *multiboot) {
- struct kmain_info info;
-
- tty_init();
- kprintf("gdt...");
- gdt_init();
- kprintf("idt...");
- idt_init();
- kprintf("irq...");
- irq_init();
-
- info.memtop = (void*) (multiboot->mem_upper * 1024);
- find_init(multiboot, &info);
- kprintf("mem...\n");
- mem_init(&info);
-
- kprintf("rootfs...");
- vfs_root_init();
- ps2_init();
- serial_init();
-
- kprintf("ata...");
- ata_init();
-
- kmain(info);
-}
diff --git a/src/kernel/arch/i386/boot.h b/src/kernel/arch/i386/boot.h
deleted file mode 100644
index 544f02d..0000000
--- a/src/kernel/arch/i386/boot.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#pragma once
-#include <kernel/arch/i386/multiboot.h>
-
-void kmain_early(struct multiboot_info *multiboot);
diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s
deleted file mode 100644
index 743c6d6..0000000
--- a/src/kernel/arch/i386/boot.s
+++ /dev/null
@@ -1,34 +0,0 @@
-.section .text
-.global _start
-.type _start, @function
-_start:
- mov $_stack_top, %esp
- call sysenter_setup
- push %ebx // address of the Multiboot struct
- call kmain_early
-
-.global cpu_shutdown
-.type cpu_shutdown, @function
-cpu_shutdown:
-/* This quits QEMU. While I couldn't find this officially documented anywhere,
- * it is used by QEMU in tests/tcg/i386/system/boot.S (as of commit 40d6ee), so
- * I assume that this is safe-ish to use */
- mov $0x604, %edx
- mov $0x2000, %eax
- outw %ax, %dx
-
-.global halt_cpu
-.type halt_cpu, @function
-halt_cpu:
- cli
-1: hlt
- jmp 1b
-
-
-.global cpu_pause
-.type cpu_pause, @function
-cpu_pause:
- sti
- hlt
- cli
- ret
diff --git a/src/kernel/arch/i386/debug.c b/src/kernel/arch/i386/debug.c
deleted file mode 100644
index b1920db..0000000
--- a/src/kernel/arch/i386/debug.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <kernel/arch/generic.h>
-
-void *debug_caller(size_t depth) {
- void **ebp;
- asm("mov %%ebp, %0"
- : "=r" (ebp));
- while (depth--) {
- if (!ebp) return NULL;
- ebp = *ebp;
- }
- return ebp[1];
-}
-
-void debug_stacktrace(void) {
- for (size_t i = 0; i < 16; i++) {
- kprintf(" k/%08x\n", (uintptr_t)debug_caller(i));
- }
-}
diff --git a/src/kernel/arch/i386/driver/fsroot.c b/src/kernel/arch/i386/driver/fsroot.c
deleted file mode 100644
index 8b1b307..0000000
--- a/src/kernel/arch/i386/driver/fsroot.c
+++ /dev/null
@@ -1,146 +0,0 @@
-#include <kernel/arch/i386/ata.h>
-#include <kernel/mem/virt.h>
-#include <kernel/panic.h>
-#include <kernel/proc.h>
-#include <kernel/util.h>
-#include <kernel/arch/i386/driver/fsroot.h>
-#include <shared/mem.h>
-#include <stdbool.h>
-
-enum {
- HANDLE_ROOT,
- HANDLE_VGA,
- HANDLE_ATA_ROOT,
- HANDLE_ATA,
- _SKIP = HANDLE_ATA + 4,
-};
-
-static bool exacteq(struct vfs_request *req, const char *str) {
- size_t len = strlen(str);
- assert(req->input.kern);
- return req->input.len == len && !memcmp(req->input.buf_kern, str, len);
-}
-
-/* truncates the length */
-static void req_preprocess(struct vfs_request *req, size_t max_len) {
- if (req->offset < 0) {
- // TODO negative offsets
- req->offset = 0;
- }
-
- if (req->offset >= capped_cast32(max_len)) {
- req->input.len = 0;
- req->output.len = 0;
- req->offset = max_len;
- return;
- }
-
- req->input.len = min(req->input.len, max_len - req->offset);
- req->output.len = min(req->output.len, max_len - req->offset);
-
- assert(req->input.len + req->offset <= max_len);
- assert(req->input.len + req->offset <= max_len);
-}
-
-
-static int handle(struct vfs_request *req) {
- assert(req->caller);
- int id = (int)req->id;
- switch (req->type) {
- case VFSOP_OPEN:
- if (exacteq(req, "/")) return HANDLE_ROOT;
- if (exacteq(req, "/vga")) return HANDLE_VGA;
-
- if (exacteq(req, "/ata/")) return HANDLE_ATA_ROOT;
- if (exacteq(req, "/ata/0"))
- return ata_available(0) ? HANDLE_ATA+0 : -1;
- if (exacteq(req, "/ata/1"))
- return ata_available(1) ? HANDLE_ATA+1 : -1;
- if (exacteq(req, "/ata/2"))
- return ata_available(2) ? HANDLE_ATA+2 : -1;
- if (exacteq(req, "/ata/3"))
- return ata_available(3) ? HANDLE_ATA+3 : -1;
-
- return -1;
-
- case VFSOP_READ:
- switch (id) {
- case HANDLE_ROOT: {
- // TODO document directory read format
- const char src[] =
- "vga\0"
- "com1\0"
- "ps2\0"
- "ata/";
- req_preprocess(req, sizeof src);
- virt_cpy_to(req->caller->pages, req->output.buf,
- src + req->offset, req->output.len);
- return req->output.len;
- }
- case HANDLE_VGA: {
- char *vga = (void*)0xB8000;
- req_preprocess(req, 80*25*2);
- virt_cpy_to(req->caller->pages, req->output.buf,
- vga + req->offset, req->output.len);
- return req->output.len;
- }
- case HANDLE_ATA_ROOT: {
- char list[8] = {};
- size_t len = 0;
- for (int i = 0; i < 4; i++) {
- if (ata_available(i)) {
- list[len] = '0' + i;
- len += 2;
- }
- }
- req_preprocess(req, len);
- virt_cpy_to(req->caller->pages, req->output.buf,
- list + req->offset, req->output.len);
- return req->output.len;
- }
- case HANDLE_ATA: case HANDLE_ATA+1:
- case HANDLE_ATA+2: case HANDLE_ATA+3: {
- if (req->offset < 0) return 0;
- char buf[512];
- uint32_t sector = req->offset / 512;
- size_t len = min(req->output.len, 512 - ((size_t)req->offset & 511));
- ata_read(id - HANDLE_ATA, sector, buf);
- virt_cpy_to(req->caller->pages, req->output.buf, buf, len);
- return len;
- }
- default: panic_invalid_state();
- }
-
- case VFSOP_WRITE:
- switch (id) {
- case HANDLE_VGA: {
- void *vga = (void*)0xB8000;
- req_preprocess(req, 80*25*2);
- virt_cpy_from(req->caller->pages, vga + req->offset,
- req->input.buf, req->input.len);
- return req->input.len;
- }
- default: return -1;
- }
-
- case VFSOP_CLOSE:
- return 0;
-
- default: panic_invalid_state();
- }
-}
-
-static void accept(struct vfs_request *req) {
- if (req->caller) {
- vfsreq_finish_short(req, handle(req));
- } else {
- vfsreq_finish_short(req, -1);
- }
-}
-
-static bool is_ready(struct vfs_backend __attribute__((unused)) *self) {
- return true;
-}
-
-static struct vfs_backend backend = BACKEND_KERN(is_ready, accept);
-void vfs_root_init(void) { vfs_mount_root_register("", &backend); }
diff --git a/src/kernel/arch/i386/driver/fsroot.h b/src/kernel/arch/i386/driver/fsroot.h
deleted file mode 100644
index dd72202..0000000
--- a/src/kernel/arch/i386/driver/fsroot.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#pragma once
-void vfs_root_init(void);
diff --git a/src/kernel/arch/i386/driver/ps2.c b/src/kernel/arch/i386/driver/ps2.c
deleted file mode 100644
index 341a7d3..0000000
--- a/src/kernel/arch/i386/driver/ps2.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include <kernel/arch/i386/driver/ps2.h>
-#include <kernel/arch/i386/interrupts/irq.h>
-#include <kernel/mem/virt.h>
-#include <kernel/panic.h>
-#include <kernel/vfs/request.h>
-#include <shared/container/ring.h>
-#include <shared/mem.h>
-
-#define BACKLOG_CAPACITY 64
-static volatile uint8_t backlog_buf[BACKLOG_CAPACITY];
-static volatile ring_t backlog = {(void*)backlog_buf, BACKLOG_CAPACITY, 0, 0};
-
-static void accept(struct vfs_request *req);
-static bool is_ready(struct vfs_backend *self);
-
-static struct vfs_request *blocked_on = NULL;
-static struct vfs_backend backend = BACKEND_KERN(is_ready, accept);
-void ps2_init(void) { vfs_mount_root_register("/ps2", &backend); }
-
-
-void ps2_recv(uint8_t s) {
- ring_put1b((void*)&backlog, s);
- if (blocked_on) {
- accept(blocked_on);
- blocked_on = NULL;
- vfs_backend_tryaccept(&backend);
- }
-}
-
-static void accept(struct vfs_request *req) {
- // when you fix something here go also fix it in the COM1 driver
- static uint8_t buf[32]; // pretty damn stupid
- int ret;
- bool valid;
- switch (req->type) {
- case VFSOP_OPEN:
- valid = req->input.len == 0;
- vfsreq_finish_short(req, valid ? 0 : -1);
- break;
- case VFSOP_READ:
- if (ring_size((void*)&backlog) == 0) {
- // nothing to read
- blocked_on = req;
- } else if (req->caller) {
- ret = clamp(0, req->output.len, sizeof buf);
- ret = ring_get((void*)&backlog, buf, ret);
- virt_cpy_to(req->caller->pages, req->output.buf, buf, ret);
- vfsreq_finish_short(req, ret);
- } else {
- vfsreq_finish_short(req, -1);
- }
- break;
- default:
- vfsreq_finish_short(req, -1);
- break;
- }
-}
-
-static bool is_ready(struct vfs_backend __attribute__((unused)) *self) {
- return blocked_on == NULL;
-}
diff --git a/src/kernel/arch/i386/driver/ps2.h b/src/kernel/arch/i386/driver/ps2.h
deleted file mode 100644
index 54e8fb2..0000000
--- a/src/kernel/arch/i386/driver/ps2.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-#include <stdint.h>
-
-void ps2_recv(uint8_t s);
-void ps2_init(void);
diff --git a/src/kernel/arch/i386/driver/serial.c b/src/kernel/arch/i386/driver/serial.c
deleted file mode 100644
index dac5b75..0000000
--- a/src/kernel/arch/i386/driver/serial.c
+++ /dev/null
@@ -1,114 +0,0 @@
-#include <kernel/arch/i386/driver/serial.h>
-#include <kernel/arch/i386/interrupts/irq.h>
-#include <kernel/arch/i386/port_io.h>
-#include <kernel/mem/virt.h>
-#include <kernel/panic.h>
-#include <shared/container/ring.h>
-#include <shared/mem.h>
-#include <stdint.h>
-
-#define BACKLOG_CAPACITY 64
-static volatile uint8_t backlog_buf[BACKLOG_CAPACITY];
-static volatile ring_t backlog = {(void*)backlog_buf, BACKLOG_CAPACITY, 0, 0};
-
-static const int COM1 = 0x3f8;
-
-static void accept(struct vfs_request *req);
-static bool is_ready(struct vfs_backend *self);
-
-static struct vfs_request *blocked_on = NULL;
-static struct vfs_backend backend = BACKEND_KERN(is_ready, accept);
-void serial_init(void) { vfs_mount_root_register("/com1", &backend); }
-
-
-static void serial_selftest(void) {
- char b = 0x69;
- port_out8(COM1 + 4, 0b00011110); // enable loopback mode
- port_out8(COM1, b);
- assert(port_in8(COM1) == b);
-}
-
-void serial_preinit(void) {
- // see https://www.sci.muni.cz/docs/pc/serport.txt
- // set baud rate divisor
- port_out8(COM1 + 3, 0b10000000); // enable DLAB
- port_out8(COM1 + 0, 0x01); // divisor = 1 (low byte)
- port_out8(COM1 + 1, 0x00); // (high byte)
-
- port_out8(COM1 + 3, 0b00000011); // 8 bits, no parity, one stop bit
- port_out8(COM1 + 1, 0x01); // enable the Data Ready IRQ
- port_out8(COM1 + 2, 0b11000111); // enable FIFO with 14-bit trigger level (???)
-
- serial_selftest();
-
- port_out8(COM1 + 4, 0b00001111); // enable everything in the MCR
-}
-
-
-void serial_irq(void) {
- ring_put1b((void*)&backlog, port_in8(COM1));
- if (blocked_on) {
- accept(blocked_on);
- blocked_on = NULL;
- vfs_backend_tryaccept(&backend);
- }
-}
-
-
-static void serial_putchar(char c) {
- while ((port_in8(COM1 + 5) & 0x20) == 0); // wait for THRE
- port_out8(COM1, c);
-}
-
-void serial_write(const char *buf, size_t len) {
- for (size_t i = 0; i < len; i++)
- serial_putchar(buf[i]);
-}
-
-
-static void accept(struct vfs_request *req) {
- static char buf[32];
- int ret;
- bool valid;
- switch (req->type) {
- case VFSOP_OPEN:
- valid = req->input.len == 0;
- vfsreq_finish_short(req, valid ? 0 : -1);
- break;
- case VFSOP_READ:
- if (ring_size((void*)&backlog) == 0) {
- /* nothing to read, join queue */
- assert(!req->postqueue_next);
- struct vfs_request **slot = &blocked_on;
- while (*slot)
- slot = &(*slot)->postqueue_next;
- *slot = req;
- } else if (req->caller) {
- ret = clamp(0, req->output.len, sizeof buf);
- ret = ring_get((void*)&backlog, buf, ret);
- virt_cpy_to(req->caller->pages, req->output.buf, buf, ret);
- vfsreq_finish_short(req, ret);
- } else {
- vfsreq_finish_short(req, -1);
- }
- break;
- case VFSOP_WRITE:
- if (req->caller) {
- struct virt_iter iter;
- virt_iter_new(&iter, req->input.buf, req->input.len,
- req->caller->pages, true, false);
- while (virt_iter_next(&iter))
- serial_write(iter.frag, iter.frag_len);
- ret = iter.prior;
- } else ret = -1;
- vfsreq_finish_short(req, ret);
- break;
- default:
- vfsreq_finish_short(req, -1);
- break;
- }
-}
-
-static bool is_ready(struct vfs_backend __attribute__((unused)) *self) {
- return true;
-}
diff --git a/src/kernel/arch/i386/driver/serial.h b/src/kernel/arch/i386/driver/serial.h
deleted file mode 100644
index 6a4876e..0000000
--- a/src/kernel/arch/i386/driver/serial.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-#include <kernel/vfs/request.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-void serial_preinit(void);
-void serial_irq(void);
-void serial_write(const char *buf, size_t len);
-
-void serial_init(void);
diff --git a/src/kernel/arch/i386/gdt.h b/src/kernel/arch/i386/gdt.h
deleted file mode 100644
index 5e40cd7..0000000
--- a/src/kernel/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);
-void gdt_farjump(int segment);
diff --git a/src/kernel/arch/i386/gdt/farjump.s b/src/kernel/arch/i386/gdt/farjump.s
deleted file mode 100644
index 2885d2b..0000000
--- a/src/kernel/arch/i386/gdt/farjump.s
+++ /dev/null
@@ -1,8 +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/kernel/arch/i386/gdt/gdt.c b/src/kernel/arch/i386/gdt/gdt.c
deleted file mode 100644
index 3521052..0000000
--- a/src/kernel/arch/i386/gdt/gdt.c
+++ /dev/null
@@ -1,130 +0,0 @@
-#include <kernel/arch/generic.h>
-#include <kernel/arch/i386/gdt.h>
-#include <shared/mem.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-extern char _isr_mini_stack;
-
-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));
-
-__attribute__((section(".shared")))
-static struct gdt_entry GDT[SEG_end];
-__attribute__((section(".shared")))
-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(void);
-static void gdt_load(void);
-
-
-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(void) {
- 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) &_isr_mini_stack;
-
- 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(void) {
- 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(void) {
- gdt_prepare();
- gdt_load();
-}
diff --git a/src/kernel/arch/i386/interrupts/idt.c b/src/kernel/arch/i386/interrupts/idt.c
deleted file mode 100644
index cd2adfd..0000000
--- a/src/kernel/arch/i386/interrupts/idt.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <kernel/arch/i386/gdt.h>
-#include <kernel/arch/i386/interrupts/idt.h>
-#include <kernel/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));
-
-__attribute__((section(".shared")))
-static struct idt_entry IDT[256];
-static struct lidt_arg lidt_arg;
-
-static void idt_prepare(void);
-static void idt_load(void);
-static void idt_test(void);
-
-
-static void idt_prepare(void) {
- uintptr_t offset;
- for (int i = 0; i < 256; i++) {
- offset = (uintptr_t) &_isr_stubs + i * 8;
-
- IDT[i] = (struct idt_entry) {
- .offset_low = offset,
- .offset_high = offset >> 16,
- .code_seg = SEG_r0code << 3,
- .zero = 0,
- .present = 1,
- .ring = 0,
- .storage = 0,
- .type = 0xE, // 32-bit interrupt gate
- };
- }
-}
-
-static void idt_load(void) {
- lidt_arg.limit = sizeof(IDT) - 1;
- lidt_arg.base = (uintptr_t) &IDT;
- asm("lidt (%0)" : : "r" (&lidt_arg) : "memory");
-}
-
-static void idt_test(void) {
- asm("int $0x34" : : : "memory");
- assert(isr_test_interrupt_called);
-}
-
-void idt_init(void) {
- idt_prepare();
- idt_load();
- idt_test();
-}
diff --git a/src/kernel/arch/i386/interrupts/idt.h b/src/kernel/arch/i386/interrupts/idt.h
deleted file mode 100644
index 6576cf9..0000000
--- a/src/kernel/arch/i386/interrupts/idt.h
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-void idt_init(void);
diff --git a/src/kernel/arch/i386/interrupts/irq.c b/src/kernel/arch/i386/interrupts/irq.c
deleted file mode 100644
index 5918169..0000000
--- a/src/kernel/arch/i386/interrupts/irq.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <kernel/arch/i386/interrupts/irq.h>
-#include <kernel/arch/i386/port_io.h>
-#include <stdint.h>
-
-static const int PIC1 = 0x20;
-static const int PIC2 = 0xA0;
-
-void irq_init(void) {
- port_out8(PIC1, 0x11); /* start init sequence */
- port_out8(PIC2, 0x11);
-
- port_out8(PIC1+1, 0x20); /* interrupt offsets */
- port_out8(PIC2+1, 0x30);
-
- port_out8(PIC1+1, 0x4); /* just look at the osdev wiki lol */
- port_out8(PIC2+1, 0x2);
-
- port_out8(PIC1+1, 0x1); /* 8086 mode */
- port_out8(PIC2+1, 0x1);
-
- uint8_t mask = 0xff;
- mask &= ~(1 << 1); // keyboard
- mask &= ~(1 << 4); // COM1
-
- port_out8(PIC1+1, mask);
- port_out8(PIC2+1, 0xff);
-}
-
-void irq_eoi(uint8_t line) {
- port_out8(PIC1, 0x20);
- if (line >= 8)
- port_out8(PIC2, 0x20);
-}
diff --git a/src/kernel/arch/i386/interrupts/irq.h b/src/kernel/arch/i386/interrupts/irq.h
deleted file mode 100644
index f523154..0000000
--- a/src/kernel/arch/i386/interrupts/irq.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-#include <stdbool.h>
-#include <stdint.h>
-
-void irq_init(void);
-void irq_eoi(uint8_t line);
diff --git a/src/kernel/arch/i386/interrupts/isr.c b/src/kernel/arch/i386/interrupts/isr.c
deleted file mode 100644
index 2d893cb..0000000
--- a/src/kernel/arch/i386/interrupts/isr.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include <kernel/arch/i386/driver/ps2.h>
-#include <kernel/arch/i386/driver/serial.h>
-#include <kernel/arch/i386/interrupts/irq.h>
-#include <kernel/arch/i386/interrupts/isr.h>
-#include <kernel/arch/i386/port_io.h>
-#include <kernel/arch/generic.h>
-#include <kernel/panic.h>
-#include <kernel/proc.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-bool isr_test_interrupt_called = false;
-
-void isr_stage3(int interrupt) {
- switch (interrupt) {
- case 0x08: // double fault
- kprintf("#DF");
- panic_invalid_state();
- case 0x34:
- isr_test_interrupt_called = true;
- return;
-
- case 0x21: // keyboard irq
- ps2_recv(port_in8(0x60));
- irq_eoi(1);
- return;
-
- case 0x24: // COM1 irq
- serial_irq();
- irq_eoi(1);
- return;
-
- default:
- // TODO check if the exception was in the kernel
- process_kill(process_current, interrupt);
- process_switch_any();
- }
-}
diff --git a/src/kernel/arch/i386/interrupts/isr.h b/src/kernel/arch/i386/interrupts/isr.h
deleted file mode 100644
index 3189538..0000000
--- a/src/kernel/arch/i386/interrupts/isr.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-#include <stdbool.h>
-
-extern bool isr_test_interrupt_called; // used in the self-test in idt.c
-extern const char _isr_stubs;
-
-void isr_stage3(int interrupt);
diff --git a/src/kernel/arch/i386/interrupts/isr_stub.s b/src/kernel/arch/i386/interrupts/isr_stub.s
deleted file mode 100644
index fdbae6f..0000000
--- a/src/kernel/arch/i386/interrupts/isr_stub.s
+++ /dev/null
@@ -1,64 +0,0 @@
-.section .shared
-
-.global _isr_stubs
-_isr_stubs:
-.rept 256
- .set _stub_start, .
-
- cli
- call _isr_stage2
-
- .if . - _stub_start > 8
- .error "isr stubs over maximum size"
- .abort
- .endif
- .align 8
-.endr
-
-_isr_stage2:
- // pushal order, without %esp
- push %eax
- push %ecx
- push %edx
- push %ebx
- push %ebp
- push %esi
- push %edi
-
- // convert the return address into the vector nr
- mov 28(%esp), %eax
- add $-_isr_stubs, %eax
- shr $3, %eax
-
- // disable paging, if present
- mov %cr0, %ebx
- push %ebx // push original cr0
- and $0x7FFFFFFF, %ebx
- mov %ebx, %cr0
-
- mov %esp, %ebp
- mov $_isr_big_stack, %esp
- push %eax // push the vector nr
- call isr_stage3
-
- mov %ebp, %esp
- pop %eax // restore old cr0
- mov %eax, %cr0
-
- // restore registers
- pop %edi
- pop %esi
- pop %ebp
- pop %ebx
- pop %edx
- pop %ecx
- pop %eax
-
- add $4, %esp // skip call's return address
- iret
-
-.align 8
-// TODO overflow check
-.skip 64 // seems to be enough
-.global _isr_mini_stack
-_isr_mini_stack:
diff --git a/src/kernel/arch/i386/multiboot.h b/src/kernel/arch/i386/multiboot.h
deleted file mode 100644
index 1d6718f..0000000
--- a/src/kernel/arch/i386/multiboot.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-#include <stdint.h>
-
-#ifndef __CHECKER__
-_Static_assert(sizeof(void*) == 4,
- "this code assumes that pointers have 4 bytes");
-#endif
-
-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/kernel/arch/i386/multiboot.s b/src/kernel/arch/i386/multiboot.s
deleted file mode 100644
index dc19b36..0000000
--- a/src/kernel/arch/i386/multiboot.s
+++ /dev/null
@@ -1,12 +0,0 @@
-.set MAGIC, 0x1BADB002
-
-/* 1<<0 - align modules on page boundaries. */
-.set FLAGS, 1<<0
-.set CHECKSUM, -(MAGIC + FLAGS)
-
-.section .multiboot
-.align 4
-multiboot_header:
- .long MAGIC
- .long FLAGS
- .long CHECKSUM
diff --git a/src/kernel/arch/i386/pagedir.c b/src/kernel/arch/i386/pagedir.c
deleted file mode 100644
index e607cc7..0000000
--- a/src/kernel/arch/i386/pagedir.c
+++ /dev/null
@@ -1,206 +0,0 @@
-#include <kernel/arch/generic.h>
-#include <kernel/mem/alloc.h>
-#include <shared/mem.h>
-#include <stdint.h>
-
-/* <heat> nitpick: I highly recommend you dont use bitfields for paging
- * structures
- * <heat> you can't change them atomically and the way they're layed out
- * in memory is implementation defined iirc
- */
-struct pagetable_entry {
- uint32_t present : 1;
- uint32_t writeable : 1;
- uint32_t user : 1;
- uint32_t writethru : 1;
- uint32_t uncached : 1;
- uint32_t dirty : 1;
- uint32_t always0 : 1; // memory type thing?
- uint32_t global : 1;
- uint32_t _unused : 3;
- uint32_t address : 21;
-};
-
-struct pagedir_entry {
- uint32_t present : 1;
- uint32_t _writeable: 1; // don't use! not checked by multiple functions here
- uint32_t _user : 1; // ^
- uint32_t writethru : 1;
- uint32_t uncached : 1;
- uint32_t accessed : 1;
- uint32_t always0 : 1;
- uint32_t large : 1; // 4 MiB instead of 4 KiB
- uint32_t _unused : 3;
- uint32_t address : 21;
-} __attribute__((packed));
-
-struct pagedir {
- struct pagedir_entry e[1024];
-} __attribute__((packed));
-
-
-struct pagedir *pagedir_new(void) {
- struct pagedir *dir = page_alloc(1);
- for (int i = 0; i < 1024; i++)
- dir->e[i].present = 0;
- return dir;
-}
-
-void pagedir_free(struct pagedir *dir) {
- // assumes all user pages are unique and can be freed
- struct pagetable_entry *pt;
- void *page;
-
- for (int i = 0; i < 1024; i++) {
- if (!dir->e[i].present) continue;
-
- pt = (void*)(dir->e[i].address << 11);
-
- for (int j = 0; j < 1024; j++) {
- if (!pt[j].present) continue;
- if (!pt[j].user) continue;
-
- page = (void*)(pt[j].address << 11);
- page_free(page, 1);
- }
- page_free(pt, 1);
- }
- page_free(dir, 1);
-}
-
-static struct pagetable_entry*
-get_entry(struct pagedir *dir, const void __user *virt) {
- uint32_t pd_idx = ((uintptr_t)virt) >> 22;
- uint32_t pt_idx = ((uintptr_t)virt) >> 12 & 0x03FF;
- struct pagetable_entry *pagetable;
-
- if (!dir->e[pd_idx].present) return NULL;
-
- pagetable = (void*)(dir->e[pd_idx].address << 11);
- return &pagetable[pt_idx];
-}
-
-void *pagedir_unmap(struct pagedir *dir, void __user *virt) {
- void *phys = pagedir_virt2phys(dir, virt, false, false);
- struct pagetable_entry *page = get_entry(dir, virt);
- page->present = false;
- return phys;
-}
-
-void pagedir_map(struct pagedir *dir, void __user *virt, void *phys,
- bool user, bool writeable)
-{
- uintptr_t virt_cast = (uintptr_t) virt;
- uint32_t pd_idx = virt_cast >> 22;
- uint32_t pt_idx = virt_cast >> 12 & 0x03FF;
- struct pagetable_entry *pagetable;
-
- if (dir->e[pd_idx].present) {
- pagetable = (void*) (dir->e[pd_idx].address << 11);
- } else {
- pagetable = page_alloc(1);
- for (int i = 0; i < 1024; i++)
- pagetable[i].present = 0;
-
- dir->e[pd_idx] = (struct pagedir_entry) {
- .present = 1,
- ._writeable= 1,
- ._user = 1,
- .writethru = 1,
- .uncached = 0,
- .accessed = 0,
- .always0 = 0,
- .large = 0,
- ._unused = 0,
- .address = (uintptr_t) pagetable >> 11
- };
- }
-
- pagetable[pt_idx] = (struct pagetable_entry) {
- .present = 1,
- .writeable = writeable,
- .user = user,
- .writethru = 1,
- .uncached = 0,
- .dirty = 0,
- .always0 = 0,
- .global = 0,
- ._unused = 0,
- .address = (uintptr_t) phys >> 11
- };
-}
-
-void pagedir_switch(struct pagedir *dir) {
- asm volatile("mov %0, %%cr3;" : : "r" (dir) : "memory");
-}
-
-// creates a new pagedir with exact copies of the user pages
-struct pagedir *pagedir_copy(const struct pagedir *orig) {
- struct pagedir *clone = page_alloc(1);
- struct pagetable_entry *orig_pt, *clone_pt;
- void *orig_page, *clone_page;
-
- for (int i = 0; i < 1024; i++) {
- clone->e[i] = orig->e[i];
- if (!orig->e[i].present) continue;
-
- orig_pt = (void*)(orig->e[i].address << 11);
- clone_pt = page_alloc(1);
- clone->e[i].address = (uintptr_t) clone_pt >> 11;
-
- for (int j = 0; j < 1024; j++) {
- clone_pt[j] = orig_pt[j];
- if (!orig_pt[j].present) continue;
- if (!orig_pt[j].user) continue;
- // i could use .global?
-
- orig_page = (void*)(orig_pt[j].address << 11);
- clone_page = page_alloc(1);
- clone_pt[j].address = (uintptr_t) clone_page >> 11;
-
- memcpy(clone_page, orig_page, PAGE_SIZE);
- }
- }
-
- return clone;
-}
-
-bool pagedir_iskern(struct pagedir *dir, const void __user *virt) {
- struct pagetable_entry *page = get_entry(dir, virt);
- return page && page->present && !page->user;
-}
-
-void *pagedir_virt2phys(struct pagedir *dir, const void __user *virt,
- bool user, bool writeable)
-{
- struct pagetable_entry *page;
- uintptr_t phys;
- page = get_entry(dir, virt);
- if (!page || !page->present) return NULL;
- if (user && !page->user) return NULL;
- if (writeable && !page->writeable) return NULL;
-
- phys = page->address << 11;
- phys |= ((uintptr_t)virt) & 0xFFF;
- return (void*)phys;
-}
-
-void __user *pagedir_findfree(struct pagedir *dir, char __user *start, size_t len) {
- struct pagetable_entry *page;
- char __user *iter;
- start = (userptr_t)(((uintptr_t __force)start + PAGE_MASK) & ~PAGE_MASK); // round up to next page
- iter = start;
-
- while (iter < (char __user *)0xFFF00000) { // TODO better boundary
- page = get_entry(dir, iter);
- if (page && page->present) {
- start = iter + PAGE_SIZE;
- } else {
- if ((size_t)(iter + PAGE_SIZE - start) >= len)
- return start;
- }
- iter += PAGE_SIZE;
- }
-
- return NULL;
-}
diff --git a/src/kernel/arch/i386/port_io.h b/src/kernel/arch/i386/port_io.h
deleted file mode 100644
index eac9331..0000000
--- a/src/kernel/arch/i386/port_io.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <stdint.h>
-
-static inline void port_out8(uint16_t port, uint8_t val) {
- asm volatile("outb %0, %1" : : "a" (val), "Nd" (port));
-}
-
-static inline void port_out16(uint16_t port, uint16_t val) {
- asm volatile("outw %0, %1" : : "a" (val), "Nd" (port));
-}
-
-static inline uint8_t port_in8(uint16_t port) {
- uint8_t val;
- asm volatile("inb %1, %0" : "=a" (val) : "Nd" (port));
- return val;
-}
-
-static inline uint16_t port_in16(uint16_t port) {
- uint16_t val;
- asm volatile("inw %1, %0" : "=a" (val) : "Nd" (port));
- return val;
-}
-
diff --git a/src/kernel/arch/i386/registers.h b/src/kernel/arch/i386/registers.h
deleted file mode 100644
index 9f481d3..0000000
--- a/src/kernel/arch/i386/registers.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-#include <shared/types.h>
-#include <stdint.h>
-
-struct registers {
- /* those are in the order of pushad/popad - so you can load/save this
- * struct in (almost) one instruction */
- uint32_t edi, esi;
- userptr_t ebp, esp;
- uint32_t ebx, edx, ecx, eax;
-
- // not part of pushad/popad, but still useful
- userptr_t eip;
-} __attribute__((__packed__));
-
-// saves a return value according to the SysV ABI
-static inline uint64_t regs_savereturn(struct registers *regs, uint64_t value) {
- regs->eax = value;
- regs->edx = value >> 32;
- return value;
-}
diff --git a/src/kernel/arch/i386/sysenter.c b/src/kernel/arch/i386/sysenter.c
deleted file mode 100644
index 5837474..0000000
--- a/src/kernel/arch/i386/sysenter.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <kernel/arch/generic.h>
-#include <kernel/arch/i386/sysenter.h>
-#include <kernel/proc.h>
-#include <shared/syscalls.h>
-
-struct registers _sysexit_regs;
-
-void sysexit(struct registers regs) {
- _sysexit_regs = regs;
- _sysexit_regs.ecx = (uintptr_t) regs.esp;
- _sysexit_regs.edx = (uintptr_t) regs.eip;
- _sysexit_real();
- __builtin_unreachable();
-}
-
-_Noreturn void sysenter_stage2(void) {
- struct registers *regs = &process_current->regs;
-
- *regs = _sysexit_regs; // save the registers
- regs->esp = (userptr_t) regs->ecx; // fix them up
- regs->eip = (userptr_t) regs->edx;
-
- _syscall(regs->eax, regs->ebx,
- regs->esi, regs->edi, (uintptr_t)regs->ebp);
- process_switch_any();
-}
diff --git a/src/kernel/arch/i386/sysenter.h b/src/kernel/arch/i386/sysenter.h
deleted file mode 100644
index b88c186..0000000
--- a/src/kernel/arch/i386/sysenter.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-// sysenter.c
-extern struct registers _sysexit_regs;
-_Noreturn void sysenter_stage2(void);
-
-// sysenter.s
-void _sysexit_real(void);
diff --git a/src/kernel/arch/i386/sysenter.s b/src/kernel/arch/i386/sysenter.s
deleted file mode 100644
index d04f839..0000000
--- a/src/kernel/arch/i386/sysenter.s
+++ /dev/null
@@ -1,89 +0,0 @@
-/* arch/i386/gdt.c */
-.set SEG_r0code, 1
-.set SEG_r3code, 3
-.set SEG_r3data, 4
-
-.set IA32_SYSENTER_CS, 0x174
-.set IA32_SYSENTER_ESP, 0x175
-.set IA32_SYSENTER_EIP, 0x176
-
-.section .text
-.global sysenter_setup
-.type sysenter_setup, @function
-sysenter_setup:
- xor %edx, %edx
-
- mov $(SEG_r0code << 3), %eax
- mov $IA32_SYSENTER_CS, %ecx
- wrmsr
-
- mov $IA32_SYSENTER_ESP, %ecx
- mov $0, %eax // unused
- wrmsr
-
- mov $IA32_SYSENTER_EIP, %ecx
- mov $sysenter_stage1, %eax
- wrmsr
-
- ret
-
-
-.section .shared
-
-.global stored_eax
-stored_eax:
-.long 0
-
-.global _sysexit_real
-.type _sysexit_real, @function
-_sysexit_real:
- mov $(SEG_r3data << 3 | 3), %ax
- mov %ax, %ds
- mov %ax, %es
- mov %ax, %fs
- mov %ax, %gs
-
- // restore the registers
- mov $_sysexit_regs, %esp
- pop %edi
- pop %esi
- pop %ebp
- add $4, %esp
- pop %ebx
- pop %edx
- pop %ecx
- pop %eax
-
- // enable paging
- mov %eax, stored_eax
- mov %cr0, %eax
- or $0x80000000, %eax
- mov %eax, %cr0
- mov stored_eax, %eax
-
- sysexit
-
-sysenter_stage1:
- cli /* prevent random IRQs in the middle of kernel code */
-
- // disable paging
- // I don't want to damage any of the registers passed in by the user,
- // so i'm using ESP as a temporary register. At this point there's nothing
- // useful in it, it's == _bss_end.
- mov %cr0, %esp
- and $0x7FFFFFFF, %esp // disable paging
- mov %esp, %cr0
-
- // save the registers
- mov $(_sysexit_regs + 32), %esp
- push %eax
- push %ecx
- push %edx
- push %ebx
- push $0x0 // pushal pushes %esp here, but that's worthless
- push %ebp
- push %esi
- push %edi
-
- mov $_bss_end, %esp
- jmp sysenter_stage2
diff --git a/src/kernel/arch/i386/tty/tty.c b/src/kernel/arch/i386/tty/tty.c
deleted file mode 100644
index 9451059..0000000
--- a/src/kernel/arch/i386/tty/tty.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <kernel/arch/generic.h>
-#include <kernel/arch/i386/driver/serial.h>
-#include <kernel/arch/i386/tty/tty.h>
-#include <shared/printf.h>
-
-void tty_init(void) {
- vga_clear();
- serial_preinit();
-
- vga_write("\x03 ", 2); // cp437 heart
- serial_write("<3 ", 3);
-}
-
-static void backend(void __attribute__((unused)) *arg, const char *buf, size_t len) {
- vga_write(buf, len);
- serial_write(buf, len);
-}
-
-int kprintf(const char *fmt, ...) {
- int ret;
- va_list argp;
- va_start(argp, fmt);
- ret = __printf_internal(fmt, argp, backend, NULL);
- va_end(argp);
- return ret;
-}
diff --git a/src/kernel/arch/i386/tty/tty.h b/src/kernel/arch/i386/tty/tty.h
deleted file mode 100644
index b96003d..0000000
--- a/src/kernel/arch/i386/tty/tty.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-#include <stddef.h>
-
-void vga_write(const char *buf, size_t len);
-void vga_clear(void);
-
-void tty_init(void);
diff --git a/src/kernel/arch/i386/tty/vga.c b/src/kernel/arch/i386/tty/vga.c
deleted file mode 100644
index 9efd326..0000000
--- a/src/kernel/arch/i386/tty/vga.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <kernel/arch/i386/tty/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 vga_scroll(void) {
- for (size_t i = 0; i < vga_len - 80; i++)
- vga[i] = vga[i + 80];
- vga_pos -= 80;
-}
-
-static void vga_putchar(char c) {
- if (vga_pos >= vga_len - 80)
- vga_scroll();
- vga[vga_pos++].c = c;
-}
-
-void vga_write(const char *buf, size_t len) {
- for (size_t i = 0; i < len; i++)
- vga_putchar(buf[i]);
-}
-
-void vga_clear(void) {
- for (size_t i = 0; i < vga_len; i++)
- vga[i].c = ' ';
- vga_pos = 0;
-}