From fd0aef9ee1df2e979993b05036c8330885fbccc1 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 21 May 2008 18:43:58 +0100 Subject: [PATCH] [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. --- src/arch/i386/prefix/libprefix.S | 64 ++++++++++++++--- src/arch/i386/prefix/pxeprefix.S | 117 +++++++++++-------------------- src/arch/i386/prefix/romprefix.S | 45 ++++++++---- 3 files changed, 131 insertions(+), 95 deletions(-) diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S index deea5ab3..cb091112 100644 --- a/src/arch/i386/prefix/libprefix.S +++ b/src/arch/i386/prefix/libprefix.S @@ -48,10 +48,9 @@ * * Parameters: * %al : character to print + * %ds:di : output buffer (or %di=0 to print to console) * Returns: - * Nothing - * Corrupts: - * %ax + * %ds:di : next character in output buffer (if applicable) ***************************************************************************** */ .section ".prefix.lib" @@ -59,19 +58,27 @@ .globl print_character print_character: /* Preserve registers */ + pushw %ax pushw %bx 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) */ movb $0x0e, %ah /* write char, tty mode */ cmpb $0x0a, %al /* '\n'? */ - jne 1f + jne 2f int $0x10 movb $0x0d, %al -1: int $0x10 +2: int $0x10 /* Restore registers and return */ - popw %bp +3: popw %bp popw %bx + popw %ax ret .size print_character, . - print_character @@ -80,8 +87,10 @@ print_character: * * Parameters: * %ds:si : string to print + * %ds:di : output buffer (or %di=0 to print to console) * Returns: * %ds:si : character after terminating NUL + * %ds:di : next character in output buffer (if applicable) ***************************************************************************** */ .section ".prefix.lib" @@ -109,8 +118,9 @@ print_message: * %al : byte to print * %ax : word to print * %eax : dword to print + * %ds:di : output buffer (or %di=0 to print to console) * Returns: - * Nothing + * %ds:di : next character in output buffer (if applicable) ***************************************************************************** */ .section ".prefix.lib" @@ -151,6 +161,44 @@ print_hex_nibble: ret .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) * diff --git a/src/arch/i386/prefix/pxeprefix.S b/src/arch/i386/prefix/pxeprefix.S index 6a8aeb3a..32ff2961 100644 --- a/src/arch/i386/prefix/pxeprefix.S +++ b/src/arch/i386/prefix/pxeprefix.S @@ -37,6 +37,7 @@ cld /* Print welcome message */ movw $10f, %si + xorw %di, %di call print_message .section ".prefix.data" 10: .asciz "PXE->EB:" @@ -48,24 +49,23 @@ */ detect_pxenv: /* Signature check */ - les pxenv_segoff, %di - cmpl $0x4e455850, %es:(%di) /* 'PXEN' signature */ + les pxenv_segoff, %bx + cmpl $0x4e455850, %es:(%bx) /* 'PXEN' signature */ jne no_pxenv - cmpw $0x2b56, %es:4(%di) /* 'V+' signature */ + cmpw $0x2b56, %es:4(%bx) /* 'V+' signature */ jne no_pxenv /* Record entry point and UNDI segments */ - pushl %es:0x0a(%di) /* Entry point */ + pushl %es:0x0a(%bx) /* Entry point */ popl entry_segoff - pushw %es:0x24(%di) /* UNDI code segment */ - pushw %es:0x26(%di) /* UNDI code size */ + pushw %es:0x24(%bx) /* UNDI code segment */ + pushw %es:0x26(%bx) /* UNDI code size */ popl undi_code_segoff - pushw %es:0x20(%di) /* UNDI data segment */ - pushw %es:0x22(%di) /* UNDI data size */ + pushw %es:0x20(%bx) /* UNDI data segment */ + pushw %es:0x22(%bx) /* UNDI data size */ popl undi_data_segoff /* Print "PXENV+ at
" */ movw $10f, %si call print_message - movw %bx, %di call print_segoff movb $',', %al call print_character @@ -86,20 +86,20 @@ no_pxenv: */ detect_ppxe: /* Signature check */ - les ppxe_segoff, %di - cmpl $0x45585021, %es:(%di) /* '!PXE' signature */ + les ppxe_segoff, %bx + cmpl $0x45585021, %es:(%bx) /* '!PXE' signature */ jne no_ppxe /* Record structure address, entry point, and UNDI segments */ pushw %es popw ppxe_segment - movw %di, ppxe_offset - pushl %es:0x10(%di) /* Entry point */ + movw %bx, ppxe_offset + pushl %es:0x10(%bx) /* Entry point */ popl entry_segoff - pushw %es:0x30(%di) /* UNDI code segment */ - pushw %es:0x36(%di) /* UNDI code size */ + pushw %es:0x30(%bx) /* UNDI code segment */ + pushw %es:0x36(%bx) /* UNDI code size */ popl undi_code_segoff - pushw %es:0x28(%di) /* UNDI data segment */ - pushw %es:0x2e(%di) /* UNDI data size */ + pushw %es:0x28(%bx) /* UNDI data segment */ + pushw %es:0x2e(%bx) /* UNDI data size */ popl undi_data_segoff /* Print "!PXE at
" */ movw $10f, %si @@ -167,7 +167,7 @@ print_structure_information: /* Print entry point */ movw $10f, %si call print_message - les entry_segoff, %di + les entry_segoff, %bx call print_segoff .section ".prefix.data" 10: .asciz " entry point at " @@ -175,7 +175,7 @@ print_structure_information: /* Print UNDI code segment */ movw $10f, %si call print_message - les undi_code_segoff, %di + les undi_code_segoff, %bx call print_segoff .section ".prefix.data" 10: .asciz "\n UNDI code segment " @@ -183,7 +183,7 @@ print_structure_information: /* Print UNDI data segment */ movw $10f, %si call print_message - les undi_data_segoff, %di + les undi_data_segoff, %bx call print_segoff .section ".prefix.data" 10: .asciz ", data segment " @@ -271,8 +271,8 @@ unload_base_code: call print_pxe_error jmp 99f 1: /* Free base memory used by PXE base code */ - movw %fs:(0x13), %si - movw undi_fbms_start, %di + movw undi_fbms_start, %ax + movw %fs:(0x13), %bx call free_basemem 99: @@ -289,8 +289,8 @@ unload_undi: call print_pxe_error jmp 99f 1: /* Free base memory used by UNDI */ - movw undi_fbms_start, %si - movw undi_fbms_end, %di + movw undi_fbms_end, %ax + movw undi_fbms_start, %bx call free_basemem /* Clear UNDI_FL_STARTED */ andw $~UNDI_FL_STARTED, flags @@ -324,9 +324,10 @@ finished: * Subroutine: print segment:offset address * * 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: - * Nothing + * %ds:di : next character in output buffer (if applicable) ***************************************************************************** */ print_segoff: @@ -337,7 +338,7 @@ print_segoff: call print_hex_word movb $':', %al call print_character - movw %di, %ax + movw %bx, %ax call print_hex_word /* Restore registers and return */ popw %ax @@ -348,8 +349,9 @@ print_segoff: * * Parameters: * %ax : word to print + * %ds:di : output buffer (or %di=0 to print to console) * Returns: - * Nothing + * %ds:di : next character in output buffer (if applicable) ***************************************************************************** */ print_word: @@ -378,44 +380,11 @@ print_word: popw %ax 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 * * Parameters: - * %si : block to zero (in kB) + * %bx : block to zero (in kB) * Returns: * Nothing ***************************************************************************** @@ -427,7 +396,7 @@ zero_kb: pushw %di pushw %es /* Zero block */ - movw %si, %ax + movw %bx, %ax shlw $6, %ax movw %ax, %es movw $0x400, %cx @@ -445,33 +414,31 @@ zero_kb: * Subroutine: free and zero base memory * * Parameters: - * %si : Expected current free base memory counter (in kB) - * %di : Desired new free base memory counter (in kB) + * %ax : Desired new free base memory counter (in kB) + * %bx : Expected current free base memory counter (in kB) * %fs : BIOS data segment (0x40) * 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 - * 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 * be leaked. ***************************************************************************** */ free_basemem: /* Zero base memory */ - pushw %si -1: cmpw %si, %di + pushw %bx +1: cmpw %bx, %ax je 2f call zero_kb - incw %si + incw %bx jmp 1b -2: popw %si +2: popw %bx /* Free base memory */ - movw %fs:(0x13), %ax /* Current FBMS to %ax */ - cmpw %ax, %si /* Update FBMS only if "old" value */ + cmpw %fs:(0x13), %bx /* Update FBMS only if "old" value */ jne 1f /* is correct */ - movw %di, %ax 1: movw %ax, %fs:(0x13) ret diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S index d37cce94..882da18b 100644 --- a/src/arch/i386/prefix/romprefix.S +++ b/src/arch/i386/prefix/romprefix.S @@ -85,11 +85,24 @@ pnpheader: .equ pnpheader_len, . - pnpheader .size pnpheader, . - pnpheader +/* Manufacturer string */ mfgstr: .asciz "http://etherboot.org" .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: - .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 undiheader: @@ -120,24 +133,31 @@ init: cld pushw %cs popw %ds + movw %di, %bx + xorw %di, %di /* Print message as early as possible */ movw $init_message, %si 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 */ - 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. */ - cmpl $PNP_SIGNATURE, %es:0(%di) + cmpl $PNP_SIGNATURE, %es:0(%bx) jne hook_int19 /* Is PnP: print PnP message */ movw $init_message_pnp, %si call print_message - xchgw %bx, %bx /* Check for BBS */ - pushw %es:0x1b(%di) /* Real-mode data segment */ + pushw %es:0x1b(%bx) /* Real-mode data segment */ pushw %ds /* &(bbs_version) */ pushw $bbs_version pushw $PNP_GET_BBS_VERSION - lcall *%es:0xd(%di) + lcall *%es:0xd(%bx) addw $8, %sp testw %ax, %ax jne hook_int19 @@ -155,18 +175,18 @@ hook_int19: popl %es:( 0x19 * 4 ) hook_bbs: /* Check for PMM */ - movw $( 0xe000 - 1 ), %di + movw $( 0xe00 - 1 ), %bx pmm_scan: - incw %di + incw %bx jz no_pmm - movw %di, %es + movw %bx, %es cmpl $PMM_SIGNATURE, %es:0 jne pmm_scan - xorw %bx, %bx + xorw %dx, %dx xorw %si, %si movzbw %es:5, %cx 1: es lodsb - addb %al, %bl + addb %al, %dl loop 1b jnz pmm_scan /* PMM found: print PMM message */ @@ -221,7 +241,7 @@ no_pmm: .size init, . - init init_message: - .asciz "gPXE (http://etherboot.org) -" + .asciz "gPXE (http://etherboot.org) - PCI " .size init_message, . - init_message init_message_pnp: .asciz " PnP" @@ -292,6 +312,7 @@ exec: /* Set %ds = %cs */ /* Print message as soon as possible */ movw $exec_message, %si + xorw %di, %di call print_message /* Store magic word on BIOS stack and remember BIOS %ss:sp */