1 /* $OpenBSD: gateA20.c,v 1.2 2004/03/21 21:37:41 tom Exp $ */ 2 3 /* 4 * Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 5 * 6 * Mach Operating System 7 * Copyright (c) 1992, 1991 Carnegie Mellon University 8 * All Rights Reserved. 9 * 10 * Permission to use, copy, modify and distribute this software and its 11 * documentation is hereby granted, provided that both the copyright 12 * notice and this permission notice appear in all copies of the 13 * software, derivative works or modified versions, and any portions 14 * thereof, and that both notices appear in supporting documentation. 15 * 16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 18 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 19 * 20 * Carnegie Mellon requests users of this software to return to 21 * 22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 23 * School of Computer Science 24 * Carnegie Mellon University 25 * Pittsburgh PA 15213-3890 26 * 27 * any improvements or extensions that they make and grant Carnegie Mellon 28 * the rights to redistribute these changes. 29 */ 30 31 #include <sys/param.h> 32 #include <sys/types.h> 33 #include <machine/pio.h> 34 #include <dev/ic/i8042reg.h> 35 #include <dev/isa/isareg.h> 36 37 #include "libsa.h" 38 39 int ps2model = 0; /* Not set in amd64 */ 40 41 #define KB_A20 0xdf /* enable A20, 42 enable output buffer full interrupt 43 enable data line 44 enable clock line */ 45 46 47 /* 48 * "Probe"-style routine (no parameters) to turn A20 on 49 */ 50 void 51 gateA20on(void) 52 { 53 gateA20(1); 54 } 55 56 57 /* 58 * Gate A20 for high memory 59 */ 60 void 61 gateA20(int on) 62 { 63 if (ps2model == 0xf82 || 64 (inb(IO_KBD + KBSTATP) == 0xff && inb(IO_KBD + KBDATAP) == 0xff)) { 65 int data; 66 67 /* Try to use 0x92 to turn on A20 */ 68 if (on) { 69 data = inb(0x92); 70 outb(0x92, data | 0x2); 71 } else { 72 data = inb(0x92); 73 outb(0x92, data & ~0x2); 74 } 75 } else { 76 77 while (inb(IO_KBD + KBSTATP) & KBS_IBF); 78 79 while (inb(IO_KBD + KBSTATP) & KBS_DIB) 80 (void)inb(IO_KBD + KBDATAP); 81 82 outb(IO_KBD + KBCMDP, KBC_CMDWOUT); 83 while (inb(IO_KBD + KBSTATP) & KBS_IBF); 84 85 if (on) 86 outb(IO_KBD + KBDATAP, KB_A20); 87 else 88 outb(IO_KBD + KBDATAP, 0xcd); 89 while (inb(IO_KBD + KBSTATP) & KBS_IBF); 90 91 while (inb(IO_KBD + KBSTATP) & KBS_DIB) 92 (void)inb(IO_KBD + KBDATAP); 93 } 94 } 95