david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[prefix] Add PCI bus:dev.fn to ROM product string

This allows multiple gPXE ROMs in a system to be disambiguated at boot
time; the PCI ID will show up in the boot menu for a BBS-compliant BIOS.
This commit is contained in:
Michael Brown 2008-05-21 18:43:58 +01:00
parent f3aef4d98d
commit fd0aef9ee1
3 changed files with 131 additions and 95 deletions

View File

@ -48,10 +48,9 @@
* *
* Parameters: * Parameters:
* %al : character to print * %al : character to print
* %ds:di : output buffer (or %di=0 to print to console)
* Returns: * Returns:
* Nothing * %ds:di : next character in output buffer (if applicable)
* Corrupts:
* %ax
***************************************************************************** *****************************************************************************
*/ */
.section ".prefix.lib" .section ".prefix.lib"
@ -59,19 +58,27 @@
.globl print_character .globl print_character
print_character: print_character:
/* Preserve registers */ /* Preserve registers */
pushw %ax
pushw %bx pushw %bx
pushw %bp pushw %bp
/* Print character */ /* If %di is non-zero, write character to buffer and exit */
testw %di, %di
jz 1f
movb %al, %ds:(%di)
incw %di
jmp 3f
1: /* Print character */
movw $0x0007, %bx /* page 0, attribute 7 (normal) */ movw $0x0007, %bx /* page 0, attribute 7 (normal) */
movb $0x0e, %ah /* write char, tty mode */ movb $0x0e, %ah /* write char, tty mode */
cmpb $0x0a, %al /* '\n'? */ cmpb $0x0a, %al /* '\n'? */
jne 1f jne 2f
int $0x10 int $0x10
movb $0x0d, %al movb $0x0d, %al
1: int $0x10 2: int $0x10
/* Restore registers and return */ /* Restore registers and return */
popw %bp 3: popw %bp
popw %bx popw %bx
popw %ax
ret ret
.size print_character, . - print_character .size print_character, . - print_character
@ -80,8 +87,10 @@ print_character:
* *
* Parameters: * Parameters:
* %ds:si : string to print * %ds:si : string to print
* %ds:di : output buffer (or %di=0 to print to console)
* Returns: * Returns:
* %ds:si : character after terminating NUL * %ds:si : character after terminating NUL
* %ds:di : next character in output buffer (if applicable)
***************************************************************************** *****************************************************************************
*/ */
.section ".prefix.lib" .section ".prefix.lib"
@ -109,8 +118,9 @@ print_message:
* %al : byte to print * %al : byte to print
* %ax : word to print * %ax : word to print
* %eax : dword to print * %eax : dword to print
* %ds:di : output buffer (or %di=0 to print to console)
* Returns: * Returns:
* Nothing * %ds:di : next character in output buffer (if applicable)
***************************************************************************** *****************************************************************************
*/ */
.section ".prefix.lib" .section ".prefix.lib"
@ -151,6 +161,44 @@ print_hex_nibble:
ret ret
.size print_hex_nibble, . - print_hex_nibble .size print_hex_nibble, . - print_hex_nibble
/*****************************************************************************
* Utility function: print PCI bus:dev.fn
*
* Parameters:
* %ax : PCI bus:dev.fn to print
* %ds:di : output buffer (or %di=0 to print to console)
* Returns:
* %ds:di : next character in output buffer (if applicable)
*****************************************************************************
*/
.section ".prefix.lib"
.code16
.globl print_pci_busdevfn
print_pci_busdevfn:
/* Preserve registers */
pushw %ax
/* Print bus */
xchgb %al, %ah
call print_hex_byte
/* Print ":" */
movb $':', %al
call print_character
/* Print device */
movb %ah, %al
shrb $3, %al
call print_hex_byte
/* Print "." */
movb $'.', %al
call print_character
/* Print function */
movb %ah, %al
andb $0x07, %al
call print_hex_nibble
/* Restore registers and return */
popw %ax
ret
.size print_pci_busdevfn, . - print_pci_busdevfn
/**************************************************************************** /****************************************************************************
* pm_call (real-mode near call) * pm_call (real-mode near call)
* *

View File

@ -37,6 +37,7 @@
cld cld
/* Print welcome message */ /* Print welcome message */
movw $10f, %si movw $10f, %si
xorw %di, %di
call print_message call print_message
.section ".prefix.data" .section ".prefix.data"
10: .asciz "PXE->EB:" 10: .asciz "PXE->EB:"
@ -48,24 +49,23 @@
*/ */
detect_pxenv: detect_pxenv:
/* Signature check */ /* Signature check */
les pxenv_segoff, %di les pxenv_segoff, %bx
cmpl $0x4e455850, %es:(%di) /* 'PXEN' signature */ cmpl $0x4e455850, %es:(%bx) /* 'PXEN' signature */
jne no_pxenv jne no_pxenv
cmpw $0x2b56, %es:4(%di) /* 'V+' signature */ cmpw $0x2b56, %es:4(%bx) /* 'V+' signature */
jne no_pxenv jne no_pxenv
/* Record entry point and UNDI segments */ /* Record entry point and UNDI segments */
pushl %es:0x0a(%di) /* Entry point */ pushl %es:0x0a(%bx) /* Entry point */
popl entry_segoff popl entry_segoff
pushw %es:0x24(%di) /* UNDI code segment */ pushw %es:0x24(%bx) /* UNDI code segment */
pushw %es:0x26(%di) /* UNDI code size */ pushw %es:0x26(%bx) /* UNDI code size */
popl undi_code_segoff popl undi_code_segoff
pushw %es:0x20(%di) /* UNDI data segment */ pushw %es:0x20(%bx) /* UNDI data segment */
pushw %es:0x22(%di) /* UNDI data size */ pushw %es:0x22(%bx) /* UNDI data size */
popl undi_data_segoff popl undi_data_segoff
/* Print "PXENV+ at <address>" */ /* Print "PXENV+ at <address>" */
movw $10f, %si movw $10f, %si
call print_message call print_message
movw %bx, %di
call print_segoff call print_segoff
movb $',', %al movb $',', %al
call print_character call print_character
@ -86,20 +86,20 @@ no_pxenv:
*/ */
detect_ppxe: detect_ppxe:
/* Signature check */ /* Signature check */
les ppxe_segoff, %di les ppxe_segoff, %bx
cmpl $0x45585021, %es:(%di) /* '!PXE' signature */ cmpl $0x45585021, %es:(%bx) /* '!PXE' signature */
jne no_ppxe jne no_ppxe
/* Record structure address, entry point, and UNDI segments */ /* Record structure address, entry point, and UNDI segments */
pushw %es pushw %es
popw ppxe_segment popw ppxe_segment
movw %di, ppxe_offset movw %bx, ppxe_offset
pushl %es:0x10(%di) /* Entry point */ pushl %es:0x10(%bx) /* Entry point */
popl entry_segoff popl entry_segoff
pushw %es:0x30(%di) /* UNDI code segment */ pushw %es:0x30(%bx) /* UNDI code segment */
pushw %es:0x36(%di) /* UNDI code size */ pushw %es:0x36(%bx) /* UNDI code size */
popl undi_code_segoff popl undi_code_segoff
pushw %es:0x28(%di) /* UNDI data segment */ pushw %es:0x28(%bx) /* UNDI data segment */
pushw %es:0x2e(%di) /* UNDI data size */ pushw %es:0x2e(%bx) /* UNDI data size */
popl undi_data_segoff popl undi_data_segoff
/* Print "!PXE at <address>" */ /* Print "!PXE at <address>" */
movw $10f, %si movw $10f, %si
@ -167,7 +167,7 @@ print_structure_information:
/* Print entry point */ /* Print entry point */
movw $10f, %si movw $10f, %si
call print_message call print_message
les entry_segoff, %di les entry_segoff, %bx
call print_segoff call print_segoff
.section ".prefix.data" .section ".prefix.data"
10: .asciz " entry point at " 10: .asciz " entry point at "
@ -175,7 +175,7 @@ print_structure_information:
/* Print UNDI code segment */ /* Print UNDI code segment */
movw $10f, %si movw $10f, %si
call print_message call print_message
les undi_code_segoff, %di les undi_code_segoff, %bx
call print_segoff call print_segoff
.section ".prefix.data" .section ".prefix.data"
10: .asciz "\n UNDI code segment " 10: .asciz "\n UNDI code segment "
@ -183,7 +183,7 @@ print_structure_information:
/* Print UNDI data segment */ /* Print UNDI data segment */
movw $10f, %si movw $10f, %si
call print_message call print_message
les undi_data_segoff, %di les undi_data_segoff, %bx
call print_segoff call print_segoff
.section ".prefix.data" .section ".prefix.data"
10: .asciz ", data segment " 10: .asciz ", data segment "
@ -271,8 +271,8 @@ unload_base_code:
call print_pxe_error call print_pxe_error
jmp 99f jmp 99f
1: /* Free base memory used by PXE base code */ 1: /* Free base memory used by PXE base code */
movw %fs:(0x13), %si movw undi_fbms_start, %ax
movw undi_fbms_start, %di movw %fs:(0x13), %bx
call free_basemem call free_basemem
99: 99:
@ -289,8 +289,8 @@ unload_undi:
call print_pxe_error call print_pxe_error
jmp 99f jmp 99f
1: /* Free base memory used by UNDI */ 1: /* Free base memory used by UNDI */
movw undi_fbms_start, %si movw undi_fbms_end, %ax
movw undi_fbms_end, %di movw undi_fbms_start, %bx
call free_basemem call free_basemem
/* Clear UNDI_FL_STARTED */ /* Clear UNDI_FL_STARTED */
andw $~UNDI_FL_STARTED, flags andw $~UNDI_FL_STARTED, flags
@ -324,9 +324,10 @@ finished:
* Subroutine: print segment:offset address * Subroutine: print segment:offset address
* *
* Parameters: * Parameters:
* %es:%di : segment:offset address to print * %es:%bx : segment:offset address to print
* %ds:di : output buffer (or %di=0 to print to console)
* Returns: * Returns:
* Nothing * %ds:di : next character in output buffer (if applicable)
***************************************************************************** *****************************************************************************
*/ */
print_segoff: print_segoff:
@ -337,7 +338,7 @@ print_segoff:
call print_hex_word call print_hex_word
movb $':', %al movb $':', %al
call print_character call print_character
movw %di, %ax movw %bx, %ax
call print_hex_word call print_hex_word
/* Restore registers and return */ /* Restore registers and return */
popw %ax popw %ax
@ -348,8 +349,9 @@ print_segoff:
* *
* Parameters: * Parameters:
* %ax : word to print * %ax : word to print
* %ds:di : output buffer (or %di=0 to print to console)
* Returns: * Returns:
* Nothing * %ds:di : next character in output buffer (if applicable)
***************************************************************************** *****************************************************************************
*/ */
print_word: print_word:
@ -378,44 +380,11 @@ print_word:
popw %ax popw %ax
ret ret
/*****************************************************************************
* Subroutine: print PCI bus:dev.fn
*
* Parameters:
* %ax : PCI bus:dev.fn to print
* Returns:
* Nothing
*****************************************************************************
*/
print_pci_busdevfn:
/* Preserve registers */
pushw %ax
/* Print bus */
xchgb %al, %ah
call print_hex_byte
/* Print ":" */
movb $':', %al
call print_character
/* Print device */
movb %ah, %al
shrb $3, %al
call print_hex_byte
/* Print "." */
movb $'.', %al
call print_character
/* Print function */
movb %ah, %al
andb $0x07, %al
call print_hex_nibble
/* Restore registers and return */
popw %ax
ret
/***************************************************************************** /*****************************************************************************
* Subroutine: zero 1kB block of base memory * Subroutine: zero 1kB block of base memory
* *
* Parameters: * Parameters:
* %si : block to zero (in kB) * %bx : block to zero (in kB)
* Returns: * Returns:
* Nothing * Nothing
***************************************************************************** *****************************************************************************
@ -427,7 +396,7 @@ zero_kb:
pushw %di pushw %di
pushw %es pushw %es
/* Zero block */ /* Zero block */
movw %si, %ax movw %bx, %ax
shlw $6, %ax shlw $6, %ax
movw %ax, %es movw %ax, %es
movw $0x400, %cx movw $0x400, %cx
@ -445,33 +414,31 @@ zero_kb:
* Subroutine: free and zero base memory * Subroutine: free and zero base memory
* *
* Parameters: * Parameters:
* %si : Expected current free base memory counter (in kB) * %ax : Desired new free base memory counter (in kB)
* %di : Desired new free base memory counter (in kB) * %bx : Expected current free base memory counter (in kB)
* %fs : BIOS data segment (0x40) * %fs : BIOS data segment (0x40)
* Returns: * Returns:
* %ax : Actual new free base memory counter (in kB) * None
* *
* The base memory from %si kB to %di kB is unconditionally zeroed. * The base memory from %bx kB to %ax kB is unconditionally zeroed.
* It will be freed if and only if the expected current free base * It will be freed if and only if the expected current free base
* memory counter (%si) matches the actual current free base memory * memory counter (%bx) matches the actual current free base memory
* counter in 0x40:0x13; if this does not match then the memory will * counter in 0x40:0x13; if this does not match then the memory will
* be leaked. * be leaked.
***************************************************************************** *****************************************************************************
*/ */
free_basemem: free_basemem:
/* Zero base memory */ /* Zero base memory */
pushw %si pushw %bx
1: cmpw %si, %di 1: cmpw %bx, %ax
je 2f je 2f
call zero_kb call zero_kb
incw %si incw %bx
jmp 1b jmp 1b
2: popw %si 2: popw %bx
/* Free base memory */ /* Free base memory */
movw %fs:(0x13), %ax /* Current FBMS to %ax */ cmpw %fs:(0x13), %bx /* Update FBMS only if "old" value */
cmpw %ax, %si /* Update FBMS only if "old" value */
jne 1f /* is correct */ jne 1f /* is correct */
movw %di, %ax
1: movw %ax, %fs:(0x13) 1: movw %ax, %fs:(0x13)
ret ret

View File

@ -85,11 +85,24 @@ pnpheader:
.equ pnpheader_len, . - pnpheader .equ pnpheader_len, . - pnpheader
.size pnpheader, . - pnpheader .size pnpheader, . - pnpheader
/* Manufacturer string */
mfgstr: mfgstr:
.asciz "http://etherboot.org" .asciz "http://etherboot.org"
.size mfgstr, . - mfgstr .size mfgstr, . - 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.
*/
prodstr: prodstr:
.asciz "gPXE" .ascii "gPXE"
prodstr_separator:
.byte 0
.ascii "(PCI "
prodstr_pci_id:
.asciz "xx:xx.x)" /* Filled in by init code */
.size prodstr, . - prodstr .size prodstr, . - prodstr
undiheader: undiheader:
@ -120,24 +133,31 @@ init:
cld cld
pushw %cs pushw %cs
popw %ds popw %ds
movw %di, %bx
xorw %di, %di
/* Print message as early as possible */ /* Print message as early as possible */
movw $init_message, %si movw $init_message, %si
call print_message call print_message
call print_pci_busdevfn
/* Fill in product name string, if possible */
movw $prodstr_pci_id, %di
call print_pci_busdevfn
movb $' ', prodstr_separator
xorw %di, %di
/* Check for PnP BIOS */ /* Check for PnP BIOS */
testw $0x0f, %di /* PnP signature must be aligned - bochs */ testw $0x0f, %bx /* PnP signature must be aligned - bochs */
jnz hook_int19 /* uses unalignment to indicate 'fake' PnP. */ jnz hook_int19 /* uses unalignment to indicate 'fake' PnP. */
cmpl $PNP_SIGNATURE, %es:0(%di) cmpl $PNP_SIGNATURE, %es:0(%bx)
jne hook_int19 jne hook_int19
/* Is PnP: print PnP message */ /* Is PnP: print PnP message */
movw $init_message_pnp, %si movw $init_message_pnp, %si
call print_message call print_message
xchgw %bx, %bx
/* Check for BBS */ /* Check for BBS */
pushw %es:0x1b(%di) /* Real-mode data segment */ pushw %es:0x1b(%bx) /* Real-mode data segment */
pushw %ds /* &(bbs_version) */ pushw %ds /* &(bbs_version) */
pushw $bbs_version pushw $bbs_version
pushw $PNP_GET_BBS_VERSION pushw $PNP_GET_BBS_VERSION
lcall *%es:0xd(%di) lcall *%es:0xd(%bx)
addw $8, %sp addw $8, %sp
testw %ax, %ax testw %ax, %ax
jne hook_int19 jne hook_int19
@ -155,18 +175,18 @@ hook_int19:
popl %es:( 0x19 * 4 ) popl %es:( 0x19 * 4 )
hook_bbs: hook_bbs:
/* Check for PMM */ /* Check for PMM */
movw $( 0xe000 - 1 ), %di movw $( 0xe00 - 1 ), %bx
pmm_scan: pmm_scan:
incw %di incw %bx
jz no_pmm jz no_pmm
movw %di, %es movw %bx, %es
cmpl $PMM_SIGNATURE, %es:0 cmpl $PMM_SIGNATURE, %es:0
jne pmm_scan jne pmm_scan
xorw %bx, %bx xorw %dx, %dx
xorw %si, %si xorw %si, %si
movzbw %es:5, %cx movzbw %es:5, %cx
1: es lodsb 1: es lodsb
addb %al, %bl addb %al, %dl
loop 1b loop 1b
jnz pmm_scan jnz pmm_scan
/* PMM found: print PMM message */ /* PMM found: print PMM message */
@ -221,7 +241,7 @@ no_pmm:
.size init, . - init .size init, . - init
init_message: init_message:
.asciz "gPXE (http://etherboot.org) -" .asciz "gPXE (http://etherboot.org) - PCI "
.size init_message, . - init_message .size init_message, . - init_message
init_message_pnp: init_message_pnp:
.asciz " PnP" .asciz " PnP"
@ -292,6 +312,7 @@ exec: /* Set %ds = %cs */
/* Print message as soon as possible */ /* Print message as soon as possible */
movw $exec_message, %si movw $exec_message, %si
xorw %di, %di
call print_message call print_message
/* Store magic word on BIOS stack and remember BIOS %ss:sp */ /* Store magic word on BIOS stack and remember BIOS %ss:sp */