|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1995-1994 The University of Utah and ! 3: * the Computer Systems Laboratory at the University of Utah (CSL). ! 4: * All rights reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software is hereby ! 7: * granted provided that (1) source code retains these copyright, permission, ! 8: * and disclaimer notices, and (2) redistributions including binaries ! 9: * reproduce the notices in supporting documentation, and (3) all advertising ! 10: * materials mentioning features or use of this software display the following ! 11: * acknowledgement: ``This product includes software developed by the ! 12: * Computer Systems Laboratory at the University of Utah.'' ! 13: * ! 14: * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS ! 15: * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF ! 16: * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 17: * ! 18: * CSL requests users of this software to return to [email protected] any ! 19: * improvements that they make and grant CSL redistribution rights. ! 20: * ! 21: * Author: Bryan Ford, University of Utah CSL ! 22: */ ! 23: ! 24: ! 25: #include <mach/machine/pio.h> ! 26: #include <mach/machine/code16.h> ! 27: ! 28: #include "i16_a20.h" ! 29: ! 30: ! 31: /* Keyboard stuff for turning on the A20 address line (gak!). */ ! 32: #define K_RDWR 0x60 /* keyboard data & cmds (read/write) */ ! 33: #define K_STATUS 0x64 /* keyboard status (read-only) */ ! 34: #define K_CMD 0x64 /* keybd ctlr command (write-only) */ ! 35: ! 36: #define K_OBUF_FUL 0x01 /* output buffer full */ ! 37: #define K_IBUF_FUL 0x02 /* input buffer full */ ! 38: ! 39: #define KC_CMD_WIN 0xd0 /* read output port */ ! 40: #define KC_CMD_WOUT 0xd1 /* write output port */ ! 41: ! 42: #define KB_ENABLE_A20 0xdf /* Linux and my BIOS uses this, ! 43: and I trust them more than Mach 3.0, ! 44: but I'd like to know what the difference is ! 45: and if it matters. */ ! 46: /*0x9f*/ /* enable A20, ! 47: enable output buffer full interrupt ! 48: enable data line ! 49: disable clock line */ ! 50: #define KB_DISABLE_A20 0xdd ! 51: ! 52: ! 53: CODE16 ! 54: ! 55: ! 56: /* ! 57: This routine ensures that the keyboard command queue is empty ! 58: (after emptying the output buffers) ! 59: ! 60: No timeout is used - if this hangs there is something wrong with ! 61: the machine, and we probably couldn't proceed anyway. ! 62: XXX should at least die properly ! 63: */ ! 64: static void i16_empty_8042(void) ! 65: { ! 66: int status; ! 67: ! 68: retry: ! 69: i16_nanodelay(1000); ! 70: status = i16_inb(K_STATUS); ! 71: ! 72: if (status & K_OBUF_FUL) ! 73: { ! 74: i16_nanodelay(1000); ! 75: i16_inb(K_RDWR); ! 76: goto retry; ! 77: } ! 78: ! 79: if (status & K_IBUF_FUL) ! 80: goto retry; ! 81: } ! 82: ! 83: int i16_raw_test_a20(void); ! 84: ! 85: /* Enable the A20 address line. */ ! 86: void i16_raw_enable_a20(void) ! 87: { ! 88: int v; ! 89: ! 90: /* XXX try int 15h function 24h */ ! 91: ! 92: if (i16_raw_test_a20()) ! 93: return; ! 94: ! 95: /* PS/2 */ ! 96: v = i16_inb(0x92); ! 97: i16_nanodelay(1000); ! 98: i16_outb(0x92,v | 2); ! 99: ! 100: if (i16_raw_test_a20()) ! 101: return; ! 102: ! 103: /* AT */ ! 104: i16_empty_8042(); ! 105: i16_outb(K_CMD, KC_CMD_WOUT); ! 106: i16_empty_8042(); ! 107: i16_outb(K_RDWR, KB_ENABLE_A20); ! 108: i16_empty_8042(); ! 109: ! 110: /* Wait until the a20 line gets enabled. */ ! 111: while (!i16_raw_test_a20()); ! 112: } ! 113: ! 114: /* Disable the A20 address line. */ ! 115: void i16_raw_disable_a20(void) ! 116: { ! 117: int v; ! 118: ! 119: if (!i16_raw_test_a20()) ! 120: return; ! 121: ! 122: /* PS/2 */ ! 123: v = i16_inb(0x92); ! 124: i16_nanodelay(1000); ! 125: i16_outb(0x92, v & ~2); ! 126: ! 127: if (!i16_raw_test_a20()) ! 128: return; ! 129: ! 130: /* AT */ ! 131: i16_empty_8042(); ! 132: i16_outb(K_CMD, KC_CMD_WOUT); ! 133: i16_empty_8042(); ! 134: i16_outb(K_RDWR, KB_DISABLE_A20); ! 135: i16_empty_8042(); ! 136: ! 137: /* Wait until the a20 line gets disabled. */ ! 138: while (i16_raw_test_a20()); ! 139: } ! 140: ! 141: ! 142: void (*i16_enable_a20)(void) = i16_raw_enable_a20; ! 143: void (*i16_disable_a20)(void) = i16_raw_disable_a20; ! 144:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.