diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 2001-08-18 02:00:50 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 2001-08-18 02:00:50 +0000 |
commit | f4293c1086d231c860bc4bd5fce6b9a061d60beb (patch) | |
tree | 4974241d004f1362f9408283a7b1e66c99bf11b7 /sys | |
parent | 51c6f5e0f5f6f300b649e518110808b2b6142098 (diff) |
Timeout non-functional KBC (e.g. when missing) and gate A20 using port 0x92
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/i386/stand/libsa/gateA20.c | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/sys/arch/i386/stand/libsa/gateA20.c b/sys/arch/i386/stand/libsa/gateA20.c index d33e4887eae..6fde066209f 100644 --- a/sys/arch/i386/stand/libsa/gateA20.c +++ b/sys/arch/i386/stand/libsa/gateA20.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gateA20.c,v 1.6 2000/11/13 15:53:34 aaron Exp $ */ +/* $OpenBSD: gateA20.c,v 1.7 2001/08/18 02:00:49 csapuntz Exp $ */ /* * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 @@ -46,6 +46,8 @@ #define A20_KBD 0 #define A20_0x92 1 +int gateA20kbd __P((int)); + /* * Check for an oddball IBM_L40 machine. */ @@ -56,6 +58,34 @@ getA20type() } +int +gateA20kbd(on) + int on; +{ + u_int i = 1000000; + + while (i && (inb(IO_KBD + KBSTATP) & KBS_IBF)) i--; + if (i == 0) + return (1); + + while (inb(IO_KBD + KBSTATP) & KBS_DIB) + (void)inb(IO_KBD + KBDATAP); + + outb(IO_KBD + KBCMDP, KC_CMD_WOUT); + while (inb(IO_KBD + KBSTATP) & KBS_IBF); + + if (on) + outb(IO_KBD + KBDATAP, KB_A20); + else + outb(IO_KBD + KBDATAP, 0xcd); + while (inb(IO_KBD + KBSTATP) & KBS_IBF); + + while (inb(IO_KBD + KBSTATP) & KBS_DIB) + (void)inb(IO_KBD + KBDATAP); + + return (0); +} + /* * Gate A20 for high memory */ @@ -63,37 +93,20 @@ void gateA20(on) int on; { + int data; - if (getA20type() == A20_0x92) { - int data; - - /* Try to use 0x92 to turn on A20 */ - if (on) { - data = inb(0x92); - outb(0x92, data | 0x2); - } else { - data = inb(0x92); - outb(0x92, data & ~0x2); - } - } else { - - /* XXX - These whiles might need to be changed to bounded for loops */ - while (inb(IO_KBD + KBSTATP) & KBS_IBF); - - while (inb(IO_KBD + KBSTATP) & KBS_DIB) - (void)inb(IO_KBD + KBDATAP); - - outb(IO_KBD + KBCMDP, KC_CMD_WOUT); - while (inb(IO_KBD + KBSTATP) & KBS_IBF); - - if (on) - outb(IO_KBD + KBDATAP, KB_A20); - else - outb(IO_KBD + KBDATAP, 0xcd); - while (inb(IO_KBD + KBSTATP) & KBS_IBF); + if (getA20type() == A20_KBD) { + if (!gateA20kbd(on)) + return; + } - while (inb(IO_KBD + KBSTATP) & KBS_DIB) - (void)inb(IO_KBD + KBDATAP); + /* Try to use 0x92 to turn on A20 */ + if (on) { + data = inb(0x92); + outb(0x92, data | 0x2); + } else { + data = inb(0x92); + outb(0x92, data & ~0x2); } } |