Hi,
This patch series changes the way SeaBIOS figures whenever it runs on qemu or not. Instead of using different ways for each configuration (CONFIG_QEMU / CONFIG_CSM / CONFIG_COREBOOT) we'll have a generic function which checks the PCI Subsystem ID of the northbridge.
cheers, Gerd
Gerd Hoffmann (3): Add generic qemu detection Drop coreboot qemu detection Add qemu detection to csm
src/coreboot.c | 4 ---- src/csm.c | 2 ++ src/paravirt.c | 42 ++++++++++++++++++++++++++++++++++++------ src/paravirt.h | 1 + 4 files changed, 39 insertions(+), 10 deletions(-)
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In case the subsystem ID matches set PF_QEMU, log a message (including the northbridge found while being at it) and also check for kvm.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/paravirt.c | 42 ++++++++++++++++++++++++++++++++++++------ src/paravirt.h | 1 + 2 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/src/paravirt.c b/src/paravirt.c index d1a5d3e..ea9fa9a 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -19,6 +19,7 @@ #include "acpi.h" // acpi_setup #include "mptable.h" // mptable_setup #include "pci.h" // create_pirtable +#include "pci_regs.h" // create_pirtable #include "xen.h" // xen_biostable_setup
// Amount of continuous ram under 4Gig @@ -33,10 +34,8 @@ int PlatformRunningOn VARFSEG; */ #define KVM_CPUID_SIGNATURE 0x40000000
-static void kvm_preinit(void) +static void kvm_detect(void) { - if (!CONFIG_QEMU) - return; unsigned int eax, ebx, ecx, edx; char signature[13];
@@ -52,9 +51,43 @@ static void kvm_preinit(void) } }
+void qemu_detect(void) +{ + if (!CONFIG_QEMU_HARDWARE) + return; + + // check northbridge @ 00:00.0 + u16 v = pci_config_readw(0, PCI_VENDOR_ID); + if (v == 0x0000 || v == 0xffff) + return; + u16 d = pci_config_readw(0, PCI_DEVICE_ID); + u16 sv = pci_config_readw(0, PCI_SUBSYSTEM_VENDOR_ID); + u16 sd = pci_config_readw(0, PCI_SUBSYSTEM_ID); + + if (sv != 0x1af4 || /* Red Hat, Inc */ + sd != 0x1100) /* Qemu virtual machine */ + return; + + PlatformRunningOn |= PF_QEMU; + switch (d) { + case 0x1237: + dprintf(1, "Running on QEMU (i440fx)\n"); + break; + case 0x29c0: + dprintf(1, "Running on QEMU (q35)\n"); + break; + default: + dprintf(1, "Running on QEMU (unknown nb: %04x:%04x)\n", v, d); + break; + } + kvm_detect(); +} + void qemu_preinit(void) { + qemu_detect(); + if (!CONFIG_QEMU) return;
@@ -63,9 +96,6 @@ qemu_preinit(void) return; }
- PlatformRunningOn = PF_QEMU; - kvm_preinit(); - // On emulators, get memory size from nvram. u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); diff --git a/src/paravirt.h b/src/paravirt.h index fce5af9..7fc00b0 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -24,6 +24,7 @@ static inline int runningOnKVM(void) { return CONFIG_QEMU && GET_GLOBAL(PlatformRunningOn) & PF_KVM; }
+void qemu_detect(void); void qemu_preinit(void); void qemu_platform_setup(void); void qemu_cfg_init(void);
On Tue, Sep 03, 2013 at 02:37:41PM +0200, Gerd Hoffmann wrote:
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In general, it looks sane to me. It does mix the "preinit" phase (on coreboot/qemu) with the "init" phase (on csm). Can the detect just be done in qemu_cfg_init (perhaps renaming it to qemu_init) and that way this detection doesn't need to be done in the preinit phase.
--- a/src/paravirt.c +++ b/src/paravirt.c @@ -19,6 +19,7 @@ #include "acpi.h" // acpi_setup #include "mptable.h" // mptable_setup #include "pci.h" // create_pirtable +#include "pci_regs.h" // create_pirtable #include "xen.h" // xen_biostable_setup
// Amount of continuous ram under 4Gig @@ -33,10 +34,8 @@ int PlatformRunningOn VARFSEG; */ #define KVM_CPUID_SIGNATURE 0x40000000
-static void kvm_preinit(void) +static void kvm_detect(void) {
- if (!CONFIG_QEMU)
unsigned int eax, ebx, ecx, edx; char signature[13];return;
@@ -52,9 +51,43 @@ static void kvm_preinit(void) } }
+void qemu_detect(void) +{
- if (!CONFIG_QEMU_HARDWARE)
return;
- // check northbridge @ 00:00.0
- u16 v = pci_config_readw(0, PCI_VENDOR_ID);
- if (v == 0x0000 || v == 0xffff)
return;
- u16 d = pci_config_readw(0, PCI_DEVICE_ID);
- u16 sv = pci_config_readw(0, PCI_SUBSYSTEM_VENDOR_ID);
- u16 sd = pci_config_readw(0, PCI_SUBSYSTEM_ID);
- if (sv != 0x1af4 || /* Red Hat, Inc */
sd != 0x1100) /* Qemu virtual machine */
return;
- PlatformRunningOn |= PF_QEMU;
Do old versions of QEMU set this also? (If not, there is a corner case where we could have CONFIG_QEMU but PlatformRunningOn != PF_QEMU - I don't think that matters, but it is weird.)
-Kevin
On Di, 2013-09-03 at 21:28 -0400, Kevin O'Connor wrote:
On Tue, Sep 03, 2013 at 02:37:41PM +0200, Gerd Hoffmann wrote:
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In general, it looks sane to me. It does mix the "preinit" phase (on coreboot/qemu) with the "init" phase (on csm).
There is no preinit on csm ...
Can the detect just be done in qemu_cfg_init (perhaps renaming it to qemu_init) and that way this detection doesn't need to be done in the preinit phase.
I'd like to do this as early as possible, because one of the things this enables is logging via qemu debug port (CONFIG_DEBUG_IO).
Also note that preinit has a runningOnKvm() call, and we'll better do the checks for qemu and kvm beforehand.
--- a/src/paravirt.c +++ b/src/paravirt.c @@ -19,6 +19,7 @@ #include "acpi.h" // acpi_setup #include "mptable.h" // mptable_setup #include "pci.h" // create_pirtable +#include "pci_regs.h" // create_pirtable #include "xen.h" // xen_biostable_setup
// Amount of continuous ram under 4Gig @@ -33,10 +34,8 @@ int PlatformRunningOn VARFSEG; */ #define KVM_CPUID_SIGNATURE 0x40000000
-static void kvm_preinit(void) +static void kvm_detect(void) {
- if (!CONFIG_QEMU)
unsigned int eax, ebx, ecx, edx; char signature[13];return;
@@ -52,9 +51,43 @@ static void kvm_preinit(void) } }
+void qemu_detect(void) +{
- if (!CONFIG_QEMU_HARDWARE)
return;
- // check northbridge @ 00:00.0
- u16 v = pci_config_readw(0, PCI_VENDOR_ID);
- if (v == 0x0000 || v == 0xffff)
return;
- u16 d = pci_config_readw(0, PCI_DEVICE_ID);
- u16 sv = pci_config_readw(0, PCI_SUBSYSTEM_VENDOR_ID);
- u16 sd = pci_config_readw(0, PCI_SUBSYSTEM_ID);
- if (sv != 0x1af4 || /* Red Hat, Inc */
sd != 0x1100) /* Qemu virtual machine */
return;
- PlatformRunningOn |= PF_QEMU;
Do old versions of QEMU set this also? (If not, there is a corner case where we could have CONFIG_QEMU but PlatformRunningOn != PF_QEMU
- I don't think that matters, but it is weird.)
Added by qemu commit d350d97d196a632b6c7493acf07a061017fc6f7d (Dec 2008), qemu version 0.10.0 + newer have this.
cheers, Gerd
On Wed, Sep 04, 2013 at 08:13:56AM +0200, Gerd Hoffmann wrote:
On Di, 2013-09-03 at 21:28 -0400, Kevin O'Connor wrote:
On Tue, Sep 03, 2013 at 02:37:41PM +0200, Gerd Hoffmann wrote:
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In general, it looks sane to me. It does mix the "preinit" phase (on coreboot/qemu) with the "init" phase (on csm).
There is no preinit on csm ...
"preinit" is code run before code relocation. It's handle_csm_0000() for csm.
Can the detect just be done in qemu_cfg_init (perhaps renaming it to qemu_init) and that way this detection doesn't need to be done in the preinit phase.
I'd like to do this as early as possible, because one of the things this enables is logging via qemu debug port (CONFIG_DEBUG_IO).
Good point.
Also note that preinit has a runningOnKvm() call, and we'll better do the checks for qemu and kvm beforehand.
Maybe call qemu_preinit() from handle_csm_0000()?
-Kevin
On 09/06/13 02:45, Kevin O'Connor wrote:
On Wed, Sep 04, 2013 at 08:13:56AM +0200, Gerd Hoffmann wrote:
I'd like to do this as early as possible, because one of the things this enables is logging via qemu debug port (CONFIG_DEBUG_IO).
Good point.
Also note that preinit has a runningOnKvm() call, and we'll better do the checks for qemu and kvm beforehand.
Maybe call qemu_preinit() from handle_csm_0000()?
I tested Gerd's patch that does this (to be posted I think), it works fine.
Thanks! Laszlo
On Fr, 2013-09-06 at 14:32 +0200, Laszlo Ersek wrote:
On 09/06/13 02:45, Kevin O'Connor wrote:
On Wed, Sep 04, 2013 at 08:13:56AM +0200, Gerd Hoffmann wrote:
I'd like to do this as early as possible, because one of the things this enables is logging via qemu debug port (CONFIG_DEBUG_IO).
Good point.
Also note that preinit has a runningOnKvm() call, and we'll better do the checks for qemu and kvm beforehand.
Maybe call qemu_preinit() from handle_csm_0000()?
I tested Gerd's patch that does this (to be posted I think), it works fine.
Yes, to be posted, here we go: attached patch replaces #3.
Patches 1+2 are unchanged, full series is at http://www.kraxel.org/cgit/seabios/log/?h=detect-qemu
cheers, Gerd
On Tue, Sep 03, 2013 at 02:37:41PM +0200, Gerd Hoffmann wrote:
This patch adds support for detecting whenever SeaBIOS runs on qemu or not. This is done by looking at the northbridge (pci device 00:00.0) and check the subsystem id. Most pci devices emulated by qemu -- the two northbridges i440fx and q35 included -- have a subsystem id of "1af4:1100".
In case the subsystem ID matches set PF_QEMU, log a message (including the northbridge found while being at it) and also check for kvm.
Why condition KVM check on QEMU?
Signed-off-by: Gerd Hoffmann kraxel@redhat.com
src/paravirt.c | 42 ++++++++++++++++++++++++++++++++++++------ src/paravirt.h | 1 + 2 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/src/paravirt.c b/src/paravirt.c index d1a5d3e..ea9fa9a 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -19,6 +19,7 @@ #include "acpi.h" // acpi_setup #include "mptable.h" // mptable_setup #include "pci.h" // create_pirtable +#include "pci_regs.h" // create_pirtable #include "xen.h" // xen_biostable_setup
// Amount of continuous ram under 4Gig @@ -33,10 +34,8 @@ int PlatformRunningOn VARFSEG; */ #define KVM_CPUID_SIGNATURE 0x40000000
-static void kvm_preinit(void) +static void kvm_detect(void) {
- if (!CONFIG_QEMU)
unsigned int eax, ebx, ecx, edx; char signature[13];return;
@@ -52,9 +51,43 @@ static void kvm_preinit(void) } }
+void qemu_detect(void) +{
- if (!CONFIG_QEMU_HARDWARE)
return;
- // check northbridge @ 00:00.0
- u16 v = pci_config_readw(0, PCI_VENDOR_ID);
- if (v == 0x0000 || v == 0xffff)
return;
- u16 d = pci_config_readw(0, PCI_DEVICE_ID);
- u16 sv = pci_config_readw(0, PCI_SUBSYSTEM_VENDOR_ID);
- u16 sd = pci_config_readw(0, PCI_SUBSYSTEM_ID);
- if (sv != 0x1af4 || /* Red Hat, Inc */
sd != 0x1100) /* Qemu virtual machine */
return;
- PlatformRunningOn |= PF_QEMU;
- switch (d) {
- case 0x1237:
dprintf(1, "Running on QEMU (i440fx)\n");
break;
- case 0x29c0:
dprintf(1, "Running on QEMU (q35)\n");
break;
- default:
dprintf(1, "Running on QEMU (unknown nb: %04x:%04x)\n", v, d);
break;
- }
- kvm_detect();
+}
void qemu_preinit(void) {
- qemu_detect();
- if (!CONFIG_QEMU) return;
@@ -63,9 +96,6 @@ qemu_preinit(void) return; }
- PlatformRunningOn = PF_QEMU;
- kvm_preinit();
- // On emulators, get memory size from nvram. u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24));
diff --git a/src/paravirt.h b/src/paravirt.h index fce5af9..7fc00b0 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -24,6 +24,7 @@ static inline int runningOnKVM(void) { return CONFIG_QEMU && GET_GLOBAL(PlatformRunningOn) & PF_KVM; }
+void qemu_detect(void); void qemu_preinit(void); void qemu_platform_setup(void); void qemu_cfg_init(void); -- 1.8.3.1
SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
-- Gleb.
Not needed any more, the new qemu_detect() function does the job instead.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/coreboot.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/src/coreboot.c b/src/coreboot.c index 983a2b5..fbfbeb7 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -188,10 +188,6 @@ coreboot_preinit(void) if (cbmb) { CBvendor = &cbmb->strings[cbmb->vendor_idx]; CBpart = &cbmb->strings[cbmb->part_idx]; - if (strcmp(CBvendor, "Emulation") == 0 && - memcmp(CBpart, "QEMU", 4) == 0) { - PlatformRunningOn |= PF_QEMU; - } dprintf(1, "Found mainboard %s %s\n", CBvendor, CBpart); }
Add a qemu_detect() call to csm initialization, so PF_QEMU gets set when running on qemu.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/csm.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/src/csm.c b/src/csm.c index 2021701..d927842 100644 --- a/src/csm.c +++ b/src/csm.c @@ -16,6 +16,7 @@ #include "acpi.h" #include "boot.h" #include "smbios.h" +#include "paravirt.h" #include "pic.h"
struct rsdp_descriptor csm_rsdp VARFSEG __aligned(16); @@ -49,6 +50,7 @@ csm_return(struct bregs *regs) static void csm_maininit(struct bregs *regs) { + qemu_detect(); interface_init(); pci_probe_devices();