|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2010 Michael Brown <[email protected]>. ! 3: * ! 4: * This program is free software; you can redistribute it and/or ! 5: * modify it under the terms of the GNU General Public License as ! 6: * published by the Free Software Foundation; either version 2 of the ! 7: * License, or any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, but ! 10: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 12: * General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with this program; if not, write to the Free Software ! 16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 17: * ! 18: */ ! 19: ! 20: FILE_LICENCE ( GPL2_OR_LATER ) ! 21: ! 22: .arch i386 ! 23: ! 24: /**************************************************************************** ! 25: * test_a20_short, test_a20_long ! 26: * ! 27: * Check to see if A20 line is enabled ! 28: * ! 29: * Parameters: ! 30: * none ! 31: * Returns: ! 32: * CF set if A20 line is not enabled ! 33: * Corrupts: ! 34: * none ! 35: **************************************************************************** ! 36: */ ! 37: #define TEST_A20_SHORT_MAX_RETRIES 0x20 ! 38: #define TEST_A20_LONG_MAX_RETRIES 0x200000 ! 39: .section ".text16.early", "awx", @progbits ! 40: .code16 ! 41: test_a20_short: ! 42: pushl %ecx ! 43: movl $TEST_A20_SHORT_MAX_RETRIES, %ecx ! 44: jmp 1f ! 45: .size test_a20_short, . - test_a20_short ! 46: test_a20_long: ! 47: pushl %ecx ! 48: movl $TEST_A20_LONG_MAX_RETRIES, %ecx ! 49: 1: pushw %ax ! 50: pushw %ds ! 51: pushw %es ! 52: ! 53: /* Set up segment registers for access across the 1MB boundary */ ! 54: xorw %ax, %ax ! 55: movw %ax, %ds ! 56: decw %ax ! 57: movw %ax, %es ! 58: ! 59: 2: /* Modify and check test pattern; succeed if we see a difference */ ! 60: pushfw ! 61: cli ! 62: xchgw %ds:0, %cx ! 63: movw %es:0x10, %ax ! 64: xchgw %ds:0, %cx ! 65: popfw ! 66: cmpw %ax, %cx ! 67: clc ! 68: jnz 99f ! 69: ! 70: /* Delay and retry */ ! 71: outb %al, $0x80 ! 72: addr32 loop 2b ! 73: stc ! 74: ! 75: 99: /* Restore registers and return */ ! 76: popw %es ! 77: popw %ds ! 78: popw %ax ! 79: popl %ecx ! 80: ret ! 81: .size test_a20_long, . - test_a20_long ! 82: ! 83: /**************************************************************************** ! 84: * enable_a20_bios ! 85: * ! 86: * Try enabling A20 line via BIOS ! 87: * ! 88: * Parameters: ! 89: * none ! 90: * Returns: ! 91: * CF set if A20 line is not enabled ! 92: * Corrupts: ! 93: * none ! 94: **************************************************************************** ! 95: */ ! 96: .section ".text16.early", "awx", @progbits ! 97: .code16 ! 98: enable_a20_bios: ! 99: /* Preserve registers */ ! 100: pushw %ax ! 101: ! 102: /* Attempt INT 15,2401 */ ! 103: movw $0x2401, %ax ! 104: int $0x15 ! 105: jc 99f ! 106: ! 107: /* Check that success was really successful */ ! 108: call test_a20_short ! 109: ! 110: 99: /* Restore registers and return */ ! 111: popw %ax ! 112: ret ! 113: .size enable_a20_bios, . - enable_a20_bios ! 114: ! 115: /**************************************************************************** ! 116: * enable_a20_kbc ! 117: * ! 118: * Try enabling A20 line via keyboard controller ! 119: * ! 120: * Parameters: ! 121: * none ! 122: * Returns: ! 123: * CF set if A20 line is not enabled ! 124: * Corrupts: ! 125: * none ! 126: **************************************************************************** ! 127: */ ! 128: #define KC_RDWR 0x60 ! 129: #define KC_RDWR_SET_A20 0xdf ! 130: #define KC_CMD 0x64 ! 131: #define KC_CMD_WOUT 0xd1 ! 132: #define KC_CMD_NULL 0xff ! 133: #define KC_STATUS 0x64 ! 134: #define KC_STATUS_OBUF_FULL 0x01 ! 135: #define KC_STATUS_IBUF_FULL 0x02 ! 136: #define KC_MAX_RETRIES 100000 ! 137: .section ".text16.early", "awx", @progbits ! 138: .code16 ! 139: enable_a20_kbc: ! 140: /* Preserve registers */ ! 141: pushw %ax ! 142: ! 143: /* Try keyboard controller */ ! 144: call empty_kbc ! 145: movb $KC_CMD_WOUT, %al ! 146: outb %al, $KC_CMD ! 147: call empty_kbc ! 148: movb $KC_RDWR_SET_A20, %al ! 149: outb %al, $KC_RDWR ! 150: call empty_kbc ! 151: movb $KC_CMD_NULL, %al ! 152: outb %al, $KC_CMD ! 153: call empty_kbc ! 154: ! 155: /* Check to see if it worked */ ! 156: call test_a20_long ! 157: ! 158: /* Restore registers and return */ ! 159: popw %ax ! 160: ret ! 161: .size enable_a20_kbc, . - enable_a20_kbc ! 162: ! 163: .section ".text16.early", "awx", @progbits ! 164: .code16 ! 165: empty_kbc: ! 166: /* Preserve registers */ ! 167: pushl %ecx ! 168: pushw %ax ! 169: ! 170: /* Wait for KBC to become empty */ ! 171: movl $KC_MAX_RETRIES, %ecx ! 172: 1: outb %al, $0x80 ! 173: inb $KC_STATUS, %al ! 174: testb $( KC_STATUS_OBUF_FULL | KC_STATUS_IBUF_FULL ), %al ! 175: jz 99f ! 176: testb $KC_STATUS_OBUF_FULL, %al ! 177: jz 2f ! 178: outb %al, $0x80 ! 179: inb $KC_RDWR, %al ! 180: 2: addr32 loop 1b ! 181: ! 182: 99: /* Restore registers and return */ ! 183: popw %ax ! 184: popl %ecx ! 185: ret ! 186: .size empty_kbc, . - empty_kbc ! 187: ! 188: /**************************************************************************** ! 189: * enable_a20_fast ! 190: * ! 191: * Try enabling A20 line via "Fast Gate A20" ! 192: * ! 193: * Parameters: ! 194: * none ! 195: * Returns: ! 196: * CF set if A20 line is not enabled ! 197: * Corrupts: ! 198: * none ! 199: **************************************************************************** ! 200: */ ! 201: #define SCP_A 0x92 ! 202: .section ".text16.early", "awx", @progbits ! 203: .code16 ! 204: enable_a20_fast: ! 205: /* Preserve registers */ ! 206: pushw %ax ! 207: ! 208: /* Try "Fast Gate A20" */ ! 209: inb $SCP_A, %al ! 210: orb $0x02, %al ! 211: andb $~0x01, %al ! 212: outb %al, $SCP_A ! 213: ! 214: /* Check to see if it worked */ ! 215: call test_a20_long ! 216: ! 217: /* Restore registers and return */ ! 218: popw %ax ! 219: ret ! 220: .size enable_a20_fast, . - enable_a20_fast ! 221: ! 222: /**************************************************************************** ! 223: * enable_a20 ! 224: * ! 225: * Try enabling A20 line via any available method ! 226: * ! 227: * Parameters: ! 228: * none ! 229: * Returns: ! 230: * CF set if A20 line is not enabled ! 231: * Corrupts: ! 232: * none ! 233: **************************************************************************** ! 234: */ ! 235: #define ENABLE_A20_RETRIES 255 ! 236: .section ".text16.early", "awx", @progbits ! 237: .code16 ! 238: .globl enable_a20 ! 239: enable_a20: ! 240: /* Preserve registers */ ! 241: pushl %ecx ! 242: pushw %ax ! 243: ! 244: /* Check to see if A20 is already enabled */ ! 245: call test_a20_short ! 246: jnc 99f ! 247: ! 248: /* Use known working method, if we have one */ ! 249: movw %cs:enable_a20_method, %ax ! 250: testw %ax, %ax ! 251: jz 1f ! 252: call *%ax ! 253: jmp 99f ! 254: 1: ! 255: /* Try all methods in turn until one works */ ! 256: movl $ENABLE_A20_RETRIES, %ecx ! 257: 2: movw $enable_a20_bios, %ax ! 258: movw %ax, %cs:enable_a20_method ! 259: call *%ax ! 260: jnc 99f ! 261: movw $enable_a20_kbc, %ax ! 262: movw %ax, %cs:enable_a20_method ! 263: call *%ax ! 264: jnc 99f ! 265: movw $enable_a20_fast, %ax ! 266: movw %ax, %cs:enable_a20_method ! 267: call *%ax ! 268: jnc 99f ! 269: addr32 loop 2b ! 270: /* Failure; exit with carry set */ ! 271: movw $0, %cs:enable_a20_method ! 272: stc ! 273: ! 274: 99: /* Restore registers and return */ ! 275: popw %ax ! 276: popl %ecx ! 277: ret ! 278: ! 279: .section ".text16.early.data", "aw", @progbits ! 280: .align 2 ! 281: enable_a20_method: ! 282: .word 0 ! 283: .size enable_a20_method, . - enable_a20_method ! 284: ! 285: /**************************************************************************** ! 286: * access_highmem (real mode far call) ! 287: * ! 288: * Open up access to high memory with A20 enabled ! 289: * ! 290: * Parameters: ! 291: * none ! 292: * Returns: ! 293: * CF set if high memory could not be accessed ! 294: * Corrupts: ! 295: * none ! 296: **************************************************************************** ! 297: */ ! 298: .section ".text16.early", "awx", @progbits ! 299: .code16 ! 300: .globl access_highmem ! 301: access_highmem: ! 302: /* Enable A20 line */ ! 303: call enable_a20 ! 304: lret ! 305: .size access_highmem, . - access_highmem
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.