Annotation of qemu/roms/ipxe/src/arch/i386/transitions/liba20.S, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.