Move ps2 specific keyboard and mouse code to ps2port.c.
diff --git a/src/config.h b/src/config.h
index 9c7c504..3881cc4 100644
--- a/src/config.h
+++ b/src/config.h
@@ -38,6 +38,8 @@
#define CONFIG_USB_OHCI 1
// Support USB keyboards
#define CONFIG_USB_KEYBOARD 1
+// Support PS2 ports (keyboard and mouse)
+#define CONFIG_PS2PORT 1
// Support for IDE disk code
#define CONFIG_ATA 1
// Use 32bit PIO accesses on ATA (minor optimization on PCI transfers)
@@ -71,7 +73,7 @@
// Disable A20 on 16bit boot
#define CONFIG_DISABLE_A20 0
// Support for int15c2 mouse calls
-#define CONFIG_PS2_MOUSE 1
+#define CONFIG_MOUSE 1
// If the target machine has multiple independent root buses, the
// extra buses may be specified here.
#define CONFIG_PCI_ROOT1 0x00
diff --git a/src/kbd.c b/src/kbd.c
index 461d1b7..e5ffa33 100644
--- a/src/kbd.c
+++ b/src/kbd.c
@@ -8,9 +8,8 @@
#include "biosvar.h" // GET_BDA
#include "util.h" // debug_enter
#include "config.h" // CONFIG_*
-#include "pic.h" // eoi_pic1
#include "bregs.h" // struct bregs
-#include "ps2port.h" // i8042_flush
+#include "ps2port.h" // kbd_command
// Bit definitions for BDA kbd_flag[012]
#define KF0_RSHIFT (1<<0)
@@ -34,74 +33,6 @@
#define KF2_RALT (1<<3)
#define KF2_101KBD (1<<4)
-static void
-keyboard_init()
-{
- /* flush incoming keys */
- int ret = i8042_flush();
- if (ret)
- return;
-
- // Controller self-test.
- u8 param[2];
- ret = i8042_command(I8042_CMD_CTL_TEST, param);
- if (ret)
- return;
- if (param[0] != 0x55) {
- dprintf(1, "i8042 self test failed (got %x not 0x55)\n", param[0]);
- return;
- }
-
- // Controller keyboard test.
- ret = i8042_command(I8042_CMD_KBD_TEST, param);
- if (ret)
- return;
- if (param[0] != 0x00) {
- dprintf(1, "i8042 keyboard test failed (got %x not 0x00)\n", param[0]);
- return;
- }
-
- // Enable keyboard and mouse ports.
- ret = i8042_command(I8042_CMD_KBD_ENABLE, NULL);
- if (ret)
- return;
- ret = i8042_command(I8042_CMD_AUX_ENABLE, NULL);
- if (ret)
- return;
-
-
- /* ------------------- keyboard side ------------------------*/
- /* reset keyboard and self test (keyboard side) */
- ret = kbd_command(ATKBD_CMD_RESET_BAT, param);
- if (ret)
- return;
- if (param[0] != 0xaa) {
- dprintf(1, "keyboard self test failed (got %x not 0xaa)\n", param[0]);
- return;
- }
-
- /* Disable keyboard */
- ret = kbd_command(ATKBD_CMD_RESET_DIS, NULL);
- if (ret)
- return;
-
- // Set scancode command (mode 2)
- param[0] = 0x02;
- ret = kbd_command(ATKBD_CMD_SSCANSET, param);
- if (ret)
- return;
-
- // Keyboard Mode: scan code convert, disable mouse, enable IRQ 1
- SET_EBDA(ps2ctr, I8042_CTR_AUXDIS | I8042_CTR_XLATE | I8042_CTR_KBDINT);
-
- /* Enable keyboard */
- ret = kbd_command(ATKBD_CMD_ENABLE, NULL);
- if (ret)
- return;
-
- dprintf(1, "keyboard initialized\n");
-}
-
void
kbd_setup()
{
@@ -114,13 +45,6 @@
SET_BDA(kbd_buf_end_offset
, x + FIELD_SIZEOF(struct bios_data_area_s, kbd_buf));
-
- if (! CONFIG_KEYBOARD)
- return;
-
- run_thread(keyboard_init, NULL);
-
- enable_hwirq(1, entry_09);
}
static u8
@@ -621,6 +545,9 @@
void
process_key(u8 key)
{
+ if (!CONFIG_KEYBOARD)
+ return;
+
if (CONFIG_KBD_CALL_INT15_4F) {
// allow for keyboard intercept
u32 eax = (0x4f << 8) | key;
@@ -632,25 +559,3 @@
}
__process_key(key);
}
-
-// INT09h : Keyboard Hardware Service Entry Point
-void VISIBLE16
-handle_09()
-{
- debug_isr(DEBUG_ISR_09);
- if (! CONFIG_KEYBOARD)
- goto done;
-
- // read key from keyboard controller
- u8 v = inb(PORT_PS2_STATUS);
- if ((v & (I8042_STR_OBF|I8042_STR_AUXDATA)) != I8042_STR_OBF) {
- dprintf(1, "keyboard irq but no keyboard data.\n");
- goto done;
- }
- v = inb(PORT_PS2_DATA);
-
- process_key(v);
-
-done:
- eoi_pic1();
-}
diff --git a/src/mouse.c b/src/mouse.c
index 5a1b81f..ca581a8 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -14,12 +14,11 @@
void
mouse_setup()
{
- if (! CONFIG_PS2_MOUSE)
+ if (! CONFIG_MOUSE)
return;
dprintf(3, "init mouse\n");
// pointing device installed
SETBITS_BDA(equipment_list_flags, 0x04);
- enable_hwirq(12, entry_74);
}
#define RET_SUCCESS 0x00
@@ -264,7 +263,7 @@
{
//debug_stub(regs);
- if (! CONFIG_PS2_MOUSE) {
+ if (! CONFIG_MOUSE) {
set_code_fail(regs, RET_EUNSUPPORTED);
return;
}
@@ -282,9 +281,12 @@
}
}
-static void
+void
process_mouse(u8 data)
{
+ if (!CONFIG_MOUSE)
+ return;
+
u16 ebda_seg = get_ebda_seg();
u8 mouse_flags_1 = GET_EBDA2(ebda_seg, mouse_flag1);
u8 mouse_flags_2 = GET_EBDA2(ebda_seg, mouse_flag2);
@@ -329,25 +331,3 @@
: "cc"
);
}
-
-// INT74h : PS/2 mouse hardware interrupt
-void VISIBLE16
-handle_74()
-{
- debug_isr(DEBUG_ISR_74);
- if (! CONFIG_PS2_MOUSE)
- goto done;
-
- u8 v = inb(PORT_PS2_STATUS);
- if ((v & (I8042_STR_OBF|I8042_STR_AUXDATA))
- != (I8042_STR_OBF|I8042_STR_AUXDATA)) {
- dprintf(1, "mouse irq but no mouse data.\n");
- goto done;
- }
- v = inb(PORT_PS2_DATA);
-
- process_mouse(v);
-
-done:
- eoi_pic2();
-}
diff --git a/src/post.c b/src/post.c
index fd60236..9417480 100644
--- a/src/post.c
+++ b/src/post.c
@@ -22,6 +22,7 @@
#include "usb.h" // usb_setup
#include "smbios.h" // smbios_init
#include "paravirt.h" // qemu_cfg_port_probe
+#include "ps2port.h" // ps2port_setup
void
__set_irq(int vector, void *loc)
@@ -185,6 +186,8 @@
// Setup interfaces that option roms may need
pmm_setup();
pnp_setup();
+ kbd_setup();
+ mouse_setup();
init_bios_tables();
// Run vga option rom (if running synchronously)
@@ -193,10 +196,9 @@
// Initialize hardware devices
usb_setup();
- kbd_setup();
+ ps2port_setup();
lpt_setup();
serial_setup();
- mouse_setup();
boot_setup();
drive_setup();
diff --git a/src/ps2port.c b/src/ps2port.c
index 39ec65f..d03c049 100644
--- a/src/ps2port.c
+++ b/src/ps2port.c
@@ -9,6 +9,7 @@
#include "util.h" // dprintf
#include "biosvar.h" // GET_EBDA
#include "ps2port.h" // kbd_command
+#include "pic.h" // eoi_pic1
/****************************************************************
@@ -281,3 +282,140 @@
dprintf(2, "mouse command %x failed\n", command);
return ret;
}
+
+
+/****************************************************************
+ * IRQ handlers
+ ****************************************************************/
+
+// INT74h : PS/2 mouse hardware interrupt
+void VISIBLE16
+handle_74()
+{
+ if (! CONFIG_PS2PORT)
+ return;
+
+ debug_isr(DEBUG_ISR_74);
+
+ u8 v = inb(PORT_PS2_STATUS);
+ if ((v & (I8042_STR_OBF|I8042_STR_AUXDATA))
+ != (I8042_STR_OBF|I8042_STR_AUXDATA)) {
+ dprintf(1, "mouse irq but no mouse data.\n");
+ goto done;
+ }
+ v = inb(PORT_PS2_DATA);
+
+ process_mouse(v);
+
+done:
+ eoi_pic2();
+}
+
+// INT09h : Keyboard Hardware Service Entry Point
+void VISIBLE16
+handle_09()
+{
+ if (! CONFIG_PS2PORT)
+ return;
+
+ debug_isr(DEBUG_ISR_09);
+
+ // read key from keyboard controller
+ u8 v = inb(PORT_PS2_STATUS);
+ if ((v & (I8042_STR_OBF|I8042_STR_AUXDATA)) != I8042_STR_OBF) {
+ dprintf(1, "keyboard irq but no keyboard data.\n");
+ goto done;
+ }
+ v = inb(PORT_PS2_DATA);
+
+ process_key(v);
+
+done:
+ eoi_pic1();
+}
+
+
+/****************************************************************
+ * Setup
+ ****************************************************************/
+
+static void
+keyboard_init()
+{
+ /* flush incoming keys */
+ int ret = i8042_flush();
+ if (ret)
+ return;
+
+ // Controller self-test.
+ u8 param[2];
+ ret = i8042_command(I8042_CMD_CTL_TEST, param);
+ if (ret)
+ return;
+ if (param[0] != 0x55) {
+ dprintf(1, "i8042 self test failed (got %x not 0x55)\n", param[0]);
+ return;
+ }
+
+ // Controller keyboard test.
+ ret = i8042_command(I8042_CMD_KBD_TEST, param);
+ if (ret)
+ return;
+ if (param[0] != 0x00) {
+ dprintf(1, "i8042 keyboard test failed (got %x not 0x00)\n", param[0]);
+ return;
+ }
+
+ // Enable keyboard and mouse ports.
+ ret = i8042_command(I8042_CMD_KBD_ENABLE, NULL);
+ if (ret)
+ return;
+ ret = i8042_command(I8042_CMD_AUX_ENABLE, NULL);
+ if (ret)
+ return;
+
+
+ /* ------------------- keyboard side ------------------------*/
+ /* reset keyboard and self test (keyboard side) */
+ ret = kbd_command(ATKBD_CMD_RESET_BAT, param);
+ if (ret)
+ return;
+ if (param[0] != 0xaa) {
+ dprintf(1, "keyboard self test failed (got %x not 0xaa)\n", param[0]);
+ return;
+ }
+
+ /* Disable keyboard */
+ ret = kbd_command(ATKBD_CMD_RESET_DIS, NULL);
+ if (ret)
+ return;
+
+ // Set scancode command (mode 2)
+ param[0] = 0x02;
+ ret = kbd_command(ATKBD_CMD_SSCANSET, param);
+ if (ret)
+ return;
+
+ // Keyboard Mode: scan code convert, disable mouse, enable IRQ 1
+ SET_EBDA(ps2ctr, I8042_CTR_AUXDIS | I8042_CTR_XLATE | I8042_CTR_KBDINT);
+
+ /* Enable keyboard */
+ ret = kbd_command(ATKBD_CMD_ENABLE, NULL);
+ if (ret)
+ return;
+
+ dprintf(1, "keyboard initialized\n");
+}
+
+void
+ps2port_setup()
+{
+ if (! CONFIG_PS2PORT)
+ return;
+ dprintf(3, "init ps2port\n");
+
+ enable_hwirq(1, entry_09);
+ enable_hwirq(12, entry_74);
+
+ run_thread(keyboard_init, NULL);
+}
diff --git a/src/ps2port.h b/src/ps2port.h
index 3c4e4d4..e13f859 100644
--- a/src/ps2port.h
+++ b/src/ps2port.h
@@ -59,5 +59,6 @@
int i8042_command(int command, u8 *param);
int kbd_command(int command, u8 *param);
int aux_command(int command, u8 *param);
+void ps2port_setup();
#endif // ps2port.h
diff --git a/src/util.h b/src/util.h
index cf98857..6458c8a 100644
--- a/src/util.h
+++ b/src/util.h
@@ -217,6 +217,7 @@
// mouse.c
void mouse_setup();
+void process_mouse(u8 data);
// system.c
extern u32 RamSize;