Annotation of qemu/roms/ipxe/src/arch/i386/prefix/libprefix.S, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2006 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: /* Image compression enabled */
                     25: #define COMPRESS 1
                     26: 
                     27: /* Protected mode flag */
                     28: #define CR0_PE 1
                     29: 
                     30: /* Allow for DBG()-style messages within libprefix */
                     31: #ifdef NDEBUG
                     32:        .macro  progress message
                     33:        .endm
                     34: #else
                     35:        .macro  progress message
                     36:        pushfl
                     37:        pushw   %ds
                     38:        pushw   %si
                     39:        pushw   %di
                     40:        pushw   %cs
                     41:        popw    %ds
                     42:        xorw    %di, %di
                     43:        movw    $progress_\@, %si
                     44:        call    print_message
                     45:        popw    %di
                     46:        popw    %si
                     47:        popw    %ds
                     48:        popfl
                     49:        .section ".prefix.data", "aw", @progbits
                     50: progress_\@:
                     51:        .asciz  "\message"
                     52:        .size   progress_\@, . - progress\@
                     53:        .previous
                     54:        .endm
                     55: #endif
                     56: 
                     57: /*****************************************************************************
                     58:  * Utility function: print character (with LF -> LF,CR translation)
                     59:  *
                     60:  * Parameters:
                     61:  *   %al : character to print
                     62:  *   %ds:di : output buffer (or %di=0 to print to console)
                     63:  * Returns:
                     64:  *   %ds:di : next character in output buffer (if applicable)
                     65:  *****************************************************************************
                     66:  */
                     67:        .section ".prefix.lib", "awx", @progbits
                     68:        .code16
                     69:        .globl  print_character
                     70: print_character:
                     71:        /* Preserve registers */
                     72:        pushw   %ax
                     73:        pushw   %bx
                     74:        pushw   %bp
                     75:        /* If %di is non-zero, write character to buffer and exit */
                     76:        testw   %di, %di
                     77:        jz      1f
                     78:        movb    %al, %ds:(%di)
                     79:        incw    %di
                     80:        jmp     3f
                     81: 1:     /* Print character */
                     82:        movw    $0x0007, %bx            /* page 0, attribute 7 (normal) */
                     83:        movb    $0x0e, %ah              /* write char, tty mode */
                     84:        cmpb    $0x0a, %al              /* '\n'? */
                     85:        jne     2f
                     86:        int     $0x10
                     87:        movb    $0x0d, %al
                     88: 2:     int     $0x10
                     89:        /* Restore registers and return */
                     90: 3:     popw    %bp
                     91:        popw    %bx
                     92:        popw    %ax
                     93:        ret
                     94:        .size   print_character, . - print_character
                     95: 
                     96: /*****************************************************************************
                     97:  * Utility function: print a NUL-terminated string
                     98:  *
                     99:  * Parameters:
                    100:  *   %ds:si : string to print
                    101:  *   %ds:di : output buffer (or %di=0 to print to console)
                    102:  * Returns:
                    103:  *   %ds:si : character after terminating NUL
                    104:  *   %ds:di : next character in output buffer (if applicable)
                    105:  *****************************************************************************
                    106:  */
                    107:        .section ".prefix.lib", "awx", @progbits
                    108:        .code16
                    109:        .globl  print_message
                    110: print_message:
                    111:        /* Preserve registers */
                    112:        pushw   %ax
                    113:        /* Print string */
                    114: 1:     lodsb
                    115:        testb   %al, %al
                    116:        je      2f
                    117:        call    print_character
                    118:        jmp     1b
                    119: 2:     /* Restore registers and return */
                    120:        popw    %ax
                    121:        ret
                    122:        .size   print_message, . - print_message
                    123: 
                    124: /*****************************************************************************
                    125:  * Utility functions: print hex digit/byte/word/dword
                    126:  *
                    127:  * Parameters:
                    128:  *   %al (low nibble) : digit to print
                    129:  *   %al : byte to print
                    130:  *   %ax : word to print
                    131:  *   %eax : dword to print
                    132:  *   %ds:di : output buffer (or %di=0 to print to console)
                    133:  * Returns:
                    134:  *   %ds:di : next character in output buffer (if applicable)
                    135:  *****************************************************************************
                    136:  */
                    137:        .section ".prefix.lib", "awx", @progbits
                    138:        .code16
                    139:        .globl  print_hex_dword
                    140: print_hex_dword:
                    141:        rorl    $16, %eax
                    142:        call    print_hex_word
                    143:        rorl    $16, %eax
                    144:        /* Fall through */
                    145:        .size   print_hex_dword, . - print_hex_dword
                    146:        .globl  print_hex_word
                    147: print_hex_word:
                    148:        xchgb   %al, %ah
                    149:        call    print_hex_byte
                    150:        xchgb   %al, %ah
                    151:        /* Fall through */
                    152:        .size   print_hex_word, . - print_hex_word
                    153:        .globl  print_hex_byte
                    154: print_hex_byte:
                    155:        rorb    $4, %al
                    156:        call    print_hex_nibble
                    157:        rorb    $4, %al
                    158:        /* Fall through */
                    159:        .size   print_hex_byte, . - print_hex_byte
                    160:        .globl  print_hex_nibble
                    161: print_hex_nibble:
                    162:        /* Preserve registers */
                    163:        pushw   %ax
                    164:        /* Print digit (technique by Norbert Juffa <[email protected]> */
                    165:        andb    $0x0f, %al
                    166:        cmpb    $10, %al
                    167:        sbbb    $0x69, %al
                    168:        das
                    169:        call    print_character
                    170:        /* Restore registers and return */
                    171:        popw    %ax
                    172:        ret
                    173:        .size   print_hex_nibble, . - print_hex_nibble
                    174: 
                    175: /*****************************************************************************
                    176:  * Utility function: print PCI bus:dev.fn
                    177:  *
                    178:  * Parameters:
                    179:  *   %ax : PCI bus:dev.fn to print
                    180:  *   %ds:di : output buffer (or %di=0 to print to console)
                    181:  * Returns:
                    182:  *   %ds:di : next character in output buffer (if applicable)
                    183:  *****************************************************************************
                    184:  */
                    185:        .section ".prefix.lib", "awx", @progbits
                    186:        .code16
                    187:        .globl  print_pci_busdevfn
                    188: print_pci_busdevfn:
                    189:        /* Preserve registers */
                    190:        pushw   %ax
                    191:        /* Print bus */
                    192:        xchgb   %al, %ah
                    193:        call    print_hex_byte
                    194:        /* Print ":" */
                    195:        movb    $( ':' ), %al
                    196:        call    print_character
                    197:        /* Print device */
                    198:        movb    %ah, %al
                    199:        shrb    $3, %al
                    200:        call    print_hex_byte
                    201:        /* Print "." */
                    202:        movb    $( '.' ), %al
                    203:        call    print_character
                    204:        /* Print function */
                    205:        movb    %ah, %al
                    206:        andb    $0x07, %al
                    207:        call    print_hex_nibble
                    208:        /* Restore registers and return */
                    209:        popw    %ax
                    210:        ret
                    211:        .size   print_pci_busdevfn, . - print_pci_busdevfn
                    212: 
                    213: /*****************************************************************************
                    214:  * Utility function: clear current line
                    215:  *
                    216:  * Parameters:
                    217:  *   %ds:di : output buffer (or %di=0 to print to console)
                    218:  * Returns:
                    219:  *   %ds:di : next character in output buffer (if applicable)
                    220:  *****************************************************************************
                    221:  */
                    222:        .section ".prefix.lib", "awx", @progbits
                    223:        .code16
                    224:        .globl  print_kill_line
                    225: print_kill_line:
                    226:        /* Preserve registers */
                    227:        pushw   %ax
                    228:        pushw   %cx
                    229:        /* Print CR */
                    230:        movb    $( '\r' ), %al
                    231:        call    print_character
                    232:        /* Print 79 spaces */
                    233:        movb    $( ' ' ), %al
                    234:        movw    $79, %cx
                    235: 1:     call    print_character
                    236:        loop    1b
                    237:        /* Print CR */
                    238:        movb    $( '\r' ), %al
                    239:        call    print_character
                    240:        /* Restore registers and return */
                    241:        popw    %cx
                    242:        popw    %ax
                    243:        ret
                    244:        .size   print_kill_line, . - print_kill_line
                    245: 
                    246: /****************************************************************************
                    247:  * copy_bytes
                    248:  *
                    249:  * Copy bytes
                    250:  *
                    251:  * Parameters:
                    252:  *   %ds:esi : source address
                    253:  *   %es:edi : destination address
                    254:  *   %ecx : length
                    255:  * Returns:
                    256:  *   %ds:esi : next source address
                    257:  *   %es:edi : next destination address
                    258:  * Corrupts:
                    259:  *   None
                    260:  ****************************************************************************
                    261:  */
                    262:        .section ".prefix.lib", "awx", @progbits
                    263:        .code16
                    264: copy_bytes:
                    265:        pushl   %ecx
                    266:        rep addr32 movsb
                    267:        popl    %ecx
                    268:        ret
                    269:        .size   copy_bytes, . - copy_bytes
                    270: 
                    271: /****************************************************************************
                    272:  * zero_bytes
                    273:  *
                    274:  * Zero bytes
                    275:  *
                    276:  * Parameters:
                    277:  *   %ds:esi : source address
                    278:  *   %es:edi : destination address
                    279:  *   %ecx : length
                    280:  * Returns:
                    281:  *   %ds:esi : next source address
                    282:  *   %es:edi : next destination address
                    283:  * Corrupts:
                    284:  *   None
                    285:  ****************************************************************************
                    286:  */
                    287:        .section ".prefix.lib", "awx", @progbits
                    288:        .code16
                    289: zero_bytes:
                    290:        pushl   %ecx
                    291:        pushw   %ax
                    292:        xorw    %ax, %ax
                    293:        rep addr32 stosb
                    294:        popw    %ax
                    295:        popl    %ecx
                    296:        ret
                    297:        .size   zero_bytes, . - zero_bytes
                    298: 
                    299: /****************************************************************************
                    300:  * process_bytes
                    301:  *
                    302:  * Call memcpy()-like function
                    303:  *
                    304:  * Parameters:
                    305:  *   %esi : source physical address
                    306:  *   %edi : destination physical address
                    307:  *   %ecx : length
                    308:  *   %bx : memcpy()-like function to call, passing parameters:
                    309:  *          %ds:esi : source address
                    310:  *          %es:edi : destination address
                    311:  *          %ecx : length
                    312:  *         and returning:
                    313:  *          %ds:esi : next source address
                    314:  *          %es:edi : next destination address
                    315:  * Returns:
                    316:  *   %esi : next source physical address
                    317:  *   %edi : next destination physical address
                    318:  * Corrupts:
                    319:  *   None
                    320:  ****************************************************************************
                    321:  */
                    322:        .section ".prefix.lib", "awx", @progbits
                    323:        .code16
                    324: process_bytes:
                    325: 
                    326: #ifndef KEEP_IT_REAL
                    327: 
                    328:        /* Preserve registers */
                    329:        pushfw
                    330:        pushl   %eax
                    331:        pushl   %ebp
                    332: 
                    333:        /* Construct GDT on stack (since .prefix may not be writable) */
                    334:        .equ    PM_DS, 0x18     /* Flat data segment */
                    335:        pushl   $0x00cf9300
                    336:        pushl   $0x0000ffff
                    337:        .equ    PM_SS, 0x10     /* Stack segment based at %ss:0000 */
                    338:        pushl   $0x008f0930
                    339:        pushw   %ss
                    340:        pushw   $0xffff
                    341:        .equ    PM_CS, 0x08     /* Code segment based at %cs:0000 */
                    342:        pushl   $0x008f09b0
                    343:        pushw   %cs
                    344:        pushw   $0xffff
                    345:        pushl   $0              /* Base and length */
                    346:        pushw   %ss
                    347:        pushw   $0x1f
                    348:        movzwl  %sp, %ebp
                    349:        shll    $4, 0x02(%bp)
                    350:        addl    %ebp, 0x02(%bp)
                    351:        shll    $4, 0x0a(%bp)
                    352:        shll    $4, 0x12(%bp)
                    353:        subw    $8, %sp
                    354:        sgdt    -8(%bp)
                    355: 
                    356:        /* Switch to protected mode */
                    357:        pushw   %gs
                    358:        pushw   %fs
                    359:        pushw   %es
                    360:        pushw   %ds
                    361:        pushw   %ss
                    362:        pushw   %cs
                    363:        pushw   $2f
                    364:        cli
                    365:        data32 lgdt (%bp)
                    366:        movl    %cr0, %eax
                    367:        orb     $CR0_PE, %al
                    368:        movl    %eax, %cr0
                    369:        ljmp    $PM_CS, $1f
                    370: 1:     movw    $PM_SS, %ax
                    371:        movw    %ax, %ss
                    372:        movw    $PM_DS, %ax
                    373:        movw    %ax, %ds
                    374:        movw    %ax, %es
                    375:        movw    %ax, %fs
                    376:        movw    %ax, %gs
                    377: 
                    378:        /* Call memcpy()-like function */
                    379:        call    *%bx
                    380: 
                    381:        /* Return to (flat) real mode */
                    382:        movl    %cr0, %eax
                    383:        andb    $0!CR0_PE, %al
                    384:        movl    %eax, %cr0
                    385:        lret
                    386: 2:     /* lret will ljmp to here */
                    387:        popw    %ss
                    388:        popw    %ds
                    389:        popw    %es
                    390:        popw    %fs
                    391:        popw    %gs
                    392: 
                    393:        /* Restore GDT */
                    394:        data32 lgdt -8(%bp)
                    395:        addw    $( 8 /* saved GDT */ + ( PM_DS + 8 ) /* GDT on stack */ ), %sp
                    396: 
                    397:        /* Restore registers and return */
                    398:        popl    %ebp
                    399:        popl    %eax
                    400:        popfw
                    401:        ret
                    402: 
                    403: #else /* KEEP_IT_REAL */
                    404: 
                    405:        /* Preserve registers */
                    406:        pushl   %eax
                    407:        pushw   %ds
                    408:        pushw   %es
                    409:        
                    410:        /* Convert %esi and %edi to %ds:esi and %es:edi */
                    411:        shrl    $4, %esi
                    412:        movw    %si, %ds
                    413:        xorw    %si, %si
                    414:        shll    $4, %esi
                    415:        shrl    $4, %edi
                    416:        movw    %di, %es
                    417:        xorw    %di, %di
                    418:        shll    $4, %edi
                    419: 
                    420:        /* Call memcpy()-like function */
                    421:        call    *%bx
                    422: 
                    423:        /* Convert %ds:esi and %es:edi back to physical addresses */
                    424:        xorl    %eax, %eax
                    425:        movw    %ds, %cx
                    426:        shll    $4, %eax
                    427:        addl    %eax, %esi
                    428:        xorl    %eax, %eax
                    429:        movw    %es, %cx
                    430:        shll    $4, %eax
                    431:        addl    %eax, %edi
                    432: 
                    433:        /* Restore registers and return */
                    434:        popw    %es
                    435:        popw    %ds
                    436:        popl    %eax
                    437:        ret
                    438: 
                    439: #endif /* KEEP_IT_REAL */
                    440: 
                    441:        .size   process_bytes, . - process_bytes
                    442: 
                    443: /****************************************************************************
                    444:  * install_block
                    445:  *
                    446:  * Install block to specified address
                    447:  *
                    448:  * Parameters:
                    449:  *   %esi : source physical address (must be a multiple of 16)
                    450:  *   %edi : destination physical address (must be a multiple of 16)
                    451:  *   %ecx : length of (decompressed) data
                    452:  *   %edx : total length of block (including any uninitialised data portion)
                    453:  * Returns:
                    454:  *   %esi : next source physical address (will be a multiple of 16)
                    455:  *   %edi : next destination physical address (will be a multiple of 16)
                    456:  * Corrupts:
                    457:  *   none
                    458:  ****************************************************************************
                    459:  */
                    460:        .section ".prefix.lib", "awx", @progbits
                    461:        .code16
                    462: install_block:
                    463:        /* Preserve registers */
                    464:        pushl   %ecx
                    465:        pushw   %bx
                    466: 
                    467:        /* Decompress (or copy) source to destination */
                    468: #if COMPRESS
                    469:        movw    $decompress16, %bx
                    470: #else
                    471:        movw    $copy_bytes, %bx
                    472: #endif
                    473:        call    process_bytes
                    474: 
                    475:        /* Zero .bss portion */
                    476:        negl    %ecx
                    477:        addl    %edx, %ecx
                    478:        movw    $zero_bytes, %bx
                    479:        call    process_bytes
                    480: 
                    481:        /* Round up %esi and %edi to start of next blocks */
                    482:        addl    $0xf, %esi
                    483:        andl    $~0xf, %esi
                    484:        addl    $0xf, %edi
                    485:        andl    $~0xf, %edi
                    486: 
                    487:        /* Restore registers and return */
                    488:        popw    %bx
                    489:        popl    %ecx
                    490:        ret
                    491:        .size install_block, . - install_block
                    492: 
                    493: /****************************************************************************
                    494:  * alloc_basemem
                    495:  *
                    496:  * Allocate space for .text16 and .data16 from top of base memory.
                    497:  * Memory is allocated using the BIOS free base memory counter at
                    498:  * 0x40:13.
                    499:  *
                    500:  * Parameters: 
                    501:  *   none
                    502:  * Returns:
                    503:  *   %ax : .text16 segment address
                    504:  *   %bx : .data16 segment address
                    505:  * Corrupts:
                    506:  *   none
                    507:  ****************************************************************************
                    508:  */
                    509:        .section ".prefix.lib", "awx", @progbits
                    510:        .code16
                    511:        .globl  alloc_basemem
                    512: alloc_basemem:
                    513:        /* Preserve registers */
                    514:        pushw   %fs
                    515: 
                    516:        /* FBMS => %ax as segment address */
                    517:        pushw   $0x40
                    518:        popw    %fs
                    519:        movw    %fs:0x13, %ax
                    520:        shlw    $6, %ax
                    521: 
                    522:        /* Calculate .data16 segment address */
                    523:        subw    $_data16_memsz_pgh, %ax
                    524:        pushw   %ax
                    525: 
                    526:        /* Calculate .text16 segment address */
                    527:        subw    $_text16_memsz_pgh, %ax
                    528:        pushw   %ax
                    529: 
                    530:        /* Update FBMS */
                    531:        shrw    $6, %ax
                    532:        movw    %ax, %fs:0x13
                    533: 
                    534:        /* Retrieve .text16 and .data16 segment addresses */
                    535:        popw    %ax
                    536:        popw    %bx
                    537: 
                    538:        /* Restore registers and return */
                    539:        popw    %fs
                    540:        ret
                    541:        .size alloc_basemem, . - alloc_basemem
                    542: 
                    543: /****************************************************************************
                    544:  * free_basemem
                    545:  *
                    546:  * Free space allocated with alloc_basemem.
                    547:  *
                    548:  * Parameters:
                    549:  *   %ax : .text16 segment address
                    550:  *   %bx : .data16 segment address
                    551:  * Returns:
                    552:  *   %ax : 0 if successfully freed
                    553:  * Corrupts:
                    554:  *   none
                    555:  ****************************************************************************
                    556:  */
                    557:        .section ".text16", "ax", @progbits
                    558:        .code16
                    559:        .globl  free_basemem
                    560: free_basemem:
                    561:        /* Preserve registers */
                    562:        pushw   %fs
                    563: 
                    564:        /* Check FBMS counter */
                    565:        pushw   %ax
                    566:        shrw    $6, %ax
                    567:        pushw   $0x40
                    568:        popw    %fs
                    569:        cmpw    %ax, %fs:0x13
                    570:        popw    %ax
                    571:        jne     1f
                    572: 
                    573:        /* Check hooked interrupt count */
                    574:        cmpw    $0, %cs:hooked_bios_interrupts
                    575:        jne     1f
                    576: 
                    577:        /* OK to free memory */
                    578:        addw    $_text16_memsz_pgh, %ax
                    579:        addw    $_data16_memsz_pgh, %ax
                    580:        shrw    $6, %ax
                    581:        movw    %ax, %fs:0x13
                    582:        xorw    %ax, %ax
                    583: 
                    584: 1:     /* Restore registers and return */
                    585:        popw    %fs
                    586:        ret
                    587:        .size free_basemem, . - free_basemem
                    588: 
                    589:        .section ".text16.data", "aw", @progbits
                    590:        .globl  hooked_bios_interrupts
                    591: hooked_bios_interrupts:
                    592:        .word   0
                    593:        .size   hooked_bios_interrupts, . - hooked_bios_interrupts
                    594: 
                    595: /****************************************************************************
                    596:  * install
                    597:  *
                    598:  * Install all text and data segments.
                    599:  *
                    600:  * Parameters:
                    601:  *   none
                    602:  * Returns:
                    603:  *   %ax  : .text16 segment address
                    604:  *   %bx  : .data16 segment address
                    605:  * Corrupts:
                    606:  *   none
                    607:  ****************************************************************************
                    608:  */
                    609:        .section ".prefix.lib", "awx", @progbits
                    610:        .code16
                    611:        .globl install
                    612: install:
                    613:        progress "install:\n"
                    614:        /* Preserve registers */
                    615:        pushl   %esi
                    616:        pushl   %edi
                    617:        /* Allocate space for .text16 and .data16 */
                    618:        call    alloc_basemem
                    619:        /* Image source = %cs:0000 */
                    620:        xorl    %esi, %esi
                    621:        /* Image destination = default */
                    622:        xorl    %edi, %edi
                    623:        /* Allow relocation */
                    624:        clc
                    625:        /* Install text and data segments */
                    626:        call    install_prealloc
                    627:        /* Restore registers and return */
                    628:        popl    %edi
                    629:        popl    %esi
                    630:        ret
                    631:        .size install, . - install
                    632: 
                    633: /****************************************************************************
                    634:  * install_prealloc
                    635:  *
                    636:  * Install all text and data segments.
                    637:  *
                    638:  * Parameters:
                    639:  *   %ax  : .text16 segment address
                    640:  *   %bx  : .data16 segment address
                    641:  *   %esi : Image source physical address (or zero for %cs:0000)
                    642:  *   %edi : Decompression temporary area physical address (or zero for default)
                    643:  *   CF set : Avoid relocating to top of memory
                    644:  * Corrupts:
                    645:  *   none
                    646:  ****************************************************************************
                    647:  */
                    648:        .section ".prefix.lib", "awx", @progbits
                    649:        .code16
                    650:        .globl install_prealloc
                    651: install_prealloc:
                    652:        progress "install_prealloc:\n"
                    653:        /* Save registers */
                    654:        pushal
                    655:        pushw   %ds
                    656:        pushw   %es
                    657:        cld                     /* Sanity: clear the direction flag asap */
                    658:        pushfw
                    659: 
                    660:        /* Set up %ds for (read-only) access to .prefix */
                    661:        pushw   %cs
                    662:        popw    %ds
                    663: 
                    664:        /* Copy decompression temporary area physical address to %ebp */
                    665:        movl    %edi, %ebp
                    666: 
                    667:        /* Install .text16.early */
                    668:        progress "  .text16.early\n"
                    669:        pushl   %esi
                    670:        xorl    %esi, %esi
                    671:        movw    %cs, %si
                    672:        shll    $4, %esi
                    673:        addl    $_text16_early_lma, %esi
                    674:        movzwl  %ax, %edi
                    675:        shll    $4, %edi
                    676:        movl    $_text16_early_filesz, %ecx
                    677:        movl    $_text16_early_memsz, %edx
                    678:        call    install_block           /* .text16.early */
                    679:        popl    %esi
                    680: 
                    681: #ifndef KEEP_IT_REAL
                    682:        /* Access high memory by enabling the A20 gate.  (We will
                    683:         * already have 4GB segment limits as a result of calling
                    684:         * install_block.)
                    685:         */
                    686:        progress "  access_highmem\n"
                    687:        pushw   %cs
                    688:        pushw   $1f
                    689:        pushw   %ax
                    690:        pushw   $access_highmem
                    691:        lret
                    692: 1:     /* Die if we could not access high memory */
                    693:        jnc     3f
                    694:        movw    $a20_death_message, %si
                    695:        xorw    %di, %di
                    696:        call    print_message
                    697: 2:     jmp     2b
                    698:        .section ".prefix.data", "aw", @progbits
                    699: a20_death_message:
                    700:        .asciz  "\nHigh memory inaccessible - cannot continue\n"
                    701:        .size   a20_death_message, . - a20_death_message
                    702:        .previous
                    703: 3:
                    704: #endif
                    705: 
                    706:        /* Open payload (which may not yet be in memory) */
                    707:        progress "  open_payload\n"
                    708:        pushw   %cs
                    709:        pushw   $1f
                    710:        pushw   %ax
                    711:        pushw   $open_payload
                    712:        lret
                    713: 1:     /* Die if we could not access the payload */
                    714:        jnc     3f
                    715:        xorw    %di, %di
                    716:        movl    %esi, %eax
                    717:        call    print_hex_dword
                    718:        movw    $payload_death_message, %si
                    719:        call    print_message
                    720: 2:     jmp     2b
                    721:        .section ".prefix.data", "aw", @progbits
                    722: payload_death_message:
                    723:        .asciz  "\nPayload inaccessible - cannot continue\n"
                    724:        .size   payload_death_message, . - payload_death_message
                    725:        .previous
                    726: 3:
                    727: 
                    728:        /* Calculate physical address of payload (i.e. first source) */
                    729:        testl   %esi, %esi
                    730:        jnz     1f
                    731:        movw    %cs, %si
                    732:        shll    $4, %esi
                    733: 1:     addl    payload_lma, %esi
                    734: 
                    735:        /* Install .text16.late and .data16 */
                    736:        progress "  .text16.late\n"
                    737:        movl    $_text16_late_filesz, %ecx
                    738:        movl    $_text16_late_memsz, %edx
                    739:        call    install_block           /* .text16.late */
                    740:        progress "  .data16\n"
                    741:        movzwl  %bx, %edi
                    742:        shll    $4, %edi
                    743:        movl    $_data16_filesz, %ecx
                    744:        movl    $_data16_memsz, %edx
                    745:        call    install_block           /* .data16 */
                    746: 
                    747:        /* Set up %ds for access to .data16 */
                    748:        movw    %bx, %ds
                    749: 
                    750: #ifdef KEEP_IT_REAL
                    751:        /* Initialise libkir */
                    752:        movw    %ax, (init_libkir_vector+2)
                    753:        lcall   *init_libkir_vector
                    754: #else
                    755:        /* Find a suitable decompression temporary area, if none specified */
                    756:        pushl   %eax
                    757:        testl   %ebp, %ebp
                    758:        jnz     1f
                    759:        /* Use INT 15,88 to find the highest available address via INT
                    760:         * 15,88.  This limits us to around 64MB, which should avoid
                    761:         * all of the POST-time memory map failure modes.
                    762:         */
                    763:        movb    $0x88, %ah
                    764:        int     $0x15
                    765:        movw    %ax, %bp
                    766:        addl    $0x400, %ebp
                    767:        subl    $_textdata_memsz_kb, %ebp
                    768:        shll    $10, %ebp
                    769:        /* Sanity check: if we have ended up below 1MB, use 1MB */
                    770:        cmpl    $0x100000, %ebp
                    771:        jae     1f
                    772:        movl    $0x100000, %ebp
                    773: 1:     popl    %eax
                    774: 
                    775:        /* Install .text and .data to temporary area in high memory,
                    776:         * prior to reading the E820 memory map and relocating
                    777:         * properly.
                    778:         */
                    779:        progress "  .textdata\n"
                    780:        movl    %ebp, %edi
                    781:        movl    $_textdata_filesz, %ecx
                    782:        movl    $_textdata_memsz, %edx
                    783:        call    install_block
                    784: 
                    785:        /* Initialise librm at current location */
                    786:        progress "  init_librm\n"
                    787:        movw    %ax, (init_librm_vector+2)
                    788:        movl    %ebp, %edi
                    789:        lcall   *init_librm_vector
                    790: 
                    791:        /* Skip relocation if CF was set on entry */
                    792:        popfw
                    793:        pushfw
                    794:        jc      skip_relocate
                    795: 
                    796:        /* Call relocate() to determine target address for relocation.
                    797:         * relocate() will return with %esi, %edi and %ecx set up
                    798:         * ready for the copy to the new location.
                    799:         */
                    800:        progress "  relocate\n"
                    801:        movw    %ax, (prot_call_vector+2)
                    802:        pushl   $relocate
                    803:        lcall   *prot_call_vector
                    804:        popl    %edx /* discard */
                    805: 
                    806:        /* Copy code to new location */
                    807:        progress "  copy\n"
                    808:        pushl   %edi
                    809:        pushw   %bx
                    810:        movw    $copy_bytes, %bx
                    811:        call    process_bytes
                    812:        popw    %bx
                    813:        popl    %edi
                    814: 
                    815:        /* Initialise librm at new location */
                    816:        progress "  init_librm\n"
                    817:        lcall   *init_librm_vector
                    818: skip_relocate:
                    819: #endif
                    820: 
                    821:        /* Close access to payload */
                    822:        progress "  close_payload\n"
                    823:        movw    %ax, (close_payload_vector+2)
                    824:        lcall   *close_payload_vector
                    825: 
                    826:        /* Restore registers */
                    827:        popfw
                    828:        popw    %es
                    829:        popw    %ds
                    830:        popal
                    831:        ret
                    832:        .size install_prealloc, . - install_prealloc
                    833: 
                    834:        /* Vectors for far calls to .text16 functions.  Must be in
                    835:         * .data16, since .prefix may not be writable.
                    836:         */
                    837:        .section ".data16", "aw", @progbits
                    838: #ifdef KEEP_IT_REAL
                    839: init_libkir_vector:
                    840:        .word init_libkir
                    841:        .word 0
                    842:        .size init_libkir_vector, . - init_libkir_vector
                    843: #else
                    844: init_librm_vector:
                    845:        .word init_librm
                    846:        .word 0
                    847:        .size init_librm_vector, . - init_librm_vector
                    848: prot_call_vector:
                    849:        .word prot_call
                    850:        .word 0
                    851:        .size prot_call_vector, . - prot_call_vector
                    852: #endif
                    853: close_payload_vector:
                    854:        .word close_payload
                    855:        .word 0
                    856:        .size close_payload_vector, . - close_payload_vector
                    857: 
                    858:        /* Payload address */
                    859:        .section ".prefix.lib", "awx", @progbits
                    860: payload_lma:
                    861:        .long 0
                    862:        .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
                    863:        .ascii  "ADHL"
                    864:        .long   payload_lma
                    865:        .long   1
                    866:        .long   0
                    867:        .previous
                    868: 
                    869:        /* Dummy routines to open and close payload */
                    870:        .section ".text16.early.data", "aw", @progbits
                    871:        .weak   open_payload
                    872:        .weak   close_payload
                    873: open_payload:
                    874: close_payload:
                    875:        clc
                    876:        lret
                    877:        .size   open_payload, . - open_payload
                    878:        .size   close_payload, . - close_payload
                    879: 
                    880: /****************************************************************************
                    881:  * uninstall
                    882:  *
                    883:  * Uninstall all text and data segments.
                    884:  *
                    885:  * Parameters:
                    886:  *   %ax  : .text16 segment address
                    887:  *   %bx  : .data16 segment address
                    888:  * Returns:
                    889:  *   none
                    890:  * Corrupts:
                    891:  *   none
                    892:  ****************************************************************************
                    893:  */
                    894:        .section ".text16", "ax", @progbits
                    895:        .code16
                    896:        .globl uninstall
                    897: uninstall:
                    898:        call    free_basemem
                    899:        ret
                    900:        .size uninstall, . - uninstall
                    901: 
                    902: 
                    903: 
                    904:        /* File split information for the compressor */
                    905: #if COMPRESS
                    906: #define PACK_OR_COPY   "PACK"
                    907: #else
                    908: #define PACK_OR_COPY   "COPY"
                    909: #endif
                    910:        .section ".zinfo", "a", @progbits
                    911:        .ascii  "COPY"
                    912:        .long   _prefix_lma
                    913:        .long   _prefix_filesz
                    914:        .long   _max_align
                    915:        .ascii  PACK_OR_COPY
                    916:        .long   _text16_early_lma
                    917:        .long   _text16_early_filesz
                    918:        .long   _max_align
                    919:        .ascii  "PAYL"
                    920:        .long   0
                    921:        .long   0
                    922:        .long   _max_align
                    923:        .ascii  PACK_OR_COPY
                    924:        .long   _text16_late_lma
                    925:        .long   _text16_late_filesz
                    926:        .long   _max_align
                    927:        .ascii  PACK_OR_COPY
                    928:        .long   _data16_lma
                    929:        .long   _data16_filesz
                    930:        .long   _max_align
                    931:        .ascii  PACK_OR_COPY
                    932:        .long   _textdata_lma
                    933:        .long   _textdata_filesz
                    934:        .long   _max_align

unix.superglobalmegacorp.com

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