From cd2ad9a44df3771fcb118b6f132d30098529077b Mon Sep 17 00:00:00 2001 From: Minep Date: Tue, 9 Aug 2022 00:44:33 +0100 Subject: [PATCH] fix: refining the tty input --- lunaix-os/includes/lunaix/peripheral/ps2kbd.h | 103 +++++++++--------- lunaix-os/kernel/lxconsole.c | 41 +++++-- lunaix-os/kernel/peripheral/ps2kbd.c | 6 +- 3 files changed, 86 insertions(+), 64 deletions(-) diff --git a/lunaix-os/includes/lunaix/peripheral/ps2kbd.h b/lunaix-os/includes/lunaix/peripheral/ps2kbd.h index 2d568a6..08a0d56 100644 --- a/lunaix-os/includes/lunaix/peripheral/ps2kbd.h +++ b/lunaix-os/includes/lunaix/peripheral/ps2kbd.h @@ -2,74 +2,76 @@ #define __LUNAIX_PS2KBD_H #include -#include #include - +#include #define PS2_PORT_ENC_DATA 0x60 #define PS2_PORT_ENC_CMDREG 0x60 #define PS2_PORT_CTRL_STATUS 0x64 #define PS2_PORT_CTRL_CMDREG 0x64 -#define PS2_STATUS_OFULL 0x1 -#define PS2_STATUS_IFULL 0x2 +#define PS2_STATUS_OFULL 0x1 +#define PS2_STATUS_IFULL 0x2 -#define PS2_RESULT_ACK 0xfa -#define PS2_RESULT_NAK 0xfe //resend -#define PS2_RESULT_ECHO 0xee -#define PS2_RESULT_TEST_OK 0x55 +#define PS2_RESULT_ACK 0xfa +#define PS2_RESULT_NAK 0xfe // resend +#define PS2_RESULT_ECHO 0xee +#define PS2_RESULT_TEST_OK 0x55 // PS/2 keyboard device related commands -#define PS2_KBD_CMD_SETLED 0xed -#define PS2_KBD_CMD_ECHO 0xee -#define PS2_KBD_CMD_SCANCODE_SET 0xf0 -#define PS2_KBD_CMD_IDENTIFY 0xf2 -#define PS2_KBD_CMD_SCAN_ENABLE 0xf4 -#define PS2_KBD_CMD_SCAN_DISABLE 0xf5 +#define PS2_KBD_CMD_SETLED 0xed +#define PS2_KBD_CMD_ECHO 0xee +#define PS2_KBD_CMD_SCANCODE_SET 0xf0 +#define PS2_KBD_CMD_IDENTIFY 0xf2 +#define PS2_KBD_CMD_SCAN_ENABLE 0xf4 +#define PS2_KBD_CMD_SCAN_DISABLE 0xf5 // PS/2 *controller* related commands -#define PS2_CMD_PORT1_DISABLE 0xad -#define PS2_CMD_PORT1_ENABLE 0xae -#define PS2_CMD_PORT2_DISABLE 0xa7 -#define PS2_CMD_PORT2_ENABLE 0xa8 -#define PS2_CMD_SELFTEST 0xaa -#define PS2_CMD_SELFTEST_PORT1 0xab +#define PS2_CMD_PORT1_DISABLE 0xad +#define PS2_CMD_PORT1_ENABLE 0xae +#define PS2_CMD_PORT2_DISABLE 0xa7 +#define PS2_CMD_PORT2_ENABLE 0xa8 +#define PS2_CMD_SELFTEST 0xaa +#define PS2_CMD_SELFTEST_PORT1 0xab -#define PS2_CMD_READ_CFG 0x20 -#define PS2_CMD_WRITE_CFG 0x60 +#define PS2_CMD_READ_CFG 0x20 +#define PS2_CMD_WRITE_CFG 0x60 -#define PS2_CFG_P1INT 0x1 -#define PS2_CFG_P2INT 0x2 -#define PS2_CFG_TRANSLATION 0x40 +#define PS2_CFG_P1INT 0x1 +#define PS2_CFG_P2INT 0x2 +#define PS2_CFG_TRANSLATION 0x40 -#define PS2_DELAY 1000 +#define PS2_DELAY 1000 #define PS2_CMD_QUEUE_SIZE 8 #define PS2_KBD_RECV_BUFFER_SIZE 8 #define PS2_NO_ARG 0xff00 - -struct ps2_cmd { +struct ps2_cmd +{ char cmd; char arg; }; -struct ps2_kbd_state { +struct ps2_kbd_state +{ volatile char state; volatile char masked; + volatile kbd_kstate_t key_state; kbd_keycode_t* translation_table; - kbd_kstate_t key_state; }; -struct ps2_cmd_queue { +struct ps2_cmd_queue +{ struct ps2_cmd cmd_queue[PS2_CMD_QUEUE_SIZE]; int queue_ptr; int queue_len; mutex_t mutex; }; -struct ps2_key_buffer { +struct ps2_key_buffer +{ struct kdb_keyinfo_pkt buffer[PS2_KBD_RECV_BUFFER_SIZE]; int read_ptr; int buffered_len; @@ -80,39 +82,42 @@ struct ps2_key_buffer { * @brief 向PS/2控制器的控制端口(0x64)发送指令并等待返回代码。 * 注意,对于没有返回代码的命令请使用`ps2_post_cmd`,否则会造成死锁。 * 通过调用该方法向控制器发送指令,请区别 ps2_issue_dev_cmd - * - * @param cmd + * + * @param cmd * @param args */ -static uint8_t ps2_issue_cmd(char cmd, uint16_t arg); +static uint8_t +ps2_issue_cmd(char cmd, uint16_t arg); /** * @brief 向PS/2控制器的编码器端口(0x60)发送指令并等待返回代码。 * 注意,对于没有返回代码的命令请使用`ps2_post_cmd`,否则会造成死锁。 * 通过调用该方法向PS/2设备发送指令,请区别 ps2_issue_cmd - * - * @param cmd + * + * @param cmd * @param args */ -static uint8_t ps2_issue_dev_cmd(char cmd, uint16_t arg); +static uint8_t +ps2_issue_dev_cmd(char cmd, uint16_t arg); /** * @brief 向PS/2控制器发送指令,不等待返回代码。 - * + * * @param port 端口号 - * @param cmd - * @param args - * @return char + * @param cmd + * @param args + * @return char */ -static void ps2_post_cmd(uint8_t port, char cmd, uint16_t arg); - -void ps2_device_post_cmd(char cmd, char arg); - -void ps2_kbd_init(); - -void ps2_process_cmd(void* arg); +static void +ps2_post_cmd(uint8_t port, char cmd, uint16_t arg); +void +ps2_device_post_cmd(char cmd, char arg); +void +ps2_kbd_init(); +void +ps2_process_cmd(void* arg); #endif /* __LUNAIX_PS2KBD_H */ diff --git a/lunaix-os/kernel/lxconsole.c b/lunaix-os/kernel/lxconsole.c index 2b20970..e58e3f1 100644 --- a/lunaix-os/kernel/lxconsole.c +++ b/lunaix-os/kernel/lxconsole.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -56,23 +57,41 @@ __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; - while (1) { - // FIXME keyboard is duplicating the key that user typed + + size_t count = fifo_read(&console->input, buf, len); + if (count > 0 && ((char*)buf)[count - 1] == '\n') { + return count; + } + + 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_yield(); continue; } - if ((keyevent.keycode & 0xff00) <= KEYPAD) { - char c = (char)(keyevent.keycode & 0x00ff); - if (c == 0x08 && !fifo_backone(&console->input)) { - continue; - } - // console_write_char(c); - if (!fifo_putone(&console->input, c) || c == '\n') { - break; + if (!(keyevent.state & KBD_KEY_FPRESSED)) { + continue; + } + if ((keyevent.keycode & 0xff00) > KEYPAD) { + continue; + } + + char c = (char)(keyevent.keycode & 0x00ff); + if (c == 0x08) { + if (fifo_backone(&console->input)) { + console_write_char(c); } + continue; + } + console_write_char(c); + if (!fifo_putone(&console->input, c) || c == '\n') { + break; } } - return fifo_read(&console->input, buf, len); + return count + fifo_read(&console->input, buf + count, len - count); } void diff --git a/lunaix-os/kernel/peripheral/ps2kbd.c b/lunaix-os/kernel/peripheral/ps2kbd.c index 6d27b10..6905b1e 100644 --- a/lunaix-os/kernel/peripheral/ps2kbd.c +++ b/lunaix-os/kernel/peripheral/ps2kbd.c @@ -427,11 +427,9 @@ kbd_recv_key(struct kdb_keyinfo_pkt* key_event) if (!key_buf.buffered_len) { return 0; } - mutex_lock(&key_buf.mutex); - - struct kdb_keyinfo_pkt* pkt_current = &key_buf.buffer[key_buf.read_ptr]; - *key_event = *pkt_current; + 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; -- 2.27.0