Matt Delco has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/33303
Change subject: libpayload/drivers/i8042: ignore special keys on keyboard ......................................................................
libpayload/drivers/i8042: ignore special keys on keyboard
Some keyboards have a fn-key (and/or fn-mode lock) that can generate 0xe0-prefixed scan codes for certain keys. Previously the 0xe0 prefix state wasn't tracked (it was ignored), so these scan codes could be misinterpreted as non-0xe0 presses (e.g., 'mute' generates 0xe0 0x20 but this would get interpreted as 0x20 and be treated as a 'D' press). Most 0xe0-prefixed codes (besides those for the 10-key) are irrelevant for firmware so we'll ignore them.
BUG=none BRANCH=none TEST=local build and flash. Verified that special keys are no longer interpreted as other keystrokes.
Change-Id: Ie6a828b6a0a3ab47456d6db2db504aa0d7aefc28 Signed-off-by: Matt Delco delco@chromium.org --- M payloads/libpayload/drivers/i8042/keyboard.c 1 file changed, 23 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/03/33303/1
diff --git a/payloads/libpayload/drivers/i8042/keyboard.c b/payloads/libpayload/drivers/i8042/keyboard.c index 3e5f988..bca916f 100644 --- a/payloads/libpayload/drivers/i8042/keyboard.c +++ b/payloads/libpayload/drivers/i8042/keyboard.c @@ -235,12 +235,30 @@ unsigned char ch; int shift; int ret = 0; - - while (!keyboard_havechar()) ; + static int prior_special = 0;
ch = keyboard_get_scancode();
- if (!(ch & 0x80) && ch < 0x59) { + if (prior_special) { + if (ch == 0x5e) + ret = POWER_BUTTON; + /* + * For now 0xe0 with 0x1c, 0x35, or 0x47 - 0x53 is the same as + * non-0xe0. For 10-key scan codes 0x47-0x53 it's probably more + * accurate for the non-0xe0 presses to use the numeric + * interpretation of the key (i.e., when num lock is on) and + * the 0xe0 prefixed versions should use the non-numeric + * interpretation (i.e., num lock off). However, the existing + * tables are using the non-numeric interpretation so for now + * the 0xe0 presses can use what's in the table for non-0xe0 + * presses. The main exception is that shift+'/' on the keypad + * (0xe0 0x35) should still produce a '/' (vs. a '?' like on + * the key that's to the left of the right-shift on English + * keyboards) so we'll ignore the shift status. + */ + else if (ch == 0x1c || ch == 0x35 || (ch >= 0x47 && ch <= 0x53)) + ret = map->map[0][ch]; + } else if (ch < 0x59) { /* implies !(ch & 0x80), i.e., key press */ shift = (modifier & KB_MOD_SHIFT) ^ (modifier & KB_MOD_CAPSLOCK) ? 1 : 0;
@@ -265,8 +283,8 @@ } }
- if (ch == 0x5e) - ret = POWER_BUTTON; + /* sequence 0xe0 0xe0 should not leave prior_special set. */ + prior_special = !prior_special && ch == 0xe0;
return ret; }