[prefix] Add PCI bus:dev.fn to ROM product string
authorMichael Brown <mcb30@etherboot.org>
Wed, 21 May 2008 17:43:58 +0000 (18:43 +0100)
committerMichael Brown <mcb30@etherboot.org>
Wed, 21 May 2008 17:43:58 +0000 (18:43 +0100)
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
src/arch/i386/prefix/pxeprefix.S
src/arch/i386/prefix/romprefix.S

index deea5ab..cb09111 100644 (file)
  *
  * 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"
        .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)
  *
index 6a8aeb3..32ff296 100644 (file)
@@ -37,6 +37,7 @@
        cld
        /* Print welcome message */
        movw    $10f, %si
+       xorw    %di, %di
        call    print_message
        .section ".prefix.data"
 10:    .asciz  "PXE->EB:"
  */
 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 <address>" */
        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 <address>" */
        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
 
index d37cce9..882da18 100644 (file)
@@ -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 */