In csm mode, the bev pointer of the pci option rom was not added to the bootentry list, resulting in failure to boot from pci option rom. This patch fixed it. Also we enabled hw timer interrupt and clock update before we call the option rom's init() funtion, so the clock tick update at BDA address 40:6C will work during the rom's init() execution. Withou this change, iPXE would hang on reading BDA 40:6C due to the value at this address is not changed.
Signed-off-by: Bin Gao gaobin@amazon.com
src/fw/csm.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/src/fw/csm.c b/src/fw/csm.c index 8359bcb..f64bc73 100644 --- a/src/fw/csm.c +++ b/src/fw/csm.c @@ -19,6 +19,7 @@ #include "std/acpi.h" // RSDP_SIGNATURE #include "std/bda.h" // struct bios_data_area_s #include "std/optionrom.h" // struct rom_header +#include "std/pnpbios.h" // PNP_SIGNATURE #include "util.h" // copy_smbios
#define UINT8 u8 @@ -219,6 +220,7 @@ handle_csm_0005(struct bregs *regs) { EFI_DISPATCH_OPROM_TABLE *table = MAKE_FLATPTR(regs->es, regs->bx); struct rom_header *rom;
struct pnp_data *pnp; u16 bdf;
if (!CONFIG_OPTIONROMS) {
@@ -240,11 +242,36 @@ handle_csm_0005(struct bregs *regs)
rom_reserve(rom->size * 512);
- // callrom() typically calls the rom's init() functions.
- // If the rom's init() function does a delay by detecting the value
- // at address 40:6C, it will fail because the value at 40:6C is
- // updated only in clock_update() which is called in hw timer ISR.
- // Thus we have to enable hw timer interrupt and set up clock before
- // calling callrom().
- pic_setup();
- timer_setup();
- clock_setup();
This doesn't look correct to me. The CSM code was originally designed not to directly setup the PIC hardware - IIRC we don't know if the OS is a "legacy OS" or not at this point. Maybe David has a more clear recollection.
In any case, it would not make sense to call clock_setup() and timer_setup() on every option rom and then again in PrepareToBoot().
After each rom dispatch, the execution returns back to BIOS, so we lose all the hardware context from SeaBIOS. That's why I did a per-dispatch time init. The ROM init() depends on the ticks updating if the ROM init() uses standard BDA 40:6C based time polling to implement a delay. Probably no one really tried PCI oprom on physical hardware so this problem was not disclosed...
-Kevin