diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/arch/i386/driver/ps2.c | 40 | ||||
-rw-r--r-- | src/kernel/arch/i386/driver/ps2.h | 4 | ||||
-rw-r--r-- | src/kernel/handle.h | 3 | ||||
-rw-r--r-- | src/kernel/proc.c | 19 | ||||
-rw-r--r-- | src/kernel/proc.h | 2 | ||||
-rw-r--r-- | src/kernel/vfs/mount.c | 22 | ||||
-rw-r--r-- | src/kernel/vfs/request.h | 1 | ||||
-rw-r--r-- | src/kernel/vfs/root.c | 9 |
8 files changed, 78 insertions, 22 deletions
diff --git a/src/kernel/arch/i386/driver/ps2.c b/src/kernel/arch/i386/driver/ps2.c index 4b7eae4..6ee24e2 100644 --- a/src/kernel/arch/i386/driver/ps2.c +++ b/src/kernel/arch/i386/driver/ps2.c @@ -1,20 +1,60 @@ #include <kernel/arch/i386/driver/ps2.h> #include <kernel/arch/i386/interrupts/irq.h> +#include <kernel/mem/virt.h> +#include <kernel/panic.h> #include <shared/container/ring.h> #include <shared/mem.h> + #define BACKLOG_CAPACITY 64 static volatile uint8_t backlog_buf[BACKLOG_CAPACITY]; static volatile ring_t backlog = {(void*)backlog_buf, BACKLOG_CAPACITY, 0, 0}; +static struct vfs_request *blocked_on = NULL; + bool ps2_ready(void) { return ring_size((void*)&backlog) > 0; } void ps2_recv(uint8_t s) { ring_put1b((void*)&backlog, s); + if (blocked_on) { + vfs_ps2_accept(blocked_on); + blocked_on = NULL; + } } size_t ps2_read(uint8_t *buf, size_t len) { return ring_get((void*)&backlog, buf, len); } + +int vfs_ps2_accept(struct vfs_request *req) { + static uint8_t buf[32]; // pretty damn stupid + int ret; + switch (req->type) { + case VFSOP_OPEN: + // allows opening /ps2/anything, TODO don't + return vfsreq_finish(req, 0); // fake file handle, whatever + case VFSOP_READ: + if (ps2_ready()) { + // TODO FUKKEN MESS + if (req->caller) { + // clamp between 0, sizeof buf + ret = req->output.len; + if (ret > sizeof buf) ret = sizeof buf; + if (ret < 0) ret = 0; + + ret = ps2_read(buf, ret); + virt_cpy_to(req->caller->pages, req->output.buf, buf, ret); + } else ret = -1; + return vfsreq_finish(req, ret); + } else { + blocked_on = req; + return -1; + } + default: + return vfsreq_finish(req, -1); + } +} + +bool vfs_ps2_ready(struct vfs_backend *self) { return blocked_on == NULL; } diff --git a/src/kernel/arch/i386/driver/ps2.h b/src/kernel/arch/i386/driver/ps2.h index 712b157..1bbc2f1 100644 --- a/src/kernel/arch/i386/driver/ps2.h +++ b/src/kernel/arch/i386/driver/ps2.h @@ -1,4 +1,5 @@ #pragma once +#include <kernel/vfs/request.h> #include <stdbool.h> #include <stddef.h> #include <stdint.h> @@ -6,3 +7,6 @@ bool ps2_ready(void); void ps2_recv(uint8_t scancode); size_t ps2_read(uint8_t *buf, size_t max_len); + +int vfs_ps2_accept(struct vfs_request *); +bool vfs_ps2_ready(struct vfs_backend *); diff --git a/src/kernel/handle.h b/src/kernel/handle.h index 3b75894..b90ab60 100644 --- a/src/kernel/handle.h +++ b/src/kernel/handle.h @@ -3,9 +3,6 @@ #include <shared/types.h> #include <stddef.h> -// TODO make accessible only from proc.c -#define HANDLE_MAX 16 - enum handle_type { HANDLE_INVALID = 0, HANDLE_FILE, diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 7c41eb2..ed317ec 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -125,22 +125,23 @@ static _Noreturn void process_switch(struct process *proc) { /** If there are any processes waiting for IRQs, wait with them. Otherwise, shut down */ static _Noreturn void process_idle(void) { + // this mess is temporary + struct process *procs[16]; size_t len = process_find_multiple(PS_WAITS4IRQ, procs, 16); if (len == 0) shutdown(); - for (;;) { - for (size_t i = 0; i < len; i++) { - if (procs[i]->waits4irq.ready()) { - /* if this is entered during the first iteration, it indicates a - * kernel bug. this should be logged. TODO? */ - procs[i]->waits4irq.callback(procs[i]); - process_switch_any(); - } + cpu_pause(); + for (size_t i = 0; i < len; i++) { + if (procs[i]->waits4irq.ready()) { + /* if this is entered during the first iteration, it indicates a + * kernel bug. this should be logged. TODO? */ + procs[i]->waits4irq.callback(procs[i]); } - cpu_pause(); } + + process_switch_any(); } _Noreturn void process_switch_any(void) { diff --git a/src/kernel/proc.h b/src/kernel/proc.h index 3102ac7..a6a8609 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -6,6 +6,8 @@ #include <shared/syscalls.h> #include <stdbool.h> +#define HANDLE_MAX 16 + enum process_state { PS_RUNNING, PS_DEAD, // return message wasn't collected diff --git a/src/kernel/vfs/mount.c b/src/kernel/vfs/mount.c index a6c5970..232e702 100644 --- a/src/kernel/vfs/mount.c +++ b/src/kernel/vfs/mount.c @@ -4,6 +4,8 @@ #include <kernel/vfs/root.h> #include <shared/mem.h> +#include <kernel/arch/i386/driver/ps2.h> + struct vfs_mount *vfs_mount_seed(void) { struct vfs_mount *mount = kmalloc(sizeof *mount); struct vfs_backend *backend = kmalloc(sizeof *backend); @@ -19,7 +21,25 @@ struct vfs_mount *vfs_mount_seed(void) { .backend = backend, .refs = 1, // never to be freed }; - return mount; + + // what a mess. + // TODO register funcs + struct vfs_mount *ps2 = kmalloc(sizeof *ps2); + backend = kmalloc(sizeof *backend); + backend->is_user = false; + backend->potential_handlers = 1; + backend->refcount = 1; + backend->kern.ready = vfs_ps2_ready; + backend->kern.accept = vfs_ps2_accept; + *ps2 = (struct vfs_mount){ + .prev = mount, + .prefix = "/ps2", + .prefix_len = 4, + .backend = backend, + .refs = 1, + }; + + return ps2; } struct vfs_mount *vfs_mount_resolve( diff --git a/src/kernel/vfs/request.h b/src/kernel/vfs/request.h index e62f28f..b4624fa 100644 --- a/src/kernel/vfs/request.h +++ b/src/kernel/vfs/request.h @@ -1,4 +1,5 @@ #pragma once +#include <kernel/proc.h> #include <shared/flags.h> #include <shared/types.h> #include <stdbool.h> diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c index 701d4e6..0c58d86 100644 --- a/src/kernel/vfs/root.c +++ b/src/kernel/vfs/root.c @@ -15,7 +15,6 @@ enum { HANDLE_ROOT, HANDLE_VGA, HANDLE_COM1, - HANDLE_PS2, HANDLE_ATA_ROOT, HANDLE_ATA, _SKIP = HANDLE_ATA + 4, @@ -72,7 +71,6 @@ static int handle(struct vfs_request *req, bool *ready) { if (exacteq(req, "/")) return HANDLE_ROOT; if (exacteq(req, "/vga")) return HANDLE_VGA; if (exacteq(req, "/com1")) return HANDLE_COM1; - if (exacteq(req, "/ps2")) return HANDLE_PS2; if (exacteq(req, "/ata/")) return HANDLE_ATA_ROOT; if (exacteq(req, "/ata/0")) @@ -113,13 +111,6 @@ static int handle(struct vfs_request *req, bool *ready) { virt_cpy_to(req->caller->pages, req->output.buf, buf, len); return len; } - case HANDLE_PS2: { - if (wait_setup(req, ready, ps2_ready)) return -1; - uint8_t buf[16]; - size_t len = ps2_read(buf, min(req->output.len, sizeof buf)); - virt_cpy_to(req->caller->pages, req->output.buf, buf, len); - return len; - } case HANDLE_ATA_ROOT: { // TODO offset char list[8] = {}; |