1 /* $OpenBSD: gateA20.c,v 1.11 2017/09/08 05:36:52 deraadt 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 <machine/pio.h> 33 #include <dev/ic/i8042reg.h> 34 #include <dev/isa/isareg.h> 35 36 #include "libsa.h" 37 38 #define KB_A20 0xdf /* enable A20, 39 enable output buffer full interrupt 40 enable data line 41 enable clock line */ 42 43 44 /* 45 * "Probe"-style routine (no parameters) to turn A20 on 46 */ 47 void 48 gateA20on(void) 49 { 50 gateA20(1); 51 } 52 53 54 /* 55 * Gate A20 for high memory 56 */ 57 void 58 gateA20(int on) 59 { 60 if (ps2model == 0xf82 || 61 (inb(IO_KBD + KBSTATP) == 0xff && inb(IO_KBD + KBDATAP) == 0xff)) { 62 int data; 63 64 /* Try to use 0x92 to turn on A20 */ 65 if (on) { 66 data = inb(0x92); 67 outb(0x92, data | 0x2); 68 } else { 69 data = inb(0x92); 70 outb(0x92, data & ~0x2); 71 } 72 } else { 73 74 while (inb(IO_KBD + KBSTATP) & KBS_IBF); 75 76 while (inb(IO_KBD + KBSTATP) & KBS_DIB) 77 (void)inb(IO_KBD + KBDATAP); 78 79 outb(IO_KBD + KBCMDP, KBC_CMDWOUT); 80 while (inb(IO_KBD + KBSTATP) & KBS_IBF); 81 82 if (on) 83 outb(IO_KBD + KBDATAP, KB_A20); 84 else 85 outb(IO_KBD + KBDATAP, 0xcd); 86 while (inb(IO_KBD + KBSTATP) & KBS_IBF); 87 88 while (inb(IO_KBD + KBSTATP) & KBS_DIB) 89 (void)inb(IO_KBD + KBDATAP); 90 } 91 } 92