diff options
-rw-r--r-- | apps/wm/wm.c | 13 | ||||
-rw-r--r-- | kernel/drivers/fb.c | 2 | ||||
-rw-r--r-- | kernel/drivers/ps2/keyboard.c | 2 | ||||
-rw-r--r-- | kernel/drivers/ps2/mouse.c | 3 | ||||
-rw-r--r-- | kernel/features/io.c | 74 | ||||
-rw-r--r-- | kernel/features/mm.c | 2 | ||||
-rw-r--r-- | libs/libc/inc/sys.h | 5 |
7 files changed, 76 insertions, 25 deletions
diff --git a/apps/wm/wm.c b/apps/wm/wm.c index 49913dc..23b5879 100644 --- a/apps/wm/wm.c +++ b/apps/wm/wm.c @@ -521,24 +521,23 @@ int main(int argc, char **argv) u8 msg[1024] = { 0 }; struct event_keyboard event_keyboard = { 0 }; struct event_mouse event_mouse = { 0 }; - u32 listeners[] = { IO_KEYBOARD, IO_MOUSE, IO_BUS, 0 }; + u32 listeners[] = { IO_KEYBOARD, IO_MOUSE, 0 }; while (1) { res poll_ret = 0; if ((poll_ret = io_poll(listeners)) >= 0) { - if (poll_ret == 0) { - if (io_read(listeners[poll_ret], &event_keyboard, 0, + if (poll_ret == IO_KEYBOARD) { + if (io_read(IO_KEYBOARD, &event_keyboard, 0, sizeof(event_keyboard)) > 0) { handle_event_keyboard(&event_keyboard); continue; } - } else if (poll_ret == 1) { - if (io_read(listeners[poll_ret], &event_mouse, 0, - sizeof(event_mouse)) > 0) { + } else if (poll_ret == IO_MOUSE) { + if (io_read(IO_MOUSE, &event_mouse, 0, sizeof(event_mouse)) > 0) { handle_event_mouse(&event_mouse); continue; } - } else if (poll_ret == 2) { + } else if (poll_ret == IO_BUS) { if (msg_receive(msg, sizeof(msg)) > 0) { handle_message(msg); continue; diff --git a/kernel/drivers/fb.c b/kernel/drivers/fb.c index c74bc28..dcccf72 100644 --- a/kernel/drivers/fb.c +++ b/kernel/drivers/fb.c @@ -34,7 +34,7 @@ static res fb_ioctl(u32 request, void *arg1, void *arg2, void *arg3) if (!info) return -ENOENT; - if (!arg1 || !memory_writable(arg1)) + if (!memory_writable(arg1)) return -EFAULT; if (fb_owner != 0 && proc_from_pid(fb_owner)) diff --git a/kernel/drivers/ps2/keyboard.c b/kernel/drivers/ps2/keyboard.c index 616c539..be057d7 100644 --- a/kernel/drivers/ps2/keyboard.c +++ b/kernel/drivers/ps2/keyboard.c @@ -60,7 +60,7 @@ static res keyboard_read(void *buf, u32 offset, u32 count) static res keyboard_ready(void) { - return !stack_empty(queue); + return !stack_empty(queue) ? EOK : -EAGAIN; } CLEAR void ps2_keyboard_reset(void) diff --git a/kernel/drivers/ps2/mouse.c b/kernel/drivers/ps2/mouse.c index 1d3c1ae..ba6d338 100644 --- a/kernel/drivers/ps2/mouse.c +++ b/kernel/drivers/ps2/mouse.c @@ -45,6 +45,7 @@ static void mouse_handler(struct regs *r) event->but3 = (mouse_byte[0] >> 2) & 1; stack_push_bot(queue, event); mouse_cycle = 0; + io_unblock(IO_MOUSE); break; default: break; @@ -53,7 +54,7 @@ static void mouse_handler(struct regs *r) static res mouse_ready(void) { - return !stack_empty(queue); + return !stack_empty(queue) ? EOK : -EAGAIN; } static res mouse_read(void *buf, u32 offset, u32 count) diff --git a/kernel/features/io.c b/kernel/features/io.c index d0f1b1c..d0cca07 100644 --- a/kernel/features/io.c +++ b/kernel/features/io.c @@ -1,11 +1,13 @@ // MIT License, Copyright (c) 2021 Marvin Borner #include <assert.h> +#include <cpu.h> #include <def.h> #include <fb.h> #include <interrupts.h> #include <io.h> #include <list.h> +#include <mem.h> #include <mm.h> #include <proc.h> #include <ps2.h> @@ -14,9 +16,16 @@ #include <syscall.h> #include <timer.h> +struct io_listener { + u32 group; + struct proc *proc; +}; + PROTECTED static struct io_dev *io_mappings[IO_MAX] = { 0 }; PROTECTED static struct list *io_listeners[IO_MAX] = { 0 }; +static u32 group_id = 0; + static u8 io_type_valid(enum io_type io) { return io > IO_MIN && io < IO_MAX; @@ -30,6 +39,24 @@ static struct io_dev *io_get(enum io_type io) return io_mappings[io]; } +// TODO: Efficiency +static void io_remove_group(u32 group) +{ + for (u32 io = IO_MIN; io < IO_MAX; io++) { + struct node *iterator = io_listeners[io]->head; + while (iterator) { + struct io_listener *listener = iterator->data; + struct node *next = iterator->next; + if (listener->group == group) + list_remove(io_listeners[io], iterator); + iterator = next; + } + } + + if (group + 1 == group_id) + group_id--; +} + CLEAR void io_add(enum io_type io, struct io_dev *dev) { assert(io_type_valid(io) && !io_mappings[io]); @@ -41,13 +68,36 @@ res io_poll(u32 *devs) if (!memory_readable(devs)) return -EFAULT; - io_block(IO_BUS, proc_current()); // TODO! - for (u32 *p = devs; p && memory_readable(p) && *p; p++) { - if (!io_get(*p)) + u32 group = group_id++; + + for (u32 *p = devs; p && memory_readable(p); p++) { + stac(); + enum io_type io = *p; + clac(); + + if (!io) + break; + + struct io_dev *dev = io_get(io); + if (!dev || !dev->read) { + io_remove_group(group); + group--; return -ENOENT; + } else if (dev->ready && dev->ready() == EOK) { + io_remove_group(group); + group--; + return io; + } else { + struct io_listener *listener = zalloc(sizeof(*listener)); + listener->group = group; + listener->proc = proc_current(); + list_add(io_listeners[io], listener); + } } - return -EFAULT; + proc_state(proc_current(), PROC_BLOCKED); + proc_yield(); + return io_poll(devs); } res io_control(enum io_type io, u32 request, void *arg1, void *arg2, void *arg3) @@ -80,7 +130,7 @@ res io_read(enum io_type io, void *buf, u32 offset, u32 count) if (!(dev = io_get(io)) || !dev->read) return -ENOENT; - if (dev->ready && !dev->ready()) + if (dev->ready && dev->ready() != EOK) return -EAGAIN; return dev->read(buf, offset, count); @@ -92,7 +142,7 @@ res io_ready(enum io_type io) if (!(dev = io_get(io))) return -ENOENT; - if (dev->ready && !dev->ready()) + if (dev->ready && dev->ready() != EOK) return -EAGAIN; return EOK; @@ -101,20 +151,26 @@ res io_ready(enum io_type io) void io_block(enum io_type io, struct proc *proc) { assert(io_type_valid(io)); - list_add(io_listeners[io], proc); + struct io_listener *listener = zalloc(sizeof(*listener)); + listener->group = group_id++; + listener->proc = proc; + list_add(io_listeners[io], listener); proc_state(proc_current(), PROC_BLOCKED); proc_yield(); } void io_unblock(enum io_type io) { + printf("%d\n", group_id); assert(io_type_valid(io)); struct node *iterator = io_listeners[io]->head; while (iterator) { - struct proc *proc = iterator->data; + struct io_listener *listener = iterator->data; + struct proc *proc = listener->proc; proc_state(proc, PROC_RUNNING); struct node *next = iterator->next; - list_remove(io_listeners[io], iterator); + io_remove_group(listener->group); + free(listener); iterator = next; } } diff --git a/kernel/features/mm.c b/kernel/features/mm.c index 9f0bd07..4ed3ab9 100644 --- a/kernel/features/mm.c +++ b/kernel/features/mm.c @@ -512,7 +512,7 @@ res memory_sys_alloc(struct page_dir *dir, u32 size, u32 *addr, u32 *id, u8 shar res memory_sys_free(struct page_dir *dir, u32 addr) { - if (!addr || !memory_readable((void *)addr)) + if (!memory_readable((void *)addr)) return -EFAULT; struct list *links = proc_current()->memory; diff --git a/libs/libc/inc/sys.h b/libs/libc/inc/sys.h index 749888a..461db2e 100644 --- a/libs/libc/inc/sys.h +++ b/libs/libc/inc/sys.h @@ -29,11 +29,6 @@ enum sys { SYS_EXIT, // Exit current process SYS_BOOT, // Boot functions (e.g. reboot/shutdown) SYS_YIELD, // Switch to next process - /* SYS_NET_OPEN, // Open network socket */ - /* SYS_NET_CLOSE, // Close network socket */ - /* SYS_NET_CONNECT, // Connect to destination */ - /* SYS_NET_SEND, // Send to socket */ - /* SYS_NET_RECEIVE, // Receive data from socket */ }; enum io_type { |