From 02a0c882275959c0fbd58754418ecc1218821e76 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Fri, 18 Jun 2021 22:30:25 +0200 Subject: Renamed device prefix from 'io_' to 'dev_' --- kernel/features/bus.c | 29 +++--- kernel/features/dev.c | 244 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/features/io.c | 244 ---------------------------------------------- kernel/features/logger.c | 6 +- kernel/features/syscall.c | 26 ++--- 5 files changed, 274 insertions(+), 275 deletions(-) create mode 100644 kernel/features/dev.c delete mode 100644 kernel/features/io.c (limited to 'kernel/features') diff --git a/kernel/features/bus.c b/kernel/features/bus.c index 3757a3a..ad7352f 100644 --- a/kernel/features/bus.c +++ b/kernel/features/bus.c @@ -4,9 +4,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -36,8 +36,8 @@ struct bus { u32 hash; }; -PROTECTED struct list *bus_list = NULL; -PROTECTED struct list *bus_conns = NULL; +PROTECTED static struct list *bus_list = NULL; +PROTECTED static struct list *bus_conns = NULL; static u32 conn_cnt = 1; // 0 is reserved static struct bus *bus_find_bus(u32 hash) @@ -104,7 +104,10 @@ static res bus_register(const char *name) u32 hash = crc32_user(0, name, len); if (bus_find_bus(hash)) - return -EBUSY; + return -EINVAL; + + if (bus_find_owner(proc_current()->pid)) + return -EEXIST; struct bus *bus = zalloc(sizeof(*bus)); strlcpy_user(bus->name, name, sizeof(bus->name)); @@ -182,10 +185,10 @@ static res bus_send(u32 conn, const void *buf, u32 count) if (bus->pid == proc_current()->pid) { stack_push_bot(bus_conn->out, msg); - io_unblock_pid(bus_conn->pid); + dev_unblock_pid(bus_conn->pid); } else { stack_push_bot(bus_conn->in, msg); - io_unblock_pid(bus->pid); + dev_unblock_pid(bus->pid); } return count; @@ -229,8 +232,6 @@ static res bus_receive(void *buf, u32 offset, u32 count) if (!bus_owner && !bus_conn) return -ENOENT; - // TODO: Better round-robin - if (bus_owner) { struct node *iterator = bus_conns->head; while (iterator) { @@ -257,13 +258,13 @@ static res bus_control(u32 request, void *arg1, void *arg2, void *arg3) UNUSED(arg3); switch (request) { - case IOCTL_BUS_CONNECT_BUS: { + case DEVCTL_BUS_CONNECT_BUS: { return bus_connect_bus(arg1, arg2); } - case IOCTL_BUS_CONNECT_CONN: { + case DEVCTL_BUS_CONNECT_CONN: { return bus_connect_conn((u32)arg1); } - case IOCTL_BUS_REGISTER: { + case DEVCTL_BUS_REGISTER: { return bus_register(arg1); } default: { @@ -307,8 +308,6 @@ static res bus_ready(void) if (!bus_owner && !bus_conn) return -ENOENT; - // TODO: Better round-robin - if (bus_owner) { struct node *iterator = bus_conns->head; while (iterator) { @@ -331,10 +330,10 @@ CLEAR void bus_install(void) bus_list = list_new(); bus_conns = list_new(); - struct io_dev *dev = zalloc(sizeof(*dev)); + struct dev_dev *dev = zalloc(sizeof(*dev)); dev->control = bus_control; dev->read = bus_read; dev->ready = bus_ready; dev->write = bus_write; - io_add(IO_BUS, dev); + dev_add(DEV_BUS, dev); } diff --git a/kernel/features/dev.c b/kernel/features/dev.c new file mode 100644 index 0000000..ecc3f0c --- /dev/null +++ b/kernel/features/dev.c @@ -0,0 +1,244 @@ +// MIT License, Copyright (c) 2021 Marvin Borner + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct dev_listener { + u32 group; + struct proc *proc; +}; + +PROTECTED static struct dev_dev *dev_mappings[DEV_MAX] = { 0 }; +PROTECTED static struct list *dev_listeners[DEV_MAX] = { 0 }; + +static u32 group_id = 0; + +static u8 dev_type_valid(enum dev_type type) +{ + return type > DEV_MIN && type < DEV_MAX; +} + +static struct dev_dev *dev_get(enum dev_type type) +{ + if (!dev_type_valid(type)) + return NULL; + + return dev_mappings[type]; +} + +// TODO: Efficiency +static void dev_remove_group(u32 group) +{ + for (u32 dev = DEV_MIN; dev < DEV_MAX; dev++) { + struct node *iterator = dev_listeners[dev]->head; + while (iterator) { + struct dev_listener *listener = iterator->data; + struct node *next = iterator->next; + if (listener->group == group) + list_remove(dev_listeners[dev], iterator); + iterator = next; + } + } + + if (group + 1 == group_id) + group_id--; +} + +CLEAR void dev_add(enum dev_type type, struct dev_dev *dev) +{ + assert(dev_type_valid(type) && !dev_mappings[type]); + dev_mappings[type] = dev; +} + +res dev_poll(u32 *devs) +{ + if (!memory_readable(devs)) + return -EFAULT; + + u32 group = group_id++; + + for (u32 *p = devs; p && memory_readable(p); p++) { + stac(); + enum dev_type type = *p; + clac(); + + if (!type) + break; + + struct dev_dev *dev = dev_get(type); + if (!dev || !dev->read) { + dev_remove_group(group); + return -ENOENT; + } + + if (dev->ready) { + res ready = dev->ready(); + if (ready == EOK) { + dev_remove_group(group); + return type; + } else if (ready != -EAGAIN) { + return ready; + } + } + + struct dev_listener *listener = zalloc(sizeof(*listener)); + listener->group = group; + listener->proc = proc_current(); + list_add(dev_listeners[type], listener); + } + + proc_state(proc_current(), PROC_BLOCKED); + proc_yield(); + return dev_poll(devs); +} + +res dev_control(enum dev_type type, u32 request, void *arg1, void *arg2, void *arg3) +{ + struct dev_dev *dev; + if (!(dev = dev_get(type)) || !dev->control) + return -ENOENT; + + return dev->control(request, arg1, arg2, arg3); +} + +res dev_write(enum dev_type type, const void *buf, u32 offset, u32 count) +{ + if (!memory_readable_range(memory_range(buf, count))) + return -EFAULT; + + struct dev_dev *dev; + if (!(dev = dev_get(type)) || !dev->write) + return -ENOENT; + + return dev->write(buf, offset, count); +} + +res dev_read(enum dev_type type, void *buf, u32 offset, u32 count) +{ + if (!memory_writable_range(memory_range(buf, count))) + return -EFAULT; + + struct dev_dev *dev; + if (!(dev = dev_get(type)) || !dev->read) + return -ENOENT; + + if (dev->ready && dev->ready() != EOK) + return -EAGAIN; + + return dev->read(buf, offset, count); +} + +res dev_ready(enum dev_type type) +{ + struct dev_dev *dev; + if (!(dev = dev_get(type))) + return -ENOENT; + + if (dev->ready && dev->ready() != EOK) + return -EAGAIN; + + return EOK; +} + +void dev_block(enum dev_type type, struct proc *proc) +{ + assert(dev_type_valid(type)); + struct dev_listener *listener = zalloc(sizeof(*listener)); + listener->group = group_id++; + listener->proc = proc; + list_add(dev_listeners[type], listener); + proc_state(proc_current(), PROC_BLOCKED); + proc_yield(); +} + +void dev_unblock(enum dev_type type) +{ + assert(dev_type_valid(type)); + struct node *iterator = dev_listeners[type]->head; + while (iterator) { + struct dev_listener *listener = iterator->data; + struct proc *proc = listener->proc; + proc_state(proc, PROC_RUNNING); + struct node *next = iterator->next; + dev_remove_group(listener->group); + free(listener); + iterator = next; + } + + if (proc_idle()) + proc_yield(); +} + +void dev_unblock_pid(u32 pid) +{ + for (u32 type = DEV_MIN; type < DEV_MAX; type++) { + struct node *iterator = dev_listeners[type]->head; + while (iterator) { + struct dev_listener *listener = iterator->data; + struct proc *proc = listener->proc; + proc_state(proc, PROC_RUNNING); + struct node *next = iterator->next; + if (proc->pid == pid) { + list_remove(dev_listeners[type], iterator); + free(listener); + } + iterator = next; + } + } + + if (proc_idle()) + proc_yield(); +} + +CLEAR void dev_install(void) +{ + for (u32 i = 0; i < DEV_MAX; i++) + dev_listeners[i] = list_new(); + + /** + * Keyboard & mouse detection + */ + + ps2_detect(); + + u8 ps2_keyboard = ps2_keyboard_detect(); + if (ps2_keyboard != U8_MAX) { + ps2_keyboard_install(ps2_keyboard); + } + + u8 ps2_mouse = ps2_mouse_detect(); + if (ps2_mouse != U8_MAX) { + if (vmware_detect() && vmware_mouse_detect()) + vmware_mouse_install(ps2_mouse); + else + ps2_mouse_install(ps2_mouse); + } + + /** + * Other devices + */ + + fb_install(); + timer_install(); + logger_install(); + bus_install(); +} diff --git a/kernel/features/io.c b/kernel/features/io.c deleted file mode 100644 index 8126ccf..0000000 --- a/kernel/features/io.c +++ /dev/null @@ -1,244 +0,0 @@ -// MIT License, Copyright (c) 2021 Marvin Borner - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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; -} - -static struct io_dev *io_get(enum io_type io) -{ - if (!io_type_valid(io)) - return NULL; - - 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]); - io_mappings[io] = dev; -} - -res io_poll(u32 *devs) -{ - if (!memory_readable(devs)) - return -EFAULT; - - 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); - return -ENOENT; - } - - if (dev->ready) { - res ready = dev->ready(); - if (ready == EOK) { - io_remove_group(group); - return io; - } else if (ready != -EAGAIN) { - return ready; - } - } - - struct io_listener *listener = zalloc(sizeof(*listener)); - listener->group = group; - listener->proc = proc_current(); - list_add(io_listeners[io], listener); - } - - 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) -{ - struct io_dev *dev; - if (!(dev = io_get(io)) || !dev->control) - return -ENOENT; - - return dev->control(request, arg1, arg2, arg3); -} - -res io_write(enum io_type io, const void *buf, u32 offset, u32 count) -{ - if (!memory_readable_range(memory_range(buf, count))) - return -EFAULT; - - struct io_dev *dev; - if (!(dev = io_get(io)) || !dev->write) - return -ENOENT; - - return dev->write(buf, offset, count); -} - -res io_read(enum io_type io, void *buf, u32 offset, u32 count) -{ - if (!memory_writable_range(memory_range(buf, count))) - return -EFAULT; - - struct io_dev *dev; - if (!(dev = io_get(io)) || !dev->read) - return -ENOENT; - - if (dev->ready && dev->ready() != EOK) - return -EAGAIN; - - return dev->read(buf, offset, count); -} - -res io_ready(enum io_type io) -{ - struct io_dev *dev; - if (!(dev = io_get(io))) - return -ENOENT; - - if (dev->ready && dev->ready() != EOK) - return -EAGAIN; - - return EOK; -} - -void io_block(enum io_type io, struct proc *proc) -{ - assert(io_type_valid(io)); - 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) -{ - assert(io_type_valid(io)); - struct node *iterator = io_listeners[io]->head; - while (iterator) { - struct io_listener *listener = iterator->data; - struct proc *proc = listener->proc; - proc_state(proc, PROC_RUNNING); - struct node *next = iterator->next; - io_remove_group(listener->group); - free(listener); - iterator = next; - } - - if (proc_idle()) - proc_yield(); -} - -void io_unblock_pid(u32 pid) -{ - 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 proc *proc = listener->proc; - proc_state(proc, PROC_RUNNING); - struct node *next = iterator->next; - if (proc->pid == pid) { - list_remove(io_listeners[io], iterator); - free(listener); - } - iterator = next; - } - } - - if (proc_idle()) - proc_yield(); -} - -CLEAR void io_install(void) -{ - for (u32 i = 0; i < IO_MAX; i++) - io_listeners[i] = list_new(); - - /** - * Keyboard & mouse detection - */ - - ps2_detect(); - - u8 ps2_keyboard = ps2_keyboard_detect(); - if (ps2_keyboard != U8_MAX) { - ps2_keyboard_install(ps2_keyboard); - } - - u8 ps2_mouse = ps2_mouse_detect(); - if (ps2_mouse != U8_MAX) { - if (vmware_detect() && vmware_mouse_detect()) - vmware_mouse_install(ps2_mouse); - else - ps2_mouse_install(ps2_mouse); - } - - /** - * Other devices - */ - - fb_install(); - timer_install(); - logger_install(); - bus_install(); -} diff --git a/kernel/features/logger.c b/kernel/features/logger.c index fd5d730..4385408 100644 --- a/kernel/features/logger.c +++ b/kernel/features/logger.c @@ -1,10 +1,10 @@ // MIT License, Copyright (c) 2021 Marvin Borner #include +#include #include #include #include -#include #include #include #include @@ -36,7 +36,7 @@ static res logger_write(const void *buf, u32 offset, u32 count) void logger_install(void) { - struct io_dev *dev = zalloc(sizeof(*dev)); + struct dev_dev *dev = zalloc(sizeof(*dev)); dev->write = logger_write; - io_add(IO_LOGGER, dev); + dev_add(DEV_LOGGER, dev); } diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c index 6e43caa..997fa96 100644 --- a/kernel/features/syscall.c +++ b/kernel/features/syscall.c @@ -1,11 +1,11 @@ // MIT License, Copyright (c) 2020 Marvin Borner +#include #include #include #include #include #include -#include #include #include #include @@ -57,29 +57,29 @@ static u32 syscall_handler(u32 esp) break; } - // I/O operations - case SYS_IOPOLL: { - frame->eax = io_poll((void *)frame->ebx); + // Device operations + case SYS_DEV_POLL: { + frame->eax = dev_poll((void *)frame->ebx); break; } - case SYS_IOREAD: { - res ready = io_ready(frame->ebx); + case SYS_DEV_READ: { + res ready = dev_ready(frame->ebx); if (ready == -EAGAIN) { - io_block(frame->ebx, proc_current()); + dev_block(frame->ebx, proc_current()); } else if (ready != EOK) { frame->eax = ready; break; } - frame->eax = io_read(frame->ebx, (void *)frame->ecx, frame->edx, frame->esi); + frame->eax = dev_read(frame->ebx, (void *)frame->ecx, frame->edx, frame->esi); break; } - case SYS_IOWRITE: { - frame->eax = io_write(frame->ebx, (void *)frame->ecx, frame->edx, frame->esi); + case SYS_DEV_WRITE: { + frame->eax = dev_write(frame->ebx, (void *)frame->ecx, frame->edx, frame->esi); break; } - case SYS_IOCONTROL: { - frame->eax = io_control(frame->ebx, frame->ecx, (void *)frame->edx, - (void *)frame->esi, (void *)frame->edi); + case SYS_DEV_CONTROL: { + frame->eax = dev_control(frame->ebx, frame->ecx, (void *)frame->edx, + (void *)frame->esi, (void *)frame->edi); break; } -- cgit v1.2.3