aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Armbruster <armbru@redhat.com>2009-08-21 10:31:34 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2009-08-27 20:35:24 -0500
commit09aaa1602f9381c0e0fb539390b1793e51bdfc7b (patch)
treeabb82ec81e3f501e46d1104ab8e1af8fdfecd58e
parent9d472d51ea26af6f3006e50a9b5088efcb95e7ce (diff)
qdev: convert watchdogs
-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 <armbru@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--Makefile.target6
-rw-r--r--hw/pc.c2
-rw-r--r--hw/watchdog.c26
-rw-r--r--hw/watchdog.h11
-rw-r--r--hw/wdt_i6300esb.c29
-rw-r--r--hw/wdt_ib700.c18
-rw-r--r--vl.c18
7 files changed, 48 insertions, 62 deletions
diff --git a/Makefile.target b/Makefile.target
index 7c5f87753..31dbdd4ad 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -179,15 +179,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 9dad10491..59f4fbc72 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1343,8 +1343,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 359c3185e..adba87253 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 bb8120470..8c54fa41f 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 282644e7a..815dacc53 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 7b54bde70..5fc3d83e0 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 e3412dfe0..10d0c5273 100644
--- a/vl.c
+++ b/vl.c
@@ -233,6 +233,7 @@ uint8_t irq0override = 1;
#ifndef _WIN32
int daemonize = 0;
#endif
+const char *watchdog;
const char *option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
int semihosting_enabled = 0;
@@ -4948,8 +4949,6 @@ int main(int argc, char **argv, char **envp)
tb_size = 0;
autostart= 1;
- register_watchdogs();
-
optind = 1;
for(;;) {
if (optind >= argc)
@@ -5361,9 +5360,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) {
@@ -5927,6 +5929,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);
}