From 5ea8e2ba737f903db81d49b56778e883634512a5 Mon Sep 17 00:00:00 2001 From: Minep Date: Mon, 22 Aug 2022 15:37:56 +0100 Subject: [PATCH 1/1] feat: input device subsystem to resolve race condition on polling input feat: simple wait queue implementation for efficient waiting. fix: dead lock when invoking sched_yieldk() inside interrupt context. chore: refactorings and clean up. --- lunaix-os/includes/lunaix/device.h | 13 ++- lunaix-os/includes/lunaix/ds/waitq.h | 26 ++++++ lunaix-os/includes/lunaix/input.h | 57 +++++++++++++ lunaix-os/includes/lunaix/keyboard.h | 83 ++++++++---------- lunaix-os/includes/lunaix/peripheral/ps2kbd.h | 9 -- lunaix-os/includes/lunaix/process.h | 4 +- lunaix-os/includes/lunaix/types.h | 1 + lunaix-os/kernel/demos/input_test.c | 32 +++++++ lunaix-os/kernel/device/devfs.c | 2 +- lunaix-os/kernel/device/device.c | 27 ++++-- lunaix-os/kernel/device/input.c | 85 +++++++++++++++++++ lunaix-os/kernel/ds/waitq.c | 50 +++++++++++ lunaix-os/kernel/k_init.c | 6 +- lunaix-os/kernel/lxconsole.c | 57 ++++++++----- lunaix-os/kernel/peripheral/ps2kbd.c | 62 +++----------- lunaix-os/kernel/proc0.c | 16 ++-- lunaix-os/kernel/sched.c | 12 +-- lunaix-os/kernel/service/pconsole.c | 22 ----- 18 files changed, 394 insertions(+), 170 deletions(-) create mode 100644 lunaix-os/includes/lunaix/ds/waitq.h create mode 100644 lunaix-os/includes/lunaix/input.h create mode 100644 lunaix-os/kernel/demos/input_test.c create mode 100644 lunaix-os/kernel/device/input.c create mode 100644 lunaix-os/kernel/ds/waitq.c delete mode 100644 lunaix-os/kernel/service/pconsole.c diff --git a/lunaix-os/includes/lunaix/device.h b/lunaix-os/includes/lunaix/device.h index c0ed989..beb8066 100644 --- a/lunaix-os/includes/lunaix/device.h +++ b/lunaix-os/includes/lunaix/device.h @@ -5,6 +5,7 @@ #include #include +#include #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 index 0000000..dfeb7c3 --- /dev/null +++ b/lunaix-os/includes/lunaix/ds/waitq.h @@ -0,0 +1,26 @@ +#ifndef __LUNAIX_CODVAR_H +#define __LUNAIX_CODVAR_H + +#include + +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 index 0000000..872ea04 --- /dev/null +++ b/lunaix-os/includes/lunaix/input.h @@ -0,0 +1,57 @@ +#ifndef __LUNAIX_INPUT_H +#define __LUNAIX_INPUT_H + +#include +#include +#include +#include +#include + +// 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 */ diff --git a/lunaix-os/includes/lunaix/keyboard.h b/lunaix-os/includes/lunaix/keyboard.h index 2dd40dd..aa4d658 100644 --- a/lunaix-os/includes/lunaix/keyboard.h +++ b/lunaix-os/includes/lunaix/keyboard.h @@ -17,33 +17,33 @@ 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 */ diff --git a/lunaix-os/includes/lunaix/peripheral/ps2kbd.h b/lunaix-os/includes/lunaix/peripheral/ps2kbd.h index 08a0d56..3ebaa98 100644 --- a/lunaix-os/includes/lunaix/peripheral/ps2kbd.h +++ b/lunaix-os/includes/lunaix/peripheral/ps2kbd.h @@ -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`,否则会造成死锁。 diff --git a/lunaix-os/includes/lunaix/process.h b/lunaix-os/includes/lunaix/process.h index 18cddb9..9686ee0 100644 --- a/lunaix-os/includes/lunaix/process.h +++ b/lunaix-os/includes/lunaix/process.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -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 { diff --git a/lunaix-os/includes/lunaix/types.h b/lunaix-os/includes/lunaix/types.h index 3069a83..fbe7e1e 100644 --- a/lunaix-os/includes/lunaix/types.h +++ b/lunaix-os/includes/lunaix/types.h @@ -1,6 +1,7 @@ #ifndef __LUNAIX_TYPES_H #define __LUNAIX_TYPES_H +#include #include #include diff --git a/lunaix-os/kernel/demos/input_test.c b/lunaix-os/kernel/demos/input_test.c new file mode 100644 index 0000000..ebb9375 --- /dev/null +++ b/lunaix-os/kernel/demos/input_test.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include + +#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 diff --git a/lunaix-os/kernel/device/devfs.c b/lunaix-os/kernel/device/devfs.c index 73abac7..0448924 100644 --- a/lunaix-os/kernel/device/devfs.c +++ b/lunaix-os/kernel/device/devfs.c @@ -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; } diff --git a/lunaix-os/kernel/device/device.c b/lunaix-os/kernel/device/device.c index aafdf0e..0990c56 100644 --- a/lunaix-os/kernel/device/device.c +++ b/lunaix-os/kernel/device/device.c @@ -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 index 0000000..5ddf6a4 --- /dev/null +++ b/lunaix-os/kernel/device/input.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include + +#include + +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 index 0000000..5241a4e --- /dev/null +++ b/lunaix-os/kernel/ds/waitq.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include + +void +pwait(waitq_t* queue) +{ + waitq_t* current_wq = &__current->waitqueue; + assert(llist_empty(¤t_wq->waiters)); + + llist_append(&queue->waiters, ¤t_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 diff --git a/lunaix-os/kernel/k_init.c b/lunaix-os/kernel/k_init.c index a443ec0..b7c5668 100644 --- a/lunaix-os/kernel/k_init.c +++ b/lunaix-os/kernel/k_init.c @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -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(); diff --git a/lunaix-os/kernel/lxconsole.c b/lunaix-os/kernel/lxconsole.c index 785330a..c718b71 100644 --- a/lunaix-os/kernel/lxconsole.c +++ b/lunaix-os/kernel/lxconsole.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -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; } } diff --git a/lunaix-os/kernel/peripheral/ps2kbd.c b/lunaix-os/kernel/peripheral/ps2kbd.c index 6905b1e..5065ef6 100644 --- a/lunaix-os/kernel/peripheral/ps2kbd.c +++ b/lunaix-os/kernel/peripheral/ps2kbd.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -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 diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index 32e1eff..c02cbe1 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -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 diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index f8f00d4..2274238 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -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 diff --git a/lunaix-os/kernel/service/pconsole.c b/lunaix-os/kernel/service/pconsole.c deleted file mode 100644 index 200303d..0000000 --- a/lunaix-os/kernel/service/pconsole.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -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 -- 2.27.0