diff options
author | Benji Dial <benji6283@gmail.com> | 2020-09-13 03:19:57 -0400 |
---|---|---|
committer | Benji Dial <benji6283@gmail.com> | 2020-09-13 03:19:57 -0400 |
commit | 1e4a254674f668839e5de273916024c16814b045 (patch) | |
tree | 6774f4d4398a29c4aafb4120070975d864ffcde4 /src/kernel | |
parent | b8284137d4e0eec11c78bc14047243fce6a51373 (diff) | |
download | portland-os-1e4a254674f668839e5de273916024c16814b045.tar.gz |
(basic, not much tested) keyboard, better panic
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/drive.c | 6 | ||||
-rw-r--r-- | src/kernel/elf.c | 16 | ||||
-rw-r--r-- | src/kernel/elf.h | 2 | ||||
-rw-r--r-- | src/kernel/fat.c | 10 | ||||
-rw-r--r-- | src/kernel/ide.c | 26 | ||||
-rw-r--r-- | src/kernel/idt.c | 55 | ||||
-rw-r--r-- | src/kernel/isrs.asm | 27 | ||||
-rw-r--r-- | src/kernel/kbd.c | 285 | ||||
-rw-r--r-- | src/kernel/kbd.h | 10 | ||||
-rw-r--r-- | src/kernel/main.c | 8 | ||||
-rw-r--r-- | src/kernel/paging.c | 41 | ||||
-rw-r--r-- | src/kernel/paging.h | 3 | ||||
-rw-r--r-- | src/kernel/panic.c | 12 | ||||
-rw-r--r-- | src/kernel/panic.h | 6 | ||||
-rw-r--r-- | src/kernel/pci.c | 6 | ||||
-rw-r--r-- | src/kernel/task.c | 22 |
16 files changed, 461 insertions, 74 deletions
diff --git a/src/kernel/drive.c b/src/kernel/drive.c index c3aa5b2..731088c 100644 --- a/src/kernel/drive.c +++ b/src/kernel/drive.c @@ -15,15 +15,15 @@ static file_id_t unknown_get_file(const struct drive *d, const char *path) { } static void unknown_free_file(const struct drive *d, file_id_t fid) { - panic("Free file called on unknown file system"); + PANIC("Free file called on unknown file system."); } static void unknown_load_sector(const struct drive *d, file_id_t fid, uint32_t sector, void *at) { - panic("Load sector called on unknown file system"); + PANIC("Load sector called on unknown file system."); } static uint32_t unknown_get_file_length(const struct drive *d, file_id_t fid) { - panic("Get file length called on unknown file system"); + PANIC("Get file length called on unknown file system."); } __attribute__ ((const)) diff --git a/src/kernel/elf.c b/src/kernel/elf.c index bd2f12d..423d51a 100644 --- a/src/kernel/elf.c +++ b/src/kernel/elf.c @@ -73,7 +73,7 @@ struct ph_entry { uint32_t align; } __attribute__ ((packed)); -bool try_elf_run(const struct drive *d, const char *path) { +bool try_elf_run(const struct drive *d, const char *path, const char *pass_old_vma) { file_id_t h = d->get_file(d, path); if (!h) return false; @@ -109,9 +109,23 @@ bool try_elf_run(const struct drive *d, const char *path) { free_pages(phtable, phtable_pages); d->free_file(d, h); + const char *pass = vma_to_pma(active_task->page_directory, pass_old_vma); + + uint32_t pass_l = 0; + while (pass[pass_l++]) + ; + + void *pass_vma; + void *pass_pma; + user_allocate_anywhere_readonly_together(pd, ((pass_l - 1) >> 12) + 1, &pass_vma, &pass_pma); + //TODO: handle error condition + + memcpy(pass_pma, pass, pass_l); + struct task_state tstate; tstate.page_directory = pd; tstate.ret_addr = ehead.entry_vma; + tstate.edx = (uint32_t)pass_vma; new_task(tstate); return true; }
\ No newline at end of file diff --git a/src/kernel/elf.h b/src/kernel/elf.h index 09aa05c..98489f2 100644 --- a/src/kernel/elf.h +++ b/src/kernel/elf.h @@ -4,6 +4,6 @@ #include <stdint.h> #include "drive.h" -bool try_elf_run(const struct drive *d, const char *path); +bool try_elf_run(const struct drive *d, const char *path, const char *pass_old_vma); #endif
\ No newline at end of file diff --git a/src/kernel/fat.c b/src/kernel/fat.c index 1b6c52d..c297cab 100644 --- a/src/kernel/fat.c +++ b/src/kernel/fat.c @@ -89,7 +89,7 @@ static struct fat_info *next_fi; static void alloc_next_fi() { if (!((uint32_t)(next_fi = (struct fat_info *)((uint32_t)next_fi + 64)) & 0xfff)) if (!(next_fi = allocate_kernel_pages(1))) - panic("Out of memory in FAT driver."); + PANIC("Out of memory in FAT driver."); } static const struct drive *cur_drive; @@ -183,9 +183,9 @@ static const char *split_path(const char *path, uint8_t *fat_name_buffer) { ++pi; } else - panic("Bad path in FAT16 driver"); + PANIC("Bad path in FAT16 driver."); else if (((fi == 8) && (path[pi - 1] != EXT_SEP_CHAR)) || (fi == 11)) - panic("Bad path in FAT16 driver"); + PANIC("Bad path in FAT16 driver."); else { fat_name_buffer[fi++] = (uint8_t)path[pi++]; } @@ -229,7 +229,7 @@ static file_id_t fat_get_file(const struct drive *d, const char *path) { return n; } - panic("Maximum number of files open reached for FAT drive."); + PANIC("Maximum number of files open reached for FAT drive."); } static void fat_free_file(const struct drive *d, file_id_t fid) { @@ -365,7 +365,7 @@ void init_fat() { bool try_fat_init_drive(struct drive *d) { if (next_id >= MAX_FAT_DRIVES) - panic("Maximum number of FAT drives reached."); + PANIC("Maximum number of FAT drives reached."); if (!d->read_sectors(d, 0, 1, fat_driver_buffer)) return false; diff --git a/src/kernel/ide.c b/src/kernel/ide.c index 70b1dee..4b6443a 100644 --- a/src/kernel/ide.c +++ b/src/kernel/ide.c @@ -24,11 +24,11 @@ static uint8_t wait_for_ready(uint16_t base_port) { for (spinner_t n = -1; n; --n) { uint8_t s = inb(base_port | ATA_REG_STATUS); if (s & ATA_STATUS_ERROR) - panic("Error status in IDE driver."); + PANIC("Error status in IDE driver."); if (s & ATA_STATUS_DRIVE_READY) return s; } - panic("Spun out in IDE driver."); + PANIC("Spun out in IDE driver."); } //returns the status after waiting @@ -38,7 +38,7 @@ static uint8_t wait_for_error_or_ready(uint16_t base_port) { if (s & (ATA_STATUS_DRIVE_READY | ATA_STATUS_ERROR)) return s; } - panic("Spun out in IDE driver."); + PANIC("Spun out in IDE driver."); } //returns the status after waiting @@ -48,9 +48,9 @@ static uint8_t wait_for_data_ready_not_busy(uint16_t base_port) { if (!(s & ATA_STATUS_BUSY) && (s & ATA_STATUS_DATA_READY)) return s; if (s & ATA_STATUS_ERROR) - panic("Error status in IDE driver."); + PANIC("Error status in IDE driver."); } - panic("Spun out in IDE driver."); + PANIC("Spun out in IDE driver."); } static uint32_t ide_ata_rs(const struct drive *d, uint32_t start, uint32_t count, void *buffer) { @@ -62,9 +62,9 @@ static uint32_t ide_ata_rs(const struct drive *d, uint32_t start, uint32_t count return 0; if (start & 0xf0000000) - panic("IDE ATA driver does not support reads starting past 256MiB currently."); + PANIC("IDE ATA driver does not support reads starting past 256MiB currently."); if (count & 0xffffff00) - panic("IDE ATA driver does not support reads over 128kiB in length currently."); + PANIC("IDE ATA driver does not support reads over 128kiB in length currently."); uint32_t lba = start & 0x00ffffff; @@ -92,7 +92,7 @@ static uint32_t ide_ata_rs(const struct drive *d, uint32_t start, uint32_t count } static uint32_t ide_ata_ws(const struct drive *d, uint32_t start, uint32_t count, const void *buffer) { - panic("IDE ATA writing not implemented yet"); + PANIC("IDE ATA writing not implemented yet."); return 0; } @@ -104,11 +104,11 @@ static uint32_t ide_atapi_rs(const struct drive *d, uint32_t start, uint32_t cou if (!count) return 0; - + PANIC("IDE ATAPI reading not implemented yet."); } static uint32_t ide_atapi_ws(const struct drive *d, uint32_t start, uint32_t count, const void *buffer) { - panic("IDE ATAPI writing not implemented yet"); + PANIC("IDE ATAPI writing not implemented yet."); return 0; } @@ -122,7 +122,7 @@ struct id_space { static void test_drive(uint16_t base_port, uint16_t alt_port, bool slave) { if (n_ide_drives == MAX_IDE_DRIVES) - panic("Maximum number of IDE drives reached."); + PANIC("Maximum number of IDE drives reached."); struct ide_drive_info *next = ide_drives + n_ide_drives; struct drive next_d; @@ -161,7 +161,7 @@ static void test_drive(uint16_t base_port, uint16_t alt_port, bool slave) { else { uint16_t code = inb(base_port | 0x4) + (inb(base_port | 0x5) << 8); if (!code) { - panic("PATA identification aborted."); + PANIC("PATA identification aborted."); } if (code == 0xeb14) { next_d.drive_type = "IDE PATAPI"; @@ -181,7 +181,7 @@ static void test_drive(uint16_t base_port, uint16_t alt_port, bool slave) { //in the future, maybe add support for 48-bit LBA, and/or CHS addressing if (!ids.max_lba) - panic("Encountered ATA drive that doesn't support 28-bit LBA"); + PANIC("Encountered ATA drive that doesn't support 28-bit LBA."); next_d.n_sectors = ids.max_lba; commit_drive(next_d); diff --git a/src/kernel/idt.c b/src/kernel/idt.c index 3d23797..4dc8a36 100644 --- a/src/kernel/idt.c +++ b/src/kernel/idt.c @@ -7,12 +7,11 @@ #include "task.h" #include "paging.h" #include "pmap.h" +#include "kbd.h" enum { IDT_PRESENT = 0x80, - IDT_INT = 0x0e, - IDT_TRAP = 0x0f }; struct idt_entry { @@ -55,21 +54,13 @@ static uint32_t sc_file_read(uint32_t handle, uint32_t file_offset, uint32_t cou return count; } -static bool sc_start_task(uint32_t drive_number, char *path) { +static bool sc_start_task(uint32_t drive_number, char *path, const char *pass) { switch_to_kernel_cr3(); - bool result = try_elf_run(drives + drive_number, path); + bool result = try_elf_run(drives + drive_number, vma_to_pma(active_task->page_directory, path), pass); 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) { return pd_user_allocate_anywhere_writable(active_task->page_directory, pages); } @@ -94,7 +85,7 @@ static uint32_t sc_memory_info(enum mi_arg arg) { case MI_USER_LEFT: return user_pages_left; case MI_TASK_LEFT: - panic("TODO: this process memory left"); + PANIC("TODO: memory info task left"); default: return -1; } @@ -106,18 +97,21 @@ void const *syscall_table[] = { &sc_file_read, &sc_file_get_size, &sc_start_task, - &sc_log_string, - &sc_get_key, + &logsz, + &get_key_code, &sc_allocate_ram, &sc_memory_info }; -typedef void isr_t; +//these aren't really void (*)()'s, but gcc complains if we take an address of a void, so we give it a type +typedef void (*isr_t)(); extern isr_t syscall_isr; extern isr_t quit_isr; extern isr_t yield_isr; +extern isr_t kbd_isr; + static void register_int(uint8_t n, isr_t *isr, uint8_t dpl) { idt[n].addr_low = (uint32_t)isr & 0xffff; idt[n].addr_high = (uint32_t)isr >> 16; @@ -125,6 +119,17 @@ static void register_int(uint8_t n, isr_t *isr, uint8_t dpl) { idt[n].flags = IDT_PRESENT | (dpl << 5) | IDT_INT; } +enum { + PIC_MCMD = 0x0020, + PIC_MDATA = 0x0021, + PIC_SCMD = 0x00a0, + PIC_SDATA = 0x00a1 +}; + +enum { + PIC_RESET = 0x11 +}; + void init_idt() { for (uint16_t i = 0; i < 256; ++i) { idt[i].flags = 0; @@ -135,8 +140,22 @@ void init_idt() { register_int(0x38, &quit_isr, 3); register_int(0x39, &yield_isr, 3); - outb(0x0021, 0xff); - outb(0x00a1, 0xff); + register_int(0x21, &kbd_isr, 0); + + outb(PIC_MCMD, PIC_RESET); + outb(PIC_SCMD, PIC_RESET); + + outb(PIC_MDATA, 0x20); + outb(PIC_SDATA, 0x28); + + outb(PIC_MDATA, 0x04); + outb(PIC_SDATA, 0x02); + + outb(PIC_MDATA, 0x01); + outb(PIC_SDATA, 0x01); + + outb(PIC_MDATA, 0xfd); + outb(PIC_SDATA, 0xff); asm volatile ( "lidt %0" diff --git a/src/kernel/isrs.asm b/src/kernel/isrs.asm index 82c17fe..9a9600c 100644 --- a/src/kernel/isrs.asm +++ b/src/kernel/isrs.asm @@ -4,12 +4,15 @@ global syscall_isr global quit_isr global yield_isr global _start_user_mode +global kbd_isr extern syscall_table extern active_task extern delete_task extern advance_active_task +extern on_kbd_isr +extern make_sure_tasks n_syscalls equ 0x9 @@ -39,6 +42,7 @@ syscall_isr: quit_isr: push dword [active_task] call delete_task + call make_sure_tasks mov dword [esp], yield_isr.return_to_task jmp advance_active_task @@ -59,7 +63,7 @@ yield_isr: mov dword [eax + 4], edx mov edx, dword [esp + 12] - mov dword [eax + 4], edx + mov dword [eax + 32], edx call advance_active_task @@ -72,8 +76,8 @@ yield_isr: mov edx, dword [eax + 4] mov cr3, edx - mov edx, dword [eax + 4] - mov dword [esp + 24], edx + mov edx, dword [eax + 32] + mov dword [esp + 12], edx mov ebx, dword [eax + 8] mov ecx, dword [eax + 12] @@ -94,4 +98,19 @@ _start_user_mode: push dword 0x00000200;interrupt flag push dword 0x23 sub esp, 4 - jmp yield_isr.return_to_task
\ No newline at end of file + jmp yield_isr.return_to_task + +kbd_isr: + push eax + push ecx + push edx + + call on_kbd_isr + + mov al, 0x20 + out 0x0020, al + + pop edx + pop ecx + pop eax + iret
\ No newline at end of file diff --git a/src/kernel/kbd.c b/src/kernel/kbd.c new file mode 100644 index 0000000..73a5ec6 --- /dev/null +++ b/src/kernel/kbd.c @@ -0,0 +1,285 @@ +#include <stdint.h> +#include <stdbool.h> +#include "panic.h" +#include "log.h" +#include "util.h" + +static uint32_t *kbd_in_pointer; +static uint32_t *kbd_out_pointer; + +#define KBD_BUFFER_LENGTH 1024 +static uint32_t kbd_buffer[KBD_BUFFER_LENGTH]; + +static uint32_t mod_mask; + +enum { + PS2_CMD = 0x64, + PS2_DATA = 0x60 +}; + +enum { + PS2C_READ_CONFIG = 0x20, + PS2C_WRITE_CONFIG = 0x60, + PS2C_DISABLE = 0xad, + PS2C_ENABLE = 0xae +}; + +enum { + PS2S_CODE_READY = 0x01 +}; + +enum { + PS2G_XT_COMPAT = 0x40 +}; + +void init_kbd() { + outb(PS2_CMD, PS2C_READ_CONFIG); + uint8_t config = inb(PS2_DATA); + outb(PS2_CMD, PS2C_WRITE_CONFIG); + outb(PS2_DATA, config | PS2G_XT_COMPAT); + + kbd_in_pointer = kbd_buffer; + kbd_out_pointer = kbd_buffer; + mod_mask = 0; +} + +uint32_t get_key_code() { + if (kbd_in_pointer == kbd_out_pointer) + return 0; + uint32_t code = *kbd_out_pointer; + if (++kbd_out_pointer == kbd_buffer + KBD_BUFFER_LENGTH) + kbd_out_pointer = kbd_buffer; + return code; +} + +enum { + MOD_LSHIFT = 0x00100, + MOD_RSHIFT = 0x00200, + MOD_CAPS = 0x00400, + MOD_INSERT = 0x00800, + MOD_NUMPAD = 0x01000, + MOD_SCROLL = 0x02000, + MOD_LALT = 0x04000, + MOD_RALT = 0x08000, + MOD_LCTRL = 0x10000, + MOD_RCTRL = 0x20000, + MOD_LMETA = 0x40000, + MOD_RMETA = 0x80000 +}; + +enum { + CODE_CAPS = 0x80, + CODE_INSERT, + CODE_NUMPAD, + CODE_SCROLL, + CODE_LSHIFT, + CODE_RSHIFT, + CODE_LALT, + CODE_RALT, + CODE_LCTRL, + CODE_RCTRL, + CODE_LMETA, + CODE_RMETA, + /* 0x8c - 0x97 reserved */ + /* 0x98 - 0x9f unassigned */ + CODE_F1 = 0xa0, + CODE_F2, + CODE_F3, + CODE_F4, + CODE_F5, + CODE_F6, + CODE_F7, + CODE_F8, + CODE_F9, + CODE_F10, + CODE_F11, + CODE_F12, + /* 0xac - 0xaf unassigned */ + CODE_NUM0 = 0xb0, + CODE_NUM1, + CODE_NUM2, + CODE_NUM3, + CODE_NUM4, + CODE_NUM5, + CODE_NUM6, + CODE_NUM7, + CODE_NUM8, + CODE_NUM9, + CODE_NTIMES, + CODE_NPLUS, + CODE_NENTER, + CODE_NMINUS, + CODE_NDOT, + CODE_NSLASH, + /* 0xc0 unassigned */ + CODE_DELETE, + CODE_HOME, + CODE_END, + CODE_PUP, + CODE_PDOWN, + CODE_UP, + CODE_DOWN, + CODE_LEFT, + CODE_RIGHT, + CODE_ESC, + CODE_MENU, + CODE_PAUSE, + CODE_PRSCR, + /* 0xce - 0xef unassigned */ + CODE_END_LSHIFT = 0xf0, + CODE_END_RSHIFT, + CODE_END_LALT, + CODE_END_RALT, + CODE_END_LCTRL, + CODE_END_RCTRL, + CODE_END_LMETA, + CODE_END_RMETA +}; + +static const uint32_t mod_bits[] = { + MOD_CAPS, + MOD_INSERT, + MOD_NUMPAD, + MOD_SCROLL, + MOD_LSHIFT, + MOD_RSHIFT, + MOD_LALT, + MOD_RALT, + MOD_LCTRL, + MOD_RCTRL, + MOD_LMETA, + MOD_RMETA +}; + +static const uint32_t *const unmod_bits = mod_bits + 4; + +//in these tables, 0x00 represents an unknown key, +// and 0xff represents a key release. + +static const uint8_t codes[] = { + 0, CODE_ESC, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', '\b', '\t', + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', '\n', CODE_LCTRL, 'a', 's', + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'', '`', CODE_LSHIFT, '\\', 'z', 'x', 'c', 'v', + 'b', 'n', 'm', ',', '.', '/', CODE_RSHIFT, CODE_NTIMES, + CODE_LALT, ' ', CODE_CAPS, CODE_F1, CODE_F2, CODE_F3, CODE_F4, CODE_F5, + CODE_F6, CODE_F7, CODE_F8, CODE_F9, CODE_F10, CODE_NUMPAD, CODE_SCROLL, CODE_NUM7, + CODE_NUM8, CODE_NUM9, CODE_NMINUS, CODE_NUM4, CODE_NUM5, CODE_NUM6, CODE_NPLUS, CODE_NUM1, + CODE_NUM2, CODE_NUM3, CODE_NUM0, CODE_NDOT, 0, 0, 0, CODE_F11, + CODE_F12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, CODE_END_LCTRL, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, CODE_END_LSHIFT, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, CODE_END_RSHIFT, 0xff, + CODE_END_LALT, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0xff, + 0xff, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static const uint8_t codes_e0[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, CODE_NENTER, CODE_RCTRL, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, CODE_NSLASH, 0, 0, + CODE_RALT, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, CODE_HOME, + CODE_UP, CODE_PUP, 0, CODE_LEFT, 0, CODE_RIGHT, 0, CODE_END, + CODE_DOWN, CODE_PDOWN, CODE_INSERT, CODE_DELETE, 0, 0, 0, 0, + 0, 0, 0, CODE_LMETA, CODE_RMETA, CODE_MENU, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xff, CODE_END_RCTRL, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0xff, 0, 0, + CODE_END_RALT, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0xff, + 0xff, 0xff, 0, 0xff, 0, 0xff, 0, 0xff, + 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, + 0, 0, 0, CODE_END_LMETA, CODE_END_RMETA, 0xff, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void on_kbd_isr() { + while (inb(PS2_CMD) & PS2S_CODE_READY) { + uint8_t code = inb(PS2_DATA); + if (code == 0xe1) { + code = inb(PS2_DATA); + if (code == 0x1d) { + if (inb(PS2_DATA) != 0x45) + code = 0; + else + code = CODE_PAUSE; + } + else if (code == 0x9d) { + if (inb(PS2_DATA) != 0xc5) + code = 0; + else + code = 0xff; + } + else + code = 0; + } + else if (code == 0xe0) { + code = inb(PS2_DATA); + if (code == 0x2a) { + if ((inb(PS2_DATA) != 0xe0) || + (inb(PS2_DATA) != 0x37)) + code = 0; + else + code = CODE_PRSCR; + } + else if (code == 0xb7) { + if ((inb(PS2_DATA) != 0xe0) || + (inb(PS2_DATA) != 0xaa)) + code = 0; + else + code = 0xff; + } + else + code = codes_e0[code]; + } + else + code = codes[code]; + + if (!code) + PANIC("Unknown scancode."); + + if (code < 0xf0) + *kbd_in_pointer++ = mod_mask | code; + if ((code >= 0x80) && (code <= 0x83)) + mod_mask ^= mod_bits[code & 0x03]; + else if ((code >= 0x84) && (code <= 0x8b)) + mod_mask |= mod_bits[code & 0x0f]; + else if (code >= 0xf0) + mod_mask &= ~unmod_bits[code & 0x0f]; + } +}
\ No newline at end of file diff --git a/src/kernel/kbd.h b/src/kernel/kbd.h new file mode 100644 index 0000000..8a4ed8b --- /dev/null +++ b/src/kernel/kbd.h @@ -0,0 +1,10 @@ +#ifndef KBD_H +#define KBD_H + +#include <stdint.h> + +void init_kbd(); +uint32_t get_key_code(); +void on_kbd_isr(); + +#endif
\ No newline at end of file diff --git a/src/kernel/main.c b/src/kernel/main.c index d99b595..e2a23e8 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -13,6 +13,7 @@ #include "elf.h" #include "log.h" #include "vga.h" +#include "kbd.h" void reset_tree(); void tree(struct drive *d); @@ -32,8 +33,6 @@ void main() { logsz("Portland v0.0.11\n\n"); - //list vesa modes? - pci_init(); u16_dec(n_pci_devices, nbuf); @@ -137,9 +136,10 @@ void main() { logsz(nbuf); logsz("k\n\n"); - if (!try_elf_run(drives, "BIN/INIT.ELF")) - panic("Failed to load init program."); + if (!try_elf_run(drives, "BIN/INIT.ELF", "")) + PANIC("Failed to load init program."); + init_kbd(); init_idt(); logsz("Switching to init task.\n"); diff --git a/src/kernel/paging.c b/src/kernel/paging.c index 36fb8a7..a0f7c3d 100644 --- a/src/kernel/paging.c +++ b/src/kernel/paging.c @@ -77,27 +77,47 @@ void *new_task_pd() { void *pd_user_allocate(void *pd, uint32_t vma, uint32_t pages, bool writable) { void *pma = allocate_user_pages(pages); if (!pma) - panic("Could not allocate user pages."); + PANIC("Could not allocate user pages."); for (uint32_t i = 0; i < pages; ++i) pd_map(pd, (uint32_t)pma + (i << 12), vma + (i << 12), writable); return pma; } -void *pd_user_allocate_anywhere_writable(void *pd, uint32_t pages) { +__attribute__ ((pure)) +static void *find_user_vma_run(void *pd, uint32_t pages) { uint32_t run = 0; for (void *vma = (void *)KERNEL_END; vma; vma += 4096) { if (pd_is_mapped(pd, (uint32_t)vma)) run = 0; - else if (++run == pages) { - vma -= (pages - 1) * 4096; - for (uint32_t i = 0; i < pages; ++i) - pd_map(pd, (uint32_t)allocate_user_pages(1), (uint32_t)vma + 4096 * i, true); - return vma; - } + else if (++run == pages) + return vma - (pages - 1) * 4096; } return 0; } +void *pd_user_allocate_anywhere_writable(void *pd, uint32_t pages) { + void *vma = find_user_vma_run(pd, pages); + if (!vma) + return 0; + for (uint32_t i = 0; i < pages; ++i) + pd_map(pd, (uint32_t)allocate_user_pages(1), (uint32_t)vma + 4096 * i, true); + return vma; +} + +void user_allocate_anywhere_readonly_together(void *pd, uint32_t pages, void **vma_out, void **pma_out) { + *vma_out = find_user_vma_run(pd, pages); + if (!*vma_out) { + *pma_out = 0; + return; + } + *pma_out = allocate_user_pages(pages); + if (!*pma_out) { + *vma_out = 0; + return; + } + pd_map(pd, (uint32_t)*pma_out, (uint32_t)*vma_out, false); +} + #define KPAGE_DIR ((uint32_t *)0x00005000) #define KPAGE_TABLE_0 ((uint32_t *)0x00400000) @@ -118,6 +138,11 @@ void init_paging() { : : : "eax"); } +__attribute__ ((pure)) +void *vma_to_pma(void *pd, const void *vma) { + return (void *)(((uint32_t *)(((uint32_t *)pd)[(uint32_t)vma >> 22] & PE_ADDR_MASK))[((uint32_t)vma >> 12) % 1024] & PE_ADDR_MASK) + (uint32_t)vma % 4096; +} + void switch_to_kernel_cr3() { asm volatile ( "mov $0x00005000, %%eax\n" diff --git a/src/kernel/paging.h b/src/kernel/paging.h index e39b3f2..07bf386 100644 --- a/src/kernel/paging.h +++ b/src/kernel/paging.h @@ -11,6 +11,9 @@ void free_task_pd(void *pd); void *new_task_pd(); void *pd_user_allocate(void *pd, uint32_t vma, uint32_t pages, bool writable); void *pd_user_allocate_anywhere_writable(void *pd, uint32_t pages); +void user_allocate_anywhere_readonly_together(void *pd, uint32_t pages, void **vma_out, void **pma_out); + +void *vma_to_pma(void *pd, const void *vma) __attribute__ ((pure)); void switch_to_kernel_cr3(); void switch_to_task_cr3();
\ No newline at end of file diff --git a/src/kernel/panic.c b/src/kernel/panic.c index a2e68e3..5d32bf7 100644 --- a/src/kernel/panic.c +++ b/src/kernel/panic.c @@ -1,11 +1,17 @@ -#include "panic.h" #include "log.h" #include "vga.h" +#include "util.h" -void panic(const char *message) { +__attribute__ ((noreturn)) +void panic(const char *filename, uint32_t line, const char *message) { set_log_mode(LOG_PANIC); vga_blank(); - logsz("Kernel panic: "); + logsz("Kernel panic ["); + logsz(filename); + char nbuf[12] = ":"; + u32_dec(line, nbuf + 1); + logsz(nbuf); + logsz("]: "); logsz(message); logsz("\nHalting."); while (1) diff --git a/src/kernel/panic.h b/src/kernel/panic.h index 08328f2..6a8609f 100644 --- a/src/kernel/panic.h +++ b/src/kernel/panic.h @@ -1,6 +1,10 @@ #ifndef PANIC_H #define PANIC_H -void panic(const char *message) __attribute__ ((noreturn)); +#include <stdint.h> + +#define PANIC(msg) panic(__FILE__, __LINE__, msg) + +void panic(const char *filename, uint32_t line, const char *message) __attribute__ ((noreturn)); #endif
\ No newline at end of file diff --git a/src/kernel/pci.c b/src/kernel/pci.c index 9e33e49..14e24a4 100644 --- a/src/kernel/pci.c +++ b/src/kernel/pci.c @@ -32,7 +32,7 @@ struct pci_device *find_pci_device_from_class_and_subclass(uint8_t class, uint8_ static struct pci_device *next_pci_device() { if (!(n_pci_devices % PCI_DEVICES_PER_PAGE)) if (!(pci_device_pages[n_pci_devices / PCI_DEVICES_PER_PAGE] = allocate_kernel_pages(1))) - panic("Out of memory in PCI enumeration"); + PANIC("Out of memory in PCI enumeration."); return nth_pci_device(n_pci_devices++); } @@ -64,9 +64,9 @@ static void pci_device_check(uint16_t number) { void pci_init() { if (!(BOOT_INFO->support_flags & BIS_PCI)) - panic("No PCI support detected."); + PANIC("No PCI support detected."); if (!(BOOT_INFO->pci_hw_char & PHC_CS_M1)) - panic("No PCI Mechanism 1 support"); + PANIC("No PCI Mechanism 1 support."); n_pci_devices = 0; diff --git a/src/kernel/task.c b/src/kernel/task.c index 2a1f4c4..e2c19ca 100644 --- a/src/kernel/task.c +++ b/src/kernel/task.c @@ -70,24 +70,26 @@ void new_task(struct task_state state) { tasks[n] = state; return; } - panic("Maximum number of tasks reached."); + PANIC("Maximum number of tasks reached."); } void advance_active_task() { - struct task_state *prev_task = active_task; - do { + do if (++active_task == tasks + MAX_TASKS) active_task = tasks; - if (active_task == prev_task) { - set_log_mode(LOG_SYSTEM); - logsz("No active tasks, halting."); - while (1) - asm ("hlt"); - } - } while (!active_task->page_directory); } +void make_sure_tasks() { + for (uint8_t n = 0; n < MAX_TASKS; ++n) + if (tasks[n].page_directory) + return; + set_log_mode(LOG_SYSTEM); + logsz("No active tasks, halting."); + while (1) + asm ("hlt"); +} + void delete_task(struct task_state *state) { free_task_pd(state->page_directory); state->page_directory = 0; |