summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>2001-08-18 02:00:50 +0000
committerConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>2001-08-18 02:00:50 +0000
commitf4293c1086d231c860bc4bd5fce6b9a061d60beb (patch)
tree4974241d004f1362f9408283a7b1e66c99bf11b7 /sys
parent51c6f5e0f5f6f300b649e518110808b2b6142098 (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.c73
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);
}
}