diff options
author | setje <none@none> | 2006-07-06 18:52:53 -0700 |
---|---|---|
committer | setje <none@none> | 2006-07-06 18:52:53 -0700 |
commit | 6ee4b8d7ef9a262e3f564e81b2b2f4d8e61ffe15 (patch) | |
tree | 5bc32d2bfb5e6451e4de94869ccde2ab49076c1d | |
parent | fef1e07ef354c2dcda4dc397c33f5a5532432c7a (diff) | |
download | illumos-gate-6ee4b8d7ef9a262e3f564e81b2b2f4d8e61ffe15.tar.gz |
6412224 GRUB hangs when no i8042 is present
6412226 multiboot hangs when no i8042 is present
Contributed by Juergen Keil <jk@tools.de>.
-rw-r--r-- | usr/src/grub/grub-0.95/stage2/asm.S | 33 | ||||
-rw-r--r-- | usr/src/psm/stand/boot/i386/common/keyboard.c | 28 |
2 files changed, 51 insertions, 10 deletions
diff --git a/usr/src/grub/grub-0.95/stage2/asm.S b/usr/src/grub/grub-0.95/stage2/asm.S index 5d4fe505ce..940313de24 100644 --- a/usr/src/grub/grub-0.95/stage2/asm.S +++ b/usr/src/grub/grub-0.95/stage2/asm.S @@ -1783,7 +1783,29 @@ ENTRY(gateA20) jnz 3f ret -3: /* use keyboard controller */ +3: /* + * try to switch gateA20 using PORT92, the "Fast A20 and Init" + * register + */ + mov $0x92, %dx + inb %dx, %al + /* skip the port92 code if it's unimplemented (read returns 0xff) */ + cmpb $0xff, %al + jz 6f + + /* set or clear bit1, the ALT_A20_GATE bit */ + movb 4(%esp), %ah + testb %ah, %ah + jz 4f + orb $2, %al + jmp 5f +4: and $0xfd, %al + + /* clear the INIT_NOW bit; don't accidently reset the machine */ +5: and $0xfe, %al + outb %al, %dx + +6: /* use keyboard controller */ pushl %eax call gloop1 @@ -1793,9 +1815,12 @@ ENTRY(gateA20) gloopint1: inb $K_STATUS + cmpb $0xff, %al + jz gloopint1_done andb $K_IBUF_FUL, %al jnz gloopint1 +gloopint1_done: movb $KB_OUTPUT_MASK, %al cmpb $0, 0x8(%esp) jz gdoit @@ -1816,6 +1841,8 @@ gdoit: gloop1: inb $K_STATUS + cmpb $0xff, %al + jz gloop2ret andb $K_IBUF_FUL, %al jnz gloop1 @@ -2123,6 +2150,10 @@ ENTRY(ascii_key_map) ENTRY(console_getkey) push %ebp +wait_for_key: + call EXT_C(console_checkkey) + incl wait_for_key + call EXT_C(prot_to_real) .code16 diff --git a/usr/src/psm/stand/boot/i386/common/keyboard.c b/usr/src/psm/stand/boot/i386/common/keyboard.c index 095a46b432..dc3f09d68c 100644 --- a/usr/src/psm/stand/boot/i386/common/keyboard.c +++ b/usr/src/psm/stand/boot/i386/common/keyboard.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -182,8 +181,10 @@ kb_ischar(void) return (1); for (;;) { - buffer_stat = - inb(I8042_STAT) & (I8042_STAT_OUTBF | I8042_STAT_AUXBF); + buffer_stat = inb(I8042_STAT); + if (buffer_stat == 0xff) + return (0); + buffer_stat &= (I8042_STAT_OUTBF | I8042_STAT_AUXBF); switch (buffer_stat) { case 0: @@ -456,7 +457,11 @@ kb_translate(unsigned char code) void kb_send(unsigned char cmd) { - while (inb(I8042_STAT) & I8042_STAT_INBF) + int retries; + + for (retries = 0; + (inb(I8042_STAT) & I8042_STAT_INBF) != 0 && retries < 100000; + retries++) /* LOOP */; outb(I8042_DATA, cmd); } @@ -487,6 +492,7 @@ void kb_init(void) { unsigned char pic_mask; + int retries; /* * Write the command byte to turn off interrupts and @@ -507,11 +513,15 @@ kb_init(void) * 0x01: 0 = Disable aux interrupts. */ - while (inb(I8042_STAT) & I8042_STAT_INBF) + for (retries = 0; + (inb(I8042_STAT) & I8042_STAT_INBF) != 0 && retries < 100000; + retries++) /* LOOP */; outb(I8042_CMD, I8042_WCB); - while (inb(I8042_STAT) & I8042_STAT_INBF) + for (retries = 0; + (inb(I8042_STAT) & I8042_STAT_INBF) != 0 && retries < 100000; + retries++) /* LOOP */; outb(I8042_DATA, 0x64); |