From 4d4e784770b576199b18f22100689125a18bfd9a Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Thu, 15 Apr 2021 22:47:54 +0200 Subject: Basic block/unblock --- kernel/features/io.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'kernel/features/io.c') diff --git a/kernel/features/io.c b/kernel/features/io.c index b8275f9..6042818 100644 --- a/kernel/features/io.c +++ b/kernel/features/io.c @@ -3,15 +3,18 @@ #include #include #include +#include #include #include #include +#include #include #include #include #include PROTECTED static struct io_dev *io_mappings[IO_MAX] = { 0 }; +PROTECTED static struct list *io_listeners[IO_MAX] = { 0 }; static u8 io_type_valid(enum io_type io) { @@ -75,11 +78,48 @@ 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()) + return -EAGAIN; + return dev->read(buf, offset, count); } +void io_block(enum io_type io, struct proc *proc, struct regs *r) +{ + assert(r->eax == SYS_IOREAD); + assert(io_type_valid(io)); + list_add(io_listeners[io], proc); + proc_state(proc_current(), PROC_BLOCKED); + proc_yield(r); +} + +void io_unblock(enum io_type io) +{ + struct page_dir *dir_bak; + memory_backup_dir(&dir_bak); + + assert(io_type_valid(io)); + struct node *iterator = io_listeners[io]->head; + while (iterator) { + struct proc *proc = iterator->data; + struct regs *r = &proc->regs; + + memory_switch_dir(proc->page_dir); + r->eax = io_read(r->ebx, (void *)r->ecx, r->edx, r->esi); + memory_switch_dir(dir_bak); + + proc_state(proc, PROC_RUNNING); + struct node *next = iterator->next; + list_remove(io_listeners[io], iterator); + iterator = next; + } +} + CLEAR void io_install(struct boot_info *boot) { + for (u32 i = 0; i < IO_MAX; i++) + io_listeners[i] = list_new(); + ps2_detect(); u8 ps2_keyboard = ps2_keyboard_detect(); -- cgit v1.2.3