feat: input device subsystem to resolve race condition on polling input
authorMinep <zelong56@gmail.com>
Mon, 22 Aug 2022 14:37:56 +0000 (15:37 +0100)
committerMinep <zelong56@gmail.com>
Mon, 22 Aug 2022 14:43:07 +0000 (15:43 +0100)
feat: simple wait queue implementation for efficient waiting.
fix: dead lock when invoking sched_yieldk() inside interrupt context.
chore: refactorings and clean up.

18 files changed:
lunaix-os/includes/lunaix/device.h
lunaix-os/includes/lunaix/ds/waitq.h [new file with mode: 0644]
lunaix-os/includes/lunaix/input.h [new file with mode: 0644]
lunaix-os/includes/lunaix/keyboard.h
lunaix-os/includes/lunaix/peripheral/ps2kbd.h
lunaix-os/includes/lunaix/process.h
lunaix-os/includes/lunaix/types.h
lunaix-os/kernel/demos/input_test.c [new file with mode: 0644]
lunaix-os/kernel/device/devfs.c
lunaix-os/kernel/device/device.c
lunaix-os/kernel/device/input.c [new file with mode: 0644]
lunaix-os/kernel/ds/waitq.c [new file with mode: 0644]
lunaix-os/kernel/k_init.c
lunaix-os/kernel/lxconsole.c
lunaix-os/kernel/peripheral/ps2kbd.c
lunaix-os/kernel/proc0.c
lunaix-os/kernel/sched.c
lunaix-os/kernel/service/pconsole.c [deleted file]

index c0ed9896382ef901e0fb676d224187b33a033520..beb8066739d5b8c046da927c0299c1f6831633a6 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <lunaix/ds/hstr.h>
 #include <lunaix/ds/llist.h>
+#include <lunaix/types.h>
 
 #define DEV_MSKIF 0x00000003
 
@@ -27,6 +28,13 @@ struct device
     int (*write)(struct device* dev, void* buf, size_t offset, size_t len);
 };
 
+struct device*
+device_add(struct device* parent,
+           void* underlay,
+           char* name_fmt,
+           uint32_t type,
+           va_list args);
+
 struct device*
 device_addseq(struct device* parent, void* underlay, char* name_fmt, ...);
 
@@ -43,7 +51,10 @@ struct device*
 device_getbyid(struct llist_header* devlist, dev_t id);
 
 struct device*
-device_getbyname(struct llist_header* devlist, struct hstr* name);
+device_getbyhname(struct llist_header* devlist, struct hstr* name);
+
+struct device*
+device_getbyname(struct llist_header* devlist, const char* name, size_t len);
 
 struct device*
 device_getbyoffset(struct llist_header* devlist, int pos);
diff --git a/lunaix-os/includes/lunaix/ds/waitq.h b/lunaix-os/includes/lunaix/ds/waitq.h
new file mode 100644 (file)
index 0000000..dfeb7c3
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef __LUNAIX_CODVAR_H
+#define __LUNAIX_CODVAR_H
+
+#include <lunaix/ds/llist.h>
+
+typedef struct waitq
+{
+    struct llist_header waiters;
+} waitq_t;
+
+inline void
+waitq_init(waitq_t* waitq)
+{
+    llist_init_head(&waitq->waiters);
+}
+
+void
+pwait(waitq_t* queue);
+
+void
+pwake_one(waitq_t* queue);
+
+void
+pwake_all(waitq_t* queue);
+
+#endif /* __LUNAIX_CODVAR_H */
diff --git a/lunaix-os/includes/lunaix/input.h b/lunaix-os/includes/lunaix/input.h
new file mode 100644 (file)
index 0000000..872ea04
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef __LUNAIX_INPUT_H
+#define __LUNAIX_INPUT_H
+
+#include <lunaix/clock.h>
+#include <lunaix/device.h>
+#include <lunaix/ds/llist.h>
+#include <lunaix/ds/waitq.h>
+#include <lunaix/types.h>
+
+// event should propagate further
+#define INPUT_EVT_NEXT 0
+// event should be captured here
+#define INPUT_EVT_CATCH 1
+
+// key pressed (key-type device)
+#define PKT_PRESS 0x1
+// key released (key-type device)
+#define PKT_RELEASE 0x2
+// vector (e.g. mice wheel scroll, mice maneuver)
+#define PKT_VECTOR 0x3
+
+struct input_evt_pkt
+{
+    uint32_t pkt_type;  // packet type
+    uint32_t scan_code; // hardware raw code
+    uint32_t sys_code;  // driver translated code
+    time_t timestamp;   // event timestamp
+};
+
+struct input_device
+{
+    struct device* dev_if;            // device interface
+    struct input_evt_pkt current_pkt; // recieved event packet
+    waitq_t readers;                  // reader wait queue
+};
+
+typedef int (*input_evt_cb)(struct input_device* dev);
+
+struct input_evt_chain
+{
+    struct llist_header chain;
+    input_evt_cb evt_cb;
+};
+
+void
+input_init();
+
+void
+input_fire_event(struct input_device* idev, struct input_evt_pkt* pkt);
+
+void
+input_add_listener(input_evt_cb listener);
+
+struct input_device*
+input_add_device(char* name_fmt, ...);
+
+#endif /* __LUNAIX_INPUT_H */
index 2dd40dd6df093af64196ad4229e949ee5b668781..aa4d6581a78959275f96475ad8b316587c9721e4 100644 (file)
 typedef unsigned short kbd_keycode_t;
 typedef unsigned short kbd_kstate_t;
 
-#define KEYPAD  0x0100
-#define FN_KEY  0x0200
-#define CURSOR  0x0300
-#define MODIFR  0x0400
-#define OTHERS  0xff00
+#define KEYPAD 0x0100
+#define FN_KEY 0x0200
+#define CURSOR 0x0300
+#define MODIFR 0x0400
+#define OTHERS 0xff00
 
-#define ON_KEYPAD(x)    ((x & 0xff) | KEYPAD)
+#define ON_KEYPAD(x) ((x & 0xff) | KEYPAD)
 
 // backspace key
-#define KEY_BS  (0x08)
+#define KEY_BS (0x08)
 
 // enter/return key
-#define KEY_LF  (0x0a)
+#define KEY_LF (0x0a)
 
 #define KEY_HTAB (0x9)
 #define KEY_SPACE (0x20)
 #define KEY_ESC (0x1b)
 
-#define KEY_F1  (0x00 | FN_KEY)
-#define KEY_F2  (0x01 | FN_KEY)
-#define KEY_F3  (0x02 | FN_KEY)
-#define KEY_F4  (0x03 | FN_KEY)
-#define KEY_F5  (0x04 | FN_KEY)
-#define KEY_F6  (0x05 | FN_KEY)
-#define KEY_F7  (0x06 | FN_KEY)
-#define KEY_F8  (0x07 | FN_KEY)
-#define KEY_F9  (0x08 | FN_KEY)
+#define KEY_F1 (0x00 | FN_KEY)
+#define KEY_F2 (0x01 | FN_KEY)
+#define KEY_F3 (0x02 | FN_KEY)
+#define KEY_F4 (0x03 | FN_KEY)
+#define KEY_F5 (0x04 | FN_KEY)
+#define KEY_F6 (0x05 | FN_KEY)
+#define KEY_F7 (0x06 | FN_KEY)
+#define KEY_F8 (0x07 | FN_KEY)
+#define KEY_F9 (0x08 | FN_KEY)
 #define KEY_F10 (0x09 | FN_KEY)
 #define KEY_F11 (0x0a | FN_KEY)
 #define KEY_F12 (0x0b | FN_KEY)
@@ -51,25 +51,25 @@ typedef unsigned short kbd_kstate_t;
 #define KEY_NUMSLK (0x0d | FN_KEY)
 #define KEY_SCRLLK (0x0e | FN_KEY)
 
-#define KEY_PG_UP       (0x0 | OTHERS)
-#define KEY_PG_DOWN     (0x1 | OTHERS)
-#define KEY_INSERT      (0x2 | OTHERS)
-#define KEY_DELETE      (0x3 | OTHERS)
-#define KEY_HOME        (0x4 | OTHERS)
-#define KEY_END         (0x5 | OTHERS)
-#define KEY_PAUSE       (0x6 | OTHERS)
-
-#define KEY_LEFT        (0x0 | CURSOR)
-#define KEY_RIGHT       (0x1 | CURSOR)
-#define KEY_UP          (0x2 | CURSOR)
-#define KEY_DOWN        (0x3 | CURSOR)
-
-#define KEY_LSHIFT       (0x0 | MODIFR)
-#define KEY_RSHIFT       (0x1 | MODIFR)
-#define KEY_LCTRL        (0x2 | MODIFR)
-#define KEY_RCTRL        (0x3 | MODIFR)
-#define KEY_LALT         (0x4 | MODIFR)
-#define KEY_RALT         (0x5 | MODIFR)
+#define KEY_PG_UP (0x0 | OTHERS)
+#define KEY_PG_DOWN (0x1 | OTHERS)
+#define KEY_INSERT (0x2 | OTHERS)
+#define KEY_DELETE (0x3 | OTHERS)
+#define KEY_HOME (0x4 | OTHERS)
+#define KEY_END (0x5 | OTHERS)
+#define KEY_PAUSE (0x6 | OTHERS)
+
+#define KEY_LEFT (0x0 | CURSOR)
+#define KEY_RIGHT (0x1 | CURSOR)
+#define KEY_UP (0x2 | CURSOR)
+#define KEY_DOWN (0x3 | CURSOR)
+
+#define KEY_LSHIFT (0x0 | MODIFR)
+#define KEY_RSHIFT (0x1 | MODIFR)
+#define KEY_LCTRL (0x2 | MODIFR)
+#define KEY_RCTRL (0x3 | MODIFR)
+#define KEY_LALT (0x4 | MODIFR)
+#define KEY_RALT (0x5 | MODIFR)
 
 #define KBD_KEY_FRELEASED 0x0
 #define KBD_KEY_FPRESSED 0x1
@@ -84,15 +84,4 @@ typedef unsigned short kbd_kstate_t;
 #define KBD_KEY_FLALT_HELD 0x100
 #define KBD_KEY_FRALT_HELD 0x200
 
-typedef unsigned char kbd_scancode_t;
-
-struct kdb_keyinfo_pkt {
-    kbd_scancode_t scancode;
-    kbd_keycode_t keycode;
-    kbd_kstate_t state;
-    time_t timestamp;
-};
-
-int kbd_recv_key(struct kdb_keyinfo_pkt* key_event);
-
 #endif /* __LUNAIX_KEYBOARD_H */
index 08a0d56c6660e2f72d6776b9e8e849a69d54c229..3ebaa984aa1770e69f43dc78c6b6b0d5f7fad07d 100644 (file)
@@ -44,7 +44,6 @@
 #define PS2_DELAY 1000
 
 #define PS2_CMD_QUEUE_SIZE 8
-#define PS2_KBD_RECV_BUFFER_SIZE 8
 
 #define PS2_NO_ARG 0xff00
 
@@ -70,14 +69,6 @@ struct ps2_cmd_queue
     mutex_t mutex;
 };
 
-struct ps2_key_buffer
-{
-    struct kdb_keyinfo_pkt buffer[PS2_KBD_RECV_BUFFER_SIZE];
-    int read_ptr;
-    int buffered_len;
-    mutex_t mutex;
-};
-
 /**
  * @brief 向PS/2控制器的控制端口(0x64)发送指令并等待返回代码。
  * 注意,对于没有返回代码的命令请使用`ps2_post_cmd`,否则会造成死锁。
index 18cddb94f6d29e4ad947e495af8c329dd74972ab..9686ee074de99ec4fb88c1e4e42703d627d7c907 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <arch/x86/interrupts.h>
 #include <lunaix/clock.h>
+#include <lunaix/ds/waitq.h>
 #include <lunaix/fs.h>
 #include <lunaix/mm/mm.h>
 #include <lunaix/signal.h>
@@ -13,7 +14,7 @@
 // 虽然内核不是进程,但为了区分,这里使用Pid=-1来指代内核。这主要是方便物理页所有权检查。
 #define KERNEL_PID -1
 
-#define PS_STOPPED 0
+#define PS_READY 0
 #define PS_RUNNING 1
 #define PS_TERMNAT 2
 #define PS_DESTROY 4
@@ -60,6 +61,7 @@ struct proc_info
     struct llist_header siblings;
     struct llist_header children;
     struct llist_header grp_member;
+    waitq_t waitqueue;
 
     struct
     {
index 3069a833bdb9b78d9eb20889fa012a8ffcbf17b7..fbe7e1e33880dd539f92c8ccb576214478bb7417 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __LUNAIX_TYPES_H
 #define __LUNAIX_TYPES_H
 
+#include <stdarg.h>
 #include <stddef.h>
 #include <stdint.h>
 
diff --git a/lunaix-os/kernel/demos/input_test.c b/lunaix-os/kernel/demos/input_test.c
new file mode 100644 (file)
index 0000000..ebb9375
--- /dev/null
@@ -0,0 +1,32 @@
+#include <lunaix/fctrl.h>
+#include <lunaix/foptions.h>
+#include <lunaix/input.h>
+#include <lunaix/lunistd.h>
+
+#define STDIN 1
+#define STDOUT 0
+
+void
+input_test()
+{
+    int fd = open("/dev/input/i8042-kbd", 0);
+
+    if (fd < 0) {
+        write(STDOUT, "fail to open", 13);
+        return;
+    }
+
+    struct input_evt_pkt event;
+
+    while (read(fd, &event, sizeof(event)) > 0) {
+        if (event.pkt_type == PKT_PRESS) {
+            write(STDOUT, "PRESSED: ", 10);
+        } else {
+            write(STDOUT, "RELEASE: ", 10);
+        }
+        char c = event.sys_code & 0xff;
+        write(STDOUT, &c, 1);
+        write(STDOUT, "\n", 2);
+    }
+    return;
+}
\ No newline at end of file
index 73abac7d885053aac1dc830ce4fb6831a139b468..0448924083fa603413b73a415b3fa669b2aca610 100644 (file)
@@ -74,7 +74,7 @@ devfs_mknod(struct v_dnode* dnode, struct device* dev)
 int
 devfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
 {
-    struct device* dev = device_getbyname(this->data, &dnode->name);
+    struct device* dev = device_getbyhname(this->data, &dnode->name);
     if (!dev) {
         return ENOENT;
     }
index aafdf0e5694b30d3566b2339dcbc2b89941aeb40..0990c56d39e7f3b8e2d7598b9661c35b21e93fbf 100644 (file)
@@ -9,11 +9,11 @@ static DEFINE_LLIST(root_list);
 static volatile dev_t devid = 0;
 
 struct device*
-__device_add(struct device* parent,
-             void* underlay,
-             char* name_fmt,
-             uint32_t type,
-             va_list args)
+device_add(struct device* parent,
+           void* underlay,
+           char* name_fmt,
+           uint32_t type,
+           va_list args)
 {
     struct device* dev = vzalloc(sizeof(struct device));
 
@@ -43,7 +43,7 @@ device_addseq(struct device* parent, void* underlay, char* name_fmt, ...)
     va_start(args, name_fmt);
 
     struct device* dev =
-      __device_add(parent, underlay, name_fmt, DEV_IFSEQ, args);
+      device_add(parent, underlay, name_fmt, DEV_IFSEQ, args);
 
     va_end(args);
     return dev;
@@ -56,7 +56,7 @@ device_addvol(struct device* parent, void* underlay, char* name_fmt, ...)
     va_start(args, name_fmt);
 
     struct device* dev =
-      __device_add(parent, underlay, name_fmt, DEV_IFVOL, args);
+      device_add(parent, underlay, name_fmt, DEV_IFVOL, args);
 
     va_end(args);
     return dev;
@@ -68,7 +68,7 @@ device_addcat(struct device* parent, char* name_fmt, ...)
     va_list args;
     va_start(args, name_fmt);
 
-    struct device* dev = __device_add(parent, NULL, name_fmt, DEV_IFCAT, args);
+    struct device* dev = device_add(parent, NULL, name_fmt, DEV_IFCAT, args);
 
     va_end(args);
     return dev;
@@ -90,7 +90,7 @@ device_getbyid(struct llist_header* devlist, dev_t id)
 }
 
 struct device*
-device_getbyname(struct llist_header* devlist, struct hstr* name)
+device_getbyhname(struct llist_header* devlist, struct hstr* name)
 {
     devlist = devlist ? devlist : &root_list;
     struct device *pos, *n;
@@ -104,6 +104,15 @@ device_getbyname(struct llist_header* devlist, struct hstr* name)
     return NULL;
 }
 
+struct device*
+device_getbyname(struct llist_header* devlist, const char* name, size_t len)
+{
+    struct hstr hname = HSTR(name, len);
+    hstr_rehash(&hname, HSTR_FULL_HASH);
+
+    return device_getbyhname(devlist, &hname);
+}
+
 void
 device_remove(struct device* dev)
 {
diff --git a/lunaix-os/kernel/device/input.c b/lunaix-os/kernel/device/input.c
new file mode 100644 (file)
index 0000000..5ddf6a4
--- /dev/null
@@ -0,0 +1,85 @@
+#include <lunaix/clock.h>
+#include <lunaix/input.h>
+#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
+#include <lunaix/status.h>
+
+#include <klibc/string.h>
+
+static DEFINE_LLIST(listener_chain);
+
+static struct device* input_devcat = NULL;
+
+void
+input_init()
+{
+    input_devcat = device_addcat(NULL, "input");
+}
+
+void
+input_fire_event(struct input_device* idev, struct input_evt_pkt* pkt)
+{
+    pkt->timestamp = clock_systime();
+    idev->current_pkt = *pkt;
+
+    struct input_evt_chain *pos, *n;
+    llist_for_each(pos, n, &listener_chain, chain)
+    {
+        if (pos->evt_cb(idev) == INPUT_EVT_CATCH) {
+            break;
+        }
+    }
+
+    // wake up all pending readers
+    pwake_all(&idev->readers);
+}
+
+void
+input_add_listener(input_evt_cb listener)
+{
+    assert(listener);
+
+    struct input_evt_chain* chain = vzalloc(sizeof(*chain));
+    llist_append(&listener_chain, &chain->chain);
+
+    chain->evt_cb = listener;
+}
+
+int
+__input_dev_read(struct device* dev, void* buf, size_t offset, size_t len)
+{
+    struct input_device* idev = dev->underlay;
+
+    if (len < sizeof(struct input_evt_pkt)) {
+        return ERANGE;
+    }
+
+    // wait for new event
+    pwait(&idev->readers);
+
+    memcpy(buf, &idev->current_pkt, sizeof(struct input_evt_pkt));
+
+    return sizeof(struct input_evt_pkt);
+}
+
+struct input_device*
+input_add_device(char* name_fmt, ...)
+{
+    assert(input_devcat);
+
+    struct input_device* idev = vzalloc(sizeof(*idev));
+    waitq_init(&idev->readers);
+
+    va_list args;
+    va_start(args, name_fmt);
+
+    struct device* dev =
+      device_add(input_devcat, idev, name_fmt, DEV_IFSEQ, args);
+
+    idev->dev_if = dev;
+    dev->read = __input_dev_read;
+
+    va_end(args);
+
+    return idev;
+}
diff --git a/lunaix-os/kernel/ds/waitq.c b/lunaix-os/kernel/ds/waitq.c
new file mode 100644 (file)
index 0000000..5241a4e
--- /dev/null
@@ -0,0 +1,50 @@
+#include <lunaix/ds/waitq.h>
+#include <lunaix/process.h>
+#include <lunaix/sched.h>
+#include <lunaix/spike.h>
+
+void
+pwait(waitq_t* queue)
+{
+    waitq_t* current_wq = &__current->waitqueue;
+    assert(llist_empty(&current_wq->waiters));
+
+    llist_append(&queue->waiters, &current_wq->waiters);
+
+    // FIXME centralize the state change.
+    __current->state = PS_BLOCKED;
+    sched_yieldk();
+}
+
+void
+pwake_one(waitq_t* queue)
+{
+    if (llist_empty(&queue->waiters)) {
+        return;
+    }
+
+    waitq_t* wq = list_entry(queue->waiters.next, waitq_t, waiters);
+    struct proc_info* proc = container_of(wq, struct proc_info, waitqueue);
+
+    assert(proc->state == PS_BLOCKED);
+    proc->state = PS_READY;
+    llist_delete(&wq->waiters);
+}
+
+void
+pwake_all(waitq_t* queue)
+{
+    if (llist_empty(&queue->waiters)) {
+        return;
+    }
+
+    struct proc_info* proc;
+    waitq_t *pos, *n;
+    llist_for_each(pos, n, &queue->waiters, waiters)
+    {
+        proc = container_of(pos, struct proc_info, waitqueue);
+
+        proc->state = PS_READY;
+        llist_delete(&pos->waiters);
+    }
+}
\ No newline at end of file
index a443ec039a724cfb575bbcfcd63ddebfdc33d4ae..b7c5668bd68ce2cb26bd9485381f0efe85e6effd 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <lunaix/device.h>
 #include <lunaix/foptions.h>
+#include <lunaix/input.h>
 #include <lunaix/lxconsole.h>
 #include <lunaix/mm/page.h>
 #include <lunaix/mm/pmm.h>
@@ -72,10 +73,9 @@ _kernel_init()
     cake_init();
     valloc_init();
 
-    lxconsole_init();
-
     vfs_init();
     fsm_init();
+    input_init();
 
     if ((errno = vfs_mount_root("ramfs", NULL))) {
         panickf("Fail to mount root. (errno=%d)", errno);
@@ -84,6 +84,8 @@ _kernel_init()
     vfs_mount("/dev", "devfs", NULL, 0);
     vfs_mount("/sys", "twifs", NULL, MNT_RO);
 
+    lxconsole_init();
+
     sched_init();
 
     spawn_proc0();
index 785330a4aa4b5d78b4ea9e06421281b55b48ea2f..c718b7124c82f284586c39c906e11150d36e4165 100644 (file)
@@ -1,5 +1,6 @@
 #include <klibc/string.h>
 #include <lunaix/device.h>
+#include <lunaix/input.h>
 #include <lunaix/keyboard.h>
 #include <lunaix/lxconsole.h>
 #include <lunaix/mm/pmm.h>
@@ -17,6 +18,34 @@ __tty_write(struct device* dev, void* buf, size_t offset, size_t len);
 int
 __tty_read(struct device* dev, void* buf, size_t offset, size_t len);
 
+static waitq_t lx_reader;
+static volatile char key;
+
+int
+__lxconsole_listener(struct input_device* dev)
+{
+    uint32_t keycode = dev->current_pkt.sys_code;
+    uint32_t type = dev->current_pkt.pkt_type;
+    if (type == PKT_PRESS) {
+        if (keycode == KEY_UP) {
+            console_view_up();
+        } else if (keycode == KEY_DOWN) {
+            console_view_down();
+        }
+        goto done;
+    }
+    if ((keycode & 0xff00) > KEYPAD) {
+        goto done;
+    }
+
+    key = (char)(keycode & 0x00ff);
+
+    pwake_all(&lx_reader);
+
+done:
+    return INPUT_EVT_NEXT;
+}
+
 void
 lxconsole_init()
 {
@@ -43,6 +72,9 @@ lxconsole_init()
     struct device* tty_dev = device_addseq(NULL, &lx_console, "tty");
     tty_dev->write = __tty_write;
     tty_dev->read = __tty_read;
+
+    waitq_init(&lx_reader);
+    input_add_listener(__lxconsole_listener);
 }
 
 int
@@ -55,7 +87,6 @@ __tty_write(struct device* dev, void* buf, size_t offset, size_t len)
 int
 __tty_read(struct device* dev, void* buf, size_t offset, size_t len)
 {
-    struct kdb_keyinfo_pkt keyevent;
     struct console* console = (struct console*)dev->underlay;
 
     size_t count = fifo_read(&console->input, buf, len);
@@ -64,30 +95,16 @@ __tty_read(struct device* dev, void* buf, size_t offset, size_t len)
     }
 
     while (count < len) {
-        // FIXME RACE!
-        //  Consider two process that is polling the input key simultaneously.
-        //  When a key is arrived, one of the processes will win the race and
-        //  swallow it (advancing the key buffer pointer)
-        if (!kbd_recv_key(&keyevent)) {
-            sched_yieldk();
-            continue;
-        }
-        if (!(keyevent.state & KBD_KEY_FPRESSED)) {
-            continue;
-        }
-        if ((keyevent.keycode & 0xff00) > KEYPAD) {
-            continue;
-        }
+        pwait(&lx_reader);
 
-        char c = (char)(keyevent.keycode & 0x00ff);
-        if (c == 0x08) {
+        if (key == 0x08) {
             if (fifo_backone(&console->input)) {
-                console_write_char(c);
+                console_write_char(key);
             }
             continue;
         }
-        console_write_char(c);
-        if (!fifo_putone(&console->input, c) || c == '\n') {
+        console_write_char(key);
+        if (!fifo_putone(&console->input, key) || key == '\n') {
             break;
         }
     }
index 6905b1eb059fc8995aeaf3c2cbb5c13a007967b8..5065ef697d8ca3a99adfa950147784b7809b7a23 100644 (file)
@@ -2,6 +2,7 @@
 #include <hal/ioapic.h>
 #include <lunaix/clock.h>
 #include <lunaix/common.h>
+#include <lunaix/input.h>
 #include <lunaix/peripheral/ps2kbd.h>
 #include <lunaix/syslog.h>
 #include <lunaix/timer.h>
@@ -17,7 +18,6 @@
 LOG_MODULE("PS2KBD");
 
 static struct ps2_cmd_queue cmd_q;
-static struct ps2_key_buffer key_buf;
 static struct ps2_kbd_state kbd_state;
 
 #define KEY_NUM(x) (x + 0x30)
@@ -69,6 +69,8 @@ static kbd_keycode_t scancode_set2_shift[] = {
 
 // clang-format on
 
+static struct input_device* kbd_idev;
+
 #define KBD_STATE_KWAIT 0x00
 #define KBD_STATE_KSPECIAL 0x01
 #define KBD_STATE_KRELEASED 0x02
@@ -79,8 +81,6 @@ static kbd_keycode_t scancode_set2_shift[] = {
 
 void
 intr_ps2_kbd_handler(const isr_param* param);
-static struct kdb_keyinfo_pkt*
-ps2_keybuffer_next_write();
 
 void
 ps2_device_post_cmd(char cmd, char arg)
@@ -107,15 +107,15 @@ ps2_kbd_init()
 {
 
     memset(&cmd_q, 0, sizeof(cmd_q));
-    memset(&key_buf, 0, sizeof(key_buf));
     memset(&kbd_state, 0, sizeof(kbd_state));
 
     mutex_init(&cmd_q.mutex);
-    mutex_init(&key_buf.mutex);
 
     kbd_state.translation_table = scancode_set2;
     kbd_state.state = KBD_STATE_KWAIT;
 
+    kbd_idev = input_add_device("i8042-kbd");
+
     acpi_context* acpi_ctx = acpi_get_context();
     if (acpi_ctx->fadt.header.rev > 1) {
         /*
@@ -132,13 +132,13 @@ ps2_kbd_init()
          *      https://bochs.sourceforge.io/cgi-bin/lxr/source/bios/rombios32.c#L1314
          */
         if (!(acpi_ctx->fadt.boot_arch & IAPC_ARCH_8042)) {
-            kprintf(KERROR "No PS/2 controller detected.\n");
+            kprintf(KERROR "i8042: not found\n");
             // FUTURE: Some alternative fallback on this? Check PCI bus for USB
             // controller instead?
             return;
         }
     } else {
-        kprintf(KWARN "Outdated FADT used, assuming 8042 always exist.\n");
+        kprintf(KWARN "i8042: outdated FADT used, assuming exists.\n");
     }
 
     char result;
@@ -271,14 +271,13 @@ kbd_buffer_key_event(kbd_keycode_t key, uint8_t scancode, kbd_kstate_t state)
         key = key & (0xffdf |
                      -('a' > key || key > 'z' || !(state & KBD_KEY_FCAPSLKED)));
 
-        if (!mutex_on_hold(&key_buf.mutex)) {
-            struct kdb_keyinfo_pkt* keyevent_pkt = ps2_keybuffer_next_write();
-            *keyevent_pkt =
-              (struct kdb_keyinfo_pkt){ .keycode = key,
-                                        .scancode = scancode,
-                                        .state = state,
-                                        .timestamp = clock_systime() };
-        }
+        struct input_evt_pkt ipkt = {
+            .pkt_type = (state & KBD_KEY_FPRESSED) ? PKT_PRESS : PKT_RELEASE,
+            .scan_code = scancode,
+            .sys_code = key,
+        };
+
+        input_fire_event(kbd_idev, &ipkt);
 
         return;
     }
@@ -419,37 +418,4 @@ ps2_issue_dev_cmd(char cmd, uint16_t arg)
         ;
 
     return io_inb(PS2_PORT_ENC_CMDREG);
-}
-
-int
-kbd_recv_key(struct kdb_keyinfo_pkt* key_event)
-{
-    if (!key_buf.buffered_len) {
-        return 0;
-    }
-
-    mutex_lock(&key_buf.mutex);
-    *key_event = key_buf.buffer[key_buf.read_ptr];
-    key_buf.buffered_len--;
-    key_buf.read_ptr = (key_buf.read_ptr + 1) % PS2_KBD_RECV_BUFFER_SIZE;
-
-    mutex_unlock(&key_buf.mutex);
-    return 1;
-}
-
-static struct kdb_keyinfo_pkt*
-ps2_keybuffer_next_write()
-{
-    int index =
-      (key_buf.read_ptr + key_buf.buffered_len) % PS2_KBD_RECV_BUFFER_SIZE;
-    if (index == key_buf.read_ptr && key_buf.buffered_len) {
-        // the reader is lagged so much such that the buffer is full.
-        // It is suggested to read from beginning for nearly up-to-date
-        // readings.
-        key_buf.read_ptr = 0;
-        key_buf.buffered_len = index;
-    } else {
-        key_buf.buffered_len++;
-    }
-    return &key_buf.buffer[index];
 }
\ No newline at end of file
index 32e1effca8044b19395e4dac5777656dcdb1117b..c02cbe1f3087f35ad9f2e4a6587c57a15f2c4411 100644 (file)
@@ -46,8 +46,9 @@ __do_reserved_memory(int unlock);
 
 #define USE_DEMO
 // #define DEMO_SIGNAL
-//#define DEMO_READDIR
-#define DEMO_IOTEST
+// #define DEMO_READDIR
+// #define DEMO_IOTEST
+#define DEMO_INPUT_TEST
 
 extern void
 _pconsole_main();
@@ -64,6 +65,9 @@ _readdir_main();
 extern void
 _iotest_main();
 
+extern void
+input_test();
+
 void __USER__
 __proc0_usr()
 {
@@ -74,9 +78,9 @@ __proc0_usr()
     int stdin = dup2(stdout, 1);
 
     pid_t p;
-    if (!fork()) {
-        _pconsole_main();
-    }
+    // if (!fork()) {
+    //     _pconsole_main();
+    // }
 
     if (!(p = fork())) {
 #ifndef USE_DEMO
@@ -87,6 +91,8 @@ __proc0_usr()
         _readdir_main();
 #elif defined DEMO_IOTEST
         _iotest_main();
+#elif defined DEMO_INPUT_TEST
+        input_test();
 #else
         _lxinit_main();
 #endif
index f8f00d40a094d62c31976cd4d54ef577673ba6de..2274238061df347181a092c2008b560d2af46ddf 100644 (file)
@@ -94,7 +94,7 @@ check_sleepers()
 
         if (wtime && now >= wtime) {
             pos->sleep.wakeup_time = 0;
-            pos->state = PS_STOPPED;
+            pos->state = PS_READY;
         }
 
         if (atime && now >= atime) {
@@ -123,7 +123,7 @@ schedule()
     int ptr = prev_ptr;
 
     if (!(__current->state & ~PS_RUNNING)) {
-        __current->state = PS_STOPPED;
+        __current->state = PS_READY;
     }
 
     check_sleepers();
@@ -133,7 +133,7 @@ redo:
     do {
         ptr = (ptr + 1) % sched_ctx.ptable_len;
         next = &sched_ctx._procs[ptr];
-    } while (next->state != PS_STOPPED && ptr != prev_ptr);
+    } while (next->state != PS_READY && ptr != prev_ptr);
 
     sched_ctx.procs_index = ptr;
 
@@ -148,6 +148,7 @@ redo:
 void
 sched_yieldk()
 {
+    cpu_enable_interrupt();
     cpu_int(LUNAIX_SCHED);
 }
 
@@ -233,7 +234,7 @@ repeat:
                 status_flags |= PEXITTERM;
                 goto done;
             }
-            if (proc->state == PS_STOPPED && (options & WUNTRACED)) {
+            if (proc->state == PS_READY && (options & WUNTRACED)) {
                 status_flags |= PEXITSTOP;
                 goto done;
             }
@@ -283,6 +284,7 @@ alloc_process()
     llist_init_head(&proc->children);
     llist_init_head(&proc->grp_member);
     llist_init_head(&proc->sleep.sleepers);
+    waitq_init(&proc->waitqueue);
 
     return proc;
 }
@@ -304,7 +306,7 @@ commit_process(struct proc_info* process)
 
     llist_append(&process->parent->children, &process->siblings);
 
-    process->state = PS_STOPPED;
+    process->state = PS_READY;
 }
 
 // from <kernel/process.c>
diff --git a/lunaix-os/kernel/service/pconsole.c b/lunaix-os/kernel/service/pconsole.c
deleted file mode 100644 (file)
index 200303d..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <lunaix/keyboard.h>
-#include <lunaix/lxconsole.h>
-#include <lunaix/proc.h>
-
-void
-_pconsole_main()
-{
-    struct kdb_keyinfo_pkt keyevent;
-    while (1) {
-        if (!kbd_recv_key(&keyevent)) {
-            yield();
-            continue;
-        }
-        if ((keyevent.state & KBD_KEY_FPRESSED)) {
-            if (keyevent.keycode == KEY_UP) {
-                console_view_up();
-            } else if (keyevent.keycode == KEY_DOWN) {
-                console_view_down();
-            }
-        }
-    }
-}
\ No newline at end of file