diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-12-12 14:36:02 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-12-14 13:56:44 -0800 |
commit | e2ab9215d792d07cfb725de290f416e331b87627 (patch) | |
tree | 7fbf2b3f921ef78b277f5d89c1a9a14960a49edc /gpxe/src/arch/i386/prefix/romprefix.S | |
parent | 36390f9712ac56be1dce7a635322bd96e15620c1 (diff) | |
download | syslinux-e2ab9215d792d07cfb725de290f416e331b87627.tar.gz |
gPXE: update to the "kkpxe" branchkkpxe
Update gPXE to the "kkpxe" branch, an experimental branch of the gPXE
tree which should let us eliminate the gpxelinux-specific hacks.
Specifically, this corresponds to checkin
0963c883a9402bd5846e687a100e196f7e8a2ef7 of
git://git.etherboot.org/scm/people/mcb30/gpxe.git.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'gpxe/src/arch/i386/prefix/romprefix.S')
-rw-r--r-- | gpxe/src/arch/i386/prefix/romprefix.S | 162 |
1 files changed, 126 insertions, 36 deletions
diff --git a/gpxe/src/arch/i386/prefix/romprefix.S b/gpxe/src/arch/i386/prefix/romprefix.S index 92a931cd..a6431cd9 100644 --- a/gpxe/src/arch/i386/prefix/romprefix.S +++ b/gpxe/src/arch/i386/prefix/romprefix.S @@ -14,6 +14,7 @@ #define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) ) #define PNP_GET_BBS_VERSION 0x60 #define PMM_ALLOCATE 0x0000 +#define PMM_DEALLOCATE 0x0002 /* ROM banner timeout. Based on the configurable BANNER_TIMEOUT in * config.h, but converted to a number of (18Hz) timer ticks, and @@ -30,7 +31,7 @@ .org 0x00 romheader: .word 0xAA55 /* BIOS extension signature */ -romheader_size: .byte _load_size_sect /* Size in 512-byte blocks */ +romheader_size: .byte _filesz_sect /* Size in 512-byte blocks */ jmp init /* Initialisation vector */ checksum: .byte 0 @@ -42,7 +43,7 @@ checksum: .word pnpheader .size romheader, . - romheader - .section ".zinfo.fixup", "a" /* Compressor fixup information */ + .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ .ascii "SUBB" .long romheader_size .long 512 @@ -58,18 +59,18 @@ pciheader: .byte 0x03 /* PCI data structure revision */ .byte 0x02, 0x00, 0x00 /* Class code */ pciheader_image_length: - .word _load_size_sect /* Image length */ + .word _filesz_sect /* Image length */ .word 0x0001 /* Revision level */ .byte 0x00 /* Code type */ .byte 0x80 /* Last image indicator */ pciheader_runtime_length: - .word _load_size_sect /* Maximum run-time image length */ + .word _filesz_sect /* Maximum run-time image length */ .word 0x0000 /* Configuration utility code header */ .word 0x0000 /* DMTF CLP entry point */ .equ pciheader_len, . - pciheader .size pciheader, . - pciheader - .section ".zinfo.fixup", "a" /* Compressor fixup information */ + .section ".zinfo.fixup", "a", @progbits /* Compressor fixups */ .ascii "SUBW" .long pciheader_image_length .long 512 @@ -109,12 +110,12 @@ mfgstr: /* Product string * - * Defaults to "gPXE". If the ROM image is writable at initialisation - * time, it will be filled in to include the PCI bus:dev.fn number of - * the card as well. + * Defaults to PRODUCT_SHORT_NAME. If the ROM image is writable at + * initialisation time, it will be filled in to include the PCI + * bus:dev.fn number of the card as well. */ prodstr: - .ascii "gPXE" + .ascii PRODUCT_SHORT_NAME prodstr_separator: .byte 0 .ascii "(PCI " @@ -130,9 +131,9 @@ undiheader: .byte 0 /* Structure revision */ .byte 0,1,2 /* PXE version: 2.1.0 */ .word undiloader /* Offset to loader routine */ - .word _data16_size /* Stack segment size */ - .word _data16_size /* Data segment size */ - .word _text16_size /* Code segment size */ + .word _data16_memsz /* Stack segment size */ + .word _data16_memsz /* Data segment size */ + .word _text16_memsz /* Code segment size */ .ascii "PCIR" /* Bus type */ .equ undiheader_len, . - undiheader .size undiheader, . - undiheader @@ -190,11 +191,11 @@ init: stc movw $0xb101, %ax int $0x1a - jc 1f + jc no_pci3 cmpl $PCI_SIGNATURE, %edx - jne 1f + jne no_pci3 testb %ah, %ah - jnz 1f + jnz no_pci3 movw $init_message_pci, %si xorw %di, %di call print_message @@ -205,11 +206,33 @@ init: movb %bl, %al call print_hex_byte cmpb $3, %bh - jae 2f -1: /* PCI <3.0: set %gs (runtime segment) = %cs (init-time segment) */ + jb no_pci3 + /* PCI >=3.0: leave %gs as-is if sane */ + movw %gs, %ax + cmpw $0xa000, %ax /* Insane if %gs < 0xa000 */ + jb pci3_insane + movw %cs, %bx /* Sane if %cs == %gs */ + cmpw %bx, %ax + je 1f + movzbw romheader_size, %cx /* Sane if %cs+len <= %gs */ + shlw $5, %cx + addw %cx, %bx + cmpw %bx, %ax + jae 1f + movw %cs, %bx /* Sane if %gs+len <= %cs */ + addw %cx, %ax + cmpw %bx, %ax + jbe 1f +pci3_insane: /* PCI 3.0 with insane %gs value: print error and ignore %gs */ + movb $'!', %al + call print_character + movw %gs, %ax + call print_hex_word +no_pci3: + /* PCI <3.0: set %gs (runtime segment) = %cs (init-time segment) */ pushw %cs popw %gs -2: popl %edi +1: popl %edi popl %edx popl %ebx @@ -268,21 +291,52 @@ pmm_scan: movw $init_message_pmm, %si xorw %di, %di call print_message - /* Try to allocate 2MB block via PMM */ + /* We have PMM and so a 1kB stack: preserve upper register halves */ + pushal + /* Calculate required allocation size in %esi */ + movzbl romheader_size, %eax + shll $9, %eax + addl $_textdata_memsz, %eax + orw $0xffff, %ax /* Ensure allocation size is at least 64kB */ + bsrl %eax, %ecx + subw $15, %cx /* Round up and convert to 64kB count */ + movw $1, %si + shlw %cl, %si +pmm_loop: + /* Try to allocate block via PMM */ pushw $0x0006 /* Aligned, extended memory */ pushl $0xffffffff /* No handle */ - pushl $( 0x00200000 / 16 ) /* 2MB in paragraphs */ + movzwl %si, %eax + shll $12, %eax + pushl %eax /* Allocation size in paragraphs */ pushw $PMM_ALLOCATE lcall *%es:7 addw $12, %sp + /* Abort if allocation fails */ + testw %dx, %dx /* %ax==0 even on success, since align>=64kB */ + jz pmm_fail + /* If block has A20==1, free block and try again with twice + * the allocation size (and hence alignment). + */ + testw $0x0010, %dx + jz got_pmm + pushw %dx + pushw $0 + pushw $PMM_DEALLOCATE + lcall *%es:7 + addw $6, %sp + addw %si, %si + jmp pmm_loop +got_pmm: /* PMM allocation succeeded */ + movw %dx, ( image_source + 2 ) movw %dx, %ax xorw %di, %di call print_hex_word - movw %dx, ( image_source + 2 ) - testw %dx, %dx /* %ax==0 even on success, since align=2MB */ - jz no_pmm - /* PMM allocation succeeded: copy ROM to PMM block */ - pushal /* PMM presence implies 1kB stack */ + movb $'@', %al + call print_character + movw %si, %ax + call print_hex_byte + /* Copy ROM to PMM block */ xorw %ax, %ax movw %ax, %es movl image_source, %edi @@ -294,13 +348,15 @@ pmm_scan: /* Shrink ROM and update checksum */ xorw %bx, %bx xorw %si, %si - movw $_prefix_size_sect, %cx + movw $_prefix_memsz_sect, %cx movb %cl, romheader_size shlw $9, %cx 1: lodsb addb %al, %bl loop 1b subb %bl, checksum +pmm_fail: + /* Restore upper register halves */ popal no_pmm: @@ -324,23 +380,28 @@ no_pmm: movw $init_message_prompt, %si xorw %di, %di call print_message + movw $prodstr, %si + call print_message + movw $init_message_dots, %si + call print_message /* Wait for Ctrl-B */ movw $0xff02, %bx call wait_for_key /* Clear prompt */ pushf - movw $clear_message, %si xorw %di, %di + call print_kill_line + movw $init_message_done, %si call print_message popf - jnz 1f + jnz 2f /* Ctrl-B was pressed: invoke gPXE. The keypress will be * picked up by the initial shell prompt, and we will drop * into a shell. */ pushw %cs call exec -1: +2: /* Restore registers */ popw %gs popw %fs @@ -353,7 +414,26 @@ no_pmm: lret .size init, . - init +/* + * Note to hardware vendors: + * + * If you wish to brand this boot ROM, please do so by defining the + * strings PRODUCT_NAME and PRODUCT_SHORT_NAME in config/general.h. + * + * While nothing in the GPL prevents you from removing all references + * to gPXE or http://etherboot.org, we prefer you not to do so. + * + * If you have an OEM-mandated branding requirement that cannot be + * satisfied simply by defining PRODUCT_NAME and PRODUCT_SHORT_NAME, + * please contact us. + * + * [ Including an ASCII NUL in PRODUCT_NAME is considered to be + * bypassing the spirit of this request! ] + */ init_message: + .ascii "\n" + .ascii PRODUCT_NAME + .ascii "\n" .asciz "gPXE (http://etherboot.org) - " .size init_message, . - init_message init_message_pci: @@ -372,11 +452,14 @@ init_message_int19: .asciz " INT19" .size init_message_int19, . - init_message_int19 init_message_prompt: - .asciz "\nPress Ctrl-B to configure gPXE..." + .asciz "\nPress Ctrl-B to configure " .size init_message_prompt, . - init_message_prompt -clear_message: - .asciz "\r \n\n" - .size clear_message, . - clear_message +init_message_dots: + .asciz "..." + .size init_message_dots, . - init_message_dots +init_message_done: + .asciz "\n\n" + .size init_message_done, . - init_message_done /* ROM image location * @@ -432,8 +515,9 @@ int19_entry: movw $0xdf42, %bx call wait_for_key pushf - movw $clear_message, %si xorw %di, %di + call print_kill_line + movw $int19_message_done, %si call print_message popf jnz 1f @@ -460,6 +544,9 @@ int19_message_prompt: int19_message_dots: .asciz "..." .size int19_message_dots, . - int19_message_dots +int19_message_done: + .asciz "\n\n" + .size int19_message_done, . - int19_message_done /* Execute as a boot device * @@ -504,8 +591,11 @@ exec: /* Set %ds = %cs */ pushl $main pushw %cs call prot_call - /* No need to clean up stack; we are about to reload %ss:sp */ - + popl %ecx /* discard */ + + /* Uninstall gPXE */ + call uninstall + /* Restore BIOS stack */ movw %dx, %ss movw %bp, %sp |