[mromprefix] Report a dummy size at offset 0x02 of .mrom payload
authorMichael Brown <mcb30@ipxe.org>
Thu, 25 Jun 2015 07:32:25 +0000 (08:32 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 25 Jun 2015 09:33:46 +0000 (10:33 +0100)
commit36817ea260331d7da9ea088f7e64d86ea9a1ac1d
treedf0e0bde42d28f5cbe3402c4ea42b0e6ac2900a0
parentc117b25e0b7de2fd116f86dd6f105447dcc3d125
[mromprefix] Report a dummy size at offset 0x02 of .mrom payload

The size of the .mrom payload (the second PCI ROM image) is defined in
its PCI header.  The code type for the .mrom payload image is
deliberately set to an invalid value (0xff) to ensure that no BIOS
tries to parse anything in the image other than the PCI header.

Since the code type is not set to 0x00 ("Intel x86, PC-AT
compatible"), bytes 0x02-0x17 should not be interpreted by the BIOS as
being in the standard ISA expansion ROM format.  In particular, the
byte at offset 0x02 does not represent the length of the ROM image (in
512-byte blocks).

However, some Dell BIOSes seem to erroneously use the byte at offset
0x02 to determine the length of the .mrom payload when walking the
list of PCI ROM images.  Since this byte is currently set to zero,
this can lead to the BIOS getting stuck in an infinite loop during
POST.  (This problem may not arise if the .mrom payload is the final
image in the ROM, since the BIOS will then have no reason to attempt
to locate the next image.)

One possible workaround would be to put the real payload size in this
byte, but doing so would constrain the .mrom payload size to 128kB
(see commit 8049a52 ("[mromprefix] Allow for .mrom images larger than
128kB") for more details).

Another possible workaround would be to put the real payload size as a
word in bytes 0x02-0x03 (as is done for EFI ROMs).  This would not
constrain the .mrom payload size, but a payload size which happened to
be exactly 128kB would result in a zero value in the byte at offset
0x02 and so could still result in infinite loops on BIOSes with this
bug.

We choose to place a fixed value of 0x01 in the byte at offset 0x02.
This should at least prevent the BIOS from getting stuck in an
infinite loop.  (The BIOS may walk into the middle of the .mrom
payload, where it will almost certainly not find a valid {0x55,0xaa}
signature or a valid PCIR header, and will therefore hopefully abort
processing.)

Reported-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/i386/prefix/mromprefix.S