Support to multi-threading and pthread interface (POSIX.1-2008) (#23)
[lunaix-os.git] / lunaix-os / hal / char / ps2kbd.c
index 47c866d09ada47b39c664db04705f7c5c758c9b4..7b14048901fd79d2808666f8842c238d5a597a30 100644 (file)
@@ -5,13 +5,13 @@
 #include <lunaix/keyboard.h>
 #include <lunaix/syslog.h>
 #include <lunaix/timer.h>
+#include <lunaix/pcontext.h>
 
 #include <hal/intc.h>
 
 #include <klibc/string.h>
 
 #include <sys/cpu.h>
-#include <sys/interrupts.h>
 #include <sys/port_io.h>
 
 #define PS2_PORT_ENC_DATA 0x60
@@ -114,9 +114,6 @@ ps2_post_cmd(u8_t port, char cmd, u16_t arg);
 static void
 ps2_device_post_cmd(char cmd, char arg);
 
-static void
-ps2_kbd_init();
-
 static void
 ps2_process_cmd(void* arg);
 
@@ -215,8 +212,8 @@ ps2_device_post_cmd(char cmd, char arg)
     mutex_unlock(&cmd_q.mutex);
 }
 
-void
-ps2_kbd_init()
+static int
+ps2_kbd_init(struct device_def* devdef)
 {
 
     memset(&cmd_q, 0, sizeof(cmd_q));
@@ -227,7 +224,7 @@ ps2_kbd_init()
     kbd_state.translation_table = scancode_set2;
     kbd_state.state = KBD_STATE_KWAIT;
 
-    kbd_idev = input_add_device("i8042-kbd");
+    kbd_idev = input_add_device(&devdef->class, devdef->name);
 
     /* FIXME This require systematical rework! */
     // acpi_context* acpi_ctx = acpi_get_context();
@@ -251,20 +248,18 @@ 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 "not found\n");
+    //         ERROR("not found\n");
     //         // FUTURE: Some alternative fallback on this? Check PCI bus for
     //         USB
     //         // controller instead?
     //         return;
     //     }
     // } else {
-    //     kprintf(KWARN "outdated FADT used, assuming exists.\n");
+    //     WARN("outdated FADT used, assuming exists.\n");
     // }
 
     char result;
 
-    cpu_disable_interrupt();
-
     // 1、禁用任何的PS/2设备
     ps2_post_cmd(PS2_PORT_CTRL_CMDREG, PS2_CMD_PORT1_DISABLE, PS2_NO_ARG);
     ps2_post_cmd(PS2_PORT_CTRL_CMDREG, PS2_CMD_PORT2_DISABLE, PS2_NO_ARG);
@@ -280,15 +275,15 @@ ps2_kbd_init()
     // 4、控制器自检
     result = ps2_issue_cmd_wretry(PS2_CMD_SELFTEST, PS2_NO_ARG);
     if (result != PS2_RESULT_TEST_OK) {
-        kprintf(KWARN "controller self-test failed. (%x)\n", result);
-        // goto done;
+        WARN("controller self-test failed. (%x)", result);
+        goto done;
     }
 
     // 5、设备自检(端口1自检,通常是我们的键盘)
     result = ps2_issue_cmd_wretry(PS2_CMD_SELFTEST_PORT1, PS2_NO_ARG);
     if (result != 0) {
-        kprintf(KERROR "interface test on port 1 failed. (%x)\n", result);
-        // goto done;
+        ERROR("interface test on port 1 failed. (%x)", result);
+        goto done;
     }
 
     ps2_post_cmd(PS2_PORT_CTRL_CMDREG, PS2_CMD_PORT2_DISABLE, PS2_NO_ARG);
@@ -302,12 +297,6 @@ ps2_kbd_init()
 
     // 至此,PS/2控制器和设备已完成初始化,可以正常使用。
 
-    // 搞一个计时器,将我们的 ps2_process_cmd
-    // 挂上去。每隔5毫秒执行排在队头的命令。
-    //  为什么只执行队头的命令,而不是全部的命令?
-    //      因为我们需要保证isr尽量的简短,运行起来快速。而发送这些命令非常的耗时。
-    timer_run_ms(5, ps2_process_cmd, NULL, TIMER_MODE_PERIODIC);
-
     /*
      *   一切准备就绪后,我们才教ioapic去启用IRQ#1。
      *   至于为什么要在这里,原因是:初始化所使用的一些指令可能会导致IRQ#1的触发(因为返回码),或者是一些什么
@@ -320,9 +309,11 @@ ps2_kbd_init()
      */
     isrm_bindirq(PC_AT_IRQ_KBD, intr_ps2_kbd_handler);
 
-    cpu_enable_interrupt();
+    return 0;
+
+done:
+    return 1;
 }
-EXPORT_INPUT_DEV(i8042_keyboard, ps2_kbd_init);
 
 static void
 ps2_process_cmd(void* arg)
@@ -456,12 +447,13 @@ intr_ps2_kbd_handler(const isr_param* param)
 
 #ifdef KBD_ENABLE_SPIRQ_FIX2
     if (scancode == PS2_RESULT_ACK || scancode == PS2_RESULT_NAK) {
+        ps2_process_cmd(NULL);
         return;
     }
 #endif
 
 #ifdef KBD_DBGLOG
-    kprintf(KDEBUG "%x\n", scancode & 0xff);
+    DEBUG("%x\n", scancode & 0xff);
 #endif
 
     switch (kbd_state.state) {
@@ -537,7 +529,7 @@ ps2_issue_cmd_wretry(char cmd, u16_t arg)
         c++;
     }
     if (c >= 5) {
-        kprintf(KWARN "max attempt reached.\n");
+        WARN("max attempt reached.");
     }
     return r;
 }
@@ -572,4 +564,11 @@ ps2_issue_dev_cmd(char cmd, u16_t arg)
         ;
 
     return port_rdbyte(PS2_PORT_ENC_CMDREG);
-}
\ No newline at end of file
+}
+
+static struct device_def devrtc_i8042kbd = {
+    .name = "i8042 Keyboard",
+    .class = DEVCLASS(DEVIF_SOC, DEVFN_INPUT, DEV_KBD),
+    .init = ps2_kbd_init
+};
+EXPORT_DEVICE(i8042_kbd, &devrtc_i8042kbd, load_onboot);