diff options
author | Ian Moffett <ian@osmora.org> | 2025-10-15 20:19:16 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-10-15 20:19:16 -0400 |
commit | 69bb0f15996ff36161ef9db400286997189f04ab (patch) | |
tree | a3fe81c2156baecf0713ead5a37e9b5a01ff7b81 /src/sys | |
parent | 00aac70b23d3fb72ea0e5878a5edfc3a098f422f (diff) |
kern/amd64: i8042: Add option to poll keyboard
Some hardware may not work too well with the i8042 and interrupts, as a
mitigation, we've added an option to poll instead of using interrupts
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src/sys')
-rw-r--r-- | src/sys/arch/amd64/conf/GENERIC | 4 | ||||
-rw-r--r-- | src/sys/arch/amd64/isa/i8042.c | 35 |
2 files changed, 37 insertions, 2 deletions
diff --git a/src/sys/arch/amd64/conf/GENERIC b/src/sys/arch/amd64/conf/GENERIC index 93919d8..f402941 100644 --- a/src/sys/arch/amd64/conf/GENERIC +++ b/src/sys/arch/amd64/conf/GENERIC @@ -2,3 +2,7 @@ // as a method. Some firmware (e.g., on some laptops) // may not handle these well and hang. option I8042_REBOOT yes + +// Controls if the i8042 should be polled +// rather than dependent on interrupts +option I8042_POLL no diff --git a/src/sys/arch/amd64/isa/i8042.c b/src/sys/arch/amd64/isa/i8042.c index 9417206..6ffea73 100644 --- a/src/sys/arch/amd64/isa/i8042.c +++ b/src/sys/arch/amd64/isa/i8042.c @@ -40,6 +40,12 @@ #include <machine/pio.h> #include <stdbool.h> +#if defined(__I8042_POLL) +#define I8042_POLL __I8042_POLL +#else +#define I8042_POLL 0 +#endif /* !I8042_POLL */ + #define RING_NENT 16 /* @@ -58,6 +64,7 @@ struct keybuf { /* I/O tap forward declarations */ static struct iotap_ops tap_port0_ops; static struct iotap_desc tap_port0; +static struct proc *kbd_poll_td; /* Key states */ static bool shift_key = false; @@ -350,6 +357,20 @@ i8042_irq(struct intr_hand *hp) return 1; } +static void +i8042_poll(void *p) +{ + char c; + uint8_t scancode; + + for (;;) { + scancode = i8042_read(); + if (i8042_getc(scancode, &c) == 0) { + keybuf_enter(&buf, c); + } + } +} + /* * Initialize i8042 interrupts (IRQ 1) */ @@ -399,8 +420,18 @@ i8042_init(struct module *modp) i8042_write(true, I8042_DISABLE_PORT1); i8042_read(); - /* Initialize interrupts and taps */ - i8042_init_intr(); + /* + * If we are configured to do interrupts, enable + * them. Otherwise, start a kernel thread and + * poll. + */ + if (!I8042_POLL) { + i8042_init_intr(); + } else { + proc_ktd(&kbd_poll_td, i8042_poll); + } + + /* Enable I/O taps */ i8042_init_tap(); /* Enable the keyboard */ |