This is the redo of the "multi-platform support" patch I sent previously.
This patch series is less ambitious than the previous - SeaBIOS can't be compiled for multiple platforms (eg, QEMU, CSM, coreboot) at the same time. However, this series still contains all the CONFIG_X reorganization and it will ensure that virtual devices aren't accessed when not on real hardware when using CONFIG_CSM. This series also enables the possibility of using some virtual devices under coreboot and CSM when it is safe to do so (and CONFIG_QEMU_HARDWARE is selected).
I have also placed this code for testing at: https://github.com/KevinOConnor/seabios/tree/test-20130209
-Kevin
Kevin O'Connor (6): Determine century during init and store in VARLOW mem during runtime. No need to check both CONFIG_THREADS and CONFIG_THREAD_OPTIONROMS. Add runningOnQEMU() and runningOnXEN() ror runtime platform detection. Consistently use CONFIG_COREBOOT, CONFIG_QEMU, and runningOnXen(). Convert kvm_para_available() to runningOnKVM(). Minor - move definitions to paravirt.c from paravirt.h.
src/Kconfig | 24 ++++++++++++++------- src/apm.c | 3 ++- src/ata.c | 2 +- src/block.c | 2 +- src/blockcmd.c | 2 +- src/boot.c | 4 ++-- src/clock.c | 26 +++++++++++++--------- src/coreboot.c | 8 +++---- src/esp-scsi.c | 3 ++- src/floppy.c | 14 ++++++------ src/lsi-scsi.c | 3 ++- src/misc.c | 2 ++ src/mtrr.c | 4 ++-- src/optionroms.c | 2 +- src/output.c | 3 ++- src/paravirt.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++----- src/paravirt.h | 59 +++++++++++++++----------------------------------- src/pciinit.c | 4 ++-- src/post.c | 8 +++---- src/ramdisk.c | 2 +- src/resume.c | 6 +----- src/shadow.c | 12 +++++++---- src/smm.c | 9 ++------ src/smp.c | 8 +++---- src/stacks.c | 10 ++++----- src/virtio-blk.c | 4 ++-- src/virtio-scsi.c | 2 +- src/xen.c | 9 +++++--- src/xen.h | 11 ---------- 29 files changed, 172 insertions(+), 138 deletions(-)
Avoid reading/writing to cmos at runtime to get the QEMU century information. Instead, read it at startup and cache the info.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/clock.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/src/clock.c b/src/clock.c index 3edcaf5..bbcafd7 100644 --- a/src/clock.c +++ b/src/clock.c @@ -281,6 +281,8 @@ bcd2bin(u8 val) return (val & 0xf) + ((val >> 4) * 10); }
+u8 Century VARLOW; + void timer_setup(void) { @@ -297,6 +299,18 @@ timer_setup(void) ticks = ((u64)ticks * PIT_TICK_RATE) / PIT_TICK_INTERVAL; SET_BDA(timer_counter, ticks);
+ // Setup Century storage + if (CONFIG_QEMU) { + Century = inb_cmos(CMOS_CENTURY); + } else { + // Infer current century from the year. + u8 year = inb_cmos(CMOS_RTC_YEAR); + if (year > 0x80) + Century = 0x19; + else + Century = 0x20; + } + enable_hwirq(0, FUNC16(entry_08)); enable_hwirq(8, FUNC16(entry_70)); } @@ -420,14 +434,7 @@ handle_1a04(struct bregs *regs) regs->cl = inb_cmos(CMOS_RTC_YEAR); regs->dh = inb_cmos(CMOS_RTC_MONTH); regs->dl = inb_cmos(CMOS_RTC_DAY_MONTH); - if (CONFIG_COREBOOT) { - if (regs->cl > 0x80) - regs->ch = 0x19; - else - regs->ch = 0x20; - } else { - regs->ch = inb_cmos(CMOS_CENTURY); - } + regs->ch = GET_LOW(Century); regs->al = regs->ch; set_success(regs); } @@ -454,8 +461,7 @@ handle_1a05(struct bregs *regs) outb_cmos(regs->cl, CMOS_RTC_YEAR); outb_cmos(regs->dh, CMOS_RTC_MONTH); outb_cmos(regs->dl, CMOS_RTC_DAY_MONTH); - if (!CONFIG_COREBOOT) - outb_cmos(regs->ch, CMOS_CENTURY); + SET_LOW(Century, regs->ch); // clear halt-clock bit u8 val8 = inb_cmos(CMOS_STATUS_B) & ~RTC_B_SET; outb_cmos(val8, CMOS_STATUS_B);
CONFIG_THREAD_OPTIONROMS depends on CONFIG_THREADS, so the code can assume that the two are always on when CONFIG_THREAD_OPTIONROMS is on.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/post.c | 4 ++-- src/stacks.c | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/src/post.c b/src/post.c index 9930ae5..6c4ff70 100644 --- a/src/post.c +++ b/src/post.c @@ -170,7 +170,7 @@ platform_hardware_setup(void) xen_hypercall_setup();
// Start hardware initialization (if optionrom threading) - if (CONFIG_THREADS && CONFIG_THREAD_OPTIONROMS) + if (CONFIG_THREAD_OPTIONROMS) device_hardware_setup();
// Find and initialize other cpus @@ -229,7 +229,7 @@ maininit(void) vgarom_setup();
// Do hardware initialization (if running synchronously) - if (!CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS) { + if (!CONFIG_THREAD_OPTIONROMS) { device_hardware_setup(); wait_threads(); } diff --git a/src/stacks.c b/src/stacks.c index 9381729..93da7b5 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -431,7 +431,7 @@ static u32 PreemptCount; void start_preempt(void) { - if (! CONFIG_THREADS || ! CONFIG_THREAD_OPTIONROMS) + if (! CONFIG_THREAD_OPTIONROMS) return; CanPreempt = 1; PreemptCount = 0; @@ -442,7 +442,7 @@ start_preempt(void) void finish_preempt(void) { - if (! CONFIG_THREADS || ! CONFIG_THREAD_OPTIONROMS) { + if (! CONFIG_THREAD_OPTIONROMS) { yield(); return; } @@ -456,8 +456,7 @@ finish_preempt(void) int wait_preempt(void) { - if (MODESEGMENT || !CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS - || !CanPreempt) + if (MODESEGMENT || !CONFIG_THREAD_OPTIONROMS || !CanPreempt) return 0; while (CanPreempt) yield(); @@ -476,8 +475,7 @@ yield_preempt(void) void check_preempt(void) { - if (! CONFIG_THREADS || ! CONFIG_THREAD_OPTIONROMS - || !GET_GLOBAL(CanPreempt) + if (! CONFIG_THREAD_OPTIONROMS || !GET_GLOBAL(CanPreempt) || GET_FLATPTR(MainThread.next) == &MainThread) return;
Introduce standard for performing and inspecting the run-time detection of para-virtualized environments.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/Kconfig | 14 +++++++++++--- src/misc.c | 2 ++ src/paravirt.c | 5 +++++ src/paravirt.h | 20 ++++++++++++++++++-- src/xen.c | 7 +++++-- 5 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig index bbcefe0..6fd45b4 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -14,9 +14,10 @@ choice Configure as a coreboot payload.
config QEMU - bool "Build for QEMU" + bool "Build for QEMU/XEN/KVM/Bochs" + select QEMU_HARDWARE help - Configure as QEMU bios. + Configure for an emulated machine (QEMU, XEN, KVM, or Bochs).
config CSM bool "Build as Compatibilty Support Module for EFI BIOS" @@ -26,9 +27,16 @@ choice
endchoice
+ config QEMU_HARDWARE + bool "Support hardware found on emulators (QEMU/XEN/KVM/Bochs)" if !QEMU + default n + help + Support virtual hardware when the code detects it is + running on an emulator. + config XEN depends on QEMU - bool "Build for Xen HVM" + bool "Support Xen HVM" default y help Configure to be used by xen hvmloader, for a HVM guest. diff --git a/src/misc.c b/src/misc.c index bcc450a..3b2ffc1 100644 --- a/src/misc.c +++ b/src/misc.c @@ -16,6 +16,8 @@ u32 RamSize VAR16VISIBLE; u64 RamSizeOver4G; // Space for bios tables built an run-time. char BiosTableSpace[CONFIG_MAX_BIOSTABLE] __aligned(MALLOC_MIN_ALIGN) VAR16VISIBLE; +// Type of emulator platform. +int PlatformRunningOn VAR16VISIBLE;
/**************************************************************** diff --git a/src/paravirt.c b/src/paravirt.c index 9022186..6e230ee 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -24,6 +24,11 @@ int qemu_cfg_present; void qemu_ramsize_preinit(void) { + if (!CONFIG_QEMU) + return; + + PlatformRunningOn = PF_QEMU; + // 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 4f2d5b8..d32ca13 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -1,8 +1,24 @@ #ifndef __PV_H #define __PV_H
-#include "config.h" // CONFIG_COREBOOT -#include "util.h" +#include "config.h" // CONFIG_* +#include "util.h" // memcpy +#include "biosvar.h" // GET_GLOBAL + +// Types of paravirtualized platforms. +#define PF_QEMU (1<<0) +#define PF_XEN (1<<1) + +// misc.c +extern int PlatformRunningOn; + +static inline int runningOnQEMU(void) { + return CONFIG_QEMU || ( + CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU); +} +static inline int runningOnXen(void) { + return CONFIG_XEN && GET_GLOBAL(PlatformRunningOn) & PF_XEN; +}
/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It * should be used to determine that a VM is running under KVM. diff --git a/src/xen.c b/src/xen.c index c9759f0..e075af2 100644 --- a/src/xen.c +++ b/src/xen.c @@ -6,7 +6,7 @@
#include "config.h" #include "xen.h" - +#include "paravirt.h" // PlatformRunningOn #include "memmap.h" // add_e820 #include "types.h" // ASM32FLAT #include "util.h" // copy_acpi_rsdp @@ -76,8 +76,11 @@ void xen_preinit(void) break; } } - if (!xen_cpuid_base) + if (!xen_cpuid_base) { dprintf(1, "No Xen hypervisor found.\n"); + return; + } + PlatformRunningOn = PF_QEMU|PF_XEN; }
static int hypercall_xen_version( int cmd, void *arg)
CONFIG_QEMU means compile to start from QEMU (and possibly Xen/KVM/Bochs) and definitely running under QEMU (or Xen/KVM/Bochs).
CONFIG_COREBOOT means compile for coreboot and definitely running under coreboot. Places that used CONFIG_COREBOOT to mean "running on real hardware" have been changed to use !CONFIG_QEMU.
CONFIG_QEMU_HARDWARE enables support for some virtual hardware devices even if QEMU didn't start SeaBIOS.
usingXen() is replaced by runningOnXen().
runningOnQEMU() is added to hardware devices that are only safe to access when we are sure we are running under QEMU (or Xen/KVM/Bochs). Neither the coreboot nor the csm code currently enable runningOnQEMU, but future patches may.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/Kconfig | 10 +++++----- src/apm.c | 3 ++- src/ata.c | 2 +- src/block.c | 2 +- src/blockcmd.c | 2 +- src/boot.c | 4 ++-- src/coreboot.c | 8 ++++---- src/esp-scsi.c | 3 ++- src/floppy.c | 14 +++++++------- src/lsi-scsi.c | 3 ++- src/mtrr.c | 4 ++-- src/optionroms.c | 2 +- src/output.c | 3 ++- src/paravirt.c | 6 +++--- src/paravirt.h | 2 +- src/pciinit.c | 4 ++-- src/post.c | 4 ++-- src/ramdisk.c | 2 +- src/resume.c | 6 +----- src/shadow.c | 12 ++++++++---- src/smm.c | 9 ++------- src/smp.c | 8 ++++---- src/virtio-blk.c | 4 ++-- src/virtio-scsi.c | 2 +- src/xen.c | 2 +- src/xen.h | 11 ----------- 26 files changed, 60 insertions(+), 72 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig index 6fd45b4..fbcc03d 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -132,25 +132,25 @@ menu "Hardware support" help Support for AHCI disk code. config VIRTIO_BLK - depends on DRIVES && QEMU + depends on DRIVES && QEMU_HARDWARE bool "virtio-blk controllers" default y help Support boot from virtio-blk storage. config VIRTIO_SCSI - depends on DRIVES && QEMU + depends on DRIVES && QEMU_HARDWARE bool "virtio-scsi controllers" default y help Support boot from virtio-scsi storage. config ESP_SCSI - depends on DRIVES && QEMU + depends on DRIVES && QEMU_HARDWARE bool "AMD PCscsi controllers" default y help Support boot from AMD PCscsi storage. config LSI_SCSI - depends on DRIVES && QEMU + depends on DRIVES && QEMU_HARDWARE bool "lsi53c895a scsi controllers" default y help @@ -407,7 +407,7 @@ menu "Debugging" Base port for serial - generally 0x3f8, 0x2f8, 0x3e8, or 0x2e8.
config DEBUG_IO - depends on QEMU && DEBUG_LEVEL != 0 + depends on QEMU_HARDWARE && DEBUG_LEVEL != 0 bool "Special IO port debugging" default y help diff --git a/src/apm.c b/src/apm.c index 8daf958..b2eac6d 100644 --- a/src/apm.c +++ b/src/apm.c @@ -11,11 +11,12 @@ #include "util.h" // dprintf #include "config.h" // CONFIG_* #include "biosvar.h" // GET_GLOBAL +#include "paravirt.h" // runningOnQEMU
static void out_str(const char *str_cs) { - if (CONFIG_COREBOOT) { + if (!runningOnQEMU()) { dprintf(1, "APM request '%s'\n", str_cs); return; } diff --git a/src/ata.c b/src/ata.c index d1d8dff..59ae765 100644 --- a/src/ata.c +++ b/src/ata.c @@ -1008,7 +1008,7 @@ static const struct pci_device_id pci_ata_tbl[] = { static void ata_scan(void) { - if (!CONFIG_COREBOOT && !PCIDevices) { + if (CONFIG_QEMU && !PCIDevices) { // No PCI devices found - probably a QEMU "-M isapc" machine. // Try using ISA ports for ATA controllers. init_controller(NULL, IRQ_ATA1 diff --git a/src/block.c b/src/block.c index e5f3038..c202f5a 100644 --- a/src/block.c +++ b/src/block.c @@ -62,7 +62,7 @@ static u8 get_translation(struct drive_s *drive_g) { u8 type = GET_GLOBAL(drive_g->type); - if (! CONFIG_COREBOOT && type == DTYPE_ATA) { + if (CONFIG_QEMU && type == DTYPE_ATA) { // Emulators pass in the translation info via nvram. u8 ataid = GET_GLOBAL(drive_g->cntl_id); u8 channel = ataid / 2; diff --git a/src/blockcmd.c b/src/blockcmd.c index e033ba7..c3e4b58 100644 --- a/src/blockcmd.c +++ b/src/blockcmd.c @@ -165,7 +165,7 @@ scsi_drive_setup(struct drive_s *drive, const char *s, int prio) // but some old USB keys only support a very small subset of SCSI which // does not even include the MODE SENSE command! // - if (! CONFIG_COREBOOT && memcmp(vendor, "QEMU", 5) == 0) { + if (CONFIG_QEMU_HARDWARE && memcmp(vendor, "QEMU", 5) == 0) { struct cdbres_mode_sense_geom geomdata; ret = cdb_mode_sense_geom(&dop, &geomdata); if (ret == 0) { diff --git a/src/boot.c b/src/boot.c index 85d5051..f70e402 100644 --- a/src/boot.c +++ b/src/boot.c @@ -250,7 +250,7 @@ boot_init(void) if (! CONFIG_BOOT) return;
- if (!CONFIG_COREBOOT) { + if (CONFIG_QEMU) { // On emulators, get boot order from nvram. if (inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1) CheckFloppySig = 0; @@ -609,7 +609,7 @@ boot_cdrom(struct drive_s *drive_g) static void boot_cbfs(struct cbfs_file *file) { - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH) + if (!CONFIG_COREBOOT_FLASH) return; printf("Booting from CBFS...\n"); cbfs_run_payload(file); diff --git a/src/coreboot.c b/src/coreboot.c index 5d013cf..5d5e03b 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -294,7 +294,7 @@ struct cbfs_file { static int cbfs_copyfile(struct romfile_s *file, void *dst, u32 maxlen) { - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH) + if (!CONFIG_COREBOOT_FLASH) return -1;
u32 size = file->rawsize; @@ -326,7 +326,7 @@ cbfs_copyfile(struct romfile_s *file, void *dst, u32 maxlen) void coreboot_cbfs_init(void) { - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH) + if (!CONFIG_COREBOOT_FLASH) return;
struct cbfs_header *hdr = *(void **)CBFS_HEADPTR_ADDR; @@ -392,7 +392,7 @@ struct cbfs_payload { void cbfs_run_payload(struct cbfs_file *file) { - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !file) + if (!CONFIG_COREBOOT_FLASH || !file) return; dprintf(1, "Run %s\n", file->filename); struct cbfs_payload *pay = (void*)file + be32_to_cpu(file->offset); @@ -443,7 +443,7 @@ cbfs_run_payload(struct cbfs_file *file) void cbfs_payload_setup(void) { - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH) + if (!CONFIG_COREBOOT_FLASH) return; struct romfile_s *file = NULL; for (;;) { diff --git a/src/esp-scsi.c b/src/esp-scsi.c index 4d1f7d2..fe70366 100644 --- a/src/esp-scsi.c +++ b/src/esp-scsi.c @@ -18,6 +18,7 @@ #include "pci_regs.h" // PCI_VENDOR_ID #include "boot.h" // bootprio_find_scsi_device #include "blockcmd.h" // scsi_drive_setup +#include "paravirt.h" // runningOnQEMU #include "disk.h"
#define ESP_TCLO 0x00 @@ -218,7 +219,7 @@ void esp_scsi_setup(void) { ASSERT32FLAT(); - if (!CONFIG_ESP_SCSI) + if (!CONFIG_ESP_SCSI || !runningOnQEMU()) return;
dprintf(3, "init esp\n"); diff --git a/src/floppy.c b/src/floppy.c index e9f8916..2887e78 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -125,19 +125,19 @@ floppy_setup(void) return; dprintf(3, "init floppy drives\n");
- if (CONFIG_COREBOOT) { + if (CONFIG_QEMU) { + u8 type = inb_cmos(CMOS_FLOPPY_DRIVE_TYPE); + if (type & 0xf0) + addFloppy(0, type >> 4); + if (type & 0x0f) + addFloppy(1, type & 0x0f); + } else { u8 type = romfile_loadint("etc/floppy0", 0); if (type) addFloppy(0, type); type = romfile_loadint("etc/floppy1", 0); if (type) addFloppy(1, type); - } else { - u8 type = inb_cmos(CMOS_FLOPPY_DRIVE_TYPE); - if (type & 0xf0) - addFloppy(0, type >> 4); - if (type & 0x0f) - addFloppy(1, type & 0x0f); }
outb(0x02, PORT_DMA1_MASK_REG); diff --git a/src/lsi-scsi.c b/src/lsi-scsi.c index 76e9d1d..305610a 100644 --- a/src/lsi-scsi.c +++ b/src/lsi-scsi.c @@ -18,6 +18,7 @@ #include "pci_regs.h" // PCI_VENDOR_ID #include "boot.h" // bootprio_find_scsi_device #include "blockcmd.h" // scsi_drive_setup +#include "paravirt.h" // runningOnQEMU #include "disk.h"
#define LSI_REG_DSTAT 0x0c @@ -197,7 +198,7 @@ void lsi_scsi_setup(void) { ASSERT32FLAT(); - if (!CONFIG_LSI_SCSI) + if (!CONFIG_LSI_SCSI || !runningOnQEMU()) return;
dprintf(3, "init lsi53c895a\n"); diff --git a/src/mtrr.c b/src/mtrr.c index 2cbf234..0575b14 100644 --- a/src/mtrr.c +++ b/src/mtrr.c @@ -6,7 +6,7 @@
#include "util.h" // dprintf #include "config.h" // CONFIG_* -#include "xen.h" // usingXen +#include "paravirt.h" // runningOnXen #include "pci.h" // pcimem_start
#define MSR_MTRRcap 0x000000fe @@ -34,7 +34,7 @@
void mtrr_setup(void) { - if (!CONFIG_MTRR_INIT || CONFIG_COREBOOT || usingXen()) + if (!CONFIG_MTRR_INIT || runningOnXen()) return;
u32 eax, ebx, ecx, edx, cpuid_features; diff --git a/src/optionroms.c b/src/optionroms.c index c9e7d7b..971b9d6 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -425,7 +425,7 @@ vgarom_setup(void)
// Load some config settings that impact VGA. EnforceChecksum = romfile_loadint("etc/optionroms-checksum", 1); - S3ResumeVga = romfile_loadint("etc/s3-resume-vga-init", !CONFIG_COREBOOT); + S3ResumeVga = romfile_loadint("etc/s3-resume-vga-init", CONFIG_QEMU); ScreenAndDebug = romfile_loadint("etc/screen-and-debug", 1);
if (CONFIG_OPTIONROMS_DEPLOYED) { diff --git a/src/output.c b/src/output.c index e623d37..27621f5 100644 --- a/src/output.c +++ b/src/output.c @@ -11,6 +11,7 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "biosvar.h" // GET_GLOBAL +#include "paravirt.h" // runningOnQEMU
struct putcinfo { void (*func)(struct putcinfo *info, char c); @@ -77,7 +78,7 @@ putc_debug(struct putcinfo *action, char c) { if (! CONFIG_DEBUG_LEVEL) return; - if (CONFIG_DEBUG_IO) + if (CONFIG_DEBUG_IO && runningOnQEMU()) // Send character to debug port. outb(c, GET_GLOBAL(DebugOutputPort)); if (c == '\n') diff --git a/src/paravirt.c b/src/paravirt.c index 6e230ee..73b06ca 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -7,7 +7,7 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "config.h" // CONFIG_COREBOOT +#include "config.h" // CONFIG_QEMU #include "util.h" // dprintf #include "byteorder.h" // be32_to_cpu #include "ioport.h" // outw @@ -108,7 +108,7 @@ void qemu_cfg_preinit(void) char *sig = "QEMU"; int i;
- if (CONFIG_COREBOOT) + if (!CONFIG_QEMU) return;
qemu_cfg_present = 1; @@ -384,7 +384,7 @@ struct QemuCfgFile {
void qemu_romfile_init(void) { - if (CONFIG_COREBOOT || !qemu_cfg_present) + if (!CONFIG_QEMU || !qemu_cfg_present) return;
u32 count; diff --git a/src/paravirt.h b/src/paravirt.h index d32ca13..62b1664 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -27,7 +27,7 @@ static inline int runningOnXen(void) {
static inline int kvm_para_available(void) { - if (CONFIG_COREBOOT) + if (!CONFIG_QEMU) return 0; unsigned int eax, ebx, ecx, edx; char signature[13]; diff --git a/src/pciinit.c b/src/pciinit.c index 34b47b6..1d34653 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -11,7 +11,7 @@ #include "pci_regs.h" // PCI_COMMAND #include "ioport.h" // PORT_ATA1_CMD_BASE #include "config.h" // CONFIG_* -#include "xen.h" // usingXen +#include "paravirt.h" // runningOnXen #include "memmap.h" // add_e820 #include "dev-q35.h"
@@ -734,7 +734,7 @@ static void pci_bios_map_devices(struct pci_bus *busses) void pci_setup(void) { - if (CONFIG_COREBOOT || usingXen()) { + if (!CONFIG_QEMU || runningOnXen()) { // PCI setup already done by coreboot or Xen - just do probe. pci_probe_devices(); return; diff --git a/src/post.c b/src/post.c index 6c4ff70..2c5e34e 100644 --- a/src/post.c +++ b/src/post.c @@ -179,7 +179,7 @@ platform_hardware_setup(void) // Setup external BIOS interface tables if (CONFIG_COREBOOT) coreboot_biostable_setup(); - else if (usingXen()) + else if (runningOnXen()) xen_biostable_setup(); else qemu_biostable_setup(); @@ -319,7 +319,7 @@ dopost(void) qemu_cfg_preinit(); if (CONFIG_COREBOOT) coreboot_preinit(); - else if (usingXen()) + else if (runningOnXen()) xen_ramsize_preinit(); else qemu_ramsize_preinit(); diff --git a/src/ramdisk.c b/src/ramdisk.c index 9249a49..b9da2ad 100644 --- a/src/ramdisk.c +++ b/src/ramdisk.c @@ -88,7 +88,7 @@ ramdisk_copy(struct disk_op_s *op, int iswrite) int process_ramdisk_op(struct disk_op_s *op) { - if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !CONFIG_FLASH_FLOPPY) + if (!CONFIG_FLASH_FLOPPY) return 0;
switch (op->command) { diff --git a/src/resume.c b/src/resume.c index ffc84fc..adc3594 100644 --- a/src/resume.c +++ b/src/resume.c @@ -130,11 +130,7 @@ tryReboot(void) dprintf(1, "Attempting a hard reboot\n");
// Setup for reset on qemu. - if (! CONFIG_COREBOOT) { - qemu_prep_reset(); - if (HaveRunPost) - apm_shutdown(); - } + qemu_prep_reset();
// Try keyboard controller reboot. i8042_reboot(); diff --git a/src/shadow.c b/src/shadow.c index a2195da..c9e8165 100644 --- a/src/shadow.c +++ b/src/shadow.c @@ -10,7 +10,7 @@ #include "config.h" // CONFIG_* #include "pci_ids.h" // PCI_VENDOR_ID_INTEL #include "pci_regs.h" // PCI_VENDOR_ID -#include "xen.h" // usingXen +#include "paravirt.h" // runningOnXen #include "dev-q35.h" // PCI_VENDOR_ID_INTEL
// On the emulators, the bios at 0xf0000 is also at 0xffff0000 @@ -119,7 +119,7 @@ static const struct pci_device_id dram_controller_make_readonly_tbl[] = { void make_bios_writable(void) { - if (CONFIG_COREBOOT || usingXen()) + if (!CONFIG_QEMU || runningOnXen()) return;
dprintf(3, "enabling shadow ram\n"); @@ -148,7 +148,7 @@ make_bios_writable(void) void make_bios_readonly(void) { - if (CONFIG_COREBOOT || usingXen()) + if (!CONFIG_QEMU || runningOnXen()) return;
dprintf(3, "locking shadow ram\n"); @@ -161,7 +161,7 @@ make_bios_readonly(void) void qemu_prep_reset(void) { - if (CONFIG_COREBOOT) + if (!CONFIG_QEMU || runningOnXen()) return; // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a // reset, so do that manually before invoking a hard reset. @@ -169,4 +169,8 @@ qemu_prep_reset(void) extern u8 code32flat_start[], code32flat_end[]; memcpy(code32flat_start, code32flat_start + BIOS_SRC_OFFSET , code32flat_end - code32flat_start); + + if (HaveRunPost) + // Memory copy failed to work - try to halt the machine. + apm_shutdown(); } diff --git a/src/smm.c b/src/smm.c index c69f0fd..4128296 100644 --- a/src/smm.c +++ b/src/smm.c @@ -10,7 +10,7 @@ #include "config.h" // CONFIG_* #include "ioport.h" // outb #include "pci_ids.h" // PCI_VENDOR_ID_INTEL -#include "xen.h" // usingXen +#include "paravirt.h" // runningOnXen #include "dev-q35.h"
ASM32FLAT( @@ -184,12 +184,7 @@ static const struct pci_device_id smm_init_tbl[] = { void smm_setup(void) { - if (CONFIG_COREBOOT) - // SMM only supported on emulators. - return; - if (!CONFIG_USE_SMM) - return; - if (usingXen()) + if (!CONFIG_USE_SMM || runningOnXen()) return;
dprintf(3, "init smm\n"); diff --git a/src/smp.c b/src/smp.c index 18bb05f..394dc4b 100644 --- a/src/smp.c +++ b/src/smp.c @@ -113,7 +113,7 @@ smp_setup(void) u32 val = readl(APIC_SVR); writel(APIC_SVR, val | APIC_ENABLED);
- if (! CONFIG_COREBOOT) { + if (CONFIG_QEMU) { /* Set LINT0 as Ext_INT, level triggered */ writel(APIC_LINT0, 0x8700);
@@ -128,12 +128,12 @@ smp_setup(void) writel(APIC_ICR_LOW, 0x000C4600 | sipi_vector);
// Wait for other CPUs to process the SIPI. - if (CONFIG_COREBOOT) { - msleep(10); - } else { + if (CONFIG_QEMU) { u8 cmos_smp_count = inb_cmos(CMOS_BIOS_SMP_COUNT); while (cmos_smp_count + 1 != readl(&CountCPUs)) yield(); + } else { + msleep(10); }
// Restore memory. diff --git a/src/virtio-blk.c b/src/virtio-blk.c index 194deaf..6c0cd74 100644 --- a/src/virtio-blk.c +++ b/src/virtio-blk.c @@ -77,7 +77,7 @@ virtio_blk_op(struct disk_op_s *op, int write) int process_virtio_blk_op(struct disk_op_s *op) { - if (! CONFIG_VIRTIO_BLK || CONFIG_COREBOOT) + if (! CONFIG_VIRTIO_BLK) return 0; switch (op->command) { case CMD_READ: @@ -159,7 +159,7 @@ void virtio_blk_setup(void) { ASSERT32FLAT(); - if (! CONFIG_VIRTIO_BLK || CONFIG_COREBOOT) + if (! CONFIG_VIRTIO_BLK) return;
dprintf(3, "init virtio-blk\n"); diff --git a/src/virtio-scsi.c b/src/virtio-scsi.c index 4bbff8f..879ddfb 100644 --- a/src/virtio-scsi.c +++ b/src/virtio-scsi.c @@ -166,7 +166,7 @@ void virtio_scsi_setup(void) { ASSERT32FLAT(); - if (! CONFIG_VIRTIO_SCSI || CONFIG_COREBOOT) + if (! CONFIG_VIRTIO_SCSI) return;
dprintf(3, "init virtio-scsi\n"); diff --git a/src/xen.c b/src/xen.c index e075af2..32edcd1 100644 --- a/src/xen.c +++ b/src/xen.c @@ -95,7 +95,7 @@ void xen_hypercall_setup(void) xen_extraversion_t extraversion; unsigned long i;
- if (!usingXen()) + if (!runningOnXen()) return;
cpuid(xen_cpuid_base + 2, &eax, &ebx, &ecx, &edx); diff --git a/src/xen.h b/src/xen.h index 9b4178a..f00f840 100644 --- a/src/xen.h +++ b/src/xen.h @@ -1,22 +1,11 @@ #ifndef __XEN_H #define __XEN_H
-#include "config.h" // CONFIG_* -#include "types.h" // u32 - -extern u32 xen_cpuid_base; - void xen_preinit(void); void xen_ramsize_preinit(void); void xen_hypercall_setup(void); void xen_biostable_setup(void);
-static inline int usingXen(void) { - if (!CONFIG_XEN) - return 0; - return (xen_cpuid_base != 0); -} - extern unsigned long xen_hypercall_page;
#define _hypercall0(type, name) \
Make the KVM detection code use the same format as the QEMU/Xen detection code.
Also, log when KVM is detected.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/paravirt.c | 27 ++++++++++++++++++++++++++- src/paravirt.h | 28 ++++------------------------ 2 files changed, 30 insertions(+), 25 deletions(-)
diff --git a/src/paravirt.c b/src/paravirt.c index 73b06ca..7080c7f 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -21,6 +21,30 @@
int qemu_cfg_present;
+/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It + * should be used to determine that a VM is running under KVM. + */ +#define KVM_CPUID_SIGNATURE 0x40000000 + +static void kvm_preinit(void) +{ + if (!CONFIG_QEMU) + return; + unsigned int eax, ebx, ecx, edx; + char signature[13]; + + cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); + memcpy(signature + 0, &ebx, 4); + memcpy(signature + 4, &ecx, 4); + memcpy(signature + 8, &edx, 4); + signature[12] = 0; + + if (strcmp(signature, "KVMKVMKVM") == 0) { + dprintf(1, "Running on KVM\n"); + PlatformRunningOn |= PF_KVM; + } +} + void qemu_ramsize_preinit(void) { @@ -28,6 +52,7 @@ qemu_ramsize_preinit(void) return;
PlatformRunningOn = PF_QEMU; + kvm_preinit();
// On emulators, get memory size from nvram. u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) @@ -60,7 +85,7 @@ qemu_ramsize_preinit(void) qemu_cfg_e820_load_next(&entry); add_e820(entry.address, entry.length, entry.type); } - } else if (kvm_para_available()) { + } else if (runningOnKVM()) { // Backwards compatibility - provide hard coded range. // 4 pages before the bios, 3 pages for vmx tss pages, the // other page for EPT real mode pagetable diff --git a/src/paravirt.h b/src/paravirt.h index 62b1664..208d0fb 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -2,12 +2,12 @@ #define __PV_H
#include "config.h" // CONFIG_* -#include "util.h" // memcpy #include "biosvar.h" // GET_GLOBAL
// Types of paravirtualized platforms. #define PF_QEMU (1<<0) #define PF_XEN (1<<1) +#define PF_KVM (1<<2)
// misc.c extern int PlatformRunningOn; @@ -19,31 +19,11 @@ static inline int runningOnQEMU(void) { static inline int runningOnXen(void) { return CONFIG_XEN && GET_GLOBAL(PlatformRunningOn) & PF_XEN; } - -/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It - * should be used to determine that a VM is running under KVM. - */ -#define KVM_CPUID_SIGNATURE 0x40000000 - -static inline int kvm_para_available(void) -{ - if (!CONFIG_QEMU) - return 0; - unsigned int eax, ebx, ecx, edx; - char signature[13]; - - cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); - memcpy(signature + 0, &ebx, 4); - memcpy(signature + 4, &ecx, 4); - memcpy(signature + 8, &edx, 4); - signature[12] = 0; - - if (strcmp(signature, "KVMKVMKVM") == 0) - return 1; - - return 0; +static inline int runningOnKVM(void) { + return CONFIG_QEMU && GET_GLOBAL(PlatformRunningOn) & PF_KVM; }
+// QEMU "firmware config (fw_cfg)" interface #define QEMU_CFG_SIGNATURE 0x00 #define QEMU_CFG_ID 0x01 #define QEMU_CFG_UUID 0x02
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/paravirt.c | 26 +++++++++++++++++++++++++- src/paravirt.h | 21 --------------------- 2 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/src/paravirt.c b/src/paravirt.c index 7080c7f..cc64094 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -19,7 +19,11 @@ #include "mptable.h" // mptable_setup #include "pci.h" // create_pirtable
-int qemu_cfg_present; +struct e820_reservation { + u64 address; + u64 length; + u32 type; +};
/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It * should be used to determine that a VM is running under KVM. @@ -102,6 +106,26 @@ qemu_biostable_setup(void) acpi_setup(); }
+ +/**************************************************************** + * QEMU firmware config (fw_cfg) interface + ****************************************************************/ + +int qemu_cfg_present; + +#define QEMU_CFG_SIGNATURE 0x00 +#define QEMU_CFG_ID 0x01 +#define QEMU_CFG_UUID 0x02 +#define QEMU_CFG_NUMA 0x0d +#define QEMU_CFG_BOOT_MENU 0x0e +#define QEMU_CFG_MAX_CPUS 0x0f +#define QEMU_CFG_FILE_DIR 0x19 +#define QEMU_CFG_ARCH_LOCAL 0x8000 +#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0) +#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1) +#define QEMU_CFG_IRQ0_OVERRIDE (QEMU_CFG_ARCH_LOCAL + 2) +#define QEMU_CFG_E820_TABLE (QEMU_CFG_ARCH_LOCAL + 3) + static void qemu_cfg_select(u16 f) { diff --git a/src/paravirt.h b/src/paravirt.h index 208d0fb..a3da04d 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -23,22 +23,6 @@ static inline int runningOnKVM(void) { return CONFIG_QEMU && GET_GLOBAL(PlatformRunningOn) & PF_KVM; }
-// QEMU "firmware config (fw_cfg)" interface -#define QEMU_CFG_SIGNATURE 0x00 -#define QEMU_CFG_ID 0x01 -#define QEMU_CFG_UUID 0x02 -#define QEMU_CFG_NUMA 0x0d -#define QEMU_CFG_BOOT_MENU 0x0e -#define QEMU_CFG_MAX_CPUS 0x0f -#define QEMU_CFG_FILE_DIR 0x19 -#define QEMU_CFG_ARCH_LOCAL 0x8000 -#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0) -#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1) -#define QEMU_CFG_IRQ0_OVERRIDE (QEMU_CFG_ARCH_LOCAL + 2) -#define QEMU_CFG_E820_TABLE (QEMU_CFG_ARCH_LOCAL + 3) - -extern int qemu_cfg_present; - void qemu_ramsize_preinit(void); void qemu_biostable_setup(void); void qemu_cfg_preinit(void); @@ -55,11 +39,6 @@ int qemu_cfg_smbios_load_external(int type, char **p, unsigned *nr_structs, int qemu_cfg_get_numa_nodes(void); void qemu_cfg_get_numa_data(u64 *data, int n); u16 qemu_cfg_get_max_cpus(void); -struct e820_reservation { - u64 address; - u64 length; - u32 type; -}; u32 qemu_cfg_e820_entries(void); void* qemu_cfg_e820_load_next(void *addr); void qemu_romfile_init(void);
On Sat, 2013-02-09 at 14:08 -0500, Kevin O'Connor wrote:
This patch series is less ambitious than the previous - SeaBIOS can't be compiled for multiple platforms (eg, QEMU, CSM, coreboot) at the same time.
Out of interest, why not include Xen in that list? Do we gain any real benefit from building a multi-platform binary that can be used both natively under qemu *and* from Xen?
Thoroughly untested patch on top of your series at git://github.com/KevinOConnor/seabios.git test-20130209
How would I go about testing this myself? And should CONFIG_XEN select CONFIG_QEMU_HARDWARE, as CONFIG_QEMU does? There a no users of runningOnXen() now, so perhaps that can be removed too?
By losing some of the runtime tests and making them purely config-based, the image size for Xen drops from 139KiB to 116KiB. And that's with MTRR, SMM and all the bios tables turned off in the config.
commit eff724e682ce557cd9d4a09d7892cb28950bb886 Author: David Woodhouse David.Woodhouse@intel.com Date: Mon Feb 11 10:47:47 2013 +0000
Make Xen one of the top-level build target choices
Signed-off-by: David Woodhouse David.Woodhouse@intel.com
diff --git a/src/Kconfig b/src/Kconfig index 6dbea79..f5dab76 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -14,10 +14,10 @@ choice Configure as a coreboot payload.
config QEMU - bool "Build for QEMU/Xen/KVM/Bochs" + bool "Build for QEMU/KVM/Bochs" select QEMU_HARDWARE help - Configure for an emulated machine (QEMU, Xen, KVM, or Bochs). + Configure for an emulated machine (QEMU, KVM, or Bochs).
config CSM bool "Build as Compatibilty Support Module for EFI BIOS" @@ -25,6 +25,11 @@ choice Configure to be used by EFI firmware as Compatibility Support module (CSM) to provide legacy BIOS services.
+ config XEN + bool "Build for Xen HVM" + help + Configure to be used by xen hvmloader, for a HVM guest. + endchoice
config QEMU_HARDWARE @@ -34,13 +39,6 @@ endchoice Support virtual hardware when the code detects it is running on an emulator.
- config XEN - depends on QEMU - bool "Support Xen HVM" - default y - help - Configure to be used by xen hvmloader, for a HVM guest. - config THREADS bool "Parallelize hardware init" default y diff --git a/src/mtrr.c b/src/mtrr.c index 0575b14..56f85f9 100644 --- a/src/mtrr.c +++ b/src/mtrr.c @@ -6,7 +6,6 @@
#include "util.h" // dprintf #include "config.h" // CONFIG_* -#include "paravirt.h" // runningOnXen #include "pci.h" // pcimem_start
#define MSR_MTRRcap 0x000000fe @@ -34,7 +33,7 @@
void mtrr_setup(void) { - if (!CONFIG_MTRR_INIT || runningOnXen()) + if (!CONFIG_MTRR_INIT) return;
u32 eax, ebx, ecx, edx, cpuid_features; diff --git a/src/pciinit.c b/src/pciinit.c index 1d34653..0781b96 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -11,7 +11,6 @@ #include "pci_regs.h" // PCI_COMMAND #include "ioport.h" // PORT_ATA1_CMD_BASE #include "config.h" // CONFIG_* -#include "paravirt.h" // runningOnXen #include "memmap.h" // add_e820 #include "dev-q35.h"
@@ -734,7 +733,7 @@ static void pci_bios_map_devices(struct pci_bus *busses) void pci_setup(void) { - if (!CONFIG_QEMU || runningOnXen()) { + if (!CONFIG_QEMU) { // PCI setup already done by coreboot or Xen - just do probe. pci_probe_devices(); return; diff --git a/src/post.c b/src/post.c index 2c5e34e..c76144a 100644 --- a/src/post.c +++ b/src/post.c @@ -179,7 +179,7 @@ platform_hardware_setup(void) // Setup external BIOS interface tables if (CONFIG_COREBOOT) coreboot_biostable_setup(); - else if (runningOnXen()) + else if (CONFIG_XEN) xen_biostable_setup(); else qemu_biostable_setup(); @@ -319,7 +319,7 @@ dopost(void) qemu_cfg_preinit(); if (CONFIG_COREBOOT) coreboot_preinit(); - else if (runningOnXen()) + else if (CONFIG_XEN) xen_ramsize_preinit(); else qemu_ramsize_preinit(); diff --git a/src/shadow.c b/src/shadow.c index c9e8165..026d966 100644 --- a/src/shadow.c +++ b/src/shadow.c @@ -10,7 +10,6 @@ #include "config.h" // CONFIG_* #include "pci_ids.h" // PCI_VENDOR_ID_INTEL #include "pci_regs.h" // PCI_VENDOR_ID -#include "paravirt.h" // runningOnXen #include "dev-q35.h" // PCI_VENDOR_ID_INTEL
// On the emulators, the bios at 0xf0000 is also at 0xffff0000 @@ -119,7 +118,7 @@ static const struct pci_device_id dram_controller_make_readonly_tbl[] = { void make_bios_writable(void) { - if (!CONFIG_QEMU || runningOnXen()) + if (!CONFIG_QEMU) return;
dprintf(3, "enabling shadow ram\n"); @@ -148,7 +147,7 @@ make_bios_writable(void) void make_bios_readonly(void) { - if (!CONFIG_QEMU || runningOnXen()) + if (!CONFIG_QEMU) return;
dprintf(3, "locking shadow ram\n"); @@ -161,7 +160,7 @@ make_bios_readonly(void) void qemu_prep_reset(void) { - if (!CONFIG_QEMU || runningOnXen()) + if (!CONFIG_QEMU) return; // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a // reset, so do that manually before invoking a hard reset. diff --git a/src/smm.c b/src/smm.c index 4128296..2083804 100644 --- a/src/smm.c +++ b/src/smm.c @@ -10,7 +10,6 @@ #include "config.h" // CONFIG_* #include "ioport.h" // outb #include "pci_ids.h" // PCI_VENDOR_ID_INTEL -#include "paravirt.h" // runningOnXen #include "dev-q35.h"
ASM32FLAT( @@ -184,8 +183,8 @@ static const struct pci_device_id smm_init_tbl[] = { void smm_setup(void) { - if (!CONFIG_USE_SMM || runningOnXen()) - return; + if (!CONFIG_USE_SMM) + return;
dprintf(3, "init smm\n"); pci_find_init_device(smm_init_tbl, NULL); diff --git a/src/xen.c b/src/xen.c index 32edcd1..e8ca9e0 100644 --- a/src/xen.c +++ b/src/xen.c @@ -76,10 +76,9 @@ void xen_preinit(void) break; } } - if (!xen_cpuid_base) { - dprintf(1, "No Xen hypervisor found.\n"); - return; - } + if (!xen_cpuid_base) + panic("No Xen hypervisor found.\n"); + PlatformRunningOn = PF_QEMU|PF_XEN; }
@@ -95,7 +94,7 @@ void xen_hypercall_setup(void) xen_extraversion_t extraversion; unsigned long i;
- if (!runningOnXen()) + if (!CONFIG_XEN) return;
cpuid(xen_cpuid_base + 2, &eax, &ebx, &ecx, &edx);
On Mon, 2013-02-11 at 10:54 +0000, David Woodhouse wrote:
On Sat, 2013-02-09 at 14:08 -0500, Kevin O'Connor wrote:
This patch series is less ambitious than the previous - SeaBIOS can't be compiled for multiple platforms (eg, QEMU, CSM, coreboot) at the same time.
Out of interest, why not include Xen in that list? Do we gain any real benefit from building a multi-platform binary that can be used both natively under qemu *and* from Xen?
I suppose it could be argued that from the PoV of SeaBIOS a Xen guest (which uses qemu for device models) is not all that different from qemu/kvm.
I don't know if distros prefer to have fewer images or not, once you have 2 I guess having N is not such a big deal for something the size and build time of SeaBIOS.
I don't have any objections to either approach from the Xen PoV.
Thoroughly untested patch on top of your series at git://github.com/KevinOConnor/seabios.git test-20130209
How would I go about testing this myself?
You would need to install and configure Xen. It's not as complex as it once was but it isn't a 5 minute hack either. I'm happy to give details if you like though.
And should CONFIG_XEN select CONFIG_QEMU_HARDWARE, as CONFIG_QEMU does?
Does QEMU_HARDWARE mean hardware "defined" (so to speak) by QEMU (e.g. virtio type stuff) or does it include regular hardware emulated by QEMU (e.g. real IDE disks etc). Xen uses the latter but not the former. The use of the symbol in both the CONFIG_VIRTIO_FOO and scsi_drive_setup() suggests it covers both?
There a no users of runningOnXen() now, so perhaps that can be removed too?
Might as well?
By losing some of the runtime tests and making them purely config-based, the image size for Xen drops from 139KiB to 116KiB. And that's with MTRR, SMM and all the bios tables turned off in the config.
commit eff724e682ce557cd9d4a09d7892cb28950bb886 Author: David Woodhouse David.Woodhouse@intel.com Date: Mon Feb 11 10:47:47 2013 +0000
Make Xen one of the top-level build target choices Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
diff --git a/src/Kconfig b/src/Kconfig index 6dbea79..f5dab76 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -14,10 +14,10 @@ choice Configure as a coreboot payload.
config QEMU
bool "Build for QEMU/Xen/KVM/Bochs"
bool "Build for QEMU/KVM/Bochs" select QEMU_HARDWARE help
Configure for an emulated machine (QEMU, Xen, KVM, or Bochs).
Configure for an emulated machine (QEMU, KVM, or Bochs).
config CSM bool "Build as Compatibilty Support Module for EFI BIOS"
@@ -25,6 +25,11 @@ choice Configure to be used by EFI firmware as Compatibility Support module (CSM) to provide legacy BIOS services.
- config XEN
bool "Build for Xen HVM"
help
Configure to be used by xen hvmloader, for a HVM guest.
endchoice
config QEMU_HARDWARE
@@ -34,13 +39,6 @@ endchoice Support virtual hardware when the code detects it is running on an emulator.
- config XEN
depends on QEMU
bool "Support Xen HVM"
default y
help
Configure to be used by xen hvmloader, for a HVM guest.
- config THREADS bool "Parallelize hardware init" default y
diff --git a/src/mtrr.c b/src/mtrr.c index 0575b14..56f85f9 100644 --- a/src/mtrr.c +++ b/src/mtrr.c @@ -6,7 +6,6 @@
#include "util.h" // dprintf #include "config.h" // CONFIG_* -#include "paravirt.h" // runningOnXen #include "pci.h" // pcimem_start
#define MSR_MTRRcap 0x000000fe @@ -34,7 +33,7 @@
void mtrr_setup(void) {
- if (!CONFIG_MTRR_INIT || runningOnXen())
if (!CONFIG_MTRR_INIT) return;
u32 eax, ebx, ecx, edx, cpuid_features;
diff --git a/src/pciinit.c b/src/pciinit.c index 1d34653..0781b96 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -11,7 +11,6 @@ #include "pci_regs.h" // PCI_COMMAND #include "ioport.h" // PORT_ATA1_CMD_BASE #include "config.h" // CONFIG_* -#include "paravirt.h" // runningOnXen #include "memmap.h" // add_e820 #include "dev-q35.h"
@@ -734,7 +733,7 @@ static void pci_bios_map_devices(struct pci_bus *busses) void pci_setup(void) {
- if (!CONFIG_QEMU || runningOnXen()) {
- if (!CONFIG_QEMU) { // PCI setup already done by coreboot or Xen - just do probe. pci_probe_devices(); return;
diff --git a/src/post.c b/src/post.c index 2c5e34e..c76144a 100644 --- a/src/post.c +++ b/src/post.c @@ -179,7 +179,7 @@ platform_hardware_setup(void) // Setup external BIOS interface tables if (CONFIG_COREBOOT) coreboot_biostable_setup();
- else if (runningOnXen())
- else if (CONFIG_XEN) xen_biostable_setup(); else qemu_biostable_setup();
@@ -319,7 +319,7 @@ dopost(void) qemu_cfg_preinit(); if (CONFIG_COREBOOT) coreboot_preinit();
- else if (runningOnXen())
- else if (CONFIG_XEN) xen_ramsize_preinit(); else qemu_ramsize_preinit();
diff --git a/src/shadow.c b/src/shadow.c index c9e8165..026d966 100644 --- a/src/shadow.c +++ b/src/shadow.c @@ -10,7 +10,6 @@ #include "config.h" // CONFIG_* #include "pci_ids.h" // PCI_VENDOR_ID_INTEL #include "pci_regs.h" // PCI_VENDOR_ID -#include "paravirt.h" // runningOnXen #include "dev-q35.h" // PCI_VENDOR_ID_INTEL
// On the emulators, the bios at 0xf0000 is also at 0xffff0000 @@ -119,7 +118,7 @@ static const struct pci_device_id dram_controller_make_readonly_tbl[] = { void make_bios_writable(void) {
- if (!CONFIG_QEMU || runningOnXen())
if (!CONFIG_QEMU) return;
dprintf(3, "enabling shadow ram\n");
@@ -148,7 +147,7 @@ make_bios_writable(void) void make_bios_readonly(void) {
- if (!CONFIG_QEMU || runningOnXen())
if (!CONFIG_QEMU) return;
dprintf(3, "locking shadow ram\n");
@@ -161,7 +160,7 @@ make_bios_readonly(void) void qemu_prep_reset(void) {
- if (!CONFIG_QEMU || runningOnXen())
- if (!CONFIG_QEMU) return; // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a // reset, so do that manually before invoking a hard reset.
diff --git a/src/smm.c b/src/smm.c index 4128296..2083804 100644 --- a/src/smm.c +++ b/src/smm.c @@ -10,7 +10,6 @@ #include "config.h" // CONFIG_* #include "ioport.h" // outb #include "pci_ids.h" // PCI_VENDOR_ID_INTEL -#include "paravirt.h" // runningOnXen #include "dev-q35.h"
ASM32FLAT( @@ -184,8 +183,8 @@ static const struct pci_device_id smm_init_tbl[] = { void smm_setup(void) {
- if (!CONFIG_USE_SMM || runningOnXen())
- return;
if (!CONFIG_USE_SMM)
return;
dprintf(3, "init smm\n"); pci_find_init_device(smm_init_tbl, NULL);
diff --git a/src/xen.c b/src/xen.c index 32edcd1..e8ca9e0 100644 --- a/src/xen.c +++ b/src/xen.c @@ -76,10 +76,9 @@ void xen_preinit(void) break; } }
- if (!xen_cpuid_base) {
dprintf(1, "No Xen hypervisor found.\n");
return;
- }
- if (!xen_cpuid_base)
panic("No Xen hypervisor found.\n");
- PlatformRunningOn = PF_QEMU|PF_XEN;
}
@@ -95,7 +94,7 @@ void xen_hypercall_setup(void) xen_extraversion_t extraversion; unsigned long i;
- if (!runningOnXen())
if (!CONFIG_XEN) return;
cpuid(xen_cpuid_base + 2, &eax, &ebx, &ecx, &edx);
On Mon, 2013-02-11 at 12:43 +0000, Ian Campbell wrote:
I don't know if distros prefer to have fewer images or not, once you have 2 I guess having N is not such a big deal for something the size and build time of SeaBIOS.
Probably not. It's not as if supporting Xen is an otherwise trivial exercise for the distros anyway; the effort of having an extra SeaBIOS binary is probably lost in the noise.
I don't have any objections to either approach from the Xen PoV.
Thoroughly untested patch on top of your series at git://github.com/KevinOConnor/seabios.git test-20130209
How would I go about testing this myself?
You would need to install and configure Xen. It's not as complex as it once was but it isn't a 5 minute hack either. I'm happy to give details if you like though.
Yes please.
I take it the first step is running 'yum install xen' on my Fedora workstation, and rebooting into Xen with the Fedora kernel as Dom0?
And should CONFIG_XEN select CONFIG_QEMU_HARDWARE, as CONFIG_QEMU does?
Does QEMU_HARDWARE mean hardware "defined" (so to speak) by QEMU (e.g. virtio type stuff) or does it include regular hardware emulated by QEMU (e.g. real IDE disks etc). Xen uses the latter but not the former. The use of the symbol in both the CONFIG_VIRTIO_FOO and scsi_drive_setup() suggests it covers both?
I think it's supposed to be the former, and would argue (and submit patches) that it *should* be the case even if Kevin's patch series doesn't quite do that. So that includes virtio *and* the emulated LSI and ESP SCSI controllers, since nobody's ever actually tested those on real hardware. The bit in scsi_driver_setup() looks right. It's doing the mode sense *only* if it's a qemu-emulated drive and it therefore knows it's safe to do so.
On Mon, Feb 11, 2013 at 05:28:11PM +0000, David Woodhouse wrote:
Does QEMU_HARDWARE mean hardware "defined" (so to speak) by QEMU (e.g. virtio type stuff) or does it include regular hardware emulated by QEMU (e.g. real IDE disks etc). Xen uses the latter but not the former. The use of the symbol in both the CONFIG_VIRTIO_FOO and scsi_drive_setup() suggests it covers both?
I think it's supposed to be the former, and would argue (and submit patches) that it *should* be the case even if Kevin's patch series doesn't quite do that.
The intent was to implement the former (QEMU_HARDWARE encapsulate virtual hardware and hardware we only trust in virtual environments - virtio, lsi, esp, debug io, etc). Did the patch get something wrong?
-Kevin
On Mon, 2013-02-11 at 19:41 -0500, Kevin O'Connor wrote:
On Mon, Feb 11, 2013 at 05:28:11PM +0000, David Woodhouse wrote:
Does QEMU_HARDWARE mean hardware "defined" (so to speak) by QEMU (e.g. virtio type stuff) or does it include regular hardware emulated by QEMU (e.g. real IDE disks etc). Xen uses the latter but not the former. The use of the symbol in both the CONFIG_VIRTIO_FOO and scsi_drive_setup() suggests it covers both?
I think it's supposed to be the former, and would argue (and submit patches) that it *should* be the case even if Kevin's patch series doesn't quite do that.
The intent was to implement the former (QEMU_HARDWARE encapsulate virtual hardware and hardware we only trust in virtual environments - virtio, lsi, esp, debug io, etc). Did the patch get something wrong?
I don't think so, although my Xen patch may have screwed it up if they do indeed use the fw_cfg stuff. I meant to ask about that; thanks for catching it.
On Mon, 2013-02-11 at 17:28 +0000, David Woodhouse wrote:
On Mon, 2013-02-11 at 12:43 +0000, Ian Campbell wrote:
I don't know if distros prefer to have fewer images or not, once you have 2 I guess having N is not such a big deal for something the size and build time of SeaBIOS.
Probably not. It's not as if supporting Xen is an otherwise trivial exercise for the distros anyway; the effort of having an extra SeaBIOS binary is probably lost in the noise.
I don't have any objections to either approach from the Xen PoV.
Thoroughly untested patch on top of your series at git://github.com/KevinOConnor/seabios.git test-20130209
How would I go about testing this myself?
You would need to install and configure Xen. It's not as complex as it once was but it isn't a 5 minute hack either. I'm happy to give details if you like though.
Yes please.
I take it the first step is running 'yum install xen' on my Fedora workstation, and rebooting into Xen with the Fedora kernel as Dom0?
I was going to say no, you need to build from source if you want to experiment with different SeaBIOS versions, but actually that isn't quite true -- you can install from packages and then use the packaged source to rebuild hvmloader against the newer SeaBIOS. This is a path less trodden but I guess might be simpler for you? You'll need a version of Fedora which includes Xen 4.2, since that is where seabios became an option, I expect this means Fedora 18+ is required.
I've CC'd Dario who is the Fedora user on our team, since I'm a Debian type myself and generally build Xen from source anyhow I'm not 100% confident in some of the bits below which may be tweaked by distros.
For docs you can find a few bits about Xen on Fedora at http://wiki.xen.org/wiki/Category:Fedora especially http://wiki.xen.org/wiki/Fedora_Host_Installation but basic install is as you suggest "yum install xen" and reboot (but see the wiki for stuff on how to tame network manager etc, if you haven't already for other reasons).
At this point you'll want to create a guest, I don't think you actually need a fully functioning one to test SeaBIOS. I suppose the Fedora way to do this would be to use virt-install or virt-manager or something (perhaps Dario can advise), but I'd be tempted to just use the xen command line tools.
There are two toolstacks in Xen today but only the new "xl" toolstack supports using SeaBIOS, the deprecated xend toolstack doesn't have this option. I'm afraid I've no idea which Fedora 18 defaults to (I hope this is something Dario can clarify), if it is xend then you will need to chkconfig xend off and perhaps reboot. If xend is running then xl will complain.
First create a guest configuration file (seabios.cfg) with the following: builder = "hvm" name = "seabios" device_model_version_override = "qemu-xen" memory = 512 serial = 'pty'
This doesn't include any disks or nics, but should boot enough to test basic seabios up until the "no bootable device" message. A nic is easy to add: vif = [''] will create one with a random mac, add mac=xx:xx:xx:xx:xx inside the '' if you want something specific.
To add a disk using a physical backing device (e.g. LVM volume): disk = ['phy:/dev/VOl00/VM,hda,w'] Or to use e.g. a qcow image: disk = ['qcow:/images/seabios.qcow,hda,w'] A raw file would be file:/....
You can also add vnc = 1 to enable that. xl.cfg(5) explains most of the interesting options
Then to start the guest: xl create -c seabios.cfg this will start the guest and connect to the serial console (-c), Ctrl=] to disconnect. "xl console seabios" to connect manually.
To kill the guest: xl dest seabios
I often use "create -e" to stop xl from automatically restarting a crashed domain, which is handy if hvmloader/seabios is crashing early on.
Once you have a guest running you'll want to rebuild hvmloader (lets try without a custom seabios first). To do that grab and unpack the .src.rpm (I expect you know better than I how to do this, rpm -bp perhaps?).
Once you have the tree you can: ./configure make -C tools/firmware to rebuild just seabios + hvmloader. The result is in tools/firmware/hvmloader/hvmloader which you can copy to /usr/lib/xen/boot/hvmloader or override by adding firmware_override = "/path/to/hvmloader" to your cfg.
Lastly to change the seabios bits, just change to tools/firmware/seabios-dir (assuming Fedora's packaging hasn't moved it) and git fetch/git reset/vim/emacs, the build system won't clobber this unless you ask it to. Then to rebuild: rm tools/firmware/hvmloader/seabios.o \ tools/firmware/seabios-dir/out/bios.bin \ tools/firmware/hvmloader/roms.inc make -C tools/firmware
(the rm is just a bit of paranoia to make sure it gets rebuilt)
The other thing which might be useful is to build a debug hypervisor, since this allows guest debug (e.g. from seabios magic i/o writes) to go the xen console (visible in "xl dmesg"), to do this just make debug=y dist-xen Then you will find a new Xen in dist/install/boot/ which you can copy to /boot and add to your bootloader etc.
I can explain the full build from source dance too if that would be useful. Looking at all the Fedora-isms above which I'm not sure about, maybe that would have been easier...
Obviously I'm also happy to test proposed changes.
Ian.
On Tue, 2013-02-12 at 10:34 +0000, Ian Campbell wrote:
On Mon, 2013-02-11 at 17:28 +0000, David Woodhouse wrote:
I take it the first step is running 'yum install xen' on my Fedora workstation, and rebooting into Xen with the Fedora kernel as Dom0?
I was going to say no, you need to build from source if you want to experiment with different SeaBIOS versions, but actually that isn't quite true -- you can install from packages and then use the packaged source to rebuild hvmloader against the newer SeaBIOS. This is a path less trodden but I guess might be simpler for you? You'll need a version of Fedora which includes Xen 4.2, since that is where seabios became an option, I expect this means Fedora 18+ is required.
Yes, anything below Fedora 18 ships Xen 4.1.something.
I've CC'd Dario who is the Fedora user on our team, since I'm a Debian type myself and generally build Xen from source anyhow I'm not 100% confident in some of the bits below which may be tweaked by distros.
Here I am. :-)
For docs you can find a few bits about Xen on Fedora at http://wiki.xen.org/wiki/Category:Fedora especially http://wiki.xen.org/wiki/Fedora_Host_Installation but basic install is as you suggest "yum install xen" and reboot (but see the wiki for stuff on how to tame network manager etc, if you haven't already for other reasons).
Yes, please, have a look at those pages and feel free to let me know if you find anything unclear or wrong! Also, I refactored the Fedora_Host_Installation page quite a bit this morning, so check it out again, even if you've been there before.
At this point you'll want to create a guest, I don't think you actually need a fully functioning one to test SeaBIOS. I suppose the Fedora way to do this would be to use virt-install or virt-manager or something (perhaps Dario can advise), but I'd be tempted to just use the xen command line tools.
Well, that depends on what you install. After an `yum install xen' + reboot, you don't have any libvirt related package installed, and you can go ahead using xl, as Ian describes.
Xend is not started automatically on boot so, again, xl is what is most suitable in this situation.
That being said, if you go on and install the various libvirt-* packages, as suggested in that page, virt-manager and virt-install will become options, but (due to some bug we're chasing but haven't fixed yet in Fedora), that will cause xend to run, which, on its turn, will make using xl impossible.
So, what toolstack you want to use, is indeed up to you. I'm not familiar with SeaBIOS and with the kind of tests you want to run but, from what I understand reading the rest of this e-mail, I also recommend just stopping after `yum install xen' and using xl _instead_ of libvirt.
There are two toolstacks in Xen today but only the new "xl" toolstack supports using SeaBIOS, the deprecated xend toolstack doesn't have this option. I'm afraid I've no idea which Fedora 18 defaults to (I hope this is something Dario can clarify), if it is xend then you will need to chkconfig xend off and perhaps reboot. If xend is running then xl will complain.
Well, I guess we can say that, as far as only Xen is installed, since xend is not started, the default toolstack is actually xl on Fedora too.
First create a guest configuration file (seabios.cfg) with the following: builder = "hvm" name = "seabios" device_model_version_override = "qemu-xen" memory = 512 serial = 'pty'
This doesn't include any disks or nics, but should boot enough to test basic seabios up until the "no bootable device" message. A nic is easy to add: vif = [''] will create one with a random mac, add mac=xx:xx:xx:xx:xx inside the '' if you want something specific.
In which case I think (if you want the NIC to work) you need to configure a bridge. The Fedora_Host_Installation wiki page should have all the info you need wrt this.
If there is anything you think I can be of more help with, please, do not hesitate to ask. :-)
Regards, Dario
On Tue, 2013-02-12 at 18:58 +0100, Dario Faggioli wrote:
So, what toolstack you want to use, is indeed up to you.
Using SeaBIOS requires you to use xl and not xend/xm, so there isn't really any choice here. Which in turn implies that virt-* is not currently an option so the direct command line method I outlined is the way to go.
Ian.
I'm running Fedora 18 with Xen 4.2.1 but using the Fedora 17 3.7.3 kernel because the F18 3.7.6 kernel doesn't find its root filesystem when booted under Xen. The Fedora KISS violation of using LVM by default bites again... but that shouldn't make any difference, right? Xen and all the userspace tools are up to date. And the kernel is fairly much the same anyway.
I've made no changes to anything so far; I'm just using the standard tools. It gets as far as the 'Daemon running' message, then sits there doing nothing for about 35 seconds before exiting back to the shell prompt. During that 35 seconds, a seabios domain does show up in 'xl list' and 'xl top' (taking 100% CPU time). I don't see *any* SeaBIOS output. This isn't a SeaBIOS with debug info (I'll possibly try that next) but I ought at least to have seen the 'No bootable device' message?
[root@i7 ~]# cat seabios.cfg builder = "hvm" name = "seabios" device_model_version_override = "qemu-xen" memory = 512 serial = 'pty' [root@i7 ~]# xl create -c seabios.cfg Parsing config from seabios.cfg xc: info: VIRTUAL MEMORY ARRANGEMENT: Loader: 0000000000100000->000000000019e3a8 TOTAL: 0000000000000000->000000001f800000 ENTRY ADDRESS: 0000000000100000 xc: info: PHYSICAL MEMORY ALLOCATION: 4KB PAGES: 0x0000000000000200 2MB PAGES: 0x00000000000000fb 1GB PAGES: 0x0000000000000000 Daemon running with PID 3071
What's the best way to debug this?
On Wed, 2013-02-13 at 11:05 +0000, David Woodhouse wrote:
I'm running Fedora 18 with Xen 4.2.1 but using the Fedora 17 3.7.3 kernel because the F18 3.7.6 kernel doesn't find its root filesystem when booted under Xen. The Fedora KISS violation of using LVM by default bites again... but that shouldn't make any difference, right? Xen and all the userspace tools are up to date. And the kernel is fairly much the same anyway.
Right, the kernel shouldn't matter that much.
I've made no changes to anything so far; I'm just using the standard tools. It gets as far as the 'Daemon running' message, then sits there doing nothing for about 35 seconds before exiting back to the shell prompt. During that 35 seconds, a seabios domain does show up in 'xl list' and 'xl top' (taking 100% CPU time). I don't see *any* SeaBIOS output. This isn't a SeaBIOS with debug info (I'll possibly try that next) but I ought at least to have seen the 'No bootable device' message?
You used -c so you should be connected to the virtual COM1, so if SeaBIOS is logging anything to that you ought to see it. You could also try enabling vnc in your config ("vnc = 1") and attaching to that. By default it will find the first available port but you can force it with vncdisplay=N (where N is 0,1,2 rather than 500N, IIRC).
You say it dies after 35 seconds, is the VM actually dying or is the tool just giving up on the serial console? Sounds like the former from your description.You might find adding: on_shutdown = "preserve" on_reboot = "preserve" on_crash = "preserve" to your config useful to give you enough time to connect to VNC and have a proper look. You'll need to explicitly "xl destroy seabios" if you do this.
Hopefully that will be enough to figure out what is going on, if not then read on...
Is there anything of interest in /var/log/xen/*seabios* or "xl dmesg"? Could you post the output of "xl -vvv create -c seabios.cfg" please.
Dario, have you ever run a domain with qemu-xen on a Fedora 18 box, it ought to work, right?
[root@i7 ~]# cat seabios.cfg builder = "hvm" name = "seabios" device_model_version_override = "qemu-xen" memory = 512 serial = 'pty' [root@i7 ~]# xl create -c seabios.cfg Parsing config from seabios.cfg xc: info: VIRTUAL MEMORY ARRANGEMENT: Loader: 0000000000100000->000000000019e3a8 TOTAL: 0000000000000000->000000001f800000 ENTRY ADDRESS: 0000000000100000 xc: info: PHYSICAL MEMORY ALLOCATION: 4KB PAGES: 0x0000000000000200 2MB PAGES: 0x00000000000000fb 1GB PAGES: 0x0000000000000000 Daemon running with PID 3071
What's the best way to debug this?
If the VNC console shows nothing then I find the easiest way is usually to build a debug hypervisor so that the magic debug I/O port goes somewhere useful.
Ian.
On Wed, 2013-02-13 at 11:30 +0000, Ian Campbell wrote:
Is there anything of interest in /var/log/xen/*seabios* or "xl dmesg"? Could you post the output of "xl -vvv create -c seabios.cfg" please.
Dario, have you ever run a domain with qemu-xen on a Fedora 18 box, it ought to work, right?
Connecting with vnc actually works. It's running Bochs rombios and powering off after 30 seconds. Was just trying to find the relevant goes on how to make my seabios.cfg make it use SeaBIOS when your mail arrived...
On Wed, 2013-02-13 at 11:31 +0000, David Woodhouse wrote:
On Wed, 2013-02-13 at 11:30 +0000, Ian Campbell wrote:
Is there anything of interest in /var/log/xen/*seabios* or "xl dmesg"? Could you post the output of "xl -vvv create -c seabios.cfg" please.
Dario, have you ever run a domain with qemu-xen on a Fedora 18 box, it ought to work, right?
Connecting with vnc actually works. It's running Bochs rombios and powering off after 30 seconds. Was just trying to find the relevant goes on how to make my seabios.cfg make it use SeaBIOS when your mail arrived...
s/goes/docs/ wtf. Anyway you'd already pointed me at xl.cfg(5). Which says that seabios ought to have been the default if device_model_version=qemu-xen. (Although you said to use 'device_model_version_override'...)
And when I set it explicitly it doesn't work...
[root@i7 ~]# cat seabios.cfg builder = "hvm" name = "seabios" device_model_version_override = "qemu-xen" bios = 'seabios' memory = 512 serial = 'pty' firmware_override = '/home/dwmw2/fedora/xen/f18/xen-4.2.1/tools/firmware/hvmloader/hvmloader'
[root@i7 ~]# xl create -c -d seabios.cfg Parsing config from seabios.cfg {"domid":null,"config":{"c_info":{"type":"hvm","hap":"<default>","oos":"<default>","ssidref":0,"name":"seabios","uuid":"a9784618-d101-437c-834e-f44181dcb236","xsdata":{},"platformdata":{},"poolid":0,"run_hotplug_scripts":"True"},"b_info":{"max_vcpus":0,"avail_vcpus":[],"cpumap":[],"numa_placement":"<default>","tsc_mode":"default","max_memkb":524288,"target_memkb":524288,"video_memkb":-1,"shadow_memkb":4096,"rtc_timeoffset":0,"localtime":"<default>","disable_migrate":"<default>","cpuid":[],"blkdev_start":null,"device_model_version":null,"device_model_stubdomain":"<default>","device_model":null,"device_model_ssidref":0,"extra":[],"extra_pv":[],"extra_hvm":[],"sched_params":{"sched":"unknown","weight":-1,"cap":-1,"period":-1,"slice":-1,"latency":-1,"extratime":-1},"ioports":[],"irqs":[],"u":{"firmware":"/home/dwmw2/fedora/xen/f18/xen-4.2.1/tools/firmware/hvmloader/hvmloader","bios":"seabios","pae":"<default>","apic":"<default>","acpi":"<default>","acpi_s3":"<default>","acpi_s4":"<default>","nx":"<default>","viridian":"<default>","timeoffset":null,"hpet":"<default>","vpt_align":"<default>","timer_mode":null,"nested_hvm":"<default>","nographic":"<default>","vga":{"kind":null},"vnc":{"enable":"<default>","listen":null,"passwd":null,"display":0,"findunused":"<default>"},"keymap":null,"sdl":{"enable":"<default>","opengl":"<default>","display":null,"xauthority":null},"spice":{"enable":"<default>","port":0,"tls_port":0,"host":null,"disable_ticketing":"<default>","passwd":null,"agent_mouse":"<default>"},"gfx_passthru":"<default>","serial":"pty","boot":null,"usb":"<default>","usbdevice":null,"soundhw":null,"xen_platform_pci":"<default>"}},"disks":[],"nics":[],"pcidevs":[],"vfbs":[],"vkbs":[],"on_poweroff":"destroy","on_reboot":"restart","on_watchdog":"destroy","on_crash":"destroy"}} failed to free memory for the domain
On Wed, 2013-02-13 at 11:37 +0000, David Woodhouse wrote:
device_model_version_override = "qemu-xen"
No "_override" on this option, sorry, that was my fault.
Ian.
On Wed, 2013-02-13 at 11:40 +0000, Ian Campbell wrote:
On Wed, 2013-02-13 at 11:37 +0000, David Woodhouse wrote:
device_model_version_override = "qemu-xen"
No "_override" on this option, sorry, that was my fault.
[root@i7 ~]# ls /usr/lib/xen/bin/ qemu-dm stubdom-dm stubdompath.sh xenpaging
[root@i7 ~]# cat seabios.cfg builder = "hvm" name = "seabios" device_model_version = "qemu-xen" memory = 512 serial = 'pty' firmware_override = '/home/dwmw2/fedora/xen/f18/xen-4.2.1/tools/firmware/hvmloader/hvmloader'
[root@i7 ~]# xl create -c -d seabios.cfg Parsing config from seabios.cfg {"domid":null,"config":{"c_info":{"type":"hvm","hap":"<default>","oos":"<default>","ssidref":0,"name":"seabios","uuid":"a2ced1af-b3ae-4efa-85d4-17f372acc5e2","xsdata":{},"platformdata":{},"poolid":0,"run_hotplug_scripts":"True"},"b_info":{"max_vcpus":0,"avail_vcpus":[],"cpumap":[],"numa_placement":"<default>","tsc_mode":"default","max_memkb":524288,"target_memkb":524288,"video_memkb":-1,"shadow_memkb":4096,"rtc_timeoffset":0,"localtime":"<default>","disable_migrate":"<default>","cpuid":[],"blkdev_start":null,"device_model_version":"qemu_xen","device_model_stubdomain":"<default>","device_model":null,"device_model_ssidref":0,"extra":[],"extra_pv":[],"extra_hvm":[],"sched_params":{"sched":"unknown","weight":-1,"cap":-1,"period":-1,"slice":-1,"latency":-1,"extratime":-1},"ioports":[],"irqs":[],"u":{"firmware":"/home/dwmw2/fedora/xen/f18/xen-4.2.1/tools/firmware/hvmloader/hvmloader","bios":null,"pae":"<default>","apic":"<default>","acpi":"<default>","acpi_s3":"<default>","acpi_s4":"<default>","nx":"<default>","viridian":"<default>","timeoffset":null,"hpet":"<default>","vpt_align":"<default>","timer_mode":null,"nested_hvm":"<default>","nographic":"<default>","vga":{"kind":null},"vnc":{"enable":"<default>","listen":null,"passwd":null,"display":0,"findunused":"<default>"},"keymap":null,"sdl":{"enable":"<default>","opengl":"<default>","display":null,"xauthority":null},"spice":{"enable":"<default>","port":0,"tls_port":0,"host":null,"disable_ticketing":"<default>","passwd":null,"agent_mouse":"<default>"},"gfx_passthru":"<default>","serial":"pty","boot":null,"usb":"<default>","usbdevice":null,"soundhw":null,"xen_platform_pci":"<default>"}},"disks":[],"nics":[],"pcidevs":[],"vfbs":[],"vkbs":[],"on_poweroff":"destroy","on_reboot":"restart","on_watchdog":"destroy","on_crash":"destroy"}} xc: info: VIRTUAL MEMORY ARRANGEMENT: Loader: 0000000000100000->00000000001be3a8 TOTAL: 0000000000000000->000000001f800000 ENTRY ADDRESS: 0000000000100000 xc: info: PHYSICAL MEMORY ALLOCATION: 4KB PAGES: 0x0000000000000200 2MB PAGES: 0x00000000000000fb 1GB PAGES: 0x0000000000000000 libxl: error: libxl_dm.c:1086:libxl__spawn_local_dm: device model /usr/lib/xen/bin/qemu-system-i386 is not executable: No such file or directory libxl: error: libxl_dm.c:1212:device_model_spawn_outcome: (null): spawn failed (rc=-3) libxl: error: libxl_qmp.c:641:libxl__qmp_initialize: Connection error: No such file or directory Daemon running with PID 5771 xenconsole: Could not read tty from store: No such file or directory libxl: error: libxl_exec.c:118:libxl_report_child_exitstatus: console child [0] exited with error status 2
On Wed, 2013-02-13 at 11:48 +0000, David Woodhouse wrote:
On Wed, 2013-02-13 at 11:40 +0000, Ian Campbell wrote:
On Wed, 2013-02-13 at 11:37 +0000, David Woodhouse wrote:
device_model_version_override = "qemu-xen"
No "_override" on this option, sorry, that was my fault.
[root@i7 ~]# ls /usr/lib/xen/bin/ qemu-dm stubdom-dm stubdompath.sh xenpaging
The qemu-dm here is the qemu-xen-traditional, i.e. the legacy Xen fork of qemu which uses ROMBIOS not SeaBIOS.
[root@i7 ~]# cat seabios.cfg builder = "hvm" name = "seabios" device_model_version = "qemu-xen" memory = 512 serial = 'pty' firmware_override = '/home/dwmw2/fedora/xen/f18/xen-4.2.1/tools/firmware/hvmloader/hvmloader'
[root@i7 ~]# xl create -c -d seabios.cfg Parsing config from seabios.cfg {"domid":null,"config":{"c_info":{"type":"hvm","hap":"<default>","oos":"<default>","ssidref":0,"name":"seabios","uuid":"a2ced1af-b3ae-4efa-85d4-17f372acc5e2","xsdata":{},"platformdata":{},"poolid":0,"run_hotplug_scripts":"True"},"b_info":{"max_vcpus":0,"avail_vcpus":[],"cpumap":[],"numa_placement":"<default>","tsc_mode":"default","max_memkb":524288,"target_memkb":524288,"video_memkb":-1,"shadow_memkb":4096,"rtc_timeoffset":0,"localtime":"<default>","disable_migrate":"<default>","cpuid":[],"blkdev_start":null,"device_model_version":"qemu_xen","device_model_stubdomain":"<default>","device_model":null,"device_model_ssidref":0,"extra":[],"extra_pv":[],"extra_hvm":[],"sched_params":{"sched":"unknown","weight":-1,"cap":-1,"period":-1,"slice":-1,"latency":-1,"extratime":-1},"ioports":[],"irqs":[],"u":{"firmware":"/home/dwmw2/fedora/xen/f18/xen-4.2.1/tools/firmware/hvmloader/hvmloader","bios":null,"pae":"<default>","apic":"<default>","acpi":"<default>","acpi_s3":"<default>","acpi_s4":"<default>","nx":"<default>","viridian":"<default>","timeoffset":null,"hpet":"<default>","vpt_align":"<default>","timer_mode":null,"nested_hvm":"<default>","nographic":"<default>","vga":{"kind":null},"vnc":{"enable":"<default>","listen":null,"passwd":null,"display":0,"findunused":"<default>"},"keymap":null,"sdl":{"enable":"<default>","opengl":"<default>","display":null,"xauthority":null},"spice":{"enable":"<default>","port":0,"tls_port":0,"host":null,"disable_ticketing":"<default>","passwd":null,"agent_mouse":"<default>"},"gfx_passthru":"<default>","serial":"pty","boot":null,"usb":"<default>","usbdevice":null,"soundhw":null,"xen_platform_pci":"<default>"}},"disks":[],"nics":[],"pcidevs":[],"vfbs":[],"vkbs":[],"on_poweroff":"destroy","on_reboot":"restart","on_watchdog":"destroy","on_crash":"destroy"}} xc: info: VIRTUAL MEMORY ARRANGEMENT: Loader: 0000000000100000->00000000001be3a8 TOTAL: 0000000000000000->000000001f800000 ENTRY ADDRESS: 0000000000100000 xc: info: PHYSICAL MEMORY ALLOCATION: 4KB PAGES: 0x0000000000000200 2MB PAGES: 0x00000000000000fb 1GB PAGES: 0x0000000000000000 libxl: error: libxl_dm.c:1086:libxl__spawn_local_dm: device model /usr/lib/xen/bin/qemu-system-i386 is not executable: No such file or directory
Hrm, this should either be provided by the Xen package (or maybe there is a separate xen-qemu package?) or the Xen package should have been patched to use the system qemu from /usr/bin. This is probably a casualty of the upstream qemu-xen stuff being non-default in 4.2.x.
Does your /usr/bin/qemu-system-{i386,x86_64} link against any Xen libraries? In which case you could try device_model_override="/path/to/it"
Ian.
On Wed, 2013-02-13 at 12:05 +0000, Ian Campbell wrote:
Hrm, this should either be provided by the Xen package (or maybe there is a separate xen-qemu package?) or the Xen package should have been patched to use the system qemu from /usr/bin. This is probably a casualty of the upstream qemu-xen stuff being non-default in 4.2.x.
Does your /usr/bin/qemu-system-{i386,x86_64} link against any Xen libraries? In which case you could try device_model_override="/path/to/it"
Aha, the Fedora package has a 'qemu-xen.tradonly.patch' which comments out the addition of qemu-xen-dir to SUBDIRS-$(CONFIG_IOEMU) in tools/Makefile. Will there have been a *reason* they did that, or if I build one and put it in the right place should it JustWork™? The patch arrived in the package in a large commit with the comment 'Update to xen-4.2.0' and no further explanation.
So much for it being easier to use the distro's toolsets with minimal modification... :)
I have to run now, but will be back and prod at this a little more later.
On Wed, 13 Feb 2013, David Woodhouse wrote:
On Wed, 2013-02-13 at 12:05 +0000, Ian Campbell wrote:
Hrm, this should either be provided by the Xen package (or maybe there is a separate xen-qemu package?) or the Xen package should have been patched to use the system qemu from /usr/bin. This is probably a casualty of the upstream qemu-xen stuff being non-default in 4.2.x.
Does your /usr/bin/qemu-system-{i386,x86_64} link against any Xen libraries? In which case you could try device_model_override="/path/to/it"
Aha, the Fedora package has a 'qemu-xen.tradonly.patch' which comments out the addition of qemu-xen-dir to SUBDIRS-$(CONFIG_IOEMU) in tools/Makefile. Will there have been a *reason* they did that, or if I build one and put it in the right place should it JustWork™? The patch arrived in the package in a large commit with the comment 'Update to xen-4.2.0' and no further explanation.
xen-4.2.0 added a second qemu-xen image - the patch takes it out again. As the traditional qemu-xen was still the default so it didn't seem worth adding another, particularly as I would ideally like to drop xen's qemu altogether and go back to Fedora's.
As this seems to be about seabios, you should note that Fedora xen 4.2 doesn't build its own seabios either, it uses the Fedora version - see the xen.use.fedora.seabios.patch patch. I didn't see any reason to duplicate what was already in Fedora (and as far as I understand it it is in general against Fedora's policy to do so).
Michael Young
On Wed, 2013-02-13 at 12:38 +0000, M A Young wrote:
xen-4.2.0 added a second qemu-xen image - the patch takes it out again. As the traditional qemu-xen was still the default so it didn't seem worth adding another, particularly as I would ideally like to drop xen's qemu altogether and go back to Fedora's.
Thanks for the quick response, Michael.
I'll enable the qemu-xen build again and then I should be fine.
As this seems to be about seabios, you should note that Fedora xen 4.2 doesn't build its own seabios either, it uses the Fedora version - see the xen.use.fedora.seabios.patch patch. I didn't see any reason to duplicate what was already in Fedora (and as far as I understand it it is in general against Fedora's policy to do so).
Right. Although AFAICT nothing in your build of Xen will *use* this SeaBIOS binary, since it's for the qemu-xen build that you disabled?
Anyway, when we get to the point that you're enabling qemu-xen in the Fedora builds, I hope you'll be using just OVMF + SeaBIOS as a CSM, and not having to mess around with a choice of firmwares according to what you're booting in it today. I'll look at fixing that in the upstream Xen build setup. But first I'll check I haven't broken native SeaBIOS... :)
On Wed, 2013-02-13 at 12:14 +0000, David Woodhouse wrote:
On Wed, 2013-02-13 at 12:05 +0000, Ian Campbell wrote:
Hrm, this should either be provided by the Xen package (or maybe there is a separate xen-qemu package?) or the Xen package should have been patched to use the system qemu from /usr/bin. This is probably a casualty of the upstream qemu-xen stuff being non-default in 4.2.x.
Does your /usr/bin/qemu-system-{i386,x86_64} link against any Xen libraries? In which case you could try device_model_override="/path/to/it"
Aha, the Fedora package has a 'qemu-xen.tradonly.patch' which comments out the addition of qemu-xen-dir to SUBDIRS-$(CONFIG_IOEMU) in tools/Makefile. Will there have been a *reason* they did that, or if I build one and put it in the right place should it JustWork™? The patch arrived in the package in a large commit with the comment 'Update to xen-4.2.0' and no further explanation.
I think it should JustWork. I expect they disabled it either because they intended to eventually use /usr/bin/qemu-foo instead or maybe just as an expedient way of getting the 4.2 package together and because it is a non-default option in 4.2 (and something of a "preview" feature at that).
So much for it being easier to use the distro's toolsets with minimal modification... :)
Yers :-/
I have to run now, but will be back and prod at this a little more later.
OK, thanks,
Ian.
On Wed, 2013-02-13 at 12:56 +0000, Ian Campbell wrote:
I think it should JustWork. I expect they disabled it either because they intended to eventually use /usr/bin/qemu-foo instead or maybe just as an expedient way of getting the 4.2 package together and because it is a non-default option in 4.2 (and something of a "preview" feature at that).
OK... I re-enabled it, I now have a /usr/lib/xen/bin/qemu-system-i386 (not x86_64 but that's fine for now) which *does* appear to have Xen support.
[root@i7 ~]# xl create -c -d seabios.cfg Parsing config from seabios.cfg {"domid":null,"config":{"c_info":{"type":"hvm","hap":"<default>","oos":"<default>","ssidref":0,"name":"seabios","uuid":"849a47f8-1333-45e1-b4a6-cde90429cfd4","xsdata":{},"platformdata":{},"poolid":0,"run_hotplug_scripts":"True"},"b_info":{"max_vcpus":0,"avail_vcpus":[],"cpumap":[],"numa_placement":"<default>","tsc_mode":"default","max_memkb":524288,"target_memkb":524288,"video_memkb":-1,"shadow_memkb":4096,"rtc_timeoffset":0,"localtime":"<default>","disable_migrate":"<default>","cpuid":[],"blkdev_start":null,"device_model_version":"qemu_xen","device_model_stubdomain":"<default>","device_model":null,"device_model_ssidref":0,"extra":[],"extra_pv":[],"extra_hvm":[],"sched_params":{"sched":"unknown","weight":-1,"cap":-1,"period":-1,"slice":-1,"latency":-1,"extratime":-1},"ioports":[],"irqs":[],"u":{"firmware":"/home/dwmw2/fedora/xen/f18/xen-4.2.1/tools/firmware/hvmloader/hvmloader","bios":null,"pae":"<default>","apic":"<default>","acpi":"<default>","acpi_s3":"<default>","acpi_s4":"<default>","nx":"<default>","viridian":"<default>","timeoffset":null,"hpet":"<default>","vpt_align":"<default>","timer_mode":null,"nested_hvm":"<default>","nographic":"<default>","vga":{"kind":null},"vnc":{"enable":"<default>","listen":null,"passwd":null,"display":0,"findunused":"<default>"},"keymap":null,"sdl":{"enable":"<default>","opengl":"<default>","display":null,"xauthority":null},"spice":{"enable":"<default>","port":0,"tls_port":0,"host":null,"disable_ticketing":"<default>","passwd":null,"agent_mouse":"<default>"},"gfx_passthru":"<default>","serial":"pty","boot":null,"usb":"<default>","usbdevice":null,"soundhw":null,"xen_platform_pci":"<default>"}},"disks":[],"nics":[],"pcidevs":[],"vfbs":[],"vkbs":[],"on_poweroff":"destroy","on_reboot":"restart","on_watchdog":"destroy","on_crash":"destroy"}} xc: info: VIRTUAL MEMORY ARRANGEMENT: Loader: 0000000000100000->00000000001be3a8 TOTAL: 0000000000000000->000000001f800000 ENTRY ADDRESS: 0000000000100000 xc: info: PHYSICAL MEMORY ALLOCATION: 4KB PAGES: 0x0000000000000200 2MB PAGES: 0x00000000000000fb 1GB PAGES: 0x0000000000000000 Daemon running with PID 1383 xenconsole: Could not read tty from store: No such file or directory libxl: error: libxl_exec.c:118:libxl_report_child_exitstatus: console child [0] exited with error status 2
At this point, the 'xl create' command is running in the background, appending this to xl-seabios.log every few seconds...
xc: info: VIRTUAL MEMORY ARRANGEMENT: Loader: 0000000000100000->00000000001be3a8 TOTAL: 0000000000000000->000000001f800000 ENTRY ADDRESS: 0000000000100000 xc: info: PHYSICAL MEMORY ALLOCATION: 4KB PAGES: 0x0000000000000200 2MB PAGES: 0x00000000000000fb 1GB PAGES: 0x0000000000000000 Waiting for domain seabios (domid 253) to die [pid 1384] Domain 253 has shut down, reason code 1 0x1 Action for shutdown reason code 1 is restart Domain 253 needs to be cleaned up: destroying the domain Done. Rebooting now
I can strace it and see that it *is* invoking qemu and then almost immediately sending it a SIGHUP for reasons I don't quite understand.
On Wed, 2013-02-13 at 16:08 +0000, David Woodhouse wrote:
On Wed, 2013-02-13 at 12:56 +0000, Ian Campbell wrote:
I think it should JustWork. I expect they disabled it either because they intended to eventually use /usr/bin/qemu-foo instead or maybe just as an expedient way of getting the 4.2 package together and because it is a non-default option in 4.2 (and something of a "preview" feature at that).
OK... I re-enabled it, I now have a /usr/lib/xen/bin/qemu-system-i386 (not x86_64 but that's fine for now) which *does* appear to have Xen support.
Actually the -i386/x86_64 designator is a bit arbitrary/meaningless since under Xen qemu only implements peripherals and not the actual processor. Even upstream we only ever build one (I forget which) regardless of platform and we use the same one regardless of guest type.
[root@i7 ~]# xl create -c -d seabios.cfg Parsing config from seabios.cfg {"domid":null,"config":{"c_info":{"type":"hvm","hap":"<default>","oos":"<default>","ssidref":0,"name":"seabios","uuid":"849a47f8-1333-45e1-b4a6-cde90429cfd4","xsdata":{},"platformdata":{},"poolid":0,"run_hotplug_scripts":"True"},"b_info":{"max_vcpus":0,"avail_vcpus":[],"cpumap":[],"numa_placement":"<default>","tsc_mode":"default","max_memkb":524288,"target_memkb":524288,"video_memkb":-1,"shadow_memkb":4096,"rtc_timeoffset":0,"localtime":"<default>","disable_migrate":"<default>","cpuid":[],"blkdev_start":null,"device_model_version":"qemu_xen","device_model_stubdomain":"<default>","device_model":null,"device_model_ssidref":0,"extra":[],"extra_pv":[],"extra_hvm":[],"sched_params":{"sched":"unknown","weight":-1,"cap":-1,"period":-1,"slice":-1,"latency":-1,"extratime":-1},"ioports":[],"irqs":[],"u":{"firmware":"/home/dwmw2/fedora/xen/f18/xen-4.2.1/tools/firmware/hvmloader/hvmloader","bios":null,"pae":"<default>","apic":"<default>","acpi":"<default>","acpi_s3":"<default>","acpi_s4":"<default>","nx":"<default>","viridian":"<default>","timeoffset":null,"hpet":"<default>","vpt_align":"<default>","timer_mode":null,"nested_hvm":"<default>","nographic":"<default>","vga":{"kind":null},"vnc":{"enable":"<default>","listen":null,"passwd":null,"display":0,"findunused":"<default>"},"keymap":null,"sdl":{"enable":"<default>","opengl":"<default>","display":null,"xauthority":null},"spice":{"enable":"<default>","port":0,"tls_port":0,"host":null,"disable_ticketing":"<default>","passwd":null,"agent_mouse":"<default>"},"gfx_passthru":"<default>","serial":"pty","boot":null,"usb":"<default>","usbdevice":null,"soundhw":null,"xen_platform_pci":"<default>"}},"disks":[],"nics":[],"pcidevs":[],"vfbs":[],"vkbs":[],"on_poweroff":"destroy","on_reboot":"restart","on_watchdog":"destroy","on_crash":"destroy"}} xc: info: VIRTUAL MEMORY ARRANGEMENT: Loader: 0000000000100000->00000000001be3a8 TOTAL: 0000000000000000->000000001f800000 ENTRY ADDRESS: 0000000000100000 xc: info: PHYSICAL MEMORY ALLOCATION: 4KB PAGES: 0x0000000000000200 2MB PAGES: 0x00000000000000fb 1GB PAGES: 0x0000000000000000 Daemon running with PID 1383 xenconsole: Could not read tty from store: No such file or directory libxl: error: libxl_exec.c:118:libxl_report_child_exitstatus: console child [0] exited with error status 2
At this point, the 'xl create' command is running in the background, appending this to xl-seabios.log every few seconds...
This usually indicates that either hvmloader or the BIOS is crashing, often with a triple fault. You should see in xl dmesg: "Triple fault on VCPU%d - " "invoking HVM system reset.\n"
Actually, that reminds me, you should add "loglvl=all guest_loglvl=all" to your hypervisor command line.
I think the on_foo = "preserve" stuff I mentioned earlier should stop the annoying constant looping reboots.
Is this is a Seabios you built yourself (modified or un) or the Fedora packaged one?
I've attached an hvmloader which I just built from the 4.2 stable branch and have smoke tested, does it work for you?
xc: info: VIRTUAL MEMORY ARRANGEMENT: Loader: 0000000000100000->00000000001be3a8 TOTAL: 0000000000000000->000000001f800000 ENTRY ADDRESS: 0000000000100000 xc: info: PHYSICAL MEMORY ALLOCATION: 4KB PAGES: 0x0000000000000200 2MB PAGES: 0x00000000000000fb 1GB PAGES: 0x0000000000000000 Waiting for domain seabios (domid 253) to die [pid 1384] Domain 253 has shut down, reason code 1 0x1 Action for shutdown reason code 1 is restart Domain 253 needs to be cleaned up: destroying the domain Done. Rebooting now
I can strace it and see that it *is* invoking qemu and then almost immediately sending it a SIGHUP for reasons I don't quite understand.
The domain died so it is tidying up. Probably qemu barely got the chance to do anything before the guest crashed.
Ian.
On Thu, 2013-02-14 at 11:27 +0000, Ian Campbell wrote:
I've attached an hvmloader which I just built from the 4.2 stable branch and have smoke tested, does it work for you?
FFS. Is it too early to start drinking yet? A 256KiB ROM image fails as I have described, while a 128KiB image works fine. So turning up the debug level — as I had done in all my builds — basically makes it fail.
If I only turn it up to 3 and then keep turning off the unused default-enabled drivers until the image fits in 128KiB again, it works. So I'm fairly sure it *is* the size limit.
Is that a known issue?
On Thu, 2013-02-14 at 12:29 +0000, David Woodhouse wrote:
On Thu, 2013-02-14 at 11:27 +0000, Ian Campbell wrote:
I've attached an hvmloader which I just built from the 4.2 stable branch and have smoke tested, does it work for you?
FFS. Is it too early to start drinking yet? A 256KiB ROM image fails as I have described, while a 128KiB image works fine. So turning up the debug level — as I had done in all my builds — basically makes it fail.
If I only turn it up to 3 and then keep turning off the unused default-enabled drivers until the image fits in 128KiB again, it works. So I'm fairly sure it *is* the size limit.
Is that a known issue?
I had observed once upon a time that turning up the limit caused odd failures, but I'd never associated it with the size. I spent ages trying to track down a NULL pointer in some level>3 message and the like...
In hvmloader I see: #define SEABIOS_PHYSICAL_ADDRESS 0x000E0000 which would have to change if the image grew >128K. Really hvmloader should check the size dynamically and DTRT. I can't remember why I did it this way.
Sorry about this, crapness on our end I think :-(
I've added this to my TODO list. Ian.
On Thu, 2013-02-14 at 12:53 +0000, Ian Campbell wrote:
I had observed once upon a time that turning up the limit caused odd failures, but I'd never associated it with the size. I spent ages trying to track down a NULL pointer in some level>3 message and the like...
In hvmloader I see: #define SEABIOS_PHYSICAL_ADDRESS 0x000E0000 which would have to change if the image grew >128K. Really hvmloader should check the size dynamically and DTRT. I can't remember why I did it this way.
No idea. If I just set .bios_address = 0x100000U - sizeof(seabios), it works just fine.
Sorry about this, crapness on our end I think :-(
Ahem, you also have //BUILD_BUG_ON(sizeof(seabios) > (0x00100000U - SEABIOS_PHYSICAL_ADDRESS));
Now *that* would have been a time-saver...
Another observation: 'xl -c seabios.cfg' misses the first output of the domain. Starting it *paused*, then running 'xl unpause seabios' in another terminal, lets me catch even the first 'Start bios ...' message.
If it *had* been crashing early in SeaBIOS, I'd have been cursing you for that one too :)
Anyway, I appear to have established that the qemu fw_cfg *doesn't* exist in your domains — so how you pass bootorder to the guest, if you successfully do so at all, I have no idea. And the patch at http://git.infradead.org/users/dwmw2/seabios.git/commitdiff/e62d1720f appears to work fine — at least in the case of a domain with nothing to actually boot from anyway, where we expect it just to die with 'no bootable device'.
I'll probably have a look at OVMF under Xen now, and making sure that my CSM code works there. Then you shouldn't need to offer people the choice between OVMF and SeaBIOS because you'll have one image that handles everything (which is what people get on real hardware, and expect).
On Thu, 2013-02-14 at 13:05 +0000, David Woodhouse wrote:
I'll probably have a look at OVMF under Xen now, and making sure that my CSM code works there. Then you shouldn't need to offer people the choice between OVMF and SeaBIOS because you'll have one image that handles everything (which is what people get on real hardware, and expect).
That part, at least, was surprisingly easy. The same OVMF images (with SeaBIOS-as-CSM) that I've been testing under Qemu work fine under Xen too. The OVMF build system is hosed for GCC 4.7 and your own Makefile also has 'GCC44' in the path when copying out the build result. when it could have been 'GCC4?' and at least been a little more robust. But that's just fluff. Basically, it works.
I did need to fix the VGA ROM you're shipping for Cirrus, which has the PCIR structure unaligned. That was it.
Again, this is without actually trying to boot any OS :)
On Thu, 2013-02-14 at 13:52 +0000, David Woodhouse wrote:
On Thu, 2013-02-14 at 13:05 +0000, David Woodhouse wrote:
I'll probably have a look at OVMF under Xen now, and making sure that my CSM code works there. Then you shouldn't need to offer people the choice between OVMF and SeaBIOS because you'll have one image that handles everything (which is what people get on real hardware, and expect).
That part, at least, was surprisingly easy. The same OVMF images (with SeaBIOS-as-CSM) that I've been testing under Qemu work fine under Xen too. The OVMF build system is hosed for GCC 4.7 and your own Makefile also has 'GCC44' in the path when copying out the build result. when it could have been 'GCC4?' and at least been a little more robust.
The chap who did our OVMF stuff has moved on to pastures new but ISTR him saying something about a build bug with GCC!=44, which had been fixed in upstream OVMF but not yet sync'd into the Xen tree.
But that's just fluff. Basically, it works.
Awesome! (I've CCd xen-devel just for their info, it's moderated for non-subscribers but valid posters get whitelisted)
I did need to fix the VGA ROM you're shipping for Cirrus, which has the PCIR structure unaligned. That was it.
I would have put a substantial sum of money on the VGA ROM we ship not being used in the SeaBIOS configuration, since SB pulls the ROM from the emulated cards ROM BAR. The Cirrus ROM we ship should be used with ROMBIOS only. I wonder what's going on there (another one for my list)
Or did you mean the VGA ROM we ship in the qemu-xen branch that we include? (rather than tools/firmware/vgabios/)
Again, this is without actually trying to boot any OS :)
Lets not get carried away :-P
Ian.
On Thu, 2013-02-14 at 14:08 +0000, Ian Campbell wrote:
The chap who did our OVMF stuff has moved on to pastures new but ISTR him saying something about a build bug with GCC!=44, which had been fixed in upstream OVMF but not yet sync'd into the Xen tree.
Yes, OVMF's toolchain handling is somewhat broken. I *do* have it building with GCC 4.6 and 4.7. There's a patch in my tree at git:// and http://git.infradead.org/users/dwmw2/edk2.git which fixes that... although I suspect it might be incomplete and I'm about to blow away my local build tree and configure from scratch to retest.
But your tools/ovmf-makefile could also do with s/GCC44/GCC4?/ in the line which does cp Build/OvmfX64/DEBUG_GCC44/FV/OVMF.fd ovmf.bin
Awesome! (I've CCd xen-devel just for their info, it's moderated for non-subscribers but valid posters get whitelisted)
In that case I think the only context I need to add, for those who want to play along at home, is the location of my trees for OVMF and SeaBIOS. The OVMF one is above, and the SeaBIOS one is next to it: git:// or http://git.infradead.org/users/dwmw2/seabios.git
There's a README.CSM file in the SeaBIOS tree which describes how to build OVMF with CSM support. The main reason I'm pointing you at my trees rather than upstream is the patch within each one that adds the UmbStart,UmbEnd fields for negotiating between UEFI and SeaBIOS which parts of the UMB memory region should be made read-only. For Qemu with KVM that's a moot point because it doesn't get made read-only anyway, so you could just use upstream now. If you don't implement the PAM protection of those regions, I suspect the same might be true for you. Suck it and see, perhaps.
I did need to fix the VGA ROM you're shipping for Cirrus, which has the PCIR structure unaligned. That was it.
... did you mean the VGA ROM we ship in the qemu-xen branch that we include? (rather than tools/firmware/vgabios/)
Yes, the one in /usr/share/qemu-xen. You want the patch from http://lists.gnu.org/archive/html/qemu-devel/2013-01/msg03650.html
On Thu, 2013-02-14 at 14:23 +0000, David Woodhouse wrote:
On Thu, 2013-02-14 at 14:08 +0000, Ian Campbell wrote:
The chap who did our OVMF stuff has moved on to pastures new but ISTR him saying something about a build bug with GCC!=44, which had been fixed in upstream OVMF but not yet sync'd into the Xen tree.
Yes, OVMF's toolchain handling is somewhat broken. I *do* have it building with GCC 4.6 and 4.7. There's a patch in my tree at git:// and http://git.infradead.org/users/dwmw2/edk2.git which fixes that... although I suspect it might be incomplete and I'm about to blow away my local build tree and configure from scratch to retest.
But your tools/ovmf-makefile could also do with s/GCC44/GCC4?/ in the line which does cp Build/OvmfX64/DEBUG_GCC44/FV/OVMF.fd ovmf.bin
Ack, thanks.
We try and support a reasonably wide range of hosts, usually we use Debian Stable as our baseline (which is currently 4.4).
Awesome! (I've CCd xen-devel just for their info, it's moderated for non-subscribers but valid posters get whitelisted)
In that case I think the only context I need to add, for those who want to play along at home, is the location of my trees for OVMF and SeaBIOS. The OVMF one is above, and the SeaBIOS one is next to it: git:// or http://git.infradead.org/users/dwmw2/seabios.git
There's a README.CSM file in the SeaBIOS tree which describes how to build OVMF with CSM support.
Do I understand correctly from the README that once CSM support is enabled at build time you can choose to use it dynamically at boot time? If so, Neat!
I suppose this selection is persistent for a given VM, but where is it saved?
The main reason I'm pointing you at my trees rather than upstream is the patch within each one that adds the UmbStart,UmbEnd fields for negotiating between UEFI and SeaBIOS which parts of the UMB memory region should be made read-only. For Qemu with KVM that's a moot point because it doesn't get made read-only anyway, so you could just use upstream now. If you don't implement the PAM protection of those regions, I suspect the same might be true for you. Suck it and see, perhaps.
Right, we really need to find someone with hours to finish properly integrating OVMF.
I did need to fix the VGA ROM you're shipping for Cirrus, which has the PCIR structure unaligned. That was it.
... did you mean the VGA ROM we ship in the qemu-xen branch that we include? (rather than tools/firmware/vgabios/)
Yes, the one in /usr/share/qemu-xen. You want the patch from http://lists.gnu.org/archive/html/qemu-devel/2013-01/msg03650.html
Thanks.
On Thu, 2013-02-14 at 16:46 +0000, Ian Campbell wrote:
On Thu, 2013-02-14 at 14:23 +0000, David Woodhouse wrote:
git.infradead.org/users/dwmw2/seabios.git
There's a README.CSM file in the SeaBIOS tree which describes how to build OVMF with CSM support.
Do I understand correctly from the README that once CSM support is enabled at build time you can choose to use it dynamically at boot time? If so, Neat!
Right. It's just another boot target. The UEFI device path for each of the bot targets, and the bootorder variable which sets their relative priorities, are stored in persistent nvram storage...
I suppose this selection is persistent for a given VM, but where is it saved?
That's another item on my TODO list. On real hardware it's actually stored in flash. On OVMF we don't have an answer. There's a dirty hack which stores them in a *file* on the EFI system partition, but that really isn't very helpful it stops working when the OS calls ExitBootServices — because you can't be touching the file system at the same time the OS might be. So when an OS installer does its install and then sets the NV variables to boot into the newly-installed OS... it can't work.
There was some initial work on supporting -pflash for qemu on i386 and working exactly like real hardware does — which meant firmware upgrades had to be done the same way since the firmware and the variables were all in the same image. And it didn't work with KVM.
I'm looking at fixing this to use a flash device *other* than the one that the firmware runs from, adjacent to it at the top of memory. Or something like that. But it's not quite solved yet. It'll *need* to be, for OVMF to be usable in the general case. And then it's solved automatically for CSM too.
On Thu, 2013-02-14 at 16:46 +0000, Ian Campbell wrote:
Right, we really need to find someone with hours to finish properly integrating OVMF.
Hm, that 'someone' may end up being me¹.
So... from the Xen point of view, what needs doing? There are some things on my TODO list which apply to Qemu/KVM too — most importantly, fixing bootorder handling, which basically involves fixing the general case of NV variable storage for UEFI as discussed. But is there anything Xen-specific that I'm likely to miss?
And on the subject of the NV storage... does -pflash work on qemu-xen, as long as we're not actually running *code* from the device and we're only using it for data storage? Are you content with my stated plan to provide a "disk" image for that, which is something like a 256KiB file on the host side, exposed as a flash device to the guest?
On Fri, 2013-02-15 at 12:09 +0000, David Woodhouse wrote:
On Thu, 2013-02-14 at 16:46 +0000, Ian Campbell wrote:
Right, we really need to find someone with hours to finish properly integrating OVMF.
Hm, that 'someone' may end up being me¹.
That would be awesome!
I was actually wondering if this might make a good GSoC project, there has been someone (the same guy IIRC) doing Tianocore on Xen stuff in the last two years, under the Tianocore umbrella although with a Xen.org co-mentor.
So... from the Xen point of view, what needs doing?
I haven't looked at or run OVMF stuff myself on Xen or otherwise, so take this with a pinch of salt...
I expect there will be some rough edges like the NV variable thing -- I have a feeling these will have a lot in common with qemu/KVM, since they would tend to interact with the "platform" (provided by qemu-dm under Xen) rather than processor or memory virt etc.
For the most part the I reckon the Xen specific things will be resync with a recent upstream and fixup the Xen build system integration, stuff like that.
We'd like to see PV I/O drivers at some point but that's a separate project in its own right I think.
There are some things on my TODO list which apply to Qemu/KVM too — most importantly, fixing bootorder handling, which basically involves fixing the general case of NV variable storage for UEFI as discussed. But is there anything Xen-specific that I'm likely to miss?
The main difference between Xen and Qemu/KVM in this context is that Xen supplied it's own SMBIOS & ACPI tables etc. There's a likelyhood of Xen and OVMF exposing each others bugs in that area I suspect.
And on the subject of the NV storage... does -pflash work on qemu-xen, as long as we're not actually running *code* from the device and we're only using it for data storage?
I'm not sure, I've CC'd Anthony & Stefano. Assuming the Xen machine type in Qemu wires it up then I don't know why it shouldn't work and if we don't wire it up I don't see why we couldn't.
Hvmloader might need to be tweaked to setup the e820 correctly and perhaps the some table or other would need to refer to it also?
If the ARM world continues moving towards UEFI then eventually we will likely want to enable this there too, but lets sort out x86 first.
Are you content with my stated plan to provide a "disk" image for that, which is something like a 256KiB file on the host side, exposed as a flash device to the guest?
It sounds OK to me. The other option would be to stash it in xenstore, but that doesn't sound like the right option to me.
Ian.
On Tue, 2013-02-19 at 10:20 +0000, Ian Campbell wrote:
I expect there will be some rough edges like the NV variable thing -- I have a feeling these will have a lot in common with qemu/KVM, since they would tend to interact with the "platform" (provided by qemu-dm under Xen) rather than processor or memory virt etc.
Well, it's mostly just storing text strings describing which device/path to boot from. So hopefully if the flash storage itself is OK for Xen, the rest should just work.
For the most part the I reckon the Xen specific things will be resync with a recent upstream and fixup the Xen build system integration, stuff like that.
Current upstream OVMF works, AFAICT. Although as I said, I haven't even tried booting an OS.
One thing I obviously *also* haven't tested, therefore, is *rebooting*., We've discovered a KVM bug on older CPUs without 'unrestricted guest' mode, where after a reset it actually runs code from 0xffff0 and not 0xfffffff0. With the former being SeaBIOS-CSM, and the latter being the OVMF startup code that we *should* be running, that's kind of a problem.
If you have a similar bug, please go and fix it so I never have to know :)
We'd like to see PV I/O drivers at some point but that's a separate project in its own right I think.
If you have an option ROM for them, that might not be a high priority. I think OVMF can thunk into INT 13h for disk access.
And on the subject of the NV storage... does -pflash work on qemu-xen, as long as we're not actually running *code* from the device and we're only using it for data storage?
I'm not sure, I've CC'd Anthony & Stefano. Assuming the Xen machine type in Qemu wires it up then I don't know why it shouldn't work and if we don't wire it up I don't see why we couldn't.
Qemu does but not in KVM mode, because it can't *execute* from a region and also catch writes to properly emulate flash. But for a flash device that we *don't* execute from, because it's only used for NV storage and not the firmware itself, that restriction isn't important. So I'll need to fix that.
Hvmloader might need to be tweaked to setup the e820 correctly and perhaps the some table or other would need to refer to it also?
Right. Haven't quite worked out how it would be 'found' by the firmware yet. I was going to suggest making the address available via fw_cfg... but you don't implement that.
On Tue, 2013-02-19 at 10:51 +0000, David Woodhouse wrote:
On Tue, 2013-02-19 at 10:20 +0000, Ian Campbell wrote:
I expect there will be some rough edges like the NV variable thing -- I have a feeling these will have a lot in common with qemu/KVM, since they would tend to interact with the "platform" (provided by qemu-dm under Xen) rather than processor or memory virt etc.
Well, it's mostly just storing text strings describing which device/path to boot from. So hopefully if the flash storage itself is OK for Xen, the rest should just work.
Ack.
For the most part the I reckon the Xen specific things will be resync with a recent upstream and fixup the Xen build system integration, stuff like that.
Current upstream OVMF works, AFAICT. Although as I said, I haven't even tried booting an OS.
One thing I obviously *also* haven't tested, therefore, is *rebooting*., We've discovered a KVM bug on older CPUs without 'unrestricted guest' mode, where after a reset it actually runs code from 0xffff0 and not 0xfffffff0. With the former being SeaBIOS-CSM, and the latter being the OVMF startup code that we *should* be running, that's kind of a problem.
If you have a similar bug, please go and fix it so I never have to know :)
I've not heard of such a thing, but I've been half following the thread and it sounds a bit, shall we say, subtle ;-)
Under Xen when qemu gets a reset event (via I/O writes or whatever) it ends up with the toolstack actually destroying and recreating the domain, so I think the issue you are thinking of doesn't come up.
We'd like to see PV I/O drivers at some point but that's a separate project in its own right I think.
If you have an option ROM for them, that might not be a high priority. I think OVMF can thunk into INT 13h for disk access.
We don't have an option ROM, but that might be an interesting way to approach things, although there are issues with teardown before the OS comes along which endbootservices solves nicely for us.
And on the subject of the NV storage... does -pflash work on qemu-xen, as long as we're not actually running *code* from the device and we're only using it for data storage?
I'm not sure, I've CC'd Anthony & Stefano. Assuming the Xen machine type in Qemu wires it up then I don't know why it shouldn't work and if we don't wire it up I don't see why we couldn't.
Qemu does but not in KVM mode, because it can't *execute* from a region and also catch writes to properly emulate flash. But for a flash device that we *don't* execute from, because it's only used for NV storage and not the firmware itself, that restriction isn't important. So I'll need to fix that.
Maybe it would be useful to emulate a dumb NV RAM region, as opposed to a full flash emulation?
Hvmloader might need to be tweaked to setup the e820 correctly and perhaps the some table or other would need to refer to it also?
Right. Haven't quite worked out how it would be 'found' by the firmware yet. I was going to suggest making the address available via fw_cfg... but you don't implement that.
There's a little protocol between HVMloader and SeaBIOS which passes the tables across, see src/xen.c struct xen_seabios_info. Perhaps HVMloader+OVMF should be (or is?) using the same (or similar). Either way it should be extensible to cover this new info. The other option is an HVM_PARAM, which is Xen specific, but pretty simple.
Ian.
Regarding the ACPI tables, OVMF takes them from Xen. It scans 0x000EA020 to 0x000FFFFF for the RSDP and goes from there. See OvmfPkg/AcpiPlatformDxe/Xen.c.
I'm not sure about the e820 table. In hvmloader's build_e820_table() [tools/firmware/hvmloader/e820.c], a range starting at RESERVED_MEMBASE is added to the table:
/* * Explicitly reserve space for special pages. * This space starts at RESERVED_MEMBASE an extends to cover various * fixed hardware mappings (e.g., LAPIC, IOAPIC, default SVGA framebuffer). * * If igd_opregion_pgbase we need to split the RESERVED region in two. */
I gather this range is found non-specially by SeaBIOS [src/xen.c] in xen_ramsize_preinit(), following the xen_seabios_info struct you mentioned, placed at 0x00001000.
However in OVMF the RESERVED_MEMBASE range is not parsed from this Xen-exported table, it is added manually in InitializeXen() [OvmfPkg/PlatformPei/Xen.c]:
// // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000). // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE. // AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000);
"MemDetect.c" in the same directory might be relevant as well (GetSystemMemorySizeBelow4gb(), GetSystemMemorySizeAbove4gb(); they work from the CMOS).
... I gather this is about the placement of the flash memory, yes? If a static address could work for the flash, I think in OVMF we should update - MemMapInitialization() [OvmfPkg/PlatformPei/Platform.c] - OvmfPkg/AcpiTables/Dsdt.asl
But I could be completely missing the topic here...
Thanks, Laszlo
On Wed, 2013-02-20 at 17:55 +0100, Laszlo Ersek wrote:
However in OVMF the RESERVED_MEMBASE range is not parsed from this Xen-exported table, it is added manually in InitializeXen() [OvmfPkg/PlatformPei/Xen.c]:
// // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000). // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE. // AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000);
ICK, it would be far preferable for OVMF to do what SeaBIOS does and actually "communicate" with hvmloader IMHO.
Ian.
On 02/20/13 18:18, Ian Campbell wrote:
On Wed, 2013-02-20 at 17:55 +0100, Laszlo Ersek wrote:
However in OVMF the RESERVED_MEMBASE range is not parsed from this Xen-exported table, it is added manually in InitializeXen() [OvmfPkg/PlatformPei/Xen.c]:
// // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000). // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE. // AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000);
ICK, it would be far preferable for OVMF to do what SeaBIOS does and actually "communicate" with hvmloader IMHO.
The table with "XenHVMSeaBIOS" signature is not created for OVMF I think; comparing the "bios_config" structure of function pointers between "seabios.c" and "ovmf.c" in tools/firmware/hvmloader/, the ovmf_config.bios_info_setup field is NULL.
However there seem to be at least two "info" tables. Referring back, "seabios_info" at BIOS_INFO_PHYSICAL_ADDRESS (0x1000) is for SeaBIOS only, but "hvm_info" just below the end of conventional memory (at HVM_INFO_PADDR, 0x9F800) looks guest firmware independent.
I guess the quoted range would be available from "hvm_info.reserved_mem_pgstart"? OvmfPkg/PlatformPei/Xen.c has a comment in XenConnect() saying
/* TBD: Locate hvm_info and reserve it away. */ mXenInfo.HvmInfo = NULL;
Is the generic approach "see if you can find all what you need in hvm_info, ask for the rest in a dedicated table"? (Out of pure curiosity.)
Thanks Laszlo
(dropping Attilio he has left Citrix).
On Wed, 2013-02-20 at 23:50 +0100, Laszlo Ersek wrote:
On 02/20/13 18:18, Ian Campbell wrote:
On Wed, 2013-02-20 at 17:55 +0100, Laszlo Ersek wrote:
However in OVMF the RESERVED_MEMBASE range is not parsed from this Xen-exported table, it is added manually in InitializeXen() [OvmfPkg/PlatformPei/Xen.c]:
// // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000). // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE. // AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000);
ICK, it would be far preferable for OVMF to do what SeaBIOS does and actually "communicate" with hvmloader IMHO.
The table with "XenHVMSeaBIOS" signature is not created for OVMF I think; comparing the "bios_config" structure of function pointers between "seabios.c" and "ovmf.c" in tools/firmware/hvmloader/, the ovmf_config.bios_info_setup field is NULL.
Yes. I think this should be changed then to provide a proper way for hvmloader to communicate to OVMF. It would seem sensible to follow a similar mechanism to SeaBIOS, or if possible just reuse the exact same thing (perhaps with a different signature).
However there seem to be at least two "info" tables. Referring back, "seabios_info" at BIOS_INFO_PHYSICAL_ADDRESS (0x1000) is for SeaBIOS only, but "hvm_info" just below the end of conventional memory (at HVM_INFO_PADDR, 0x9F800) looks guest firmware independent.
hvm_info is used by the toolstack to pass parameters to hvmloader itself when it starts, it is not intended to pass options from hvmloader to the bios. It is not a stable ABI struct (since hvmloader and the toolstack are a matched pair it doesn't have to be) and we hope to eventually get rid of it. Possibly hvmloader should scrub it before calling the BIOS to discourage its use.
I guess the quoted range would be available from "hvm_info.reserved_mem_pgstart"? OvmfPkg/PlatformPei/Xen.c has a comment in XenConnect() saying
/* TBD: Locate hvm_info and reserve it away. */ mXenInfo.HvmInfo = NULL;
Oh dear.
Is the generic approach "see if you can find all what you need in hvm_info, ask for the rest in a dedicated table"? (Out of pure curiosity.)
As I hope is clear from the above, Nope ;-)
Ian.
On Thu, 2013-02-14 at 13:05 +0000, David Woodhouse wrote:
On Thu, 2013-02-14 at 12:53 +0000, Ian Campbell wrote:
I had observed once upon a time that turning up the limit caused odd failures, but I'd never associated it with the size. I spent ages trying to track down a NULL pointer in some level>3 message and the like...
In hvmloader I see: #define SEABIOS_PHYSICAL_ADDRESS 0x000E0000 which would have to change if the image grew >128K. Really hvmloader should check the size dynamically and DTRT. I can't remember why I did it this way.
No idea. If I just set .bios_address = 0x100000U - sizeof(seabios), it works just fine.
Sorry about this, crapness on our end I think :-(
Ahem, you also have //BUILD_BUG_ON(sizeof(seabios) > (0x00100000U - SEABIOS_PHYSICAL_ADDRESS));
Now *that* would have been a time-saver...
Oh god, sorry.
Another observation: 'xl -c seabios.cfg' misses the first output of the domain. Starting it *paused*, then running 'xl unpause seabios' in another terminal, lets me catch even the first 'Start bios ...' message.
If it *had* been crashing early in SeaBIOS, I'd have been cursing you for that one too :)
Justifiably so I think.
Anyway, I appear to have established that the qemu fw_cfg *doesn't* exist in your domains — so how you pass bootorder to the guest, if you successfully do so at all, I have no idea. And the patch at http://git.infradead.org/users/dwmw2/seabios.git/commitdiff/e62d1720f appears to work fine — at least in the case of a domain with nothing to actually boot from anyway, where we expect it just to die with 'no bootable device'.
Erm, this might be something we Xen folks need to fix! I'm not sure if that fix will involve using fwcfg or not...
I'll probably have a look at OVMF under Xen now, and making sure that my CSM code works there. Then you shouldn't need to offer people the choice between OVMF and SeaBIOS because you'll have one image that handles everything (which is what people get on real hardware, and expect).
That would be pretty sweet, thanks!
On Thu, 2013-02-14 at 13:05 +0000, David Woodhouse wrote:
Anyway, I appear to have established that the qemu fw_cfg *doesn't* exist in your domains — so how you pass bootorder to the guest, if you successfully do so at all, I have no idea.
Asking around no one seems to have any idea how this works, other than we pass it to qemu.
Oh well, this is our mystery not yours, I think.
Ian.
On Thu, 2013-02-14 at 16:41 +0000, Ian Campbell wrote:
On Thu, 2013-02-14 at 13:05 +0000, David Woodhouse wrote:
Anyway, I appear to have established that the qemu fw_cfg *doesn't* exist in your domains — so how you pass bootorder to the guest, if
you
successfully do so at all, I have no idea.
Asking around no one seems to have any idea how this works, other than we pass it to qemu.
*Does* it work?
And — more to the point, since this is my only real reason for caring about it at all — does it *stop* working if you build SeaBIOS from my tree at git.infradead.org/users/dwmw2/seabios.git ?
On Thu, 2013-02-14 at 16:47 +0000, David Woodhouse wrote:
On Thu, 2013-02-14 at 16:41 +0000, Ian Campbell wrote:
On Thu, 2013-02-14 at 13:05 +0000, David Woodhouse wrote:
Anyway, I appear to have established that the qemu fw_cfg *doesn't* exist in your domains — so how you pass bootorder to the guest, if
you
successfully do so at all, I have no idea.
Asking around no one seems to have any idea how this works, other than we pass it to qemu.
*Does* it work?
People seem to think so, but I'm starting to wonder. I'm going to go and check for myself now.
And — more to the point, since this is my only real reason for caring about it at all — does it *stop* working if you build SeaBIOS from my tree at git.infradead.org/users/dwmw2/seabios.git ?
I will give that a go second.
Ian.
On Thu, 2013-02-14 at 17:11 +0000, Ian Campbell wrote:
On Thu, 2013-02-14 at 16:47 +0000, David Woodhouse wrote:
On Thu, 2013-02-14 at 16:41 +0000, Ian Campbell wrote:
On Thu, 2013-02-14 at 13:05 +0000, David Woodhouse wrote:
Anyway, I appear to have established that the qemu fw_cfg *doesn't* exist in your domains — so how you pass bootorder to the guest, if
you
successfully do so at all, I have no idea.
Asking around no one seems to have any idea how this works, other than we pass it to qemu.
*Does* it work?
People seem to think so, but I'm starting to wonder. I'm going to go and check for myself now.
I can indeed select between disk, network and cdrom using the boot="c" (or "d" or "n") option.
And — more to the point, since this is my only real reason for caring about it at all — does it *stop* working if you build SeaBIOS from my tree at git.infradead.org/users/dwmw2/seabios.git ?
I will give that a go second.
I tested: HEAD is now at e62d172 Make Xen one of the top-level build target choices with the attached config and I'm afraid it booted from the cdrom no matter what I did in my config file.
I enabled CONFIG_QEMU_HARDWARE (seabios2.config) and that didn't help (which surprised me because I associate that option with fw_cfg).
The following quick hack didn't help, so something deeper must be up, I can have another poke tomorrow and see if I can work out how this ever worked...
BTW, the disk stanza for a cdrom is 'file:/scratch/mini.iso,hdc:cdrom,r'
Ian.
diff --git a/src/paravirt.c b/src/paravirt.c index cc64094..c4ffd32 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -157,7 +157,7 @@ void qemu_cfg_preinit(void) char *sig = "QEMU"; int i;
- if (!CONFIG_QEMU) + if (!CONFIG_QEMU&&!CONFIG_XEN) return;
qemu_cfg_present = 1; @@ -433,7 +433,7 @@ struct QemuCfgFile {
void qemu_romfile_init(void) { - if (!CONFIG_QEMU || !qemu_cfg_present) + if ((!CONFIG_QEMU && !CONFIG_XEN) || !qemu_cfg_present) return;
u32 count;
On Thu, 2013-02-14 at 18:10 +0000, Ian Campbell wrote:
I tested: HEAD is now at e62d172 Make Xen one of the top-level build target choices with the attached config and I'm afraid it booted from the cdrom no matter what I did in my config file.
I enabled CONFIG_QEMU_HARDWARE (seabios2.config) and that didn't help (which surprised me because I associate that option with fw_cfg).
OK, fw_cfg *is* active in your setup, although my own SeaBIOS build (before my patch) isn't detecting it for some local reason. Perhaps because I don't *have* any disks, so it doesn't set the bootorder. And maybe doesn't expose fw_cfg to the guest at all? Or maybe just other weirdness here.
Anyway, I *know* my patch breaks it because it's associated with CONFIG_QEMU not CONFIG_QEMU_HARDWARE. Will modify, but not when there's a 2-year-old shouting and climbing between me and the keyboard shouting 'Daddy Duddle!'...
Thanks for testing.
On Thu, 2013-02-14 at 18:10 +0000, Ian Campbell wrote:
I tested: HEAD is now at e62d172 Make Xen one of the top-level build target choices with the attached config and I'm afraid it booted from the cdrom no matter what I did in my config file.
The patch I sent earlier seems to have fixed it. As was pointed out to me in private email (thanks), it's in the CMOS not fw_cfg.
To bombadil:public_git/seabios.git + e62d172...d8ff442 master -> master (forced update)
That version ought to work. Thanks for your help with this.
On Thu, 2013-02-14 at 20:48 +0000, David Woodhouse wrote:
On Thu, 2013-02-14 at 18:10 +0000, Ian Campbell wrote:
I tested: HEAD is now at e62d172 Make Xen one of the top-level build target choices with the attached config and I'm afraid it booted from the cdrom no matter what I did in my config file.
The patch I sent earlier seems to have fixed it. As was pointed out to me in private email (thanks), it's in the CMOS not fw_cfg.
Oh of course, I 'd forgotten all about that functionality.
To bombadil:public_git/seabios.git
- e62d172...d8ff442 master -> master (forced update)
I tested this version and it looks good to me too.
That version ought to work. Thanks for your help with this.
Thank you too for thinking of us.
Ian.
On Wed, 2013-02-13 at 11:05 +0000, David Woodhouse wrote:
I'm running Fedora 18 with Xen 4.2.1 but using the Fedora 17 3.7.3 kernel because the F18 3.7.6 kernel doesn't find its root filesystem when booted under Xen.
Sorry for changing topic for a bit, but since I've been in this situation you describe before, is it possible that you're hitting these:
https://bugzilla.redhat.com/show_bug.cgi?id=783851 http://markmail.org/message/k6gdno6mf7geynnl
If yes, just running `grub2-mkconfig -o /boot/grub2/grub.cfg' should fix this, and you'll be able to use the new kernel.
Unfortunately, for now, that has to be done all the time Fedora updates the kernel, because their use of grubby right after that (instead of grub2-mkconfig), does not play well with Xen. We're working on trying to fix this.
If that is not the case, sorry for interrupting the discussion. If it is, I wish I could have been of help. :-)
Regards, Dario
On Tue, 2013-02-12 at 10:34 +0000, Ian Campbell wrote:
Lastly to change the seabios bits, just change to tools/firmware/seabios-dir (assuming Fedora's packaging hasn't moved it) and git fetch/git reset/vim/emacs, the build system won't clobber this unless you ask it to. Then to rebuild: rm tools/firmware/hvmloader/seabios.o \ tools/firmware/seabios-dir/out/bios.bin \ tools/firmware/hvmloader/roms.inc make -C tools/firmware
The standard way to rebuild Fedora packages is 'fedpkg clone' (which is just a helper around 'git clone', then 'fedpkg local' to build them.
Fedora applies a patch to use a prebuilt bios.bin from their SeaBIOS package instead of a build from within the Xen build tree; I've hacked that further to set SEABIOS_ROM=/home/dwmw2/git/seabios/out/bios.bin instead. Then 'make' in the tools/firmware/hvmloader directory, check with 'strings' that my own build is actually in there, and add the firmware_override line to the config as you suggested.
There is no change in behaviour; I still get 35 seconds of 'Daemon running with PID xxxx' and then it exits. I've enabled both debug-port *and* serial debug (at 0x3f8) in my SeaBIOS build.
On Mon, Feb 11, 2013 at 12:43:29PM +0000, Ian Campbell wrote:
On Mon, 2013-02-11 at 10:54 +0000, David Woodhouse wrote:
On Sat, 2013-02-09 at 14:08 -0500, Kevin O'Connor wrote:
This patch series is less ambitious than the previous - SeaBIOS can't be compiled for multiple platforms (eg, QEMU, CSM, coreboot) at the same time.
Out of interest, why not include Xen in that list? Do we gain any real benefit from building a multi-platform binary that can be used both natively under qemu *and* from Xen?
I suppose it could be argued that from the PoV of SeaBIOS a Xen guest (which uses qemu for device models) is not all that different from qemu/kvm.
I don't know if distros prefer to have fewer images or not, once you have 2 I guess having N is not such a big deal for something the size and build time of SeaBIOS.
Looking briefly at the fc18 rpms, it appears that seabios is included into the hvmloader binary. If so, I doubt it would matter to the distros as then it's already a separate copy (embedded within hvmloader).
BTW, does Xen implement the "fw_cfg" interface to pass config info (eg, bootorder) to SeaBIOS?
-Kevin
On Mon, 2013-02-11 at 19:06 -0500, Kevin O'Connor wrote:
On Mon, Feb 11, 2013 at 12:43:29PM +0000, Ian Campbell wrote:
On Mon, 2013-02-11 at 10:54 +0000, David Woodhouse wrote:
On Sat, 2013-02-09 at 14:08 -0500, Kevin O'Connor wrote:
This patch series is less ambitious than the previous - SeaBIOS can't be compiled for multiple platforms (eg, QEMU, CSM, coreboot) at the same time.
Out of interest, why not include Xen in that list? Do we gain any real benefit from building a multi-platform binary that can be used both natively under qemu *and* from Xen?
I suppose it could be argued that from the PoV of SeaBIOS a Xen guest (which uses qemu for device models) is not all that different from qemu/kvm.
I don't know if distros prefer to have fewer images or not, once you have 2 I guess having N is not such a big deal for something the size and build time of SeaBIOS.
Looking briefly at the fc18 rpms, it appears that seabios is included into the hvmloader binary. If so, I doubt it would matter to the distros as then it's already a separate copy (embedded within hvmloader).
Right. The separate copy I was thinking of is in the SeaBIOS package which the Xen build depends on and pulls in the image to link into hvmloader, this is how it is done on Debian at least. The other option is to embed a copy of the SeaBIOS source into Xen which is what we as upstream do but I can see why distros might not want to carry two copies of the same source.
BTW, does Xen implement the "fw_cfg" interface to pass config info (eg, bootorder) to SeaBIOS?
We support setting boot order in our toolstack, which finds its way to qemu's command line and then to the guest. So I guess the answer must be yes.
Ian.
On 02/09/13 20:08, Kevin O'Connor wrote:
This is the redo of the "multi-platform support" patch I sent previously.
This patch series is less ambitious than the previous - SeaBIOS can't be compiled for multiple platforms (eg, QEMU, CSM, coreboot) at the same time. However, this series still contains all the CONFIG_X reorganization and it will ensure that virtual devices aren't accessed when not on real hardware when using CONFIG_CSM. This series also enables the possibility of using some virtual devices under coreboot and CSM when it is safe to do so (and CONFIG_QEMU_HARDWARE is selected).
I have also placed this code for testing at: https://github.com/KevinOConnor/seabios/tree/test-20130209
When trying to build it on RHEL-6.3.z with the attached config (prepared with "make menuconfig"), I get
out/vgaccode16.o: In function `runningOnQEMU': /home/lacos/src/upstream/seabios/out/../src/paravirt.h:17: undefined reference to `PlatformRunningOn' /home/lacos/src/upstream/seabios/out/../src/paravirt.h:17: undefined reference to `PlatformRunningOn' /home/lacos/src/upstream/seabios/out/../src/paravirt.h:17: undefined reference to `PlatformRunningOn' /home/lacos/src/upstream/seabios/out/../src/paravirt.h:17: undefined reference to `PlatformRunningOn' /home/lacos/src/upstream/seabios/out/../src/paravirt.h:17: undefined reference to `PlatformRunningOn' out/vgaccode16.o:/home/lacos/src/upstream/seabios/out/../src/paravirt.h:17: more undefined references to `PlatformRunningOn' follow
I might have mis-configured the build...
Thanks Laszlo
On Tue, Feb 12, 2013 at 01:06:34PM +0100, Laszlo Ersek wrote:
On 02/09/13 20:08, Kevin O'Connor wrote:
This is the redo of the "multi-platform support" patch I sent previously.
This patch series is less ambitious than the previous - SeaBIOS can't be compiled for multiple platforms (eg, QEMU, CSM, coreboot) at the same time. However, this series still contains all the CONFIG_X reorganization and it will ensure that virtual devices aren't accessed when not on real hardware when using CONFIG_CSM. This series also enables the possibility of using some virtual devices under coreboot and CSM when it is safe to do so (and CONFIG_QEMU_HARDWARE is selected).
I have also placed this code for testing at: https://github.com/KevinOConnor/seabios/tree/test-20130209
When trying to build it on RHEL-6.3.z with the attached config (prepared with "make menuconfig"), I get
out/vgaccode16.o: In function `runningOnQEMU': /home/lacos/src/upstream/seabios/out/../src/paravirt.h:17: undefined reference to `PlatformRunningOn'
Oops. This is because CONFIG_DEBUG_IO looks at PlatformRunningOn (with certain config options) and the vgabios doesn't include the C file that defines the variable. I'll fix it up. For now, just don't build the vgabios with CONFIG_CSM set.
-Kevin
On 02/12/13 14:55, Kevin O'Connor wrote:
On Tue, Feb 12, 2013 at 01:06:34PM +0100, Laszlo Ersek wrote:
out/vgaccode16.o: In function `runningOnQEMU': /home/lacos/src/upstream/seabios/out/../src/paravirt.h:17: undefined reference to `PlatformRunningOn'
Oops. This is because CONFIG_DEBUG_IO looks at PlatformRunningOn (with certain config options) and the vgabios doesn't include the C file that defines the variable. I'll fix it up. For now, just don't build the vgabios with CONFIG_CSM set.
I'd like to test David's most recent CSM changes. What config options are recommended then?
Thanks! Laszlo
On Tue, Feb 12, 2013 at 03:29:44PM +0100, Laszlo Ersek wrote:
On 02/12/13 14:55, Kevin O'Connor wrote:
On Tue, Feb 12, 2013 at 01:06:34PM +0100, Laszlo Ersek wrote:
out/vgaccode16.o: In function `runningOnQEMU': /home/lacos/src/upstream/seabios/out/../src/paravirt.h:17: undefined reference to `PlatformRunningOn'
Oops. This is because CONFIG_DEBUG_IO looks at PlatformRunningOn (with certain config options) and the vgabios doesn't include the C file that defines the variable. I'll fix it up. For now, just don't build the vgabios with CONFIG_CSM set.
I'd like to test David's most recent CSM changes. What config options are recommended then?
Don't build a vgabios (make sure CONFIG_NO_VGABIOS is true).
-Kevin
This series bears witness to my extreme cluelessness. With it I'm only asking if we can move the hypervisor/platform detection logic to SRCBOTH code, so that it sets up "PlatformRunningOn" for all of CSM, vgabios, and "normal" SeaBIOS. The motivation is that running on qemu is now a requirement for logging to the qemu debug port, and logging to that port would be nice in all flavors & parts.
The series applies to f8c70b87 ("Add UmbStart,UmbEnd fields to EFI_COMPATIBILITY16_TABLE") in git://git.infradead.org/users/dwmw2/seabios.git, which is basically 53d2ddd6 ("Minor - move definitions to paravirt.c from paravirt.h") from git://github.com/KevinOConnor/seabios.git plus the following patches from David:
eff724e Make Xen one of the top-level build target choices 60258aa Clean up Kconfig options for CSM 87f4dca Enable VGA output when settings bochs-specific mode 5b5356d Fix rom_reserve()/rom_confirm() for CSM oprom dispatch 6cca1bf Don't calibrate TSC if PMTIMER is already set up 2468d84 Move find_pmtimer() to ACPI table setup where it logically belongs 9d8ecac Use find_pmtimer() after copying Xen ACPI tables 7d95992 Use find_pmtimer() after copying coreboot ACPI tables 70ac823 Initialise BIOS tables (and hence PMTIMER) early for Coreboot and Xen b41a46f Reject non-compliant PCI option ROMs with unaligned PCIR structure 5c87ddb Unify return path for CSM to go via csm_return() f8c70b8 Add UmbStart,UmbEnd fields to EFI_COMPATIBILITY16_TABLE
I got the messages that I wanted, but I probably broke everything in the process. Another approach would be to replace the runtime runningOnQEMU() check in putc_debug() with the build-time constant
(CONFIG_QEMU || (CONFIG_CSM && CONFIG_QEMU_HARDWARE) || CONFIG_XEN)
condition.
Laszlo Ersek (5): add .config for CSM testing move hypervisor detection to "util.c" (SRCBOTH) vga_post(): detect hypervisors for the qemu debug port's sake Legacy16InitializeYourself(): detect hypervisors for the qemu debug port's sake make QEMU_HARDWARE mean "assume virtual hardware"
src/paravirt.h | 22 ------------- src/util.h | 29 +++++++++++++++++ src/misc.c | 2 - src/paravirt.c | 29 +---------------- src/xen.c | 30 +---------------- src/util.c | 66 ++++++++++++++++++++++++++++++++++++++ src/apm.c | 1 - src/esp-scsi.c | 1 - src/lsi-scsi.c | 1 - src/output.c | 1 - .config | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 1 - src/Kconfig | 9 +++-- src/csm.c | 3 ++ vgasrc/vgabios.c | 2 + 15 files changed, 201 insertions(+), 88 deletions(-) create mode 100644 .config
On Wed, Feb 13, 2013 at 04:52:09AM +0100, Laszlo Ersek wrote:
This series bears witness to my extreme cluelessness. With it I'm only asking if we can move the hypervisor/platform detection logic to SRCBOTH code, so that it sets up "PlatformRunningOn" for all of CSM, vgabios, and "normal" SeaBIOS.
It's possible to do this, but it's not a great way of detecting the platform - it can only detect Xen/KVM and not raw QEMU. On coreboot, it's possible to determine if qemu (or its derivatives) launched SeaBIOS by looking for the qemu signature in the vendor/part identifiers in the coreboot tables. David suggested that something similar could be done for CSM by looking at the SMBIOS tables.
The motivation is that running on qemu is now a requirement for logging to the qemu debug port, and logging to that port would be nice in all flavors & parts.
I recently pushed the "Improved multi-platform support" series, but I pulled out the CONFIG_DEBUG_IO change that allowed it to work with just CONFIG_QEMU_HARDWARE. I think it's possible to get it working with CONFIG_QEMU_HARDWARE with something like the patch below.
Also, the current SeaVGABIOS code is checking for "!COREBOOT" in its Kconfig file - that should be changed to "QEMU". With that fixed this will be even less of a concern. (It really only makes sense to build a cirrus/bochs vgabios for QEMU - which would always have the debug port available.)
-Kevin
diff --git a/Makefile b/Makefile index e02803e..b9fed0f 100644 --- a/Makefile +++ b/Makefile @@ -36,14 +36,14 @@ COMMONCFLAGS += $(call cc-option,$(CC),-nopie,) COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector,) COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
-CFLAGS32FLAT := $(COMMONCFLAGS) -DMODE16=0 -DMODESEGMENT=0 -fomit-frame-pointer +CFLAGS32FLAT := $(COMMONCFLAGS) -DMODE16=0 -DMODESEGMENT=0 -fomit-frame-pointer -DMODEVGA=0 CFLAGSSEG := $(COMMONCFLAGS) -DMODESEGMENT=1 -fno-defer-pop \ $(call cc-option,$(CC),-fno-jump-tables,-DMANUAL_NO_JUMP_TABLE) \ $(call cc-option,$(CC),-fno-tree-switch-conversion,) -CFLAGS32SEG := $(CFLAGSSEG) -DMODE16=0 -fomit-frame-pointer +CFLAGS32SEG := $(CFLAGSSEG) -DMODE16=0 -fomit-frame-pointer -DMODEVGA=0 CFLAGS16INC := $(CFLAGSSEG) -DMODE16=1 -Wa,src/code16gcc.s \ $(call cc-option,$(CC),--param large-stack-frame=4,-fno-inline) -CFLAGS16 := $(CFLAGS16INC) -fomit-frame-pointer +CFLAGS16 := $(CFLAGS16INC) -fomit-frame-pointer -DMODEVGA=0
# Run with "make V=1" to see the actual compile commands ifdef V @@ -179,7 +179,7 @@ SRCVGA=src/output.c src/util.c src/pci.c \ vgasrc/stdvga.c vgasrc/stdvgamodes.c vgasrc/stdvgaio.c \ vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodevga.c
-CFLAGS16VGA = $(CFLAGS16INC) -Isrc +CFLAGS16VGA = $(CFLAGS16INC) -Isrc -DMODEVGA=1
$(OUT)vgaccode16.raw.s: $(OUT)autoconf.h ; $(call whole-compile, $(CFLAGS16VGA) -S, $(SRCVGA),$@)
diff --git a/src/Kconfig b/src/Kconfig index 4ddf9da..7df6c67 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -406,7 +406,7 @@ menu "Debugging" Base port for serial - generally 0x3f8, 0x2f8, 0x3e8, or 0x2e8.
config DEBUG_IO - depends on QEMU && DEBUG_LEVEL != 0 + depends on QEMU_HARDWARE && DEBUG_LEVEL != 0 bool "Special IO port debugging" default y help diff --git a/src/output.c b/src/output.c index e623d37..27621f5 100644 --- a/src/output.c +++ b/src/output.c @@ -11,6 +11,7 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "biosvar.h" // GET_GLOBAL +#include "paravirt.h" // runningOnQEMU
struct putcinfo { void (*func)(struct putcinfo *info, char c); @@ -77,7 +78,7 @@ putc_debug(struct putcinfo *action, char c) { if (! CONFIG_DEBUG_LEVEL) return; - if (CONFIG_DEBUG_IO) + if (CONFIG_DEBUG_IO && runningOnQEMU()) // Send character to debug port. outb(c, GET_GLOBAL(DebugOutputPort)); if (c == '\n') diff --git a/src/paravirt.h b/src/paravirt.h index 4438273..11343cd 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -14,7 +14,7 @@ extern int PlatformRunningOn;
static inline int runningOnQEMU(void) { return CONFIG_QEMU || ( - CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU); + !MODEVGA && CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU); } static inline int runningOnXen(void) { return CONFIG_XEN && GET_GLOBAL(PlatformRunningOn) & PF_XEN;
On 02/13/13 06:19, Kevin O'Connor wrote:
On Wed, Feb 13, 2013 at 04:52:09AM +0100, Laszlo Ersek wrote:
This series bears witness to my extreme cluelessness. With it I'm only asking if we can move the hypervisor/platform detection logic to SRCBOTH code, so that it sets up "PlatformRunningOn" for all of CSM, vgabios, and "normal" SeaBIOS.
It's possible to do this, but it's not a great way of detecting the platform - it can only detect Xen/KVM and not raw QEMU. On coreboot, it's possible to determine if qemu (or its derivatives) launched SeaBIOS by looking for the qemu signature in the vendor/part identifiers in the coreboot tables. David suggested that something similar could be done for CSM by looking at the SMBIOS tables.
The motivation is that running on qemu is now a requirement for logging to the qemu debug port, and logging to that port would be nice in all flavors & parts.
I recently pushed the "Improved multi-platform support" series, but I pulled out the CONFIG_DEBUG_IO change that allowed it to work with just CONFIG_QEMU_HARDWARE.
I think I understand. DEBUG_IO still depends on QEMU (from Gerd's commit 9600c800), and selecting CSM will not satisfy that.
I think it's possible to get it working with CONFIG_QEMU_HARDWARE with something like the patch below.
Are two builds necessary with this change? One with CSM && QEMU_HARDWARE (which will build a CSM-ized bios.bin that logs to the debug port, and a vgabios.bin that doesn't), and another with QEMU (implying QEMU_HARDWARE, from which build the bios.bin is to be ignored for CSM purposes, and the vgabios.bin is to be installed, because it logs to the debug port)?
Also, the current SeaVGABIOS code is checking for "!COREBOOT" in its Kconfig file - that should be changed to "QEMU". With that fixed this will be even less of a concern. (It really only makes sense to build a cirrus/bochs vgabios for QEMU - which would always have the debug port available.)
Yes, I think it would eliminate the non-debugport-logging vgabios.bin from the first (== CSM && QEMU_HARDWARE) build above.
... However, I think the (CSM && QEMU_HARDWARE) bios.bin would still not log to the debug port. The (GET_GLOBAL(PlatformRunningOn) & PF_QEMU) part would evaluate to false, for two reasons: first, qemu_ramsize_preinit() will not set the flag when !CONFIG_QEMU (which is implied by CONFIG_CSM); second, qemu_ramsize_preinit() is never even invoked in the CSM build.
Anyway I've been beating this dead horse long enough; I guess I can easily hack the DEBUG_IO dependency (and nothing else) in scratch builds.
Thanks for your help! Laszlo
-Kevin
diff --git a/Makefile b/Makefile index e02803e..b9fed0f 100644 --- a/Makefile +++ b/Makefile @@ -36,14 +36,14 @@ COMMONCFLAGS += $(call cc-option,$(CC),-nopie,) COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector,) COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
-CFLAGS32FLAT := $(COMMONCFLAGS) -DMODE16=0 -DMODESEGMENT=0 -fomit-frame-pointer +CFLAGS32FLAT := $(COMMONCFLAGS) -DMODE16=0 -DMODESEGMENT=0 -fomit-frame-pointer -DMODEVGA=0 CFLAGSSEG := $(COMMONCFLAGS) -DMODESEGMENT=1 -fno-defer-pop \ $(call cc-option,$(CC),-fno-jump-tables,-DMANUAL_NO_JUMP_TABLE) \ $(call cc-option,$(CC),-fno-tree-switch-conversion,) -CFLAGS32SEG := $(CFLAGSSEG) -DMODE16=0 -fomit-frame-pointer +CFLAGS32SEG := $(CFLAGSSEG) -DMODE16=0 -fomit-frame-pointer -DMODEVGA=0 CFLAGS16INC := $(CFLAGSSEG) -DMODE16=1 -Wa,src/code16gcc.s \ $(call cc-option,$(CC),--param large-stack-frame=4,-fno-inline) -CFLAGS16 := $(CFLAGS16INC) -fomit-frame-pointer +CFLAGS16 := $(CFLAGS16INC) -fomit-frame-pointer -DMODEVGA=0
# Run with "make V=1" to see the actual compile commands ifdef V @@ -179,7 +179,7 @@ SRCVGA=src/output.c src/util.c src/pci.c \ vgasrc/stdvga.c vgasrc/stdvgamodes.c vgasrc/stdvgaio.c \ vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodevga.c
-CFLAGS16VGA = $(CFLAGS16INC) -Isrc +CFLAGS16VGA = $(CFLAGS16INC) -Isrc -DMODEVGA=1
$(OUT)vgaccode16.raw.s: $(OUT)autoconf.h ; $(call whole-compile, $(CFLAGS16VGA) -S, $(SRCVGA),$@)
diff --git a/src/Kconfig b/src/Kconfig index 4ddf9da..7df6c67 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -406,7 +406,7 @@ menu "Debugging" Base port for serial - generally 0x3f8, 0x2f8, 0x3e8, or 0x2e8.
config DEBUG_IO
depends on QEMU && DEBUG_LEVEL != 0
depends on QEMU_HARDWARE && DEBUG_LEVEL != 0 bool "Special IO port debugging" default y help
diff --git a/src/output.c b/src/output.c index e623d37..27621f5 100644 --- a/src/output.c +++ b/src/output.c @@ -11,6 +11,7 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "biosvar.h" // GET_GLOBAL +#include "paravirt.h" // runningOnQEMU
struct putcinfo { void (*func)(struct putcinfo *info, char c); @@ -77,7 +78,7 @@ putc_debug(struct putcinfo *action, char c) { if (! CONFIG_DEBUG_LEVEL) return;
- if (CONFIG_DEBUG_IO)
- if (CONFIG_DEBUG_IO && runningOnQEMU()) // Send character to debug port. outb(c, GET_GLOBAL(DebugOutputPort)); if (c == '\n')
diff --git a/src/paravirt.h b/src/paravirt.h index 4438273..11343cd 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -14,7 +14,7 @@ extern int PlatformRunningOn;
static inline int runningOnQEMU(void) { return CONFIG_QEMU || (
CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU);
!MODEVGA && CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU);
} static inline int runningOnXen(void) { return CONFIG_XEN && GET_GLOBAL(PlatformRunningOn) & PF_XEN;
On Wed, Feb 13, 2013 at 01:13:45PM +0100, Laszlo Ersek wrote:
On 02/13/13 06:19, Kevin O'Connor wrote:
I think it's possible to get it working with CONFIG_QEMU_HARDWARE with something like the patch below.
Are two builds necessary with this change? One with CSM && QEMU_HARDWARE (which will build a CSM-ized bios.bin that logs to the debug port, and a vgabios.bin that doesn't), and another with QEMU (implying QEMU_HARDWARE, from which build the bios.bin is to be ignored for CSM purposes, and the vgabios.bin is to be installed, because it logs to the debug port)?
If building for CSM, it's a separate build anyway - one for bios.bin for QEMU and one for bios.bin for CSM (and another for bios.bin.elf for coreboot if desired). It only makes sense to build the vgabios under QEMU as the virtual vga hardware is not really like any real hardware (and the goal is for the CSM bios.bin to be to run on real hardware).
Also, the current SeaVGABIOS code is checking for "!COREBOOT" in its Kconfig file - that should be changed to "QEMU". With that fixed this will be even less of a concern. (It really only makes sense to build a cirrus/bochs vgabios for QEMU - which would always have the debug port available.)
Yes, I think it would eliminate the non-debugport-logging vgabios.bin from the first (== CSM && QEMU_HARDWARE) build above.
... However, I think the (CSM && QEMU_HARDWARE) bios.bin would still not log to the debug port. The (GET_GLOBAL(PlatformRunningOn) & PF_QEMU) part would evaluate to false, for two reasons: first, qemu_ramsize_preinit() will not set the flag when !CONFIG_QEMU (which is implied by CONFIG_CSM); second, qemu_ramsize_preinit() is never even invoked in the CSM build.
It would be incorrect to call qemu_ramsize_preinit in a CSM boot as the ramsize needs to come from UEFI in that situation (and not directly from QEMU). I think the high-level plan in this case is to detect that the code is running under QEMU by inspecting the SMBIOS tables passed in from UEFI and then set the flag.
-Kevin
Signed-off-by: Laszlo Ersek lersek@redhat.com --- .config | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 1 - 2 files changed, 92 insertions(+), 1 deletions(-) create mode 100644 .config
diff --git a/.config b/.config new file mode 100644 index 0000000..e58a55e --- /dev/null +++ b/.config @@ -0,0 +1,92 @@ +# +# Automatically generated make config: don't edit +# SeaBIOS Configuration +# Tue Feb 12 22:34:47 2013 +# + +# +# General Features +# +# CONFIG_COREBOOT is not set +# CONFIG_QEMU is not set +CONFIG_CSM=y +# CONFIG_XEN is not set +CONFIG_QEMU_HARDWARE=y +CONFIG_THREADS=y +# CONFIG_THREAD_OPTIONROMS is not set +CONFIG_RELOCATE_INIT=y +CONFIG_BOOTMENU=y +CONFIG_BOOTSPLASH=y +CONFIG_BOOTORDER=y + +# +# Hardware support +# +CONFIG_ATA=y +# CONFIG_ATA_DMA is not set +# CONFIG_ATA_PIO32 is not set +CONFIG_AHCI=y +CONFIG_VIRTIO_BLK=y +CONFIG_VIRTIO_SCSI=y +CONFIG_ESP_SCSI=y +CONFIG_LSI_SCSI=y +CONFIG_MEGASAS=y +CONFIG_FLOPPY=y +CONFIG_PS2PORT=y +CONFIG_USB=y +CONFIG_USB_UHCI=y +CONFIG_USB_OHCI=y +CONFIG_USB_EHCI=y +CONFIG_USB_MSC=y +CONFIG_USB_UAS=y +CONFIG_USB_HUB=y +CONFIG_USB_KEYBOARD=y +CONFIG_USB_MOUSE=y +CONFIG_SERIAL=y +CONFIG_LPT=y +CONFIG_PMTIMER=y + +# +# BIOS interfaces +# +CONFIG_DRIVES=y +CONFIG_CDROM_BOOT=y +CONFIG_CDROM_EMU=y +CONFIG_PCIBIOS=y +CONFIG_APMBIOS=y +CONFIG_PNPBIOS=y +CONFIG_OPTIONROMS=y +CONFIG_PERMIT_UNALIGNED_PCIROM=y +# CONFIG_OPTIONROMS_DEPLOYED is not set +CONFIG_PMM=y +CONFIG_BOOT=y +CONFIG_KEYBOARD=y +CONFIG_KBD_CALL_INT15_4F=y +CONFIG_MOUSE=y +CONFIG_S3_RESUME=y +CONFIG_VGAHOOKS=y +# CONFIG_DISABLE_A20 is not set + +# +# VGA ROM +# +# CONFIG_NO_VGABIOS is not set +# CONFIG_VGA_STANDARD_VGA is not set +CONFIG_VGA_CIRRUS=y +# CONFIG_VGA_BOCHS is not set +# CONFIG_VGA_GEODEGX2 is not set +# CONFIG_VGA_GEODELX is not set +CONFIG_BUILD_VGABIOS=y +CONFIG_VGA_VBE=y +CONFIG_VGA_PCI=y +# CONFIG_OVERRIDE_PCI_ID is not set +CONFIG_VGA_VID=0x1013 +CONFIG_VGA_DID=0x00b8 + +# +# Debugging +# +CONFIG_DEBUG_LEVEL=20 +CONFIG_DEBUG_SERIAL=y +CONFIG_DEBUG_SERIAL_PORT=0x3f8 +CONFIG_DEBUG_IO=y diff --git a/.gitignore b/.gitignore index f9990fe..21a1269 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ out *.pyc -.config .config.old
Enabling CONFIG_DEBUG_IO for putc_debug() [src/output.c] exposes the following during the vgabios build:
- the "PlatformRunningOn" variable has no external definition in that build, and
- even though putc_debug() is SRCBOTH (consequently, SRC16 too), the hypervisor-dependent initialization functions of "PlatformRunningOn" (kvm_preinit() / xen_preinit()) are defined in SRC32FLAT files only ([src/paravirt.c] / [src/xen.c], respectively).
This makes it impossible to use "PlatformRunningOn" in SRC16 code (even if it was defined, it wouldn't be initialized), which means that we can't print to the qemu debug port in SRC16 code.
The init functions depend on SRCBOTH functionality only: - [src/util.c]: cpuid(), memcpy(), strcmp(), dprintf(), - [src/output.c]: panic(), DebugOutputPort,
hence extract / move both definition and initialization of "PlatformRunningOn" to SRCBOTH [src/util.c]. Assignment to global variables is made with SET_FARVAR(), mimicking SET_VGA().
This should allow us to use CONFIG_DEBUG_IO even in vgabios and Legacy16 CSM callbacks.
Signed-off-by: Laszlo Ersek lersek@redhat.com --- src/paravirt.h | 22 ------------------ src/util.h | 30 +++++++++++++++++++++++++ src/misc.c | 2 - src/paravirt.c | 27 +---------------------- src/xen.c | 30 +----------------------- src/util.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/apm.c | 1 - src/esp-scsi.c | 1 - src/lsi-scsi.c | 1 - src/output.c | 1 - 10 files changed, 99 insertions(+), 82 deletions(-)
diff --git a/src/paravirt.h b/src/paravirt.h index a3da04d..d6fbf99 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -1,28 +1,6 @@ #ifndef __PV_H #define __PV_H
-#include "config.h" // CONFIG_* -#include "biosvar.h" // GET_GLOBAL - -// Types of paravirtualized platforms. -#define PF_QEMU (1<<0) -#define PF_XEN (1<<1) -#define PF_KVM (1<<2) - -// misc.c -extern int PlatformRunningOn; - -static inline int runningOnQEMU(void) { - return CONFIG_QEMU || ( - CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU); -} -static inline int runningOnXen(void) { - return CONFIG_XEN && GET_GLOBAL(PlatformRunningOn) & PF_XEN; -} -static inline int runningOnKVM(void) { - return CONFIG_QEMU && GET_GLOBAL(PlatformRunningOn) & PF_KVM; -} - void qemu_ramsize_preinit(void); void qemu_biostable_setup(void); void qemu_cfg_preinit(void); diff --git a/src/util.h b/src/util.h index 04c5a9d..15e7ce9 100644 --- a/src/util.h +++ b/src/util.h @@ -7,6 +7,8 @@ #define __UTIL_H
#include "types.h" // u32 +#include "config.h" // CONFIG_* +#include "biosvar.h" // GET_GLOBAL
static inline void irq_disable(void) { @@ -149,6 +151,34 @@ struct descloc_s { } PACKED;
// util.c + +// Types of paravirtualized platforms. +#define PF_QEMU (1<<0) +#define PF_XEN (1<<1) +#define PF_KVM (1<<2) + +extern int PlatformRunningOn; + +static inline int runningOnQEMU(void) { + return CONFIG_QEMU || ( + CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU); +} +static inline int runningOnXen(void) { + return CONFIG_XEN && GET_GLOBAL(PlatformRunningOn) & PF_XEN; +} +static inline int runningOnKVM(void) { + return CONFIG_QEMU && GET_GLOBAL(PlatformRunningOn) & PF_KVM; +} + +void qemu_kvm_preinit(void); + +#define XEN_CPUID_BASE_MIN 0x40000000 +#define XEN_CPUID_BASE_MAX 0x40010000 + +// return Xen CPUID base in [XEN_CPUID_BASE_MIN, XEN_CPUID_BASE_MAX) +// returns >= XEN_CPUID_BASE_MAX if Xen was not found +u32 __xen_preinit(void); + void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); u8 checksum_far(u16 buf_seg, void *buf_far, u32 len); u8 checksum(void *buf, u32 len); diff --git a/src/misc.c b/src/misc.c index 3b2ffc1..bcc450a 100644 --- a/src/misc.c +++ b/src/misc.c @@ -16,8 +16,6 @@ u32 RamSize VAR16VISIBLE; u64 RamSizeOver4G; // Space for bios tables built an run-time. char BiosTableSpace[CONFIG_MAX_BIOSTABLE] __aligned(MALLOC_MIN_ALIGN) VAR16VISIBLE; -// Type of emulator platform. -int PlatformRunningOn VAR16VISIBLE;
/**************************************************************** diff --git a/src/paravirt.c b/src/paravirt.c index cc64094..0e6bc92 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -25,38 +25,13 @@ struct e820_reservation { u32 type; };
-/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It - * should be used to determine that a VM is running under KVM. - */ -#define KVM_CPUID_SIGNATURE 0x40000000 - -static void kvm_preinit(void) -{ - if (!CONFIG_QEMU) - return; - unsigned int eax, ebx, ecx, edx; - char signature[13]; - - cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); - memcpy(signature + 0, &ebx, 4); - memcpy(signature + 4, &ecx, 4); - memcpy(signature + 8, &edx, 4); - signature[12] = 0; - - if (strcmp(signature, "KVMKVMKVM") == 0) { - dprintf(1, "Running on KVM\n"); - PlatformRunningOn |= PF_KVM; - } -} - void qemu_ramsize_preinit(void) { if (!CONFIG_QEMU) return;
- PlatformRunningOn = PF_QEMU; - kvm_preinit(); + qemu_kvm_preinit();
// On emulators, get memory size from nvram. u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) diff --git a/src/xen.c b/src/xen.c index e34f25c..8eb7ab4 100644 --- a/src/xen.c +++ b/src/xen.c @@ -6,7 +6,6 @@
#include "config.h" #include "xen.h" -#include "paravirt.h" // PlatformRunningOn #include "memmap.h" // add_e820 #include "types.h" // ASM32FLAT #include "util.h" // copy_acpi_rsdp @@ -50,37 +49,12 @@ static void validate_info(struct xen_seabios_info *t)
void xen_preinit(void) { - u32 base, eax, ebx, ecx, edx; - char signature[13]; - if (!CONFIG_XEN) return;
- for (base = 0x40000000; base < 0x40010000; base += 0x100) { - cpuid(base, &eax, &ebx, &ecx, &edx); - memcpy(signature + 0, &ebx, 4); - memcpy(signature + 4, &ecx, 4); - memcpy(signature + 8, &edx, 4); - signature[12] = 0; - - dprintf(9, "Found hypervisor signature "%s" at %x\n", - signature, base); - if (strcmp(signature, "XenVMMXenVMM") == 0) { - /* Set debug_io_port first, so the following messages work. */ - DebugOutputPort = 0xe9; - dprintf(1, "SeaBIOS (version %s)\n\n", VERSION); - dprintf(1, "Found Xen hypervisor signature at %x\n", base); - if ((eax - base) < 2) - panic("Insufficient Xen cpuid leaves. eax=%x at base %x\n", - eax, base); - xen_cpuid_base = base; - break; - } - } - if (!xen_cpuid_base) + xen_cpuid_base = __xen_preinit(); + if (xen_cpuid_base >= XEN_CPUID_BASE_MAX) panic("No Xen hypervisor found.\n"); - - PlatformRunningOn = PF_QEMU|PF_XEN; }
static int hypercall_xen_version( int cmd, void *arg) diff --git a/src/util.c b/src/util.c index dcc0b71..8ba4eb0 100644 --- a/src/util.c +++ b/src/util.c @@ -8,6 +8,72 @@ #include "bregs.h" // struct bregs #include "config.h" // BUILD_STACK_ADDR
+// Type of emulator platform. +int PlatformRunningOn VAR16VISIBLE; + +/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It + * should be used to determine that a VM is running under KVM. + */ +#define KVM_CPUID_SIGNATURE 0x40000000 + +void qemu_kvm_preinit(void) +{ + unsigned int eax, ebx, ecx, edx; + char signature[13]; + + if (!CONFIG_QEMU) + return; + + SET_FARVAR(get_global_seg(), PlatformRunningOn, PF_QEMU); + + cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); + memcpy(signature + 0, &ebx, 4); + memcpy(signature + 4, &ecx, 4); + memcpy(signature + 8, &edx, 4); + signature[12] = 0; + + if (strcmp(signature, "KVMKVMKVM") == 0) { + dprintf(1, "Running on KVM\n"); + SET_FARVAR(get_global_seg(), PlatformRunningOn, PF_QEMU|PF_KVM); + } +} + +u32 __xen_preinit(void) +{ + u32 base, eax, ebx, ecx, edx; + char signature[13]; + + if (!CONFIG_XEN) + return XEN_CPUID_BASE_MAX; + + for (base = XEN_CPUID_BASE_MIN; base < XEN_CPUID_BASE_MAX; base += 0x100) { + cpuid(base, &eax, &ebx, &ecx, &edx); + memcpy(signature + 0, &ebx, 4); + memcpy(signature + 4, &ecx, 4); + memcpy(signature + 8, &edx, 4); + signature[12] = 0; + + dprintf(9, "Found hypervisor signature "%s" at %x\n", + signature, base); + if (strcmp(signature, "XenVMMXenVMM") == 0) { + /* Set debug_io_port first, so the following messages work. */ + SET_FARVAR(get_global_seg(), DebugOutputPort, 0xe9); + dprintf(1, "SeaBIOS (version %s)\n\n", VERSION); + dprintf(1, "Found Xen hypervisor signature at %x\n", base); + if ((eax - base) < 2) + panic("Insufficient Xen cpuid leaves. eax=%x at base %x\n", + eax, base); + break; + } + } + + if (base < XEN_CPUID_BASE_MAX) { + SET_FARVAR(get_global_seg(), PlatformRunningOn, PF_QEMU|PF_XEN); + } + + return base; +} + void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx) { diff --git a/src/apm.c b/src/apm.c index b2eac6d..6f9434b 100644 --- a/src/apm.c +++ b/src/apm.c @@ -11,7 +11,6 @@ #include "util.h" // dprintf #include "config.h" // CONFIG_* #include "biosvar.h" // GET_GLOBAL -#include "paravirt.h" // runningOnQEMU
static void out_str(const char *str_cs) diff --git a/src/esp-scsi.c b/src/esp-scsi.c index fe70366..e875676 100644 --- a/src/esp-scsi.c +++ b/src/esp-scsi.c @@ -18,7 +18,6 @@ #include "pci_regs.h" // PCI_VENDOR_ID #include "boot.h" // bootprio_find_scsi_device #include "blockcmd.h" // scsi_drive_setup -#include "paravirt.h" // runningOnQEMU #include "disk.h"
#define ESP_TCLO 0x00 diff --git a/src/lsi-scsi.c b/src/lsi-scsi.c index 305610a..78d2f3d 100644 --- a/src/lsi-scsi.c +++ b/src/lsi-scsi.c @@ -18,7 +18,6 @@ #include "pci_regs.h" // PCI_VENDOR_ID #include "boot.h" // bootprio_find_scsi_device #include "blockcmd.h" // scsi_drive_setup -#include "paravirt.h" // runningOnQEMU #include "disk.h"
#define LSI_REG_DSTAT 0x0c diff --git a/src/output.c b/src/output.c index 27621f5..9d8f8d9 100644 --- a/src/output.c +++ b/src/output.c @@ -11,7 +11,6 @@ #include "bregs.h" // struct bregs #include "config.h" // CONFIG_* #include "biosvar.h" // GET_GLOBAL -#include "paravirt.h" // runningOnQEMU
struct putcinfo { void (*func)(struct putcinfo *info, char c);
Signed-off-by: Laszlo Ersek lersek@redhat.com --- vgasrc/vgabios.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index 3e26e32..0855338 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -1282,6 +1282,8 @@ void VISIBLE16 vga_post(struct bregs *regs) { debug_serial_preinit(); + qemu_kvm_preinit(); + __xen_preinit(); dprintf(1, "Start SeaVGABIOS (version %s)\n", VERSION); debug_enter(regs, DEBUG_VGA_POST);
Signed-off-by: Laszlo Ersek lersek@redhat.com --- src/csm.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/src/csm.c b/src/csm.c index 554b304..aac9e78 100644 --- a/src/csm.c +++ b/src/csm.c @@ -68,6 +68,9 @@ csm_maininit(struct bregs *regs) static void handle_csm_0000(struct bregs *regs) { + qemu_kvm_preinit(); + __xen_preinit(); + dprintf(3, "Legacy16InitializeYourself table %04x:%04x\n", regs->es, regs->bx);
seabios:
build QEMU_HARDWARE runningOnQEMU runningOnXen runningOnKVM target -------- ------------- + ------------- ------------ ------------ COREBOOT n (forced) | n n n QEMU y (forced) | y n cpuid==KVM CSM n | n n n CSM y | y n cpuid==KVM XEN y (forced) | y (or panic) y (or panic) n
vgabios / CSM:
build QEMU_HARDWARE runningOnQEMU runningOnXen runningOnKVM target -------- ------------- + ------------- ------------ ------------ COREBOOT n (forced) | n n n QEMU y (forced) | y n cpuid==KVM CSM n | n n n CSM y | y n cpuid==KVM XEN y (forced) | y cpuid==Xen cpuid==KVM
Signed-off-by: Laszlo Ersek lersek@redhat.com --- src/util.h | 7 +++---- src/paravirt.c | 2 +- src/util.c | 2 +- src/Kconfig | 9 +++++---- 4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/util.h b/src/util.h index 15e7ce9..cf9b31a 100644 --- a/src/util.h +++ b/src/util.h @@ -160,14 +160,13 @@ struct descloc_s { extern int PlatformRunningOn;
static inline int runningOnQEMU(void) { - return CONFIG_QEMU || ( - CONFIG_QEMU_HARDWARE && GET_GLOBAL(PlatformRunningOn) & PF_QEMU); + return GET_GLOBAL(PlatformRunningOn) & PF_QEMU; } static inline int runningOnXen(void) { - return CONFIG_XEN && GET_GLOBAL(PlatformRunningOn) & PF_XEN; + return GET_GLOBAL(PlatformRunningOn) & PF_XEN; } static inline int runningOnKVM(void) { - return CONFIG_QEMU && GET_GLOBAL(PlatformRunningOn) & PF_KVM; + return GET_GLOBAL(PlatformRunningOn) & PF_KVM; }
void qemu_kvm_preinit(void); diff --git a/src/paravirt.c b/src/paravirt.c index 0e6bc92..ce79666 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -28,7 +28,7 @@ struct e820_reservation { void qemu_ramsize_preinit(void) { - if (!CONFIG_QEMU) + if (!CONFIG_QEMU_HARDWARE) return;
qemu_kvm_preinit(); diff --git a/src/util.c b/src/util.c index 8ba4eb0..2b66f2e 100644 --- a/src/util.c +++ b/src/util.c @@ -21,7 +21,7 @@ void qemu_kvm_preinit(void) unsigned int eax, ebx, ecx, edx; char signature[13];
- if (!CONFIG_QEMU) + if (!CONFIG_QEMU_HARDWARE) return;
SET_FARVAR(get_global_seg(), PlatformRunningOn, PF_QEMU); diff --git a/src/Kconfig b/src/Kconfig index db2ecc8..e5e1cec 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -17,7 +17,8 @@ choice bool "Build for QEMU/KVM/Bochs" select QEMU_HARDWARE help - Configure for an emulated machine (QEMU, KVM, or Bochs). + Configure for an emulated machine (QEMU, KVM, or Bochs), and assume + the VM will start SeaBIOS directly.
config CSM bool "Build as Compatibilty Support Module for EFI BIOS" @@ -27,17 +28,17 @@ choice
config XEN bool "Build for Xen HVM" + select QEMU_HARDWARE help Configure to be used by xen hvmloader, for a HVM guest.
endchoice
config QEMU_HARDWARE - bool "Support hardware found on emulators (QEMU/Xen/KVM/Bochs)" if !QEMU + bool "Assume hardware found on emulators (QEMU/Xen/KVM/Bochs)" if CSM default n help - Support virtual hardware when the code detects it is - running on an emulator. + Assume the presence of virtual hardware / being run on an emulator.
config THREADS bool "Parallelize hardware init"