@@ -14,7 +14,7 @@ OUT=out/
SRCBOTH=output.c util.c block.c floppy.c ata.c misc.c mouse.c kbd.c pci.c \
serial.c clock.c pic.c cdrom.c ps2port.c smp.c resume.c \
pnpbios.c pirtable.c vgahooks.c pmm.c ramdisk.c \
- usb.c usb-uhci.c usb-hid.c
+ usb.c usb-uhci.c usb-hid.c paravirt.c
SRC16=$(SRCBOTH) system.c disk.c apm.c pcibios.c font.c
SRC32=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
@@ -12,6 +12,7 @@
#include "bregs.h" // struct bregs
#include "boot.h" // struct ipl_s
#include "cmos.h" // inb_cmos
+#include "paravirt.h"
struct ipl_s IPL;
@@ -206,7 +207,7 @@ menu_show_cbfs(struct ipl_entry_s *ie, int menupos)
static void
interactive_bootmenu()
{
- if (! CONFIG_BOOTMENU)
+ if (! CONFIG_BOOTMENU || ! qemu_cfg_show_boot_menu())
return;
while (get_keystroke(0) >= 0)
new file mode 100644
@@ -0,0 +1,74 @@
+// Paravirtualization support.
+//
+// Copyright (C) 2009 Red Hat Inc.
+//
+// Authors:
+// Gleb Natapov <gnatapov@redhat.com>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "config.h"
+#include "ioport.h"
+#include "paravirt.h"
+
+int qemu_cfg_present;
+
+static void
+qemu_cfg_select(u16 f)
+{
+ outw(f, PORT_QEMU_CFG_CTL);
+}
+
+static void
+qemu_cfg_read(u8 *buf, int len)
+{
+ while (len--)
+ *(buf++) = inb(PORT_QEMU_CFG_DATA);
+}
+
+static void
+qemu_cfg_read_entry(void *buf, int e, int len)
+{
+ qemu_cfg_select(e);
+ qemu_cfg_read(buf, len);
+}
+
+void qemu_cfg_port_probe(void)
+{
+ char *sig = "QEMU";
+ int i;
+
+ if (CONFIG_COREBOOT)
+ return;
+
+ qemu_cfg_present = 1;
+
+ qemu_cfg_select(QEMU_CFG_SIGNATURE);
+
+ for (i = 0; i < 4; i++)
+ if (inb(PORT_QEMU_CFG_DATA) != sig[i]) {
+ qemu_cfg_present = 0;
+ break;
+ }
+ dprintf(4, "qemu_cfg_present=%d\n", qemu_cfg_present);
+}
+
+void qemu_cfg_get_uuid(u8 *uuid)
+{
+ if (!qemu_cfg_present)
+ return;
+
+ qemu_cfg_read_entry(uuid, QEMU_CFG_UUID, 16);
+}
+
+int qemu_cfg_show_boot_menu(void)
+{
+ u16 v;
+ if (!qemu_cfg_present)
+ return 1;
+
+ qemu_cfg_read_entry(&v, QEMU_CFG_BOOT_MENU, sizeof(v));
+
+ return v;
+}
+
new file mode 100644
@@ -0,0 +1,44 @@
+#ifndef __PV_H
+#define __PV_H
+
+#include "util.h"
+
+/* 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)
+{
+ 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;
+}
+
+#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_ARCH_LOCAL 0x8000
+#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
+#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
+
+extern int qemu_cfg_present;
+
+void qemu_cfg_port_probe(void);
+int qemu_cfg_show_boot_menu(void);
+void qemu_cfg_get_uuid(u8 *uuid);
+
+#endif
@@ -20,6 +20,7 @@
#include "mptable.h" // mptable_init
#include "boot.h" // IPL
#include "usb.h" // usb_setup
+#include "paravirt.h"
void
__set_irq(int vector, void *loc)
@@ -184,6 +185,8 @@ post()
serial_setup();
mouse_setup();
+ qemu_cfg_port_probe();
+
init_bios_tables();
boot_setup();
@@ -7,33 +7,12 @@
#include "util.h" // dprintf
#include "biosvar.h" // GET_EBDA
-
+#include "paravirt.h"
/****************************************************************
* UUID probe
****************************************************************/
-#define QEMU_CFG_SIGNATURE 0x00
-#define QEMU_CFG_ID 0x01
-#define QEMU_CFG_UUID 0x02
-
-static void
-qemu_cfg_read(u8 *buf, u16 f, int len)
-{
- outw(f, PORT_QEMU_CFG_CTL);
- while (len--)
- *(buf++) = inb(PORT_QEMU_CFG_DATA);
-}
-
-static int
-qemu_cfg_port_probe()
-{
- u8 sig[4] = "QEMU";
- u8 buf[4];
- qemu_cfg_read(buf, QEMU_CFG_SIGNATURE, 4);
- return *(u32*)buf == *(u32*)sig;
-}
-
static void
uuid_probe(u8 *bios_uuid)
{
@@ -44,11 +23,8 @@ uuid_probe(u8 *bios_uuid)
return;
if (CONFIG_COREBOOT)
return;
- if (! qemu_cfg_port_probe())
- // Feature not available
- return;
- qemu_cfg_read(bios_uuid, QEMU_CFG_UUID, 16);
+ qemu_cfg_get_uuid(bios_uuid);
}
Move qemu config code from smbios.c to its own files. Add support for -boot menu=on|off qemu option. Signed-off-by: Gleb Natapov <gleb@redhat.com> --- v1->v2: - move qemu_cfg_show_boot_menu() into interactive_bootmenu() - don't check for qemu config port if coreboot enabled to prevent problems on real HW. v2->v3 - rename pv.[ch] to paravirt.[ch] -- Gleb.