aboutsummaryrefslogtreecommitdiff
path: root/hw/core
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-10-30 13:35:12 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-10-30 13:35:12 +0000
commit08118672d06c8d2fb937cab5c97b2dfdc8786520 (patch)
tree0ebf76ff76a35725d083012abfcac1af2aeaddd1 /hw/core
parentcbd5ac699173b684e678d66df3aea33df81fd89f (diff)
parente218052f9288609bb8c53b31cae3bed7d7516728 (diff)
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
virtio-scsi fixes, the first part of dynamic sysbus devices, MAINTAINERS updates, and AVX512 support. # gpg: Signature made Mon 27 Oct 2014 15:12:13 GMT using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (28 commits) aio / timers: De-document -clock hw/scsi/virtio-scsi.c: fix the "type" use error in virtio_scsi_handle_ctrl virtio-scsi: sense in virtio_scsi_command_complete target-i386: add Intel AVX-512 support get_maintainer.pl: restrict cases where it falls back to --git get_maintainer.pl: move git loop under "if ($email) {" qtest: fix qtest log fd should be initialized before qtest chardev MAINTAINERS: avoid M entries that point to mailing lists MAINTAINERS: add some tests directories MAINTAINERS: Add more TCG files MAINTAINERS: add myself for X86 MAINTAINERS: add Samuel Thibault as usb-serial.c and baum.c maintainer MAINTAINERS: grab more files from Anthony's pile target-i386: warns users when CPU threads>1 for non-Intel CPUs sysbus: Use TYPE_DEVICE GPIO functionality qdev: gpio: Define qdev_pass_gpios() qdev: gpio: Remove qdev_init_gpio_out x1 restriction qdev: gpio: delete NamedGPIOList::out irq: Remove qemu_irq_intercept_out qtest/irq: Rework IRQ interception ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/core')
-rw-r--r--hw/core/irq.c8
-rw-r--r--hw/core/qdev.c70
-rw-r--r--hw/core/sysbus.c20
3 files changed, 68 insertions, 30 deletions
diff --git a/hw/core/irq.c b/hw/core/irq.c
index cffced040f..8a62a36d5e 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -140,16 +140,10 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
for (i = 0; i < n; i++) {
*old_irqs[i] = *gpio_in[i];
gpio_in[i]->handler = handler;
- gpio_in[i]->opaque = old_irqs;
+ gpio_in[i]->opaque = &old_irqs[i];
}
}
-void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n)
-{
- qemu_irq *old_irqs = *gpio_out;
- *gpio_out = qemu_allocate_irqs(handler, old_irqs, n);
-}
-
static const TypeInfo irq_type_info = {
.name = TYPE_IRQ,
.parent = TYPE_OBJECT,
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 9357aba455..b3d519645a 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -404,9 +404,7 @@ void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-out");
assert(gpio_list->num_in == 0 || !name);
- assert(gpio_list->num_out == 0);
- gpio_list->num_out = n;
- gpio_list->out = pins;
+ gpio_list->num_out += n;
for (i = 0; i < n; ++i) {
memset(&pins[i], 0, sizeof(*pins));
@@ -440,10 +438,44 @@ qemu_irq qdev_get_gpio_in(DeviceState *dev, int 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);
+ char *propname = g_strdup_printf("%s[%d]",
+ name ? name : "unnamed-gpio-out", n);
+ if (pin) {
+ /* We need a name for object_property_set_link to work. If the
+ * object has a parent, object_property_add_child will come back
+ * 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_set_link(OBJECT(dev), OBJECT(pin), propname, &error_abort);
+ g_free(propname);
+}
+
+/* disconnect a GPIO ouput, returning the disconnected input (if any) */
+
+static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev,
+ const char *name, int n)
+{
+ char *propname = g_strdup_printf("%s[%d]",
+ name ? name : "unnamed-gpio-out", n);
+
+ qemu_irq ret = (qemu_irq)object_property_get_link(OBJECT(dev), propname,
+ NULL);
+ if (ret) {
+ object_property_set_link(OBJECT(dev), NULL, propname, NULL);
+ }
+ g_free(propname);
+ return ret;
+}
- assert(n >= 0 && n < gpio_list->num_out);
- gpio_list->out[n] = pin;
+qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt,
+ const char *name, int n)
+{
+ qemu_irq disconnected = qdev_disconnect_gpio_out_named(dev, name, n);
+ qdev_connect_gpio_out_named(dev, name, n, icpt);
+ return disconnected;
}
void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
@@ -451,6 +483,32 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
qdev_connect_gpio_out_named(dev, NULL, n, pin);
}
+void qdev_pass_gpios(DeviceState *dev, DeviceState *container,
+ const char *name)
+{
+ int i;
+ NamedGPIOList *ngl = qdev_get_named_gpio_list(dev, name);
+
+ for (i = 0; i < ngl->num_in; i++) {
+ const char *nm = ngl->name ? ngl->name : "unnamed-gpio-in";
+ char *propname = g_strdup_printf("%s[%d]", nm, i);
+
+ object_property_add_alias(OBJECT(container), propname,
+ OBJECT(dev), propname,
+ &error_abort);
+ }
+ for (i = 0; i < ngl->num_out; i++) {
+ const char *nm = ngl->name ? ngl->name : "unnamed-gpio-out";
+ char *propname = g_strdup_printf("%s[%d]", nm, i);
+
+ object_property_add_alias(OBJECT(container), propname,
+ OBJECT(dev), propname,
+ &error_abort);
+ }
+ QLIST_REMOVE(ngl, node);
+ QLIST_INSERT_HEAD(&container->gpios, ngl, node);
+}
+
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
{
BusState *bus;
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 414e2a1921..e55c3c1d6d 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -41,11 +41,7 @@ static const TypeInfo system_bus_info = {
void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq)
{
- assert(n >= 0 && n < dev->num_irq);
- dev->irqs[n] = NULL;
- if (dev->irqp[n]) {
- *dev->irqp[n] = irq;
- }
+ qdev_connect_gpio_out_named(DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ, n, irq);
}
static void sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr,
@@ -89,22 +85,13 @@ void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr,
/* Request an IRQ source. The actual IRQ object may be populated later. */
void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p)
{
- int n;
-
- assert(dev->num_irq < QDEV_MAX_IRQ);
- n = dev->num_irq++;
- dev->irqp[n] = p;
+ qdev_init_gpio_out_named(DEVICE(dev), p, SYSBUS_DEVICE_GPIO_IRQ, 1);
}
/* Pass IRQs from a target device. */
void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target)
{
- int i;
- assert(dev->num_irq == 0);
- dev->num_irq = target->num_irq;
- for (i = 0; i < dev->num_irq; i++) {
- dev->irqp[i] = target->irqp[i];
- }
+ qdev_pass_gpios(DEVICE(target), DEVICE(dev), SYSBUS_DEVICE_GPIO_IRQ);
}
void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory)
@@ -210,7 +197,6 @@ static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent)
hwaddr size;
int i;
- monitor_printf(mon, "%*sirq %d\n", indent, "", s->num_irq);
for (i = 0; i < s->num_mmio; i++) {
size = memory_region_size(s->mmio[i].memory);
monitor_printf(mon, "%*smmio " TARGET_FMT_plx "/" TARGET_FMT_plx "\n",