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.c200
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
+}