Sven Schnelle svens@stackframe.org writes:
Hi Setfan,
Stefan Reinauer stefan.reinauer@coreboot.org writes:
- Sven Schnelle svens@stackframe.org [110503 21:41]:
Stefan Reinauer stefan.reinauer@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:
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;