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