From patchwork Fri Dec 18 11:16:04 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 41395 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 D2F62B6F07 for ; Fri, 18 Dec 2009 22:49:42 +1100 (EST) Received: from localhost ([127.0.0.1]:60185 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NLbL1-0004ko-W2 for incoming@patchwork.ozlabs.org; Fri, 18 Dec 2009 06:49:40 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NLaoj-0005je-QK for qemu-devel@nongnu.org; Fri, 18 Dec 2009 06:16:17 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NLaoe-0005dI-AC for qemu-devel@nongnu.org; Fri, 18 Dec 2009 06:16:16 -0500 Received: from [199.232.76.173] (port=51220 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NLaod-0005ch-CX for qemu-devel@nongnu.org; Fri, 18 Dec 2009 06:16:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:11324) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NLaoc-0005PQ-RQ for qemu-devel@nongnu.org; Fri, 18 Dec 2009 06:16:11 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id nBIBG9kT007779 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 18 Dec 2009 06:16:09 -0500 Received: from zweiblum.home.kraxel.org (vpn1-6-184.ams2.redhat.com [10.36.6.184]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id nBIBG78w020887; Fri, 18 Dec 2009 06:16:07 -0500 Received: by zweiblum.home.kraxel.org (Postfix, from userid 500) id 9C95870FCE; Fri, 18 Dec 2009 12:16:04 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org, seabios@seabios.org Date: Fri, 18 Dec 2009 12:16:04 +0100 Message-Id: <1261134964-12427-5-git-send-email-kraxel@redhat.com> In-Reply-To: <1261134964-12427-1-git-send-email-kraxel@redhat.com> References: <1261134964-12427-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH 4/4] qemu: add rom loading via fw_cfg 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 Add support for loading roms using the qemu fw_cfg interface, modeled after the existing cbfs support. Use it to look for vgabios (vgaroms/*) and option roms (genroms/*). Signed-off-by: Gerd Hoffmann --- src/optionroms.c | 22 ++++++++++++++++++++++ src/paravirt.c | 37 +++++++++++++++++++++++++++++++++++++ src/paravirt.h | 11 +++++++++++ 3 files changed, 70 insertions(+), 0 deletions(-) diff --git a/src/optionroms.c b/src/optionroms.c index 27465ad..c5de1ad 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -247,6 +247,26 @@ run_cbfs_roms(const char *prefix, int isvga) } } +static void +run_qemu_roms(const char *prefix, int isvga) +{ + struct QemuCfgFile entry; + int plen = strlen(prefix); + int rc, dlen; + + rc = qemu_cfg_first_file(&entry); + while (rc > 0) { + if (memcmp(prefix, entry.name, plen) == 0) { + dlen = qemu_cfg_read_file(&entry, (void*)RomEnd, max_rom() - RomEnd); + if (dlen > 0) { + dprintf(1, "init qemu rom: %s\n", entry.name); + init_optionrom((void*)RomEnd, 0, isvga); + } + } + rc = qemu_cfg_next_file(&entry); + } +} + /**************************************************************** * PCI roms @@ -375,6 +395,7 @@ optionrom_setup() // Find and deploy CBFS roms not associated with a device. run_cbfs_roms("genroms/", 0); + run_qemu_roms("genroms/", 0); } // All option roms found and deployed - now build BEV/BCV vectors. @@ -434,6 +455,7 @@ vga_setup() // Find and deploy CBFS vga-style roms not associated with a device. run_cbfs_roms("vgaroms/", 1); + run_qemu_roms("vgaroms/", 1); } if (RomEnd == BUILD_ROM_START) { diff --git a/src/paravirt.c b/src/paravirt.c index 6f48d2e..7171bac 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -8,6 +8,7 @@ // This file may be distributed under the terms of the GNU LGPLv3 license. #include "config.h" // CONFIG_COREBOOT +#include "util.h" // ntoh[ls] #include "ioport.h" // outw #include "paravirt.h" // qemu_cfg_port_probe #include "smbios.h" // struct smbios_structure_header @@ -287,3 +288,39 @@ u16 qemu_cfg_get_max_cpus(void) return cnt; } + +u16 qemu_cfg_first_file(QemuCfgFile *entry) +{ + memset(entry, 0, sizeof(*entry)); + return qemu_cfg_next_file(entry); +} + +u16 qemu_cfg_next_file(QemuCfgFile *entry) +{ + u16 last = ntohs(entry->select); + u32 e,count; + + if (!qemu_cfg_present) + return 0; + + qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count)); + for (e = 0; e < ntohl(count); e++) { + qemu_cfg_read((void*)entry, sizeof(*entry)); + if (ntohs(entry->select) > last) { + return 1; + } + } + return 0; +} + +u32 qemu_cfg_read_file(QemuCfgFile *entry, void *dst, u32 maxlen) +{ + int len = ntohl(entry->size); + + if (!qemu_cfg_present) + return 0; + if (len > maxlen) + return 0; + qemu_cfg_read_entry(dst, ntohs(entry->select), len); + return len; +} diff --git a/src/paravirt.h b/src/paravirt.h index 29a2c04..d33e10d 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -31,6 +31,7 @@ static inline int kvm_para_available(void) #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) @@ -53,4 +54,14 @@ int qemu_cfg_get_numa_nodes(void); void qemu_cfg_get_numa_data(u64 *data, int n); u16 qemu_cfg_get_max_cpus(void); +typedef struct QemuCfgFile { + u32 size; /* file size */ + u16 select; /* write this to 0x510 to read it */ + u16 reserved; + char name[56]; +} QemuCfgFile; + +u16 qemu_cfg_first_file(QemuCfgFile *entry); +u16 qemu_cfg_next_file(QemuCfgFile *entry); + #endif