libpayload: Reset PS/2 keyboard

Loading a libpayload based payload like coreinfo or FILO from SeaBIOS or
GRUB pressing keys does not give the expected results.

For example, pressing F1 gives the character 24 translated to scan code
6a. ESC for example 43 (111) in coreinfo loaded from SeaBIOS on QEMU
Q35.

The problem is not reproducible using the payload directly, that means
without SeaBIOS or GRUB. The problem seems to be, that those have already
initialized the PS/2 controller and AT keyboard.

Comparing it with coreboot’s PS/2 keyboard code, the keyboard needs to
be reset. That seems to fix the issue, when the keyboard was initialized
before.

TEST=Build coreboot for QEMU Q35 with SeaBIOS, and coreinfo as secondary
payload. Run

    qemu-system-i386 -M q35 -L /dev/shm -bios build/coreboot.rom -serial stdio

press 3 to select the coreinfo payload, and verify that the keys F1 and
F2 are working.

Same with coreinfo loaded from GRUB on the ASRock E350M1.

Change-Id: I2732292ac316d4bc0029ecb5c95fa7d1e7d68947
Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/32951
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Paul Menzel 2019-05-22 19:19:15 +02:00 committed by Patrick Georgi
parent 82882288c9
commit 7ae606f57f
2 changed files with 8 additions and 0 deletions

View File

@ -63,6 +63,7 @@
#define I8042_KBCMD_EN 0xf4 #define I8042_KBCMD_EN 0xf4
#define I8042_KBCMD_DEFAULT_DIS 0xf5 #define I8042_KBCMD_DEFAULT_DIS 0xf5
#define I8042_KBCMD_SET_DEFAULT 0xf6 #define I8042_KBCMD_SET_DEFAULT 0xf6
#define I8042_KBCMD_ACK 0xfa
#define I8042_KBCMD_RESEND 0xfe #define I8042_KBCMD_RESEND 0xfe
#define I8042_KBCMD_RESET 0xff #define I8042_KBCMD_RESET 0xff

View File

@ -317,6 +317,13 @@ void keyboard_init(void)
/* Enable first PS/2 port */ /* Enable first PS/2 port */
i8042_cmd(I8042_CMD_EN_KB); i8042_cmd(I8042_CMD_EN_KB);
/* Reset keyboard and self test (keyboard side) */
ret = keyboard_cmd(I8042_KBCMD_RESET);
if (ret != I8042_KBCMD_ACK) {
printf("ERROR: Keyboard reset failed ACK: 0x%x\n", ret);
return;
}
/* Set scancode set 1 */ /* Set scancode set 1 */
ret = keyboard_cmd(I8042_KBCMD_SET_SCANCODE); ret = keyboard_cmd(I8042_KBCMD_SET_SCANCODE);
if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE))