[coreboot] Keyboard not working on Thinkpad X60/T60
Sven Schnelle
svens at stackframe.org
Wed May 4 10:16:17 CEST 2011
Sven Schnelle <svens at stackframe.org> writes:
> Hi Setfan,
>
> Stefan Reinauer <stefan.reinauer at coreboot.org> writes:
>
>> * Sven Schnelle <svens at stackframe.org> [110503 21:41]:
>>> Stefan Reinauer <stefan.reinauer at coreboot.org> writes:
>>> > Can you do a new analysis on where the boot time goes now? It would be
>>> > nice to see if there are more optimizations we can do...
>>>
>>> Will do. But right now i have the problem that the Keyboard isn't
>>> working on cold boot - seabios is probably started so early that some
>>> hardware parts are not finished with reset or similar things.
>>>
>>> Just enabling debug output in coreboot slows down things enough to
>>> make the Keyboard working again.
>>
>> Does just putting in a delay of some 100ms fix the issue, too? Do you do
>> keyboard init in coreboot? Did you do it before?
>> Just want to make sure there are no side effects coming in through
>> debugging. However, having an EC/SuperIO that needs more than 200ms to boot up
>> does not sound too unlikely.
>
> I do not initialize the Keyboard in coreboot, i'll leave that to
> seabios. (Enabling it in coreboot doesn't help either).
>
>>> The original Vendor BIOS talks after around ~1s to the Keyboard
>>> controller, so that's quite different to coreboot (coreboot is handing
>>> over to seabios after ~200ms)
>>
>> Getting through all of coreboot in as little as 200ms? This is totally
>> awesome!
>>
>>> So i want to figure out first if there's some
>>> 'i-finished-reset-you-can-talk-to-me' flag, or if that problem is caused
>>> by another reason.
>>
>> Does the keyboard init code get any type of timeout?
>
>
> Well, i've enabled some debugging in seabios, and it's pretty obvious
> what's happening here. SeaBIOS sends command 0xff (which is RESET i
> think), and SeabIOS gets 0xfe as response (which is RESEND, but seabios
> handles that as NAK, and doesn't resend the command).
>
> You can find the boot log here:
>
> http://stackframe.org/seriallog-20110503_175245.log
I've just modified seabios to resend commands when 0xfe is received as a
quick hack. It makes my keyboard working again. I'm not sure if SeabIOS
should handle 0xfe as RESEND or not - have not monitored much Keyboards,
and don't know wether this has any side effects.
The boot log can be found here:
http://stackframe.org/seriallog-20110504_100837.log
The diff i've made to seabios is: (beware, it's just an ugly hack just for
testing)
diff --git a/src/ps2port.c b/src/ps2port.c
index d1e6d48..a4cd4de 100644
--- a/src/ps2port.c
+++ b/src/ps2port.c
@@ -186,7 +186,8 @@ ps2_recvbyte(int aux, int needack, int timeout)
static int
ps2_sendbyte(int aux, u8 command, int timeout)
{
- dprintf(7, "ps2_sendbyte aux=%d cmd=%x\n", aux, command);
+resend:
+ dprintf(7, "ps2_sendbyte aux=%d cmd=%x\n", aux, command);
int ret;
if (aux)
ret = i8042_aux_write(command);
@@ -199,6 +200,8 @@ ps2_sendbyte(int aux, u8 command, int timeout)
ret = ps2_recvbyte(aux, 1, timeout);
if (ret < 0)
return ret;
+ if (ret == 0xfe)
+ goto resend;
if (ret != PS2_RET_ACK)
return -1;
@@ -232,7 +235,7 @@ __ps2_command(int aux, int command, u8 *param)
ret = i8042_command(I8042_CMD_CTL_WCTR, &newctr);
if (ret)
goto fail;
-
+resend:
if (command == ATKBD_CMD_RESET_BAT) {
// Reset is special wrt timeouts and bytes received.
@@ -243,10 +246,14 @@ __ps2_command(int aux, int command, u8 *param)
// Receive parameters.
ret = ps2_recvbyte(aux, 0, 4000);
+ if (ret == 0xfe)
+ goto resend;
if (ret < 0)
goto fail;
param[0] = ret;
ret = ps2_recvbyte(aux, 0, 100);
+ if (ret == 0xfe)
+ goto resend;
if (ret < 0)
// Some devices only respond with one byte on reset.
ret = 0;
@@ -261,6 +268,8 @@ __ps2_command(int aux, int command, u8 *param)
// Receive parameters.
ret = ps2_recvbyte(aux, 0, 500);
+ if (ret == 0xfe)
+ goto resend;
if (ret < 0)
goto fail;
param[0] = ret;
@@ -268,6 +277,8 @@ __ps2_command(int aux, int command, u8 *param)
|| ret == 0x60 || ret == 0x47) {
// These ids (keyboards) return two bytes.
ret = ps2_recvbyte(aux, 0, 500);
+ if (ret == 0xfe)
+ goto resend;
if (ret < 0)
goto fail;
param[1] = ret;
@@ -291,6 +302,8 @@ __ps2_command(int aux, int command, u8 *param)
// Receive parameters (if any).
for (i = 0; i < receive; i++) {
ret = ps2_recvbyte(aux, 0, 500);
+ if (ret == 0xfe)
+ goto resend;
if (ret < 0)
goto fail;
param[i] = ret;
More information about the coreboot
mailing list