aboutsummaryrefslogtreecommitdiffstats
path: root/src/arch/i386/prefix
diff options
context:
space:
mode:
authorMichael Brown <mcb30@etherboot.org>2008-05-21 18:43:58 +0100
committerMichael Brown <mcb30@etherboot.org>2008-05-21 18:43:58 +0100
commitfd0aef9ee1df2e979993b05036c8330885fbccc1 (patch)
tree11d0c63c698d0af944195bfbbe0f56343792b55d /src/arch/i386/prefix
parentf3aef4d98dc962e14d5fa1b4adee73168042a468 (diff)
downloadipxe-fd0aef9ee1df2e979993b05036c8330885fbccc1.tar.gz
[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.
Diffstat (limited to 'src/arch/i386/prefix')
-rw-r--r--src/arch/i386/prefix/libprefix.S64
-rw-r--r--src/arch/i386/prefix/pxeprefix.S117
-rw-r--r--src/arch/i386/prefix/romprefix.S45
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 <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:
@@ -379,43 +381,10 @@ print_word:
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 */