summaryrefslogtreecommitdiff
path: root/src/kernel/idt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/idt.c')
-rw-r--r--src/kernel/idt.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/kernel/idt.c b/src/kernel/idt.c
new file mode 100644
index 0000000..460cfb0
--- /dev/null
+++ b/src/kernel/idt.c
@@ -0,0 +1,116 @@
+#include "drive.h"
+#include "elf.h"
+#include "util.h"
+#include "idt.h"
+#include "log.h"
+#include "panic.h"
+#include "task.h"
+#include "paging.h"
+
+enum {
+ IDT_PRESENT = 0x80,
+
+ IDT_INT = 0x0e,
+ IDT_TRAP = 0x0f
+};
+
+struct idt_entry {
+ uint16_t addr_low;
+ uint16_t cs;
+ uint8_t zero;
+ uint8_t flags;
+ uint16_t addr_high;
+} __attribute__ ((packed));
+
+struct idt_entry idt[256];
+
+struct {
+ uint16_t limit;
+ uint32_t start;
+} __attribute__ ((packed)) idtr = {
+ .limit = 256 * sizeof(struct idt_entry) - 1,
+ .start = (uint32_t)idt
+};
+
+//file handles as (drive_number << 8) + file_id_t
+
+static uint32_t sc_open_file(uint32_t drive_number, char *path) {
+ return (drive_number << 8) + drives[drive_number].get_file(drives + drive_number, path);
+}
+
+static void sc_close_file(uint32_t handle) {
+ drives[handle >> 8].free_file(drives + (handle >> 8), handle & 0xff);
+}
+
+static uint32_t sc_file_get_size(uint32_t handle) {
+ return drives[handle >> 8].get_file_length(drives + (handle >> 8), handle & 0xff);
+}
+
+static uint32_t sc_file_read(uint32_t handle, uint32_t file_offset, uint32_t count, void *buffer) {
+ uint32_t len = sc_file_get_size(handle);
+ if (file_offset + count > len)
+ count = len - file_offset;
+ fmcpy(buffer, drives + (handle >> 8), handle & 0xff, file_offset, count);
+ return count;
+}
+
+static bool sc_start_task(uint32_t drive_number, char *path) {
+ switch_to_kernel_cr3();
+ bool result = try_elf_run(drives + drive_number, path);
+ switch_to_task_cr3();
+ return result;
+}
+
+static void sc_log_string(char *sz) {
+ logsz(sz);
+}
+
+static char sc_get_key() {
+ panic("TODO: get key system call");
+}
+
+static void *sc_allocate_ram(uint32_t pages) {
+//switch_to_kernel_cr3();
+ void *result = pd_user_allocate_anywhere_writable(active_task->page_directory, pages);
+//switch_to_task_cr3();
+}
+
+void const *syscall_table[] = {
+ &sc_open_file,
+ &sc_close_file,
+ &sc_file_read,
+ &sc_file_get_size,
+ &sc_start_task,
+ &sc_log_string,
+ &sc_get_key,
+ &sc_allocate_ram
+};
+
+extern void syscall_isr;
+extern void quit_isr;
+extern void yield_isr;
+
+void register_int(uint8_t n, void *isr, uint8_t dpl) {
+ idt[n].addr_low = (uint32_t)isr & 0xffff;
+ idt[n].addr_high = (uint32_t)isr >> 16;
+ idt[n].cs = 0x10;
+ idt[n].flags = IDT_PRESENT | (dpl << 5) | IDT_INT;
+}
+
+void init_idt() {
+ for (uint16_t i = 0; i < 256; ++i) {
+ idt[i].flags = 0;
+ idt[i].zero = 0;
+ }
+
+ register_int(0x30, &syscall_isr, 3);
+ register_int(0x38, &quit_isr, 3);
+ register_int(0x39, &yield_isr, 3);
+
+ outb(0x0021, 0xff);
+ outb(0x00a1, 0xff);
+
+ asm volatile (
+ "lidt %0"
+ : : "m" (idtr) : "al");
+} \ No newline at end of file