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);