diff options
Diffstat (limited to 'src/kernel/idt.c')
-rw-r--r-- | src/kernel/idt.c | 200 |
1 files changed, 142 insertions, 58 deletions
diff --git a/src/kernel/idt.c b/src/kernel/idt.c index ebeea17..b8990f2 100644 --- a/src/kernel/idt.c +++ b/src/kernel/idt.c @@ -1,14 +1,14 @@ +#include "paging.h" +#include "window.h" #include "drive.h" -#include "elf.h" -#include "util.h" -#include "idt.h" -#include "log.h" #include "panic.h" -#include "task.h" -#include "paging.h" #include "pmap.h" +#include "task.h" +#include "util.h" +#include "elf.h" +#include "idt.h" #include "kbd.h" -#include "vga.h" +#include "log.h" enum { IDT_PRESENT = 0x80, @@ -35,19 +35,27 @@ struct { //file handles as (drive_number << 8) + file_id_t -static uint32_t sc_open_file(uint32_t drive_number, char *path) { +uint32_t sc_open_file(uint32_t drive_number, char *path) { //not static to ensure sysv abi return (drive_number << 8) + drives[drive_number].get_file(drives + drive_number, path); + //logf(LOG_INFO, "sc_open_file(%d, \"%s\") -> %d", drive_number, path, handle); } -static void sc_close_file(uint32_t handle) { +void sc_close_file(uint32_t handle) { //not static to ensure sysv abi + if (!handle) + return; drives[handle >> 8].free_file(drives + (handle >> 8), handle & 0xff); } -static uint32_t sc_file_get_size(uint32_t handle) { +uint32_t sc_file_get_size(uint32_t handle) { //not static to ensure sysv abi + //logf(LOG_INFO, "sc_file_get_size(%d)", handle); + if (!handle) + return 0; 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 sc_file_read(uint32_t handle, uint32_t file_offset, uint32_t count, void *buffer) { //not static to ensure sysv abi + if (!handle) + return 0; uint32_t len = sc_file_get_size(handle); if (file_offset + count > len) count = len - file_offset; @@ -55,14 +63,14 @@ static uint32_t sc_file_read(uint32_t handle, uint32_t file_offset, uint32_t cou return count; } -static uint32_t sc_start_task(uint32_t drive_number, char *path, const char *pass) { +uint32_t sc_start_task(uint32_t drive_number, char *path, const char *pass, uint32_t esi_dummy, uint32_t io_task) { //not static to ensure sysv abi switch_to_kernel_cr3(); - uint32_t process_id = try_elf_run(drives + drive_number, vma_to_pma(active_task->page_directory, path), pass); + uint32_t process_id = try_elf_run(drives + drive_number, vma_to_pma(active_task->page_directory, path), pass, io_task); switch_to_task_cr3(); return process_id; } -static void *sc_allocate_ram(uint32_t pages) { +void *sc_allocate_ram(uint32_t pages) { //not static to ensure sysv abi return pd_user_allocate_anywhere_writable(active_task->page_directory, pages); } @@ -75,7 +83,7 @@ enum mi_arg { }; __attribute__ ((pure)) -static uint32_t sc_memory_info(enum mi_arg arg) { +uint32_t sc_memory_info(enum mi_arg arg) { //not static to ensure sysv abi switch (arg) { case MI_KERNEL_MAX: return max_kernel_pages; @@ -92,36 +100,73 @@ static uint32_t sc_memory_info(enum mi_arg arg) { } } -static void sc_wait_for_task(uint32_t handle) { - active_task->wait_mode = PROCESS_END; - active_task->wait_arg = handle; +void sc_wait_for_task(uint32_t handle) { //not static to ensure sysv abi + add_wait((struct wait){.mode = PROCESS_END, .task = tasks + handle - 1}); } -static uint32_t sc_enumerate_dir(uint32_t drive_number, const char *path, struct directory_content_info *buffer, uint32_t max_entries) { +uint32_t sc_enumerate_dir(uint32_t drive_number, const char *path, struct directory_content_info *buffer, uint32_t max_entries) { //not static to ensure sysv abi return drives[drive_number].enumerate_dir(drives + drive_number, path, buffer, max_entries); } -static uint32_t sc_count_of_dir(uint32_t drive_number, const char *path) { +uint32_t sc_count_of_dir(uint32_t drive_number, const char *path) { //not static to ensure sysv abi return drives[drive_number].n_dir_entries(drives + drive_number, path); } +void sc_get_next_window_action(struct window *w, struct window_action *action) { //not static to ensure sysv abi + *action = next_window_action(w); +} + +void sc_wait_window_action() { + add_wait((struct wait){.mode = WINDOW_ACTION}); +} + +void sc_wait_ipc(uint32_t task_handle) { + add_wait((struct wait){.mode = IPC_RECEIVE, .task = tasks + task_handle - 1}); +} + +void sc_system_log(const char *sz) { + logf(LOG_USER, "[%s] %s", active_task->name, sz); +} + +void sc_wait_any_ipc() { + add_wait((struct wait){.mode = IPC_RECEIVE_ANY}); +} + +void sc_wait_ipc_read(uint32_t handle) { + add_wait((struct wait){.mode = IPC_SEND, .task = tasks + handle - 1}); +} + +__attribute__ ((pure)) +bool sc_is_task_running(uint32_t handle) { + return tasks[handle - 1].page_directory; +} + void const *syscall_table[] = { &sc_open_file, &sc_close_file, &sc_file_read, &sc_file_get_size, &sc_start_task, - &logsz, - &get_key_code, + &ipc_send, + &ipc_read, &sc_allocate_ram, &sc_memory_info, &sc_wait_for_task, &sc_enumerate_dir, - &vga_print_at, + &sc_system_log, &sc_count_of_dir, - &vga_blank, - &vga_set_color, - &vga_swap_color + &new_window, + &del_window, + &resize_window, + &reassign_pixel_buffer, + &push_window_paint, + &sc_get_next_window_action, + &sc_wait_window_action, + &sc_wait_ipc, + &sc_wait_any_ipc, + &find_unread_ipc, + &sc_wait_ipc_read, + &sc_is_task_running }; //these aren't really void ()'s, but gcc complains if we take an address of a void, so we give it a type @@ -141,38 +186,77 @@ extern isr_t ssf_isr; extern isr_t gpf_isr; extern isr_t pff_isr; +enum { + F_ID = 0x00200000, + F_VIP = 0x00100000, + F_VIF = 0x00080000, + F_AC = 0x00040000, + F_VM = 0x00020000, + F_RF = 0x00010000, + F_NT = 0x00004000, + F_OF = 0x00000800, + F_DF = 0x00000400, + F_IF = 0x00000200, + F_TF = 0x00000100, + F_SF = 0x00000080, + F_ZF = 0x00000040, + F_AF = 0x00000010, + F_PF = 0x00000004, + F_CF = 0x00000001, + + F_IOPL_MASK = 0x00003000 +}; + __attribute__ ((noreturn)) -void exception_halt(const char *id, uint32_t code, uint32_t eip, uint32_t cs) { - char nbuf[11]; - - set_log_mode(LOG_PANIC); - logsz("Exception #"); - logsz(id); - logsz(" at 0x"); - u8_hex(cs, nbuf); - logsz(nbuf); - logsz(":0x"); - u32_hex(eip, nbuf); - logsz(nbuf); - - logsz("\nerror code = 0x"); - u32_hex(code, nbuf); - logsz(nbuf); - - logsz("\ntask name = "); - logsz(active_task->name); - - logsz("\ncr3 = 0x"); - uint32_t cr3; - asm ( - "mov %%cr3, %0" - : "=r" (cr3)); - u32_hex(cr3, nbuf); - logsz(nbuf); - - logsz("\nHalting."); - while (1) - asm ("hlt"); +void exception_halt(uint32_t eax, uint32_t ebx, uint32_t ecx, + uint32_t edx, uint32_t esi, uint32_t edi, + const char *id, uint32_t code, + uint32_t eip, uint32_t cs, uint32_t eflags, + uint32_t esp, uint32_t ss) { + if (code) + logf(LOG_ERROR, "Exception #%s (0x%h) in %s", id, code, active_task->name); + else + logf(LOG_ERROR, "Exception #%s in %s:", id, active_task->name); + logf(LOG_ERROR, " cs: 0x%hb ss: 0x%hb", cs, ss); + logf(LOG_ERROR, " eip: 0x%h esp: 0x%h", eip, esp); + logf(LOG_ERROR, " eax: 0x%h ebx: 0x%h", eax, ebx); + logf(LOG_ERROR, " ecx: 0x%h edx: 0x%h", ecx, edx); + logf(LOG_ERROR, " esi: 0x%h edi: 0x%h", esi, edi); + logf(LOG_ERROR, " eflags:%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + eflags & F_ID ? " ID" : "", eflags & F_VIP ? " VIP" : "", + eflags & F_VIF ? " VIF" : "", eflags & F_AC ? " AC" : "", + eflags & F_VM ? " VM" : "", eflags & F_RF ? " RF" : "", + eflags & F_NT ? " NT" : "", eflags & F_OF ? " OF" : "", + eflags & F_DF ? " DF" : "", eflags & F_IF ? " IF" : "", + eflags & F_TF ? " TF" : "", eflags & F_SF ? " SF" : "", + eflags & F_ZF ? " ZF" : "", eflags & F_AF ? " AF" : "", + eflags & F_PF ? " PF" : "", eflags & F_CF ? " CF" : "", + eflags & ~F_IOPL_MASK ? "" : " none"); + logf(LOG_ERROR, " iopl: %d", (eflags >> 12) & 3); + + logf(LOG_INFO, "Killing %s.", active_task->name); + quit_isr(); + __builtin_unreachable(); +} + +//returns true if stack was expanded +bool pf_check_stack(uint32_t cr2/*, uint32_t edx, uint32_t ecx, uint32_t eax, + uint32_t code, uint32_t eip*/) { +//logf(LOG_INFO, "page fault in %s at 0x%h trying to access 0x%h", active_task->name, eip, cr2); +//logf(LOG_INFO, "stack bottom is 0x%h", active_task->stack_bottom); + + if (cr2 >= active_task->stack_bottom - 0x1000) { + //logf(LOG_INFO, "expanding stack"); + switch_to_kernel_cr3(); + pd_user_allocate(active_task->page_directory, active_task->stack_bottom -= 4096, 1, true); + switch_to_task_cr3(); + //logf(LOG_INFO, "new stack bottom is 0x%h", active_task->stack_bottom); + return true; + } + else { + logf(LOG_ERROR, "Illegal access of 0x%h", cr2); + return false; + } } static void register_int(uint8_t n, isr_t *isr, uint8_t dpl) { @@ -231,4 +315,4 @@ void init_idt() { asm volatile ( "lidt %0" : : "m" (idtr) : "al"); -}
\ No newline at end of file +} |