#define __LUNAIX_PS2KBD_H
#include <hal/io.h>
-#include <lunaix/keyboard.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_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;
* @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 */
#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>
{
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