diff options
Diffstat (limited to 'kernel/drivers')
-rw-r--r-- | kernel/drivers/fb.c | 64 | ||||
-rw-r--r-- | kernel/drivers/interrupts.c | 46 | ||||
-rw-r--r-- | kernel/drivers/keyboard.c | 6 | ||||
-rw-r--r-- | kernel/drivers/mouse.c | 6 |
4 files changed, 99 insertions, 23 deletions
diff --git a/kernel/drivers/fb.c b/kernel/drivers/fb.c new file mode 100644 index 0000000..8e73f5b --- /dev/null +++ b/kernel/drivers/fb.c @@ -0,0 +1,64 @@ +// MIT License, Copyright (c) 2021 Marvin Borner + +#include <assert.h> +#include <def.h> +#include <fb.h> +#include <fs.h> +#include <ioctl.h> +#include <mem.h> +#include <mm.h> +#include <str.h> +#include <sys.h> + +struct vbe_basic { + u8 stuff1[16]; + u16 pitch; + u16 width; + u16 height; + u8 stuff2[18]; + u8 *fb; + u8 stuff3[212]; +}; + +static u32 dev_id = 0; +static struct vid_info *info = NULL; + +static s32 fb_ioctl(u32 request, void *arg1, void *arg2, void *arg3, struct device *dev) +{ + UNUSED(arg2); + UNUSED(arg3); + UNUSED(dev); + + switch (request) { + case IO_FB_GET: { + if (!info) + return -1; + struct vbe_basic *vbe = (struct vbe_basic *)info->vbe; + memcpy(arg1, info->vbe, sizeof(struct vbe_basic)); + u32 size = vbe->height * vbe->pitch; + memory_map_identity(proc_current()->page_dir, + memory_range_around((u32)vbe->fb, size), MEMORY_USER); + return 0; + } + default: + return -1; + } +} + +static u8 fb_ready(void) +{ + return 1; +} + +void fb_install(struct vid_info *boot) +{ + info = boot; + + struct device *dev = zalloc(sizeof(*dev)); + dev->name = strdup("fb"); + dev->type = DEV_CHAR; + dev->ioctl = fb_ioctl; + dev->ready = fb_ready; + device_add(dev); + dev_id = dev->id; +} diff --git a/kernel/drivers/interrupts.c b/kernel/drivers/interrupts.c index fa455d7..2e1444f 100644 --- a/kernel/drivers/interrupts.c +++ b/kernel/drivers/interrupts.c @@ -5,6 +5,7 @@ #include <def.h> #include <interrupts.h> #include <mem.h> +#include <mm.h> #include <print.h> #include <proc.h> #include <serial.h> @@ -169,26 +170,30 @@ void isr_uninstall_handler(int isr) isr_routines[isr] = 0; } -void isr_handler(struct regs *r); -void isr_handler(struct regs *r) +void isr_panic(struct regs *r) { - if (r->int_no <= 32) { - struct proc *proc = proc_current(); - printf("%s Exception at 0x%x, exiting!\n", isr_exceptions[r->int_no], r->eip); - if (proc) { - printf("\t-> Exception occurred in %s at addr 0x%x\n", proc->name, - r->eip - proc->entry); - proc_exit(proc, 1); - } else { - __asm__ volatile("cli\nhlt"); - } - proc_yield(r); + printf("%s Exception (%x) at 0x%x (ring %d), exiting!\n", isr_exceptions[r->int_no], + r->err_code, r->eip, r->cs & 3); + struct proc *proc = proc_current(); + if (proc) { + printf("\t-> Exception occurred in %s at addr 0x%x\n", proc->name, + r->eip - proc->entry); + proc_exit(proc, 1); } else { - // Execute fault handler if exists - void (*handler)(struct regs * r) = isr_routines[r->int_no]; - if (handler) - handler(r); + __asm__ volatile("cli\nhlt"); } + proc_yield(r); +} + +void isr_handler(struct regs *r); +void isr_handler(struct regs *r) +{ + // Execute fault handler if exists + void (*handler)(struct regs * r) = isr_routines[r->int_no]; + if (handler) + handler(r); + else + isr_panic(r); } static void isr_install(void) @@ -228,6 +233,13 @@ static void isr_install(void) idt_set_gate(29, (u32)isr29, 0x08, 0x8E); idt_set_gate(30, (u32)isr30, 0x08, 0x8E); idt_set_gate(31, (u32)isr31, 0x08, 0x8E); + + // Set default routines + for (u32 i = 0; i < 256; i++) + isr_routines[i] = isr_panic; + + // Set page fault handler + isr_install_handler(14, page_fault_handler); } /** diff --git a/kernel/drivers/keyboard.c b/kernel/drivers/keyboard.c index 3ae3c0e..dbee8e1 100644 --- a/kernel/drivers/keyboard.c +++ b/kernel/drivers/keyboard.c @@ -66,10 +66,10 @@ static s32 keyboard_read(void *buf, u32 offset, u32 count, struct device *dev) if (stack_empty(queue)) return -1; - struct event *e = stack_pop(queue); - memcpy(buf, (u8 *)e + offset, count); + struct event_keyboard *e = stack_pop(queue); + memcpy(buf, (u8 *)e + offset, MIN(count, sizeof(*e))); free(e); - return count; + return MIN(count, sizeof(*e)); } static u8 keyboard_ready(void) diff --git a/kernel/drivers/mouse.c b/kernel/drivers/mouse.c index 40094d1..5c481da 100644 --- a/kernel/drivers/mouse.c +++ b/kernel/drivers/mouse.c @@ -94,10 +94,10 @@ static s32 mouse_read(void *buf, u32 offset, u32 count, struct device *dev) if (stack_empty(queue)) return -1; - struct event *e = stack_pop(queue); - memcpy(buf, (u8 *)e + offset, count); + struct event_mouse *e = stack_pop(queue); + memcpy(buf, (u8 *)e + offset, MIN(count, sizeof(*e))); free(e); - return count; + return MIN(count, sizeof(*e)); } void mouse_install(void) |