From patchwork Sun Jul 15 20:25:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Corey Minyard X-Patchwork-Id: 171101 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 7971C2C00DE for ; Mon, 16 Jul 2012 07:05:10 +1000 (EST) Received: from localhost ([::1]:48970 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SqVOs-0003T4-Qw for incoming@patchwork.ozlabs.org; Sun, 15 Jul 2012 16:26:42 -0400 Received: from eggs.gnu.org ([208.118.235.92]:42650) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SqVOH-0002TZ-56 for qemu-devel@nongnu.org; Sun, 15 Jul 2012 16:26:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SqVOG-00087m-0Y for qemu-devel@nongnu.org; Sun, 15 Jul 2012 16:26:05 -0400 Received: from vms173017pub.verizon.net ([206.46.173.17]:30757) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SqVOF-00087i-RE for qemu-devel@nongnu.org; Sun, 15 Jul 2012 16:26:03 -0400 Received: from wf-rch.minyard.home ([unknown] [173.57.151.210]) by vms173017.mailsrvcs.net (Sun Java(tm) System Messaging Server 7u2-7.02 32bit (built Apr 16 2009)) with ESMTPA id <0M77002BIY28C400@vms173017.mailsrvcs.net> for qemu-devel@nongnu.org; Sun, 15 Jul 2012 15:25:32 -0500 (CDT) Received: from i.minyard.home (i2.minyard.home [192.168.27.116]) by wf-rch.minyard.home (Postfix) with ESMTP id B45ED1F955; Sun, 15 Jul 2012 15:25:13 -0500 (CDT) Received: by i.minyard.home (Postfix, from userid 1000) id 9114581812; Sun, 15 Jul 2012 15:25:12 -0500 (CDT) From: minyard@acm.org To: qemu-devel@nongnu.org Date: Sun, 15 Jul 2012 15:25:04 -0500 Message-id: <1342383911-6094-9-git-send-email-minyard@acm.org> X-Mailer: git-send-email 1.7.4.1 In-reply-to: <1342383911-6094-1-git-send-email-minyard@acm.org> References: <1342383911-6094-1-git-send-email-minyard@acm.org> X-detected-operating-system: by eggs.gnu.org: Solaris 10 (1203?) X-Received-From: 206.46.173.17 Cc: Corey Minyard Subject: [Qemu-devel] [PATCH 09/16] qdev: Add a pre-firmware init capability X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Corey Minyard Some devices may need to do some firmware-type initialization before the firmware itself is initialized. For instance, any device that adds SMBIOS table entries (like IPMI) will need to do that before the BIOS is initialized. So add a list of devices that get initialized before the firmware initialization. Since those devices get removed from the list so they don't get initialized twice, convert the qemu_opt_foreach() to use the safe list traversal. Signed-off-by: Corey Minyard --- hw/pc.c | 2 ++ hw/qdev-monitor.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ hw/qdev.h | 3 +++ qemu-option.c | 4 ++-- 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index bc753c0..a0e8824 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1010,6 +1010,8 @@ void *pc_bios_init(const char *kernel_filename, void *fw_cfg; int linux_boot, i; + qdev_prefw_init_check(); + /* Initialize PC system firmware */ pc_system_firmware_init(rom_memory); diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index 7915b45..a874f1b 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -486,6 +486,56 @@ DeviceState *qdev_device_add(QemuOpts *opts) return qdev; } +/* + * Some devices may need to be initialized before the firmware is + * initialized, so they may add information to the firmware + * structures. + */ +typedef struct prefw_list +{ + const char *name; + struct prefw_list *next; +} prefw_list; + +prefw_list *prefw_init; + +void qdev_add_prefw_init(const char *name) +{ + prefw_list *e = g_malloc(sizeof(*e)); + e->name = name; + e->next = prefw_init; + prefw_init = e; +} + +static int prefw_check_func(QemuOpts *opts, void *opaque) +{ + DeviceState *dev; + const char *driver; + prefw_list *e; + + driver = qemu_opt_get(opts, "driver"); + if (!driver) + return 0; + + for (e = prefw_init; e; e = e->next) { + if (strcmp(driver, e->name) == 0) { + dev = qdev_device_add(opts); + if (!dev) + return -1; + qemu_opts_del(opts); + break; + } + } + return 0; +} + +void qdev_prefw_init_check(void) +{ + /* init generic devices */ + if (qemu_opts_foreach(qemu_find_opts("device"), + prefw_check_func, NULL, 1) != 0) + exit(1); +} #define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__) static void qbus_print(Monitor *mon, BusState *bus, int indent); diff --git a/hw/qdev.h b/hw/qdev.h index f4683dc..2be4c95 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -167,6 +167,9 @@ int qdev_simple_unplug_cb(DeviceState *dev); void qdev_machine_creation_done(void); bool qdev_machine_modified(void); +void qdev_add_prefw_init(const char *name); +void qdev_prefw_init_check(void); + qemu_irq qdev_get_gpio_in(DeviceState *dev, int n); void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); diff --git a/qemu-option.c b/qemu-option.c index bb3886c..1d000f8 100644 --- a/qemu-option.c +++ b/qemu-option.c @@ -709,10 +709,10 @@ int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val) int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque, int abort_on_failure) { - QemuOpt *opt; + QemuOpt *opt, *next_opt; int rc = 0; - QTAILQ_FOREACH(opt, &opts->head, next) { + QTAILQ_FOREACH_SAFE(opt, &opts->head, next, next_opt) { rc = func(opt->name, opt->str, opaque); if (abort_on_failure && rc != 0) break;