summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2011-05-04 11:04:43 +0200
committerMichael Brown2011-05-04 11:04:43 +0200
commit38cd3512434e9ded2b56b59921074e3d86606631 (patch)
tree8316a351326d664b92e0e73d5bb3d8ff3cd2d801
parent[netdevice] Improve detection of bugs in drivers' TX completion handling (diff)
downloadipxe-38cd3512434e9ded2b56b59921074e3d86606631.tar.gz
ipxe-38cd3512434e9ded2b56b59921074e3d86606631.tar.xz
ipxe-38cd3512434e9ded2b56b59921074e3d86606631.zip
[romprefix] Attempt to gracefully handle semi-PnP IBM BIOSes
Some IBM BIOSes provide partial support for PnP: they will use the BEV entry point but will not advertise PnP support. This causes iPXE to hook INT 19, which disrupts the boot process. Attempt to improve this situation by detecting an IBM BIOS and treating it as a PnP BIOS despite the absence of a PnP signature. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/arch/i386/prefix/romprefix.S26
1 files changed, 20 insertions, 6 deletions
diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S
index dd602ddb7..49fd24b9a 100644
--- a/src/arch/i386/prefix/romprefix.S
+++ b/src/arch/i386/prefix/romprefix.S
@@ -13,6 +13,7 @@ FILE_LICENCE ( GPL2_OR_LATER )
#define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) )
#define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) )
#define PCI_SIGNATURE ( 'P' + ( 'C' << 8 ) + ( 'I' << 16 ) + ( ' ' << 24 ) )
+#define IBM_SIGNATURE ( ( 'I' << 24 ) + ( 'B' << 16 ) + ( 'M' << 8 ) + ' ' )
#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
#define PMM_ALLOCATE 0x0000
#define PMM_FIND 0x0001
@@ -172,6 +173,7 @@ undiheader:
init:
/* Preserve registers, clear direction flag, set %ds=%cs */
pushaw
+ pushl %ebx
pushw %ds
pushw %es
pushw %fs
@@ -180,15 +182,14 @@ init:
pushw %cs
popw %ds
- /* Shuffle some registers around. We need %di available for
- * the print_xxx functions, and in a register that's
- * addressable from %es, so shuffle as follows:
+ /* Shuffle some registers around. We need to use %di for the
+ * print_xxx functions, so shuffle as follows:
*
- * %di (pointer to PnP structure) => %bx
* %bx (runtime segment address, for PCI 3.0) => %gs
+ * %edi (IBM signature) => %ebx
*/
movw %bx, %gs
- movw %di, %bx
+ movl %edi, %ebx
/* Store PCI bus:dev.fn address */
movw %ax, init_pci_busdevfn
@@ -263,7 +264,16 @@ no_pci3:
popl %edx
popl %ebx
- /* Check for PnP BIOS. Although %es:di should point to the
+ /* Check for IBM BIOS, which uses the PnP entry points but
+ * doesn't indicate PnP support.
+ */
+ cmpl $IBM_SIGNATURE, %ebx
+ jne no_ibm
+ movw $init_message_ibm, %si
+ xorw %di, %di
+ call print_message
+ jmp pnp_done
+no_ibm: /* Check for PnP BIOS. Although %es:di should point to the
* PnP BIOS signature on entry, some BIOSes fail to do this.
*/
movw $( 0xf000 - 1 ), %bx
@@ -416,6 +426,7 @@ no_pmm:
popw %fs
popw %es
popw %ds
+ popl %ebx
popaw
/* Indicate boot capability to PnP BIOS, if present */
@@ -530,6 +541,9 @@ init_message:
init_message_pci:
.asciz " PCI"
.size init_message_pci, . - init_message_pci
+init_message_ibm:
+ .asciz " IBM"
+ .size init_message_ibm, . - init_message_ibm
init_message_pnp:
.asciz " PnP"
.size init_message_pnp, . - init_message_pnp