qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [PATCH][SEABIOS] Move qemu config port access functions


From: Gleb Natapov
Subject: [Qemu-devel] Re: [PATCH][SEABIOS] Move qemu config port access functions into separate file.
Date: Thu, 1 Oct 2009 18:35:55 +0200

> As an aside, it would be good to have a conversation on general BIOS
> configuration options.  These types of settings are going to be useful
> on real hardware also - it would be nice to come up with a scheme that
> would work on qemu and coreboot.  Maybe something like
> get_config_u32("ShowBootMenu") - where on qemu it would get the info
> from the qemu port but on coreboot it would pull the setting from the
> coreboot flash filesystem.
> 
I started to implement this approach, but found a serious disadvantage:
What if config option is not known to qemu or coreboot? What is it
present only in qemu and meaningful default behaviour is required
for coreboot? Like ShowBootMenu for instance. We want to return qemu
setting or coreboot setting or 1 if neither is present. This kind
of logic does not belong to general function like get_config_u32().
So how about another approach: qemu and core boot provide functions like
void cfg_get_uuid(u8 *uuid);
int cfg_show_boot_menu(void);
...
with all necessary fall-back logic and we use coreboot or qemu file during
build time depending what our target is. Something like attached patch.

diff --git a/Makefile b/Makefile
index c4016e8..8d5c913 100644
--- a/Makefile
+++ b/Makefile
@@ -10,11 +10,20 @@ VERSION=pre-0.4.3-$(shell date +"%Y%m%d_%H%M%S")-$(shell 
hostname)
 # Output directory
 OUT=out/
 
+# Configure as a coreboot payload.
+COREBOOT=y
+
+ifdef COREBOOT
+CFGSRC=cbcfg.c
+else
+CFGSRC=pv.c
+endif
+
 # Source files
 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 $(CFGSRC)
 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 \
diff --git a/src/boot.c b/src/boot.c
index 7b74007..71d6e27 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -12,6 +12,7 @@
 #include "bregs.h" // struct bregs
 #include "boot.h" // struct ipl_s
 #include "cmos.h" // inb_cmos
+#include "cfg.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 || ! cfg_show_boot_menu())
         return;
 
     while (get_keystroke(0) >= 0)
diff --git a/src/cbcfg.c b/src/cbcfg.c
new file mode 100644
index 0000000..56b6076
--- /dev/null
+++ b/src/cbcfg.c
@@ -0,0 +1,13 @@
+#include "config.h"
+#include "util.h"
+#include "cfg.h"
+
+void cfg_get_uuid(u8 *uuid)
+{
+    memset(uuid, 0, 16);
+}
+
+int cfg_show_boot_menu(void)
+{
+    return 1;
+}
diff --git a/src/cfg.h b/src/cfg.h
new file mode 100644
index 0000000..1f6b488
--- /dev/null
+++ b/src/cfg.h
@@ -0,0 +1,6 @@
+#ifndef __CFG_H
+#define __CFG_H
+
+void cfg_get_uuid(u8 *uuid);
+int cfg_show_boot_menu(void);
+#endif
diff --git a/src/post.c b/src/post.c
index f72e134..e8ae3f0 100644
--- a/src/post.c
+++ b/src/post.c
@@ -20,6 +20,7 @@
 #include "mptable.h" // mptable_init
 #include "boot.h" // IPL
 #include "usb.h" // usb_setup
+#include "pv.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();
diff --git a/src/pv.c b/src/pv.c
new file mode 100644
index 0000000..fa57b5b
--- /dev/null
+++ b/src/pv.c
@@ -0,0 +1,67 @@
+#include "config.h"
+#include "ioport.h"
+#include "pv.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 cfg_get_uuid(u8 *uuid)
+{
+    memset(uuid, 0, 16);
+
+    if (!qemu_cfg_present || !CONFIG_UUID_BACKDOOR)
+        return;
+
+    qemu_cfg_read_entry(uuid, QEMU_CFG_UUID, 16);
+}
+
+int 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;
+}
+
diff --git a/src/pv.h b/src/pv.h
new file mode 100644
index 0000000..632a29c
--- /dev/null
+++ b/src/pv.h
@@ -0,0 +1,42 @@
+#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);
+
+#endif
diff --git a/src/smbios.c b/src/smbios.c
index 6fbddd9..4caab19 100644
--- a/src/smbios.c
+++ b/src/smbios.c
@@ -7,50 +7,7 @@
 
 #include "util.h" // dprintf
 #include "biosvar.h" // GET_EBDA
-
-
-/****************************************************************
- * 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)
-{
-    // Default to UUID not set
-    memset(bios_uuid, 0, 16);
-
-    if (! CONFIG_UUID_BACKDOOR)
-        return;
-    if (CONFIG_COREBOOT)
-        return;
-    if (! qemu_cfg_port_probe())
-        // Feature not available
-        return;
-
-    qemu_cfg_read(bios_uuid, QEMU_CFG_UUID, 16);
-}
-
+#include "cfg.h"
 
 /****************************************************************
  * smbios tables
@@ -304,7 +261,7 @@ smbios_type_1_init(void *start)
     p->version_str = 0;
     p->serial_number_str = 0;
 
-    uuid_probe(p->uuid);
+    cfg_get_uuid(p->uuid);
 
     p->wake_up_type = 0x06; /* power switch */
     p->sku_number_str = 0;
--
                        Gleb.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]