diff --git a/kernel/hal/x86_64/intr.c b/kernel/hal/x86_64/intr.c index ad27f56..c36bd53 100644 --- a/kernel/hal/x86_64/intr.c +++ b/kernel/hal/x86_64/intr.c @@ -15,6 +15,7 @@ #include "drivers/ps2kb/ps2kb.h" #include "ipc/pipe/pipe.h" #include "proc/ps2kbproc/ps2kbproc.h" +#include "rbuf/rbuf.h" void hal_intr_disable(void) { asm volatile("cli"); @@ -200,9 +201,13 @@ void intr_handleintr(IntrStackFrame *frame) { break; case INTR_IRQBASE+1: int32_t c = ps2kb_intr(); - uint8_t *bytes = (uint8_t *)&c; - ipc_pipewrite(PS2KBPROC->pipes[0], bytes, sizeof(c)); intr_eoi(frame->trapnum - INTR_IRQBASE); + uint8_t *bytes = (uint8_t *)&c; + spinlock_acquire(&PS2KB_BUF.spinlock); + for (size_t i = 0; i < sizeof(c); i++) { + rbuf_push(&PS2KB_BUF.rbuf, bytes[i]); + } + spinlock_release(&PS2KB_BUF.spinlock); break; } } else if (frame->trapnum == 0x80) { diff --git a/kernel/ipc/pipe/pipe.h b/kernel/ipc/pipe/pipe.h index 0b883cf..a039189 100644 --- a/kernel/ipc/pipe/pipe.h +++ b/kernel/ipc/pipe/pipe.h @@ -8,7 +8,8 @@ #define IPC_PIPE_MAX 0x1000 -typedef struct { +typedef struct IpcPipe { + struct IpcPipe *next; RBuf rbuf; SpinLock spinlock; } IpcPipe; diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index 8d947dc..44278e7 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -101,6 +101,7 @@ Proc *proc_spawnkern(void (*ent)(void), char *name) { proc->platformdata.cr3 = hal_vmm_current_cr3(); proc->state = PROC_READY; proc->pid = pids++; + spinlock_init(&proc->eventpipes_spinlock); return proc; } @@ -166,6 +167,7 @@ Proc *proc_spawnuser(char *mountpoint, char *path) { proc->platformdata.trapframe.rip = aux.entry; proc->state = PROC_READY; proc->pid = pids++; + spinlock_init(&proc->eventpipes_spinlock); return proc; } diff --git a/kernel/proc/proc.h b/kernel/proc/proc.h index aababaf..4664783 100644 --- a/kernel/proc/proc.h +++ b/kernel/proc/proc.h @@ -47,6 +47,8 @@ typedef struct Proc { uint64_t vobjcnt; IpcPipe *pipes[PROC_PIPEHANDLES_MAX]; + IpcPipe *eventpipes; + SpinLock eventpipes_spinlock; } Proc; typedef struct { diff --git a/kernel/proc/ps2kbproc/ps2kbproc.c b/kernel/proc/ps2kbproc/ps2kbproc.c index 5ffa38e..bec3f86 100644 --- a/kernel/proc/ps2kbproc/ps2kbproc.c +++ b/kernel/proc/ps2kbproc/ps2kbproc.c @@ -2,18 +2,45 @@ #include "proc/proc.h" #include "dlmalloc/malloc.h" #include "ipc/pipe/pipe.h" +#include "kprintf.h" +#include "rbuf/rbuf.h" +#include "ps2kbproc.h" + +Proc *PS2KBPROC = NULL; +Ps2KbFastBuf PS2KB_BUF; -Proc *PS2KBPROC; void ps2kbproc_init(Proc *proc) { PS2KBPROC = proc; - PS2KBPROC->pipes[0] = dlmalloc(sizeof(IpcPipe)); - ipc_pipeinit(PS2KBPROC->pipes[0]); + + PS2KBPROC->eventpipes = NULL; + + PS2KB_BUF.rbuf.buffer = dlmalloc(IPC_PIPE_MAX); + PS2KB_BUF.rbuf.cap = IPC_PIPE_MAX; + spinlock_init(&PS2KB_BUF.spinlock); } void ps2kbproc_fn(void) { for (;;) { - + int32_t kbchr; + uint8_t *buf = (uint8_t *)&kbchr; + size_t i = 0; + spinlock_acquire(&PS2KB_BUF.spinlock); + for (; i < sizeof(kbchr); i++) { + if (rbuf_pop(&PS2KB_BUF.rbuf, &buf[i]) < 0) { + break; + } + } + spinlock_release(&PS2KB_BUF.spinlock); + if (i > 0) { + spinlock_acquire(&PS2KBPROC->eventpipes_spinlock); + IpcPipe *head = PS2KBPROC->eventpipes; + while (head != NULL) { + ipc_pipewrite(head, (uint8_t *)&kbchr, sizeof(kbchr)); + head = head->next; + } + spinlock_release(&PS2KBPROC->eventpipes_spinlock); + } } } diff --git a/kernel/proc/ps2kbproc/ps2kbproc.h b/kernel/proc/ps2kbproc/ps2kbproc.h index a3dc6e0..67a76b3 100644 --- a/kernel/proc/ps2kbproc/ps2kbproc.h +++ b/kernel/proc/ps2kbproc/ps2kbproc.h @@ -2,8 +2,16 @@ #define PROC_PS2KB_PS2KBPROC_H_ #include "proc/proc.h" +#include "rbuf/rbuf.h" +#include "spinlock/spinlock.h" + +typedef struct { + RBuf rbuf; + SpinLock spinlock; +} Ps2KbFastBuf; extern Proc *PS2KBPROC; +extern Ps2KbFastBuf PS2KB_BUF; void ps2kbproc_fn(void); void ps2kbproc_init(Proc *proc); diff --git a/kernel/syscall/ipcpipe.c b/kernel/syscall/ipcpipe.c index f5696a6..62fe8f9 100644 --- a/kernel/syscall/ipcpipe.c +++ b/kernel/syscall/ipcpipe.c @@ -44,6 +44,7 @@ int32_t SYSCALL5(sys_ipcpipe, pid1, pipenum1, cmd1, buffer1, len1) { } if ((ret = ipc_pipeinit(pipe)) < 0) { + ret = E_NOMEMORY; goto done; } @@ -93,6 +94,37 @@ int32_t SYSCALL5(sys_ipcpipe, pid1, pipenum1, cmd1, buffer1, len1) { ret = ipc_piperead(pipe, buffer, len1); } break; + case IPCPIPE_REG_EVT_PIPE: { + if (pipenum >= PROC_PIPEHANDLES_MAX) { + ret = E_NOMEMORY; + goto done; + } + + IpcPipe *pipe = proc->pipes[pipenum]; + + if (pipe == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + uint64_t pid2 = len1; + + Proc *proc2 = NULL; + spinlock_acquire(&PROCS.spinlock); + LL_FINDPROP(PROCS.procs, proc2, pid, pid2); + spinlock_release(&PROCS.spinlock); + + if (proc2 == NULL) { + ret = E_INVALIDARGUMENT; + goto done; + } + + spinlock_acquire(&proc2->eventpipes_spinlock); + LL_APPEND(proc2->eventpipes, pipe); + spinlock_release(&proc2->eventpipes_spinlock); + + ret = E_OK; + } break; default: { ret = E_INVALIDARGUMENT; } break; diff --git a/share/sysdefs/ipcpipe.h b/share/sysdefs/ipcpipe.h index 9f83e23..358f67e 100644 --- a/share/sysdefs/ipcpipe.h +++ b/share/sysdefs/ipcpipe.h @@ -5,12 +5,15 @@ #include #define IPCPIPE_SELFPID (-1) + #define IPCPIPE_OUT (0) +#define IPCPIPE_IN (1) enum { IPCPIPE_MAKE = 0, IPCPIPE_READ = 1, IPCPIPE_WRITE = 2, + IPCPIPE_REG_EVT_PIPE = 3, }; #endif // SHARE_SYSDEFS_IPCPIPE_H_ diff --git a/user/init/main.c b/user/init/main.c index dd50d1c..9e9b19f 100644 --- a/user/init/main.c +++ b/user/init/main.c @@ -27,13 +27,21 @@ void main(void) { uprintf("Hello world using uprintf\n"); - while(1) { - int32_t kbchar; - int32_t read = dev_ps2kb_read(&kbchar); + if (ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_MAKE, NULL, 0) < 0) { + uprintf("failed to create 10th pipe\n"); + } - if (read > 0 && (kbchar >= 0x20 && kbchar <= 0x7F || kbchar == 0xA)) { - uprintf("%c", kbchar & 0xFF); - ipcpipe(3, 1, IPCPIPE_WRITE, (uint8_t *)&kbchar, 1); + int32_t r = ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_REG_EVT_PIPE, NULL, 1); + uprintf("%d\n", r); + + while(1) { + int32_t kbchr; + int32_t read = ipcpipe(IPCPIPE_SELFPID, 10, IPCPIPE_READ, (uint8_t *)&kbchr, sizeof(kbchr)); + if (read > 0) { + kbchr &= 0xFF; + if ((kbchr >= 0x20 && kbchr <= 0x7F) || kbchr == 0xA) { + uprintf("%c", kbchr & 0xFF); + } } }