fix: refining the tty input
authorMinep <zelong56@gmail.com>
Mon, 8 Aug 2022 23:44:33 +0000 (00:44 +0100)
committerMinep <zelong56@gmail.com>
Mon, 8 Aug 2022 23:44:33 +0000 (00:44 +0100)
lunaix-os/includes/lunaix/peripheral/ps2kbd.h
lunaix-os/kernel/lxconsole.c
lunaix-os/kernel/peripheral/ps2kbd.c

index 2d568a6bc9ebd31fcd33006fef435f1bf4d9e1cd..08a0d56c6660e2f72d6776b9e8e849a69d54c229 100644 (file)
@@ -2,74 +2,76 @@
 #define __LUNAIX_PS2KBD_H
 
 #include <hal/io.h>
 #define __LUNAIX_PS2KBD_H
 
 #include <hal/io.h>
-#include <lunaix/keyboard.h>
 #include <lunaix/ds/mutex.h>
 #include <lunaix/ds/mutex.h>
-
+#include <lunaix/keyboard.h>
 
 #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_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
 
 // 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
 
 // 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
 
 
 #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;
 };
 
     char cmd;
     char arg;
 };
 
-struct ps2_kbd_state {
+struct ps2_kbd_state
+{
     volatile char state;
     volatile char masked;
     volatile char state;
     volatile char masked;
+    volatile kbd_kstate_t key_state;
     kbd_keycode_t* translation_table;
     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_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;
     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
  * @brief 向PS/2控制器的控制端口(0x64)发送指令并等待返回代码。
  * 注意,对于没有返回代码的命令请使用`ps2_post_cmd`,否则会造成死锁。
  * 通过调用该方法向控制器发送指令,请区别 ps2_issue_dev_cmd
- * 
- * @param cmd 
+ *
+ * @param cmd
  * @param args
  */
  * @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
 
 /**
  * @brief 向PS/2控制器的编码器端口(0x60)发送指令并等待返回代码。
  * 注意,对于没有返回代码的命令请使用`ps2_post_cmd`,否则会造成死锁。
  * 通过调用该方法向PS/2设备发送指令,请区别 ps2_issue_cmd
- * 
- * @param cmd 
+ *
+ * @param cmd
  * @param args
  */
  * @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控制器发送指令,不等待返回代码。
 
 /**
  * @brief 向PS/2控制器发送指令,不等待返回代码。
- * 
+ *
  * @param port 端口号
  * @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 */
 
 #endif /* __LUNAIX_PS2KBD_H */
index 2b209706de8f0ec0331e8aa9ab64ffbd5a03834a..e58e3f108fb7de8da6504ad617e1f1911f00afea 100644 (file)
@@ -5,6 +5,7 @@
 #include <lunaix/mm/pmm.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/mm/vmm.h>
 #include <lunaix/mm/pmm.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/mm/vmm.h>
+#include <lunaix/sched.h>
 #include <lunaix/tty/console.h>
 #include <lunaix/tty/tty.h>
 
 #include <lunaix/tty/console.h>
 #include <lunaix/tty/tty.h>
 
@@ -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;
 {
     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)) {
         if (!kbd_recv_key(&keyevent)) {
+            sched_yield();
             continue;
         }
             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
 }
 
 void
index 6d27b10847c8f28802548aa77a806f3a395a5205..6905b1eb059fc8995aeaf3c2cbb5c13a007967b8 100644 (file)
@@ -427,11 +427,9 @@ kbd_recv_key(struct kdb_keyinfo_pkt* key_event)
     if (!key_buf.buffered_len) {
         return 0;
     }
     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;
 
     key_buf.buffered_len--;
     key_buf.read_ptr = (key_buf.read_ptr + 1) % PS2_KBD_RECV_BUFFER_SIZE;