From 3ef9622182e598392855931e7a0437d3855cef5e Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Wed, 7 May 2014 17:42:57 +0300 Subject: machine: Conversion of QEMUMachineInitArgs to MachineState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Total removal of QEMUMachineInitArgs struct. QEMUMachineInitArgs's fields are copied into MachineState. Removed duplicated fields from MachineState. All the other changes are only mechanical refactoring, no semantic changes. Signed-off-by: Marcel Apfelbaum Acked-by: Cornelia Huck (s390) Reviewed-by: Michael S. Tsirkin (PC) [AF: Renamed ms -> machine, use MACHINE_GET_CLASS()] Signed-off-by: Andreas Färber --- hw/core/null-machine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/core') diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c index d813c089e7..1ec7c3bbe0 100644 --- a/hw/core/null-machine.c +++ b/hw/core/null-machine.c @@ -15,7 +15,7 @@ #include "hw/hw.h" #include "hw/boards.h" -static void machine_none_init(QEMUMachineInitArgs *args) +static void machine_none_init(MachineState *machine) { } -- cgit 1.4.1 From 6b1b1440199c1a910b91bc9e029974f44746633d Mon Sep 17 00:00:00 2001 From: Marcel Apfelbaum Date: Mon, 26 May 2014 15:40:58 +0300 Subject: machine: Make -machine opts properties of MachineState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make machine's QemuOpts QOM properties of /machine. The properties are automatically filled in. This opens the possibility to create opts per machine rather than global. Signed-off-by: Marcel Apfelbaum Acked-by: Michael S. Tsirkin Acked-by: Michael Roth Signed-off-by: Andreas Färber --- hw/core/machine.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/boards.h | 6 +- vl.c | 11 ++- 3 files changed, 291 insertions(+), 6 deletions(-) (limited to 'hw/core') diff --git a/hw/core/machine.c b/hw/core/machine.c index d3ffef7e07..cbba6791d2 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -11,6 +11,284 @@ */ #include "hw/boards.h" +#include "qapi/visitor.h" + +static char *machine_get_accel(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return g_strdup(ms->accel); +} + +static void machine_set_accel(Object *obj, const char *value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->accel = g_strdup(value); +} + +static bool machine_get_kernel_irqchip(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return ms->kernel_irqchip; +} + +static void machine_set_kernel_irqchip(Object *obj, bool value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->kernel_irqchip = value; +} + +static void machine_get_kvm_shadow_mem(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ + MachineState *ms = MACHINE(obj); + int64_t value = ms->kvm_shadow_mem; + + visit_type_int(v, &value, name, errp); +} + +static void machine_set_kvm_shadow_mem(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ + MachineState *ms = MACHINE(obj); + Error *error = NULL; + int64_t value; + + visit_type_int(v, &value, name, &error); + if (error) { + error_propagate(errp, error); + return; + } + + ms->kvm_shadow_mem = value; +} + +static char *machine_get_kernel(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return g_strdup(ms->kernel_filename); +} + +static void machine_set_kernel(Object *obj, const char *value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->kernel_filename = g_strdup(value); +} + +static char *machine_get_initrd(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return g_strdup(ms->initrd_filename); +} + +static void machine_set_initrd(Object *obj, const char *value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->initrd_filename = g_strdup(value); +} + +static char *machine_get_append(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return g_strdup(ms->kernel_cmdline); +} + +static void machine_set_append(Object *obj, const char *value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->kernel_cmdline = g_strdup(value); +} + +static char *machine_get_dtb(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return g_strdup(ms->dtb); +} + +static void machine_set_dtb(Object *obj, const char *value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->dtb = g_strdup(value); +} + +static char *machine_get_dumpdtb(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return g_strdup(ms->dumpdtb); +} + +static void machine_set_dumpdtb(Object *obj, const char *value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->dumpdtb = g_strdup(value); +} + +static void machine_get_phandle_start(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ + MachineState *ms = MACHINE(obj); + int64_t value = ms->phandle_start; + + visit_type_int(v, &value, name, errp); +} + +static void machine_set_phandle_start(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ + MachineState *ms = MACHINE(obj); + Error *error = NULL; + int64_t value; + + visit_type_int(v, &value, name, &error); + if (error) { + error_propagate(errp, error); + return; + } + + ms->phandle_start = value; +} + +static char *machine_get_dt_compatible(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return g_strdup(ms->dt_compatible); +} + +static void machine_set_dt_compatible(Object *obj, const char *value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->dt_compatible = g_strdup(value); +} + +static bool machine_get_dump_guest_core(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return ms->dump_guest_core; +} + +static void machine_set_dump_guest_core(Object *obj, bool value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->dump_guest_core = value; +} + +static bool machine_get_mem_merge(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return ms->mem_merge; +} + +static void machine_set_mem_merge(Object *obj, bool value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->mem_merge = value; +} + +static bool machine_get_usb(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return ms->usb; +} + +static void machine_set_usb(Object *obj, bool value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->usb = value; +} + +static char *machine_get_firmware(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return g_strdup(ms->firmware); +} + +static void machine_set_firmware(Object *obj, const char *value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->firmware = g_strdup(value); +} + +static void machine_initfn(Object *obj) +{ + object_property_add_str(obj, "accel", + machine_get_accel, machine_set_accel, NULL); + object_property_add_bool(obj, "kernel_irqchip", + machine_get_kernel_irqchip, + machine_set_kernel_irqchip, + NULL); + object_property_add(obj, "kvm_shadow_mem", "int", + machine_get_kvm_shadow_mem, + machine_set_kvm_shadow_mem, + NULL, NULL, NULL); + object_property_add_str(obj, "kernel", + machine_get_kernel, machine_set_kernel, NULL); + object_property_add_str(obj, "initrd", + machine_get_initrd, machine_set_initrd, NULL); + object_property_add_str(obj, "append", + machine_get_append, machine_set_append, NULL); + object_property_add_str(obj, "dtb", + machine_get_dtb, machine_set_dtb, NULL); + object_property_add_str(obj, "dumpdtb", + machine_get_dumpdtb, machine_set_dumpdtb, NULL); + object_property_add(obj, "phandle_start", "int", + machine_get_phandle_start, + machine_set_phandle_start, + NULL, NULL, NULL); + object_property_add_str(obj, "dt_compatible", + machine_get_dt_compatible, + machine_set_dt_compatible, + NULL); + object_property_add_bool(obj, "dump-guest-core", + machine_get_dump_guest_core, + machine_set_dump_guest_core, + NULL); + object_property_add_bool(obj, "mem-merge", + machine_get_mem_merge, machine_set_mem_merge, NULL); + object_property_add_bool(obj, "usb", machine_get_usb, machine_set_usb, NULL); + object_property_add_str(obj, "firmware", + machine_get_firmware, machine_set_firmware, NULL); +} + +static void machine_finalize(Object *obj) +{ + MachineState *ms = MACHINE(obj); + + g_free(ms->accel); + g_free(ms->kernel_filename); + g_free(ms->initrd_filename); + g_free(ms->kernel_cmdline); + g_free(ms->dtb); + g_free(ms->dumpdtb); + g_free(ms->dt_compatible); + g_free(ms->firmware); +} static const TypeInfo machine_info = { .name = TYPE_MACHINE, @@ -18,6 +296,8 @@ static const TypeInfo machine_info = { .abstract = true, .class_size = sizeof(MachineClass), .instance_size = sizeof(MachineState), + .instance_init = machine_initfn, + .instance_finalize = machine_finalize, }; static void machine_register_types(void) diff --git a/include/hw/boards.h b/include/hw/boards.h index b62de4ab7a..2d2e2bef19 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -114,9 +114,9 @@ struct MachineState { ram_addr_t ram_size; const char *boot_order; - const char *kernel_filename; - const char *kernel_cmdline; - const char *initrd_filename; + char *kernel_filename; + char *kernel_cmdline; + char *initrd_filename; const char *cpu_model; }; diff --git a/vl.c b/vl.c index 8a4e58ce5c..0c15608bcb 100644 --- a/vl.c +++ b/vl.c @@ -4220,6 +4220,13 @@ int main(int argc, char **argv, char **envp) exit(0); } + machine_opts = qemu_get_machine_opts(); + if (qemu_opt_foreach(machine_opts, object_set_property, current_machine, + 1) < 0) { + object_unref(OBJECT(current_machine)); + exit(1); + } + configure_accelerator(machine_class); if (qtest_chrdev) { @@ -4264,6 +4271,7 @@ int main(int argc, char **argv, char **envp) if (!kernel_cmdline) { kernel_cmdline = ""; + current_machine->kernel_cmdline = (char *)kernel_cmdline; } linux_boot = (kernel_filename != NULL); @@ -4428,9 +4436,6 @@ int main(int argc, char **argv, char **envp) current_machine->ram_size = ram_size; current_machine->boot_order = boot_order; - current_machine->kernel_filename = kernel_filename; - current_machine->kernel_cmdline = kernel_cmdline; - current_machine->initrd_filename = initrd_filename; current_machine->cpu_model = cpu_model; machine_class->init(current_machine); -- cgit 1.4.1 From a5f54290ceb31281158413d4cda1ca80908a56cc Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Mon, 19 May 2014 23:30:58 -0700 Subject: qdev: Implement named GPIOs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement named GPIOs on the Device layer. Listifies the existing GPIOs stuff using string keys. Legacy un-named GPIOs are preserved by using a NULL name string - they are just a single matchable element in the name list. Reviewed-by: Peter Maydell Signed-off-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- hw/core/qdev.c | 85 ++++++++++++++++++++++++++++++++++++++++++++------ include/hw/qdev-core.h | 24 +++++++++++--- qdev-monitor.c | 16 +++++++--- qtest.c | 19 ++++++++--- 4 files changed, 120 insertions(+), 24 deletions(-) (limited to 'hw/core') diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 936eae6412..e65a5aa3a8 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -312,30 +312,82 @@ BusState *qdev_get_parent_bus(DeviceState *dev) return dev->parent_bus; } +static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev, + const char *name) +{ + NamedGPIOList *ngl; + + QLIST_FOREACH(ngl, &dev->gpios, node) { + /* NULL is a valid and matchable name, otherwise do a normal + * strcmp match. + */ + if ((!ngl->name && !name) || + (name && ngl->name && strcmp(name, ngl->name) == 0)) { + return ngl; + } + } + + ngl = g_malloc0(sizeof(*ngl)); + ngl->name = g_strdup(name); + QLIST_INSERT_HEAD(&dev->gpios, ngl, node); + return ngl; +} + +void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler, + const char *name, int n) +{ + NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name); + + gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler, + dev, n); + gpio_list->num_in += n; +} + void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n) { - dev->gpio_in = qemu_extend_irqs(dev->gpio_in, dev->num_gpio_in, handler, - dev, n); - dev->num_gpio_in += n; + qdev_init_gpio_in_named(dev, handler, NULL, n); +} + +void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, + const char *name, int n) +{ + NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name); + + assert(gpio_list->num_out == 0); + gpio_list->num_out = n; + gpio_list->out = pins; } void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n) { - assert(dev->num_gpio_out == 0); - dev->num_gpio_out = n; - dev->gpio_out = pins; + qdev_init_gpio_out_named(dev, pins, NULL, n); +} + +qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n) +{ + NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name); + + assert(n >= 0 && n < gpio_list->num_in); + return gpio_list->in[n]; } qemu_irq qdev_get_gpio_in(DeviceState *dev, int n) { - assert(n >= 0 && n < dev->num_gpio_in); - return dev->gpio_in[n]; + return qdev_get_gpio_in_named(dev, NULL, n); +} + +void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, + qemu_irq pin) +{ + NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name); + + assert(n >= 0 && n < gpio_list->num_out); + gpio_list->out[n] = pin; } void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin) { - assert(n >= 0 && n < dev->num_gpio_out); - dev->gpio_out[n] = pin; + qdev_connect_gpio_out_named(dev, NULL, n, pin); } BusState *qdev_get_child_bus(DeviceState *dev, const char *name) @@ -844,6 +896,7 @@ static void device_initfn(Object *obj) object_property_add_link(OBJECT(dev), "parent_bus", TYPE_BUS, (Object **)&dev->parent_bus, NULL, 0, &error_abort); + QLIST_INIT(&dev->gpios); } static void device_post_init(Object *obj) @@ -854,10 +907,22 @@ static void device_post_init(Object *obj) /* Unlink device from bus and free the structure. */ static void device_finalize(Object *obj) { + NamedGPIOList *ngl, *next; + DeviceState *dev = DEVICE(obj); if (dev->opts) { qemu_opts_del(dev->opts); } + + QLIST_FOREACH_SAFE(ngl, &dev->gpios, node, next) { + QLIST_REMOVE(ngl, node); + qemu_free_irqs(ngl->in); + g_free(ngl->name); + g_free(ngl); + /* ngl->out irqs are owned by the other end and should not be freed + * here + */ + } } static void device_class_base_init(ObjectClass *class, void *data) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index dbe473c344..ae31575577 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -131,6 +131,17 @@ typedef struct DeviceClass { const char *bus_type; } DeviceClass; +typedef struct NamedGPIOList NamedGPIOList; + +struct NamedGPIOList { + char *name; + qemu_irq *in; + int num_in; + qemu_irq *out; + int num_out; + QLIST_ENTRY(NamedGPIOList) node; +}; + /** * DeviceState: * @realized: Indicates whether the device has been fully constructed. @@ -148,10 +159,7 @@ struct DeviceState { QemuOpts *opts; int hotplugged; BusState *parent_bus; - int num_gpio_out; - qemu_irq *gpio_out; - int num_gpio_in; - qemu_irq *gpio_in; + QLIST_HEAD(, NamedGPIOList) gpios; QLIST_HEAD(, BusState) child_bus; int num_child_bus; int instance_id_alias; @@ -252,7 +260,11 @@ void qdev_machine_creation_done(void); bool qdev_machine_modified(void); qemu_irq qdev_get_gpio_in(DeviceState *dev, int n); +qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n); + void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); +void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, + qemu_irq pin); BusState *qdev_get_child_bus(DeviceState *dev, const char *name); @@ -262,6 +274,10 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name); /* GPIO inputs also double as IRQ sinks. */ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); +void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler, + const char *name, int n); +void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, + const char *name, int n); BusState *qdev_get_parent_bus(DeviceState *dev); diff --git a/qdev-monitor.c b/qdev-monitor.c index 02cbe43bce..f87f3d89cd 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -613,14 +613,20 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent) { ObjectClass *class; BusState *child; + NamedGPIOList *ngl; + qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)), dev->id ? dev->id : ""); indent += 2; - if (dev->num_gpio_in) { - qdev_printf("gpio-in %d\n", dev->num_gpio_in); - } - if (dev->num_gpio_out) { - qdev_printf("gpio-out %d\n", dev->num_gpio_out); + QLIST_FOREACH(ngl, &dev->gpios, node) { + if (ngl->num_in) { + qdev_printf("gpio-in \"%s\" %d\n", ngl->name ? ngl->name : "", + ngl->num_in); + } + if (ngl->num_out) { + qdev_printf("gpio-out \"%s\" %d\n", ngl->name ? ngl->name : "", + ngl->num_out); + } } class = object_get_class(OBJECT(dev)); do { diff --git a/qtest.c b/qtest.c index 2aba20d104..f9695a8ff6 100644 --- a/qtest.c +++ b/qtest.c @@ -233,7 +233,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) g_assert(command); if (strcmp(words[0], "irq_intercept_out") == 0 || strcmp(words[0], "irq_intercept_in") == 0) { - DeviceState *dev; + DeviceState *dev; + NamedGPIOList *ngl; g_assert(words[1]); dev = DEVICE(object_resolve_path(words[1], NULL)); @@ -253,10 +254,18 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) return; } - if (words[0][14] == 'o') { - qemu_irq_intercept_out(&dev->gpio_out, qtest_irq_handler, dev->num_gpio_out); - } else { - qemu_irq_intercept_in(dev->gpio_in, qtest_irq_handler, dev->num_gpio_in); + QLIST_FOREACH(ngl, &dev->gpios, node) { + /* We don't support intercept of named GPIOs yet */ + if (ngl->name) { + continue; + } + if (words[0][14] == 'o') { + qemu_irq_intercept_out(&ngl->out, qtest_irq_handler, + ngl->num_out); + } else { + qemu_irq_intercept_in(ngl->in, qtest_irq_handler, + ngl->num_in); + } } irq_intercept_dev = dev; qtest_send_prefix(chr); -- cgit 1.4.1