Annotation of qemu/roms/ipxe/src/arch/i386/transitions/liba20.S, revision 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.