From patchwork Thu Oct 1 16:35:55 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gleb Natapov X-Patchwork-Id: 34753 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 5A7ACB7BD3 for ; Fri, 2 Oct 2009 03:23:57 +1000 (EST) Received: from localhost ([127.0.0.1]:48842 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MtPNi-0003sF-6t for incoming@patchwork.ozlabs.org; Thu, 01 Oct 2009 13:23:54 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MtOdY-0007MS-Qd for qemu-devel@nongnu.org; Thu, 01 Oct 2009 12:36:12 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MtOdU-0007G4-T2 for qemu-devel@nongnu.org; Thu, 01 Oct 2009 12:36:12 -0400 Received: from [199.232.76.173] (port=45501 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MtOdU-0007Fn-Dl for qemu-devel@nongnu.org; Thu, 01 Oct 2009 12:36:08 -0400 Received: from mx20.gnu.org ([199.232.41.8]:59422) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MtOdT-0002IJ-80 for qemu-devel@nongnu.org; Thu, 01 Oct 2009 12:36:07 -0400 Received: from mx1.redhat.com ([209.132.183.28]) by mx20.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MtOdR-0007Qy-Em for qemu-devel@nongnu.org; Thu, 01 Oct 2009 12:36:05 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n91GZvOa025767; Thu, 1 Oct 2009 12:35:57 -0400 Received: from dhcp-1-237.tlv.redhat.com (dhcp-1-237.tlv.redhat.com [10.35.1.237]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n91GZtXp001160; Thu, 1 Oct 2009 12:35:56 -0400 Received: by dhcp-1-237.tlv.redhat.com (Postfix, from userid 13519) id 4C54818D410; Thu, 1 Oct 2009 18:35:55 +0200 (IST) Date: Thu, 1 Oct 2009 18:35:55 +0200 From: Gleb Natapov To: "Kevin O'Connor" Message-ID: <20091001163555.GV9832@redhat.com> References: <20090914125141.GB30746@redhat.com> <20090915000824.GA16210@morn.localdomain> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20090915000824.GA16210@morn.localdomain> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by mx20.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Cc: qemu-devel@nongnu.org Subject: [Qemu-devel] Re: [PATCH][SEABIOS] Move qemu config port access functions into separate file. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org > 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. --- Gleb. 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;