miny...@acm.org writes: > From: Corey Minyard <cminy...@mvista.com> > > 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 <cminy...@mvista.com>
This should go away if you move the SMBIOS changes to BIOS. Regards, Anthony Liguori > --- > hw/pc.c | 2 ++ > hw/qdev-monitor.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > hw/qdev.h | 3 +++ > qemu-option.c | 4 ++-- > 4 files changed, 59 insertions(+), 2 deletions(-) > > diff --git a/hw/pc.c b/hw/pc.c > index bedd5be..811d99c 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..bb8e955 100644 > --- a/hw/qdev-monitor.c > +++ b/hw/qdev-monitor.c > @@ -486,6 +486,58 @@ 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; > -- > 1.7.4.1