From 9ca6590769692b99e98acf48acc3ce700238e451 Mon Sep 17 00:00:00 2001 From: gaobin gaobin@amazon.com Date: Thu, 19 Sep 2019 22:47:43 -0700 Subject: [PATCH 3/4] csm: Enable boot from pci option rom
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.
Signed-off-by: gaobin gaobin@amazon.com --- src/fw/csm.c | 18 ++++++++++++++++++ src/optionroms.c | 2 +- src/util.h | 1 + 3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/fw/csm.c b/src/fw/csm.c index c8111cd..8e2a1aa 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 @@ -218,12 +219,16 @@ handle_csm_0003(struct bregs *regs) regs->ax = 1; }
+static int rom_instance; + /* Legacy16DispatchOprom */ static void 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; + u64 sources[(BUILD_BIOS_ADDR - BUILD_ROM_START) / OPTION_ROM_ALIGN]; u16 bdf;
if (!CONFIG_OPTIONROMS) { @@ -250,6 +255,19 @@ handle_csm_0005(struct bregs *regs)
rom_confirm(rom->size * 512);
+ // PnP rom - check for BEV and BCV boot capabilities. + pnp = (void*)((u8*)rom + rom->pnpoffset); + if (pnp->signature == PNP_SIGNATURE) { + if (pnp->bev) + boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname, + getRomPriority(sources, rom, rom_instance++)); + else if (pnp->bcv) + boot_add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname, + getRomPriority(sources, rom, rom_instance++)); + } else { + dprintf(1, "rom 0x%p is not PnP rom, no BEV and BCV capability\n", table); + } + regs->bx = 0; // FIXME regs->ax = 0; } diff --git a/src/optionroms.c b/src/optionroms.c index e906ab9..4f3848d 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -153,7 +153,7 @@ setRomSource(u64 *sources, struct rom_header *rom, u64 source) sources[((u32)rom - BUILD_ROM_START) / OPTION_ROM_ALIGN] = source; }
-static int +int getRomPriority(u64 *sources, struct rom_header *rom, int instance) { u64 source = sources[((u32)rom - BUILD_ROM_START) / OPTION_ROM_ALIGN]; diff --git a/src/util.h b/src/util.h index b173fa8..0a52338 100644 --- a/src/util.h +++ b/src/util.h @@ -217,6 +217,7 @@ int is_pci_vga(struct pci_device *pci); void optionrom_setup(void); void vgarom_setup(void); void s3_resume_vga(void); +int getRomPriority(u64 *sources, struct rom_header *rom, int instance); extern int ScreenAndDebug;
// pcibios.c
On Mon, Nov 25, 2019 at 07:26:17PM -0800, Your Real Name wrote:
From 9ca6590769692b99e98acf48acc3ce700238e451 Mon Sep 17 00:00:00 2001 From: gaobin gaobin@amazon.com Date: Thu, 19 Sep 2019 22:47:43 -0700 Subject: [PATCH 3/4] csm: Enable boot from pci option rom
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.
Signed-off-by: gaobin gaobin@amazon.com
src/fw/csm.c | 18 ++++++++++++++++++ src/optionroms.c | 2 +- src/util.h | 1 + 3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/fw/csm.c b/src/fw/csm.c index c8111cd..8e2a1aa 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 @@ -218,12 +219,16 @@ handle_csm_0003(struct bregs *regs) regs->ax = 1; }
+static int rom_instance;
What is this? Not used anywhere in the patch ...
cheers, Gerd
On Wed, Nov 27, 2019 at 08:09:18AM +0100, Gerd Hoffmann wrote:
On Mon, Nov 25, 2019 at 07:26:17PM -0800, Your Real Name wrote:
From 9ca6590769692b99e98acf48acc3ce700238e451 Mon Sep 17 00:00:00 2001 From: gaobin gaobin@amazon.com Date: Thu, 19 Sep 2019 22:47:43 -0700 Subject: [PATCH 3/4] csm: Enable boot from pci option rom
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.
Signed-off-by: gaobin gaobin@amazon.com
src/fw/csm.c | 18 ++++++++++++++++++ src/optionroms.c | 2 +- src/util.h | 1 + 3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/fw/csm.c b/src/fw/csm.c index c8111cd..8e2a1aa 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 @@ -218,12 +219,16 @@ handle_csm_0003(struct bregs *regs) regs->ax = 1; }
+static int rom_instance;
What is this? Not used anywhere in the patch ...
This is required on calling getRomPriority(). Please check below lines in the patch. boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname, getRomPriority(sources, rom, rom_instance++));
cheers, Gerd
+static int rom_instance;
What is this? Not used anywhere in the patch ...
This is required on calling getRomPriority(). Please check below lines in the patch. boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname, getRomPriority(sources, rom, rom_instance++));
I think you can just pass "0" instead of using rom_instance.
I suspect you can even drop the getRomPriority call altogether as it probably isn't going to give any useful results in CSM mode anyway.
cheers, Gerd
On Tue, Dec 03, 2019 at 11:07:36AM +0100, Gerd Hoffmann wrote:
+static int rom_instance;
What is this? Not used anywhere in the patch ...
This is required on calling getRomPriority(). Please check below lines in the patch. boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname, getRomPriority(sources, rom, rom_instance++));
I think you can just pass "0" instead of using rom_instance.
I suspect you can even drop the getRomPriority call altogether as it probably isn't going to give any useful results in CSM mode anyway.
The priority value(the last argument we pass to boot_add_bev()) will affect the order of the boot list. The getRomPriority() will calculate the final priority based on the system provided BBS, etc. This is even true in CSM case. If we drop the getRomPriority call and instead do: boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname, 0); then this bev entry will be the first boot option in the boot list because hard disk typically has priority larger than 100 (lower priority will be closer to the beginning of the boot list). I'm fine to drop the getRomPriority call and pass 0 to the boot_add_bev() call since I need manually adjust do_boot() logic anyway for my case.
cheers, Gerd
Hi,
The priority value(the last argument we pass to boot_add_bev()) will affect the order of the boot list. The getRomPriority() will calculate the final priority based on the system provided BBS, etc. This is even true in CSM case. If we drop the getRomPriority call and instead do: boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname, 0); then this bev entry will be the first boot option in the boot list because hard disk typically has priority larger than 100 (lower priority will be closer to the beginning of the boot list).
HD gets 103 (DefaultHDPrio). I'd suggest to use 104 (DefaultBEVPrio) instead of 0.
Or maybe better keep the getRomPriority() call and drop the rom_instance variable only. While getRomPriority() doesn't do anything for your use case (on physical hardware) it will have an effect when running as seabios as OVMF CSM in qemu.
I'm fine to drop the getRomPriority call and pass 0 to the boot_add_bev() call since I need manually adjust do_boot() logic anyway for my case.
I guess that is another patch which is not upstream? How about posting that too? Seeing the big picture (how do you handle boot order on physical hardware where you have no bootorder fw_cfg file) might be helpful for discussing this patch.
cheers, Gerd
On Thu, Dec 05, 2019 at 07:06:37AM +0100, Gerd Hoffmann wrote:
Hi,
The priority value(the last argument we pass to boot_add_bev()) will affect the order of the boot list. The getRomPriority() will calculate the final priority based on the system provided BBS, etc. This is even true in CSM case. If we drop the getRomPriority call and instead do: boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname, 0); then this bev entry will be the first boot option in the boot list because hard disk typically has priority larger than 100 (lower priority will be closer to the beginning of the boot list).
HD gets 103 (DefaultHDPrio). I'd suggest to use 104 (DefaultBEVPrio) instead of 0.
Or maybe better keep the getRomPriority() call and drop the rom_instance variable only. While getRomPriority() doesn't do anything for your use case (on physical hardware) it will have an effect when running as seabios as OVMF CSM in qemu.
As far as I know, QEMU only supports UEFI PCI Rom, not legacy PCI Rom:-) And yes, I'll keep getRomPriority() but drop "rom_instance", and use a hard coded default priority(104).
I'm fine to drop the getRomPriority call and pass 0 to the boot_add_bev() call since I need manually adjust do_boot() logic anyway for my case.
I guess that is another patch which is not upstream? How about posting that too? Seeing the big picture (how do you handle boot order on physical hardware where you have no bootorder fw_cfg file) might be helpful for discussing this patch.
That patch is pretty easy but may not be appropriate for upstream because it's not generic. Basically in do_boot() we filter the boot entry from BEV[] by type. For example, we may want to try BEV device(pci rom) first, then we try HD drives. If there are multiple HD drives, then we filer by PCI IDs. All those orders and priorities are hard coded.
cheers, Gerd
On Fri, Dec 06, 2019 at 08:17:04PM -0800, Your Real Name wrote:
On Thu, Dec 05, 2019 at 07:06:37AM +0100, Gerd Hoffmann wrote:
Hi,
The priority value(the last argument we pass to boot_add_bev()) will affect the order of the boot list. The getRomPriority() will calculate the final priority based on the system provided BBS, etc. This is even true in CSM case. If we drop the getRomPriority call and instead do: boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname, 0); then this bev entry will be the first boot option in the boot list because hard disk typically has priority larger than 100 (lower priority will be closer to the beginning of the boot list).
HD gets 103 (DefaultHDPrio). I'd suggest to use 104 (DefaultBEVPrio) instead of 0.
Or maybe better keep the getRomPriority() call and drop the rom_instance variable only. While getRomPriority() doesn't do anything for your use case (on physical hardware) it will have an effect when running as seabios as OVMF CSM in qemu.
As far as I know, QEMU only supports UEFI PCI Rom, not legacy PCI Rom:-)
qemu doesn't care at all ;)
It's the firmware which cares. seabios uses the legacy PCI Rom. OVMF uses the UEFI PCI Rom. OVMF with seabios as CSM can use both.
Building OVMF with CSM isn't very common though. A virtual machine can (unlike physical hardware) easily switch the fimware, so if you need legacy bios support you can just run seabios directly instead of going the CSM route.
I guess that is another patch which is not upstream? How about posting that too? Seeing the big picture (how do you handle boot order on physical hardware where you have no bootorder fw_cfg file) might be helpful for discussing this patch.
That patch is pretty easy but may not be appropriate for upstream because it's not generic. Basically in do_boot() we filter the boot entry from BEV[] by type. For example, we may want to try BEV device(pci rom) first, then we try HD drives. If there are multiple HD drives, then we filer by PCI IDs. All those orders and priorities are hard coded.
One option to deal with that would be to allow compiling in a fallback bootorder file, which seabios would use when it there isn't one supplied by qemu and the also isn't one provided by coreboot (in cbfs). Works only if bootorder matching can handle your needs. I think looking at PCI IDs doesn't work. BDFs will work though.
cheers, Gerd
On Mon, Dec 09, 2019 at 01:09:11PM +0100, Gerd Hoffmann wrote:
On Fri, Dec 06, 2019 at 08:17:04PM -0800, Your Real Name wrote:
On Thu, Dec 05, 2019 at 07:06:37AM +0100, Gerd Hoffmann wrote:
Hi,
The priority value(the last argument we pass to boot_add_bev()) will affect the order of the boot list. The getRomPriority() will calculate the final priority based on the system provided BBS, etc. This is even true in CSM case. If we drop the getRomPriority call and instead do: boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname, 0); then this bev entry will be the first boot option in the boot list because hard disk typically has priority larger than 100 (lower priority will be closer to the beginning of the boot list).
HD gets 103 (DefaultHDPrio). I'd suggest to use 104 (DefaultBEVPrio) instead of 0.
Or maybe better keep the getRomPriority() call and drop the rom_instance variable only. While getRomPriority() doesn't do anything for your use case (on physical hardware) it will have an effect when running as seabios as OVMF CSM in qemu.
As far as I know, QEMU only supports UEFI PCI Rom, not legacy PCI Rom:-)
qemu doesn't care at all ;)
It's the firmware which cares. seabios uses the legacy PCI Rom. OVMF uses the UEFI PCI Rom. OVMF with seabios as CSM can use both.
Building OVMF with CSM isn't very common though. A virtual machine can (unlike physical hardware) easily switch the fimware, so if you need legacy bios support you can just run seabios directly instead of going the CSM route.
I guess that is another patch which is not upstream? How about posting that too? Seeing the big picture (how do you handle boot order on physical hardware where you have no bootorder fw_cfg file) might be helpful for discussing this patch.
That patch is pretty easy but may not be appropriate for upstream because it's not generic. Basically in do_boot() we filter the boot entry from BEV[] by type. For example, we may want to try BEV device(pci rom) first, then we try HD drives. If there are multiple HD drives, then we filer by PCI IDs. All those orders and priorities are hard coded.
One option to deal with that would be to allow compiling in a fallback bootorder file, which seabios would use when it there isn't one supplied by qemu and the also isn't one provided by coreboot (in cbfs). Works only if bootorder matching can handle your needs. I think looking at PCI IDs doesn't work. BDFs will work though.
Yes, bootorder file doesn't handle PCI IDs. But we have plug-in HD drives so BDFs are dynamic on different system configuraton. In my casePCI ID is the only way to choose boot device, but it's not generic:-)
cheers, Gerd