1 /* $NetBSD: gatea20.c,v 1.5 2002/08/12 14:27:34 thorpej Exp $ */ 2 3 /* extracted from freebsd:sys/i386/boot/biosboot/io.c */ 4 5 #include <sys/types.h> 6 #include <machine/pio.h> 7 8 #include <lib/libsa/stand.h> 9 10 #include "libi386.h" 11 #include "biosmca.h" 12 13 #define K_RDWR 0x60 /* keyboard data & cmds (read/write) */ 14 #define K_STATUS 0x64 /* keyboard status */ 15 #define K_CMD 0x64 /* keybd ctlr command (write-only) */ 16 17 #define K_OBUF_FUL 0x01 /* output buffer full */ 18 #define K_IBUF_FUL 0x02 /* input buffer full */ 19 20 #define KC_CMD_WIN 0xd0 /* read output port */ 21 #define KC_CMD_WOUT 0xd1 /* write output port */ 22 #define KB_A20 0x9f /* enable A20, 23 reset (!), 24 enable output buffer full interrupt 25 enable data line 26 disable clock line */ 27 28 /* 29 * Gate A20 for high memory 30 */ 31 static unsigned char x_20 = KB_A20; 32 void gateA20() 33 { 34 __asm("pushfl ; cli"); 35 /* 36 * Not all systems enable A20 via the keyboard controller. 37 * * IBM PS/2 L40 38 * * AMD Elan SC520-based systems 39 */ 40 if ( 41 #ifdef SUPPORT_PS2 42 biosmca_ps2model == 0xf82 || 43 #endif 44 /* XXX How to check for AMD Elan SC520? */ 45 0) { 46 outb(0x92, 0x2); 47 } else { 48 while (inb(K_STATUS) & K_IBUF_FUL); 49 while (inb(K_STATUS) & K_OBUF_FUL) 50 (void)inb(K_RDWR); 51 52 outb(K_CMD, KC_CMD_WOUT); 53 delay(100); 54 while (inb(K_STATUS) & K_IBUF_FUL); 55 outb(K_RDWR, x_20); 56 delay(100); 57 while (inb(K_STATUS) & K_IBUF_FUL); 58 } 59 __asm("popfl"); 60 } 61