Thank you. SeaBIOS does:
$ grep 7fee4000 seabios.log
/7fee4000\ Start thread
|7fee4000| i8042_flush
|7fee4000| i8042_command cmd=ad
|7fee4000| i8042_wait_write
|7fee4000| i8042_command cmd=a7
|7fee4000| i8042_wait_write
|7fee4000| i8042_flush
|7fee4000| i8042_command cmd=1aa
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_read
|7fee4000| i8042 param=55
|7fee4000| i8042_command cmd=1ab
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_read
|7fee4000| i8042 param=0
|7fee4000| ps2_command aux=0 cmd=1ff
|7fee4000| i8042 ctr old=30 new=30
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_sendbyte aux=0 cmd=ff
|7fee4000| i8042_kbd_write c=255
|7fee4000| i8042_wait_write
|7fee4000| ps2 read fa
|7fee4000| ps2 read aa
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_command aux=0 cmd=f5
|7fee4000| i8042 ctr old=30 new=30
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_sendbyte aux=0 cmd=f5
|7fee4000| i8042_kbd_write c=245
|7fee4000| i8042_wait_write
|7fee4000| ps2 read fa
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_command aux=0 cmd=10f0
|7fee4000| i8042 ctr old=30 new=30
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_sendbyte aux=0 cmd=f0
|7fee4000| i8042_kbd_write c=240
|7fee4000| i8042_wait_write
|7fee4000| ps2 read fa
|7fee4000| ps2_sendbyte aux=0 cmd=2
|7fee4000| i8042_kbd_write c=2
|7fee4000| i8042_wait_write
|7fee4000| ps2 read fa
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_command aux=0 cmd=f4
|7fee4000| i8042 ctr old=61 new=70
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| ps2_sendbyte aux=0 cmd=f4
|7fee4000| i8042_kbd_write c=244
|7fee4000| i8042_wait_write
|7fee4000| ps2 read fa
|7fee4000| i8042_command cmd=1060
|7fee4000| i8042_wait_write
|7fee4000| i8042_wait_write
|7fee4000| PS2 keyboard initialized
\7fee4000/ End thread
Now, one has to find out, what GRUB is doing.
As you found out, that it’s hanging below
static void keyboard_controller_wait_until_ready (void) { /* 50 us would be enough but our current time resolution is 1ms. */ grub_millisleep (1); while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))); }
What about adding a timeout there too?
#define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02)