From 4fe907a73336f99c3172c498fdb659c9efcdc7d3 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Tue, 11 Nov 2025 23:10:38 +0100 Subject: [PATCH] Clean up PS/2 keyboard driver, new IPC mechanism MBus (message bus) --- kernel/Makefile | 1 + kernel/dev/ps2kbdev.c | 82 ++--------------- kernel/ipc/mbus/mbus.c | 202 +++++++++++++++++++++++++++++++++++++++++ kernel/ipc/mbus/mbus.h | 39 ++++++++ kernel/kmain.c | 2 + kernel/proc/proc.c | 2 + 6 files changed, 253 insertions(+), 75 deletions(-) create mode 100644 kernel/ipc/mbus/mbus.c create mode 100644 kernel/ipc/mbus/mbus.h diff --git a/kernel/Makefile b/kernel/Makefile index ea0290c..a31dc64 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -52,6 +52,7 @@ SRCFILES += $(call GRABSRC, \ path \ rbuf \ ipc/pipe \ + ipc/mbus \ dev \ randcrypto \ time \ diff --git a/kernel/dev/ps2kbdev.c b/kernel/dev/ps2kbdev.c index 7b0cb65..e15190b 100644 --- a/kernel/dev/ps2kbdev.c +++ b/kernel/dev/ps2kbdev.c @@ -7,6 +7,7 @@ #include "sysdefs/dev.h" #include "proc/proc.h" #include "io/io.h" +#include "ipc/mbus/mbus.h" #include "errors.h" #include "hshtb.h" #include "kprintf.h" @@ -152,100 +153,31 @@ int32_t ps2kb_intr(void) { return c; } -typedef struct Ps2kbEvConsumer { - struct Ps2kbEvConsumer *next; - Proc *proc; - RBuf rbuf; -} Ps2kbEvConsumer; - -struct { - SpinLock spinlock; - Ps2kbEvConsumer *list; -} PS2KB_CONSUMERS = {0}; +IpcMBus *PS2KB_MBUS; int32_t ps2kbdev_readch(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { (void)dev; (void)buffer; (void)len; - Proc *consproc = NULL; - spinlock_acquire(&PROCS.spinlock); - Proc *proc, *proctmp; - LL_FOREACH_SAFE(PROCS.procs, proc, proctmp) { - if (proc->pid == pid) { - consproc = proc; - } - } - spinlock_release(&PROCS.spinlock); - - if (consproc == NULL) { - return E_INVALIDOPER; - } - uint8_t b; - int32_t r = -1; - - spinlock_acquire(&PS2KB_CONSUMERS.spinlock); - Ps2kbEvConsumer *cons, *constmp; - LL_FOREACH_SAFE(PS2KB_CONSUMERS.list, cons, constmp) { - if (cons->proc == consproc) { - r = rbuf_pop(&cons->rbuf, &b); - break; - } - } - spinlock_release(&PS2KB_CONSUMERS.spinlock); - - if (r == 0) { + int32_t r = ipc_mbusconsume("ps2kb", &b, pid); + if (r > 0) { return b; } else { return E_NOTYET; } } -#define CONSUMER_RBUF_MAX 0x400 - int32_t ps2kbdev_attchcons(struct Dev *dev, uint8_t *buffer, size_t len, uint64_t pid) { (void)dev; (void)buffer; (void)len; - spinlock_acquire(&PROCS.spinlock); - Proc *proc, *proctmp; - LL_FOREACH_SAFE(PROCS.procs, proc, proctmp) { - if (proc->pid == pid) { - Ps2kbEvConsumer *cons = dlmalloc(sizeof(*cons)); - cons->proc = proc; - uint8_t *buf = dlmalloc(CONSUMER_RBUF_MAX); - rbuf_init(&cons->rbuf, buf, CONSUMER_RBUF_MAX); - spinlock_acquire(&PS2KB_CONSUMERS.spinlock); - LL_APPEND(PS2KB_CONSUMERS.list, cons); - spinlock_release(&PS2KB_CONSUMERS.spinlock); - break; - } - } - spinlock_release(&PROCS.spinlock); - return E_OK; + return ipc_mbusattchcons("ps2kb", pid); } void ps2kbdev_intr(void) { int32_t c = ps2kb_intr(); if (c >= 0) { uint8_t b = c; - spinlock_acquire(&PS2KB_CONSUMERS.spinlock); - Ps2kbEvConsumer *cons, *constmp; - LL_FOREACH_SAFE(PS2KB_CONSUMERS.list, cons, constmp) { - bool found = false; - spinlock_acquire(&PROCS.spinlock); - Proc *proc, *proctmp; - LL_FOREACH_SAFE(PROCS.procs, proc, proctmp) { - if (proc == cons->proc) { - found = true; - } - } - if (!found) { - LL_REMOVE(PS2KB_CONSUMERS.list, cons); - } - spinlock_release(&PROCS.spinlock); - - rbuf_push(&cons->rbuf, b); - } - spinlock_release(&PS2KB_CONSUMERS.spinlock); + ipc_mbuspublish("ps2kb", &b); } } @@ -255,7 +187,7 @@ void ps2kbdev_init(void) { Dev *ps2kbdev; HSHTB_ALLOC(DEVTABLE.devs, ident, "ps2kbdev", ps2kbdev); spinlock_init(&ps2kbdev->spinlock); - spinlock_init(&PS2KB_CONSUMERS.spinlock); + PS2KB_MBUS = ipc_mbusmake("ps2kb", 1, 0x100); ps2kbdev->fns[DEV_PS2KBDEV_READCH] = &ps2kbdev_readch; ps2kbdev->fns[DEV_PS2KBDEV_ATTCHCONS] = &ps2kbdev_attchcons; } diff --git a/kernel/ipc/mbus/mbus.c b/kernel/ipc/mbus/mbus.c new file mode 100644 index 0000000..5d14d92 --- /dev/null +++ b/kernel/ipc/mbus/mbus.c @@ -0,0 +1,202 @@ +#include +#include +#include "spinlock/spinlock.h" +#include "rbuf/rbuf.h" +#include "proc/proc.h" +#include "ipc/mbus/mbus.h" +#include "std/string.h" +#include "dlmalloc/malloc.h" +#include "util/util.h" +#include "hshtb.h" +#include "errors.h" +#include "kprintf.h" + +IpcMBuses IPC_MBUSES; + +void ipc_mbusinit(void) { + memset(&IPC_MBUSES, 0, sizeof(IPC_MBUSES)); + spinlock_init(&IPC_MBUSES.spinlock); +} + +IpcMBus *ipc_mbusmake(const char *name, size_t objsize, size_t objmax) { + IpcMBus *mbus = NULL; + + spinlock_acquire(&IPC_MBUSES.spinlock); + HSHTB_ALLOC(IPC_MBUSES.mbuses, ident, (char *)name, mbus); + spinlock_release(&IPC_MBUSES.spinlock); + + if (mbus == NULL) { + return NULL; + } + + mbus->objsize = objsize; + mbus->objmax = objmax; + + return mbus; +} + +int32_t ipc_mbusdelete(const char *name) { + IpcMBus *mbus = NULL; + + spinlock_acquire(&IPC_MBUSES.spinlock); + HSHTB_GET(IPC_MBUSES.mbuses, ident, (char *)name, mbus); + spinlock_release(&IPC_MBUSES.spinlock); + + if (mbus == NULL) { + return E_NOENTRY; + } + + IpcMBusCons *cons, *constmp; + spinlock_acquire(&mbus->spinlock); + LL_FOREACH_SAFE(mbus->consumers, cons, constmp) { + LL_REMOVE(mbus->consumers, cons); + dlfree(cons->rbuf.buffer); + dlfree(cons); + } + spinlock_release(&mbus->spinlock); + + spinlock_acquire(&IPC_MBUSES.spinlock); + HSHTB_DELETE(IPC_MBUSES.mbuses, ident, (char *)name); + spinlock_release(&IPC_MBUSES.spinlock); + + return E_OK; +} + +int32_t ipc_mbuspublish(const char *name, const uint8_t *const buffer) { + IpcMBus *mbus = NULL; + + spinlock_acquire(&IPC_MBUSES.spinlock); + HSHTB_GET(IPC_MBUSES.mbuses, ident, (char *)name, mbus); + spinlock_release(&IPC_MBUSES.spinlock); + + if (mbus == NULL) { + return E_NOENTRY; + } + + size_t i = 0; + IpcMBusCons *cons, *constmp; + spinlock_acquire(&mbus->spinlock); + LL_FOREACH_SAFE(mbus->consumers, cons, constmp) { + for (; i < mbus->objsize; i++) { + if (rbuf_push(&cons->rbuf, buffer[i]) < 0) { + break; + } + } + } + spinlock_release(&mbus->spinlock); + + return i; +} + +int32_t ipc_mbusconsume(const char *name, uint8_t *const buffer, uint64_t pid) { + IpcMBus *mbus = NULL; + + spinlock_acquire(&IPC_MBUSES.spinlock); + HSHTB_GET(IPC_MBUSES.mbuses, ident, (char *)name, mbus); + spinlock_release(&IPC_MBUSES.spinlock); + + if (mbus == NULL) { + return E_NOENTRY; + } + + size_t i = 0; + IpcMBusCons *cons, *constmp; + spinlock_acquire(&mbus->spinlock); + LL_FOREACH_SAFE(mbus->consumers, cons, constmp) { + if (cons->pid == pid) { + for (; i < mbus->objsize; i++) { + if (rbuf_pop(&cons->rbuf, &buffer[i]) < 0) { + break; + } + } + break; + } + } + spinlock_release(&mbus->spinlock); + + return i; +} + +int32_t ipc_mbusattchcons(const char *name, uint64_t pid) { + IpcMBus *mbus = NULL; + + spinlock_acquire(&IPC_MBUSES.spinlock); + HSHTB_GET(IPC_MBUSES.mbuses, ident, (char *)name, mbus); + spinlock_release(&IPC_MBUSES.spinlock); + + if (mbus == NULL) { + return E_NOENTRY; + } + + IpcMBusCons *cons = dlmalloc(sizeof(*cons)); + if (cons == NULL) { + return E_NOMEMORY; + } + + memset(cons, 0, sizeof(*cons)); + cons->pid = pid; + + uint8_t *buffer = dlmalloc(mbus->objsize * mbus->objmax); + if (buffer == NULL) { + dlfree(cons); + return E_NOMEMORY; + } + rbuf_init(&cons->rbuf, buffer, mbus->objsize * mbus->objmax); + + LL_APPEND(mbus->consumers, cons); + + return E_OK; +} + +int32_t ipc_mbusdttchcons(const char *name, uint64_t pid) { + IpcMBus *mbus = NULL; + + spinlock_acquire(&IPC_MBUSES.spinlock); + HSHTB_GET(IPC_MBUSES.mbuses, ident, (char *)name, mbus); + spinlock_release(&IPC_MBUSES.spinlock); + + if (mbus == NULL) { + return E_NOENTRY; + } + + IpcMBusCons *cons, *constmp; + spinlock_acquire(&mbus->spinlock); + LL_FOREACH_SAFE(mbus->consumers, cons, constmp) { + if (cons->pid == pid) { + LL_REMOVE(mbus->consumers, cons); + dlfree(cons->rbuf.buffer); + dlfree(cons); + break; + } + } + spinlock_release(&mbus->spinlock); + + return E_OK; +} + +void ipc_mbustick(void) { + spinlock_acquire(&IPC_MBUSES.spinlock); + for (size_t i = 0; i < LEN(IPC_MBUSES.mbuses); i++) { + IpcMBus *mbus = &IPC_MBUSES.mbuses[i]; + if (mbus->_hshtbstate != HSHTB_TAKEN) { + continue; + } + + IpcMBusCons *cons, *constmp; + spinlock_acquire(&mbus->spinlock); + LL_FOREACH_SAFE(mbus->consumers, cons, constmp) { + spinlock_acquire(&PROCS.spinlock); + Proc *proc = NULL; + LL_FINDPROP(PROCS.procs, proc, pid, cons->pid); + spinlock_release(&PROCS.spinlock); + + if (proc == NULL) { + LL_REMOVE(mbus->consumers, cons); + dlfree(cons->rbuf.buffer); + dlfree(cons); + } + } + spinlock_release(&mbus->spinlock); + } + spinlock_release(&IPC_MBUSES.spinlock); +} diff --git a/kernel/ipc/mbus/mbus.h b/kernel/ipc/mbus/mbus.h new file mode 100644 index 0000000..c3e0486 --- /dev/null +++ b/kernel/ipc/mbus/mbus.h @@ -0,0 +1,39 @@ +#ifndef IPC_MBUS_MBUS_H_ +#define IPC_MBUS_MBUS_H_ + +#include +#include +#include "proc/proc.h" +#include "rbuf/rbuf.h" + +typedef struct IpcMBusCons { + struct IpcMBusCons *next; + uint64_t pid; + RBuf rbuf; +} IpcMBusCons; + +typedef struct { + int _hshtbstate; + char ident[0x100]; + SpinLock spinlock; + IpcMBusCons *consumers; + size_t objsize, objmax; +} IpcMBus; + +typedef struct { + SpinLock spinlock; + IpcMBus mbuses[0x100]; +} IpcMBuses; + +extern IpcMBuses IPC_MBUSES; + +void ipc_mbusinit(void); +IpcMBus *ipc_mbusmake(const char *name, size_t objsize, size_t objmax); +int32_t ipc_mbusdelete(const char *name); +int32_t ipc_mbuspublish(const char *name, const uint8_t *const buffer); +int32_t ipc_mbusconsume(const char *name, uint8_t *const buffer, uint64_t pid); +int32_t ipc_mbusattchcons(const char *name, uint64_t pid); +int32_t ipc_mbusdttchcons(const char *name, uint64_t pid); +void ipc_mbustick(void); + +#endif // IPC_MBUS_MBUS_H_ diff --git a/kernel/kmain.c b/kernel/kmain.c index fbc9201..3d8201e 100644 --- a/kernel/kmain.c +++ b/kernel/kmain.c @@ -17,6 +17,7 @@ #include "vmm/vmm.h" #include "cpu/hang.h" #include "cpu/gdt.h" +#include "ipc/mbus/mbus.h" void log_bootinfo(void) { char buf[100]; @@ -48,6 +49,7 @@ void kmain(void) { pmm_init(); vmm_init(); randcrypto_init(); + ipc_mbusinit(); dev_init(); storedev_init(); diskpart_init(); diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index edaf2de..2e1f76f 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -9,6 +9,7 @@ #include "vfs/vfs.h" #include "bootinfo/bootinfo.h" #include "ipc/pipe/pipe.h" +#include "ipc/mbus/mbus.h" #include "sysdefs/proc.h" #include "sysdefs/fs.h" #include "time/time.h" @@ -222,6 +223,7 @@ void proc_reaper(void) { void proc_tick(void) { proc_reaper(); + ipc_mbustick(); } void proc_sched(void *cpustate) {