From patchwork Fri Aug 21 08:31:34 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 31811 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 bilbo.ozlabs.org (Postfix) with ESMTPS id F270DB7BB7 for ; Fri, 21 Aug 2009 18:35:30 +1000 (EST) Received: from localhost ([127.0.0.1]:45332 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MePan-0007OH-5n for incoming@patchwork.ozlabs.org; Fri, 21 Aug 2009 04:35:25 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MePXE-0006bl-00 for qemu-devel@nongnu.org; Fri, 21 Aug 2009 04:31:44 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MePX9-0006aU-Kt for qemu-devel@nongnu.org; Fri, 21 Aug 2009 04:31:43 -0400 Received: from [199.232.76.173] (port=38064 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MePX9-0006aR-FS for qemu-devel@nongnu.org; Fri, 21 Aug 2009 04:31:39 -0400 Received: from oxygen.pond.sub.org ([213.239.205.148]:38611) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MePX8-0007Iu-Ea for qemu-devel@nongnu.org; Fri, 21 Aug 2009 04:31:39 -0400 Received: from pike.pond.sub.org (pD9E39621.dip.t-dialin.net [217.227.150.33]) by oxygen.pond.sub.org (Postfix) with ESMTPA id 28246276D2B for ; Fri, 21 Aug 2009 10:31:35 +0200 (CEST) Received: by pike.pond.sub.org (Postfix, from userid 1000) id AF43010092; Fri, 21 Aug 2009 10:31:34 +0200 (CEST) From: Markus Armbruster To: qemu-devel@nongnu.org Date: Fri, 21 Aug 2009 10:31:34 +0200 Message-Id: <1250843494-28326-4-git-send-email-armbru@redhat.com> X-Mailer: git-send-email 1.6.0.6 In-Reply-To: <1250843494-28326-1-git-send-email-armbru@redhat.com> References: <1250843494-28326-1-git-send-email-armbru@redhat.com> X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Subject: [Qemu-devel] [PATCH 3/3] qdev: convert watchdogs 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 -watchdog NAME is now equivalent to -device NAME, except it treats option argument '?' specially, and supports only one watchdog. A side effect is that a device created with -watchdog may now receive a different PCI address. i6300esb is now available on any machine with a PCI bus, not just PCs. ib700 is still PC only, but that could be changed easily. The only remaining use of struct WatchdogTimerModel and watchdog_add_model() is supporting '-watchdog ?'. Should be replaced by searching device_info_list for watchdog devices when we can identify them there. Also fixes ib700 not to use vm_clock before it is initialized: in wdt_ib700_init(), called from register_watchdogs(), which runs before init_timers(). The bug made ib700_write_enable_reg() crash in qemu_del_timer(). Signed-off-by: Markus Armbruster --- Makefile.target | 6 +++--- hw/pc.c | 2 -- hw/watchdog.c | 26 ++++++-------------------- hw/watchdog.h | 11 ----------- hw/wdt_i6300esb.c | 29 ++++++++++++++--------------- hw/wdt_ib700.c | 18 ++++++++++++------ vl.c | 18 +++++++++++++----- 7 files changed, 48 insertions(+), 62 deletions(-) diff --git a/Makefile.target b/Makefile.target index 066af8d..a3492b9 100644 --- a/Makefile.target +++ b/Makefile.target @@ -184,15 +184,15 @@ obj-y += pcnet.o obj-y += rtl8139.o obj-y += e1000.o -# Generic watchdog support and some watchdog devices -obj-y += wdt_ib700.o wdt_i6300esb.o +# PCI watchdog devices +obj-y += wdt_i6300esb.o # Hardware support obj-i386-y = ide.o pckbd.o vga.o $(sound-obj-y) dma.o isa-bus.o obj-i386-y += fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o obj-i386-y += cirrus_vga.o apic.o ioapic.o parallel.o acpi.o piix_pci.o obj-i386-y += usb-uhci.o vmmouse.o vmport.o vmware_vga.o hpet.o -obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o +obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o # shared objects obj-ppc-y = ppc.o ide.o vga.o $(sound-obj-y) dma.o isa-bus.o openpic.o diff --git a/hw/pc.c b/hw/pc.c index cc6e7e8..167ff0e 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1331,8 +1331,6 @@ static void pc_init1(ram_addr_t ram_size, } } - watchdog_pc_init(pci_bus); - for(i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; diff --git a/hw/watchdog.c b/hw/watchdog.c index 359c318..adba872 100644 --- a/hw/watchdog.c +++ b/hw/watchdog.c @@ -20,6 +20,8 @@ */ #include "qemu-common.h" +#include "qemu-option.h" +#include "qemu-config.h" #include "sys-queue.h" #include "sysemu.h" #include "hw/watchdog.h" @@ -32,7 +34,6 @@ #define WDT_DEBUG 5 /* Prints a message and continues running. */ #define WDT_NONE 6 /* Do nothing. */ -static WatchdogTimerModel *watchdog; static int watchdog_action = WDT_RESET; static LIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list; @@ -49,12 +50,7 @@ void watchdog_add_model(WatchdogTimerModel *model) int select_watchdog(const char *p) { WatchdogTimerModel *model; - - if (watchdog) { - fprintf(stderr, - "qemu: only one watchdog option may be given\n"); - return 1; - } + QemuOpts *opts; /* -watchdog ? lists available devices and exits cleanly. */ if (strcmp(p, "?") == 0) { @@ -67,7 +63,9 @@ int select_watchdog(const char *p) LIST_FOREACH(model, &watchdog_list, entry) { if (strcasecmp(model->wdt_name, p) == 0) { - watchdog = model; + /* add the device */ + opts = qemu_opts_create(&qemu_device_opts, NULL, 0); + qemu_opt_set(opts, "driver", p); return 0; } } @@ -130,15 +128,3 @@ void watchdog_perform_action(void) break; } } - -void watchdog_pc_init(PCIBus *pci_bus) -{ - if (watchdog) - watchdog->wdt_pc_init(pci_bus); -} - -void register_watchdogs(void) -{ - wdt_ib700_init(); - wdt_i6300esb_init(); -} diff --git a/hw/watchdog.h b/hw/watchdog.h index bb81204..8c54fa4 100644 --- a/hw/watchdog.h +++ b/hw/watchdog.h @@ -22,10 +22,6 @@ #ifndef QEMU_WATCHDOG_H #define QEMU_WATCHDOG_H -extern void wdt_i6300esb_init(void); -extern void wdt_ib700_init(void); - - struct WatchdogTimerModel { LIST_ENTRY(WatchdogTimerModel) entry; @@ -33,11 +29,6 @@ struct WatchdogTimerModel { const char *wdt_name; /* Longer description (eg. manufacturer and full model number). */ const char *wdt_description; - - /* This callback should create/register the device. It is called - * indirectly from hw/pc.c when the virtual PC is being set up. - */ - void (*wdt_pc_init)(PCIBus *pci_bus); }; typedef struct WatchdogTimerModel WatchdogTimerModel; @@ -46,7 +37,5 @@ extern int select_watchdog(const char *p); extern int select_watchdog_action(const char *action); extern void watchdog_add_model(WatchdogTimerModel *model); extern void watchdog_perform_action(void); -extern void watchdog_pc_init(PCIBus *pci_bus); -extern void register_watchdogs(void); #endif /* QEMU_WATCHDOG_H */ diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c index 2227303..2318738 100644 --- a/hw/wdt_i6300esb.c +++ b/hw/wdt_i6300esb.c @@ -413,22 +413,11 @@ static int i6300esb_load(QEMUFile *f, void *vp, int version) return 0; } -/* Create and initialize a virtual Intel 6300ESB during PC creation. */ -static void i6300esb_pc_init(PCIBus *pci_bus) +static void i6300esb_init(PCIDevice *dev) { - I6300State *d; + I6300State *d = container_of(dev, I6300State, dev); uint8_t *pci_conf; - if (!pci_bus) { - fprintf(stderr, "wdt_i6300esb: no PCI bus in this machine\n"); - return; - } - - d = (I6300State *) - pci_register_device (pci_bus, "i6300esb_wdt", sizeof (I6300State), - -1, - i6300esb_config_read, i6300esb_config_write); - d->reboot_enabled = 1; d->clock_scale = CLOCK_SCALE_1KHZ; d->int_type = INT_TYPE_IRQ; @@ -458,10 +447,20 @@ static void i6300esb_pc_init(PCIBus *pci_bus) static WatchdogTimerModel model = { .wdt_name = "i6300esb", .wdt_description = "Intel 6300ESB", - .wdt_pc_init = i6300esb_pc_init, }; -void wdt_i6300esb_init(void) +static PCIDeviceInfo i6300esb_info = { + .qdev.name = "i6300esb", + .qdev.size = sizeof(I6300State), + .config_read = i6300esb_config_read, + .config_write = i6300esb_config_write, + .init = i6300esb_init, +}; + +static void i6300esb_register_devices(void) { watchdog_add_model(&model); + pci_qdev_register(&i6300esb_info); } + +device_init(i6300esb_register_devices); diff --git a/hw/wdt_ib700.c b/hw/wdt_ib700.c index 7b54bde..5fc3d83 100644 --- a/hw/wdt_ib700.c +++ b/hw/wdt_ib700.c @@ -88,11 +88,10 @@ static int ib700_load(QEMUFile *f, void *vp, int version) return 0; } -/* Create and initialize a virtual IB700 during PC creation. */ -static void ib700_pc_init(PCIBus *unused) +static void wdt_ib700_init(ISADevice *dev) { + timer = qemu_new_timer(vm_clock, ib700_timer_expired, NULL); register_savevm("ib700_wdt", -1, 0, ib700_save, ib700_load, NULL); - register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, NULL); register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, NULL); } @@ -100,11 +99,18 @@ static void ib700_pc_init(PCIBus *unused) static WatchdogTimerModel model = { .wdt_name = "ib700", .wdt_description = "iBASE 700", - .wdt_pc_init = ib700_pc_init, }; -void wdt_ib700_init(void) +static ISADeviceInfo wdt_ib700_info = { + .qdev.name = "ib700", + .qdev.size = sizeof(ISADevice), + .init = wdt_ib700_init, +}; + +static void wdt_ib700_register_devices(void) { watchdog_add_model(&model); - timer = qemu_new_timer(vm_clock, ib700_timer_expired, NULL); + isa_qdev_register(&wdt_ib700_info); } + +device_init(wdt_ib700_register_devices); diff --git a/vl.c b/vl.c index 9b73ea3..1e2e0e6 100644 --- a/vl.c +++ b/vl.c @@ -233,6 +233,7 @@ int graphic_rotate = 0; #ifndef _WIN32 int daemonize = 0; #endif +const char *watchdog; const char *option_rom[MAX_OPTION_ROMS]; int nb_option_roms; int semihosting_enabled = 0; @@ -4884,8 +4885,6 @@ int main(int argc, char **argv, char **envp) tb_size = 0; autostart= 1; - register_watchdogs(); - optind = 1; for(;;) { if (optind >= argc) @@ -5301,9 +5300,12 @@ int main(int argc, char **argv, char **envp) serial_device_index++; break; case QEMU_OPTION_watchdog: - i = select_watchdog(optarg); - if (i > 0) - exit (i == 1 ? 1 : 0); + if (watchdog) { + fprintf(stderr, + "qemu: only one watchdog option may be given\n"); + return 1; + } + watchdog = optarg; break; case QEMU_OPTION_watchdog_action: if (select_watchdog_action(optarg) == -1) { @@ -5911,6 +5913,12 @@ int main(int argc, char **argv, char **envp) module_call_init(MODULE_INIT_DEVICE); + if (watchdog) { + i = select_watchdog(watchdog); + if (i > 0) + exit (i == 1 ? 1 : 0); + } + if (machine->compat_props) { qdev_prop_register_compat(machine->compat_props); }