From 96f209264f642365052983dcb50a0f3d7b688f6b Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Fri, 27 Feb 2015 11:48:58 +1000 Subject: [PATCH 1/7] cadence_uart: Convert to QOM realize() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use DeviceClass::realize() and TypeInfo::instance_init() instead of the deprecated SysBusDevice::init(). Signed-off-by: Alistair Francis Reviewed-by: Peter Crosthwaite Signed-off-by: Andreas Färber --- hw/char/cadence_uart.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 7044b357dc..a5dc2a4366 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -476,18 +476,12 @@ static void cadence_uart_reset(DeviceState *dev) uart_update_status(s); } -static int cadence_uart_init(SysBusDevice *dev) +static void cadence_uart_realize(DeviceState *dev, Error **errp) { UartState *s = CADENCE_UART(dev); - memory_region_init_io(&s->iomem, OBJECT(s), &uart_ops, s, "uart", 0x1000); - sysbus_init_mmio(dev, &s->iomem); - sysbus_init_irq(dev, &s->irq); - s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL, - (QEMUTimerCB *)fifo_trigger_update, s); - - s->char_tx_time = (get_ticks_per_sec() / 9600) * 10; + fifo_trigger_update, s); s->chr = qemu_char_get_next_serial(); @@ -495,8 +489,18 @@ static int cadence_uart_init(SysBusDevice *dev) qemu_chr_add_handlers(s->chr, uart_can_receive, uart_receive, uart_event, s); } +} - return 0; +static void cadence_uart_init(Object *obj) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + UartState *s = CADENCE_UART(obj); + + memory_region_init_io(&s->iomem, obj, &uart_ops, s, "uart", 0x1000); + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->irq); + + s->char_tx_time = (get_ticks_per_sec() / 9600) * 10; } static int cadence_uart_post_load(void *opaque, int version_id) @@ -528,9 +532,8 @@ static const VMStateDescription vmstate_cadence_uart = { static void cadence_uart_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); - sdc->init = cadence_uart_init; + dc->realize = cadence_uart_realize; dc->vmsd = &vmstate_cadence_uart; dc->reset = cadence_uart_reset; } @@ -539,6 +542,7 @@ static const TypeInfo cadence_uart_info = { .name = TYPE_CADENCE_UART, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(UartState), + .instance_init = cadence_uart_init, .class_init = cadence_uart_class_init, }; From eb60aa5737463d9143c0edde0fcd3a1eff44a633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 5 Feb 2014 18:31:06 +0100 Subject: [PATCH 2/7] scripts: Add qom-tree script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Functionally it is a recursive qom-list with qom-get per non-child<> property. Some failures needed to be handled, such as trying to read a pointer property, which is not representable in QMP. Those print a literal "". Tested-by: Alistair Francis Signed-off-by: Andreas Färber --- scripts/qmp/qom-tree | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100755 scripts/qmp/qom-tree diff --git a/scripts/qmp/qom-tree b/scripts/qmp/qom-tree new file mode 100755 index 0000000000..aea11d4b1a --- /dev/null +++ b/scripts/qmp/qom-tree @@ -0,0 +1,70 @@ +#!/usr/bin/python +## +# QEMU Object Model test tools +# +# Copyright IBM, Corp. 2011 +# Copyright (c) 2013 SUSE LINUX Products GmbH +# +# Authors: +# Anthony Liguori +# Andreas Faerber +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. See +# the COPYING file in the top-level directory. +## + +import sys +import os +from qmp import QEMUMonitorProtocol + +cmd, args = sys.argv[0], sys.argv[1:] +socket_path = None +path = None +prop = None + +def usage(): + return '''environment variables: + QMP_SOCKET= +usage: + %s [-h] [-s ] [] +''' % cmd + +def usage_error(error_msg = "unspecified error"): + sys.stderr.write('%s\nERROR: %s\n' % (usage(), error_msg)) + exit(1) + +if len(args) > 0: + if args[0] == "-h": + print usage() + exit(0); + elif args[0] == "-s": + try: + socket_path = args[1] + except: + usage_error("missing argument: QMP socket path or address"); + args = args[2:] + +if not socket_path: + if os.environ.has_key('QMP_SOCKET'): + socket_path = os.environ['QMP_SOCKET'] + else: + usage_error("no QMP socket path or address given"); + +srv = QEMUMonitorProtocol(socket_path) +srv.connect() + +def list_node(path): + print '%s' % path + items = srv.command('qom-list', path=path) + for item in items: + if not item['type'].startswith('child<'): + try: + print ' %s: %s (%s)' % (item['name'], srv.command('qom-get', path=path, property=item['name']), item['type']) + except: + print ' %s: (%s)' % (item['name'], item['type']) + print '' + for item in items: + if item['type'].startswith('child<'): + list_node(path + '/' + item['name']) + +list_node('/machine') From 89d7fa9eb4a0a75bb1bc1bf24e9e79ebe91fd7b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 7 May 2014 18:08:29 +0200 Subject: [PATCH 3/7] qom: Implement qom-list HMP command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement it as a wrapper for QMP qom-list, but mimic the behavior of scripts/qmp/qom-list in making the path argument optional and listing the root if absent, to hint users what kind of path to pass. Reviewed-by: Gonglei Tested-by: Alistair Francis Signed-off-by: Andreas Färber --- hmp-commands.hx | 13 +++++++++++++ hmp.c | 26 ++++++++++++++++++++++++++ hmp.h | 1 + 3 files changed, 40 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 9c1e849859..527fa2dc1a 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1671,6 +1671,19 @@ ETEXI STEXI @item cpu-add @var{id} Add CPU with id @var{id} +ETEXI + + { + .name = "qom-list", + .args_type = "path:s?", + .params = "path", + .help = "list QOM properties", + .mhandler.cmd = hmp_qom_list, + }, + +STEXI +@item qom-list [@var{path}] +Print QOM properties of object at location @var{path} ETEXI { diff --git a/hmp.c b/hmp.c index f6cde86b93..92decae338 100644 --- a/hmp.c +++ b/hmp.c @@ -1866,3 +1866,29 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) qapi_free_MemoryDeviceInfoList(info_list); } + +void hmp_qom_list(Monitor *mon, const QDict *qdict) +{ + const char *path = qdict_get_try_str(qdict, "path"); + ObjectPropertyInfoList *list; + Error *err = NULL; + + if (path == NULL) { + monitor_printf(mon, "/\n"); + return; + } + + list = qmp_qom_list(path, &err); + if (err == NULL) { + ObjectPropertyInfoList *start = list; + while (list != NULL) { + ObjectPropertyInfo *value = list->value; + + monitor_printf(mon, "%s (%s)\n", + value->name, value->type); + list = list->next; + } + qapi_free_ObjectPropertyInfoList(start); + } + hmp_handle_error(mon, &err); +} diff --git a/hmp.h b/hmp.h index 371f8d45cd..c5676e2f2e 100644 --- a/hmp.h +++ b/hmp.h @@ -96,6 +96,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict); void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_info_memdev(Monitor *mon, const QDict *qdict); void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); +void hmp_qom_list(Monitor *mon, const QDict *qdict); void object_add_completion(ReadLineState *rs, int nb_args, const char *str); void object_del_completion(ReadLineState *rs, int nb_args, const char *str); void device_add_completion(ReadLineState *rs, int nb_args, const char *str); From c0e6ee9e6f49d4a3183b05f457cc2704a966fce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 7 May 2014 19:48:15 +0200 Subject: [PATCH 4/7] qom: Implement qom-set HMP command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-implemented based on qmp_qom_set() to facilitate argument parsing. Warn about ambiguous path arguments. Reviewed-by: Gonglei Tested-by: Alistair Francis Signed-off-by: Andreas Färber --- hmp-commands.hx | 13 +++++++++++++ hmp.c | 21 +++++++++++++++++++++ hmp.h | 1 + 3 files changed, 35 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 527fa2dc1a..d9f6c037dc 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1684,6 +1684,19 @@ ETEXI STEXI @item qom-list [@var{path}] Print QOM properties of object at location @var{path} +ETEXI + + { + .name = "qom-set", + .args_type = "path:s,property:s,value:s", + .params = "path property value", + .help = "set QOM property", + .mhandler.cmd = hmp_qom_set, + }, + +STEXI +@item qom-set @var{path} @var{property} @var{value} +Set QOM property @var{property} of object at location @var{path} to value @var{value} ETEXI { diff --git a/hmp.c b/hmp.c index 92decae338..ad1beba80d 100644 --- a/hmp.c +++ b/hmp.c @@ -1892,3 +1892,24 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict) } hmp_handle_error(mon, &err); } + +void hmp_qom_set(Monitor *mon, const QDict *qdict) +{ + const char *path = qdict_get_str(qdict, "path"); + const char *property = qdict_get_str(qdict, "property"); + const char *value = qdict_get_str(qdict, "value"); + Error *err = NULL; + bool ambiguous = false; + Object *obj; + + obj = object_resolve_path(path, &ambiguous); + if (obj == NULL) { + error_set(&err, QERR_DEVICE_NOT_FOUND, path); + } else { + if (ambiguous) { + monitor_printf(mon, "Warning: Path '%s' is ambiguous\n", path); + } + object_property_parse(obj, value, property, &err); + } + hmp_handle_error(mon, &err); +} diff --git a/hmp.h b/hmp.h index c5676e2f2e..2b9308be7c 100644 --- a/hmp.h +++ b/hmp.h @@ -97,6 +97,7 @@ void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_info_memdev(Monitor *mon, const QDict *qdict); void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); void hmp_qom_list(Monitor *mon, const QDict *qdict); +void hmp_qom_set(Monitor *mon, const QDict *qdict); void object_add_completion(ReadLineState *rs, int nb_args, const char *str); void object_del_completion(ReadLineState *rs, int nb_args, const char *str); void device_add_completion(ReadLineState *rs, int nb_args, const char *str); From a01ff75fcdb4d91809ccdd2b95efda6ee1239cbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Wed, 7 May 2014 17:03:18 +0200 Subject: [PATCH 5/7] qom: Implement info qom-tree HMP command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To complement qdev's bus-oriented info qtree, info qom-tree prints a hierarchical view of the QOM composition tree. By default, the machine composition tree is shown. This can be overriden by supplying a path argument, such as "info qom-tree /". Tested-by: Alistair Francis Signed-off-by: Andreas Färber --- hmp-commands.hx | 2 ++ include/monitor/qdev.h | 1 + monitor.c | 7 ++++++ qdev-monitor.c | 57 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index d9f6c037dc..328709dc8d 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1782,6 +1782,8 @@ show balloon information show device tree @item info qdm show qdev device model list +@item info qom-tree +show object composition tree @item info roms show roms @item info tpm diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h index 5eb4a1171e..719075283c 100644 --- a/include/monitor/qdev.h +++ b/include/monitor/qdev.h @@ -8,6 +8,7 @@ void hmp_info_qtree(Monitor *mon, const QDict *qdict); void hmp_info_qdm(Monitor *mon, const QDict *qdict); +void hmp_info_qom_tree(Monitor *mon, const QDict *dict); int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data); int qdev_device_help(QemuOpts *opts); DeviceState *qdev_device_add(QemuOpts *opts); diff --git a/monitor.c b/monitor.c index 8b703f97be..42116a942e 100644 --- a/monitor.c +++ b/monitor.c @@ -2889,6 +2889,13 @@ static mon_cmd_t info_cmds[] = { .help = "show qdev device model list", .mhandler.cmd = hmp_info_qdm, }, + { + .name = "qom-tree", + .args_type = "path:s?", + .params = "[path]", + .help = "show QOM composition tree", + .mhandler.cmd = hmp_info_qom_tree, + }, { .name = "roms", .args_type = "", diff --git a/qdev-monitor.c b/qdev-monitor.c index 5d30ac534c..1d87f573e8 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -678,6 +678,63 @@ void hmp_info_qdm(Monitor *mon, const QDict *qdict) qdev_print_devinfos(true); } +typedef struct QOMCompositionState { + Monitor *mon; + int indent; +} QOMCompositionState; + +static void print_qom_composition(Monitor *mon, Object *obj, int indent); + +static int print_qom_composition_child(Object *obj, void *opaque) +{ + QOMCompositionState *s = opaque; + + print_qom_composition(s->mon, obj, s->indent); + + return 0; +} + +static void print_qom_composition(Monitor *mon, Object *obj, int indent) +{ + QOMCompositionState s = { + .mon = mon, + .indent = indent + 2, + }; + char *name; + + if (obj == object_get_root()) { + name = g_strdup(""); + } else { + name = object_get_canonical_path_component(obj); + } + monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name, + object_get_typename(obj)); + g_free(name); + object_child_foreach(obj, print_qom_composition_child, &s); +} + +void hmp_info_qom_tree(Monitor *mon, const QDict *dict) +{ + const char *path = qdict_get_try_str(dict, "path"); + Object *obj; + bool ambiguous = false; + + if (path) { + obj = object_resolve_path(path, &ambiguous); + if (!obj) { + monitor_printf(mon, "Path '%s' could not be resolved.\n", path); + return; + } + if (ambiguous) { + monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path); + return; + } + } else { + obj = qdev_get_machine(); + } + print_qom_composition(mon, obj, 0); +} + int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data) { Error *local_err = NULL; From 210eb9364be384e7c7f6ef106e6ac8c996dadffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 12 Mar 2015 15:37:07 +0100 Subject: [PATCH 6/7] memory: Move owner-less MemoryRegions to /machine/unattached MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This cleans up the official /machine namespace. In particular /machine/system[0] and /machine/io[0], as well as entries with non-sanitized node names such as "/machine/qemu extended regs[0]". The actual MemoryRegion names remain unchanged. Acked-by: Paolo Bonzini Tested-by: Alistair Francis Signed-off-by: Andreas Färber --- memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/memory.c b/memory.c index 20f6d9eeac..ee3f2a8a95 100644 --- a/memory.c +++ b/memory.c @@ -868,7 +868,7 @@ void memory_region_init(MemoryRegion *mr, uint64_t size) { if (!owner) { - owner = qdev_get_machine(); + owner = container_get(qdev_get_machine(), "/unattached"); } object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION); From 88950eeff59834b3b4bea98b954a3fe854468ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Thu, 12 Mar 2015 16:09:34 +0100 Subject: [PATCH 7/7] qdev: Move owner-less IRQs to /machine/unattached MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move non-qdev-gpio[*] from /machine into /machine/unattached. For the PC this moves 25 nodes from the stable namespace into the unstable. Cc: Peter Crosthwaite Tested-by: Alistair Francis Signed-off-by: Andreas Färber --- hw/core/qdev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 6be58669f7..6e6a65d49b 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -501,8 +501,9 @@ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, * with an error without doing anything. If it has none, it will * never fail. So we can just call it with a NULL Error pointer. */ - object_property_add_child(qdev_get_machine(), "non-qdev-gpio[*]", - OBJECT(pin), NULL); + object_property_add_child(container_get(qdev_get_machine(), + "/unattached"), + "non-qdev-gpio[*]", OBJECT(pin), NULL); } object_property_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort); g_free(propname);