aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/9pfs/9p.c6
-rw-r--r--hw/acpi/pcihp.c3
-rw-r--r--hw/acpi/piix4.c2
-rw-r--r--hw/arm/armsse.c61
-rw-r--r--hw/arm/armv7m.c7
-rw-r--r--hw/arm/aspeed_ast2600.c35
-rw-r--r--hw/arm/aspeed_soc.c29
-rw-r--r--hw/arm/bcm2835_peripherals.c12
-rw-r--r--hw/arm/fsl-imx25.c12
-rw-r--r--hw/arm/fsl-imx6.c12
-rw-r--r--hw/arm/fsl-imx6ul.c10
-rw-r--r--hw/arm/mcimx6ul-evk.c2
-rw-r--r--hw/arm/nrf51_soc.c6
-rw-r--r--hw/arm/pxa2xx_pic.c9
-rw-r--r--hw/arm/spitz.c505
-rw-r--r--hw/arm/stm32f205_soc.c2
-rw-r--r--hw/arm/stm32f405_soc.c2
-rw-r--r--hw/arm/virt-acpi-build.c5
-rw-r--r--hw/arm/virt.c37
-rw-r--r--hw/arm/z2.c11
-rw-r--r--hw/char/virtio-serial-bus.c4
-rw-r--r--hw/core/bus.c8
-rw-r--r--hw/core/qdev-properties.c89
-rw-r--r--hw/display/ads7846.c9
-rw-r--r--hw/display/ati.c92
-rw-r--r--hw/display/ati_dbg.c1
-rw-r--r--hw/display/ati_regs.h1
-rw-r--r--hw/display/bcm2835_fb.c4
-rw-r--r--hw/display/sm501.c157
-rw-r--r--hw/display/ssd0323.c10
-rw-r--r--hw/display/trace-events12
-rw-r--r--hw/display/virtio-gpu-pci.c2
-rw-r--r--hw/display/virtio-vga.c2
-rw-r--r--hw/dma/sparc32_dma.c6
-rw-r--r--hw/dma/xilinx_axidma.c12
-rw-r--r--hw/gpio/zaurus.c12
-rw-r--r--hw/i386/amd_iommu.c6
-rw-r--r--hw/i386/x86.c8
-rw-r--r--hw/m68k/mcf5206.c39
-rw-r--r--hw/mips/cps.c35
-rw-r--r--hw/misc/macio/macio.c3
-rw-r--r--hw/misc/max111x.c86
-rw-r--r--hw/net/imx_fec.c24
-rw-r--r--hw/net/trace-events4
-rw-r--r--hw/net/virtio-net.c2
-rw-r--r--hw/net/xilinx_axienet.c12
-rw-r--r--hw/pci/pci.c3
-rw-r--r--hw/pci/pcie.c2
-rw-r--r--hw/pci/shpc.c2
-rw-r--r--hw/ppc/spapr.c4
-rw-r--r--hw/ppc/spapr_drc.c4
-rw-r--r--hw/ppc/spapr_pci.c4
-rw-r--r--hw/riscv/riscv_hart.c14
-rw-r--r--hw/riscv/sifive_clint.c2
-rw-r--r--hw/riscv/sifive_plic.c20
-rw-r--r--hw/riscv/sifive_u.c12
-rw-r--r--hw/s390x/ap-bridge.c2
-rw-r--r--hw/s390x/css-bridge.c2
-rw-r--r--hw/s390x/s390-pci-bus.c30
-rw-r--r--hw/s390x/virtio-ccw.c18
-rw-r--r--hw/scsi/scsi-bus.c2
-rw-r--r--hw/scsi/virtio-scsi.c4
-rw-r--r--hw/scsi/vmw_pvscsi.c2
-rw-r--r--hw/sd/milkymist-memcard.c5
-rw-r--r--hw/sd/ssi-sd.c4
-rw-r--r--hw/ssi/ssi.c7
-rw-r--r--hw/usb/bus.c2
-rw-r--r--hw/usb/dev-mtp.c2
-rw-r--r--hw/usb/dev-smartcard-reader.c2
-rw-r--r--hw/virtio/trace-events1
-rw-r--r--hw/virtio/virtio-iommu-pci.c15
-rw-r--r--hw/virtio/virtio-iommu.c114
-rw-r--r--hw/xen/xen-bus.c2
-rw-r--r--hw/xen/xen-legacy-backend.c2
74 files changed, 1037 insertions, 654 deletions
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 45a788f..9755fba 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -1399,7 +1399,6 @@ static void coroutine_fn v9fs_attach(void *opaque)
size_t offset = 7;
V9fsQID qid;
ssize_t err;
- Error *local_err = NULL;
v9fs_string_init(&uname);
v9fs_string_init(&aname);
@@ -1437,9 +1436,8 @@ static void coroutine_fn v9fs_attach(void *opaque)
error_setg(&s->migration_blocker,
"Migration is disabled when VirtFS export path '%s' is mounted in the guest using mount_tag '%s'",
s->ctx.fs_root ? s->ctx.fs_root : "NULL", s->tag);
- err = migrate_add_blocker(s->migration_blocker, &local_err);
- if (local_err) {
- error_free(local_err);
+ err = migrate_add_blocker(s->migration_blocker, NULL);
+ if (err < 0) {
error_free(s->migration_blocker);
s->migration_blocker = NULL;
clunk_fid(s, fid);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 33ea2b7..9e31ab2 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -246,8 +246,7 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
- qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev),
- &error_abort);
+ qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev));
/* We don't have to overwrite any other hotplug handler yet */
assert(QLIST_EMPTY(&sec->child));
}
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 630ca6e..283422e 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -506,7 +506,7 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
piix4_acpi_system_hot_add_init(pci_address_space_io(dev),
pci_get_bus(dev), s);
- qbus_set_hotplug_handler(BUS(pci_get_bus(dev)), OBJECT(s), &error_abort);
+ qbus_set_hotplug_handler(BUS(pci_get_bus(dev)), OBJECT(s));
piix4_pm_add_propeties(s);
}
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
index 9ddde33..2fbd970 100644
--- a/hw/arm/armsse.c
+++ b/hw/arm/armsse.c
@@ -563,16 +563,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
&s->container, -1);
}
object_property_set_link(cpuobj, OBJECT(&s->cpu_container[i]),
- "memory", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- object_property_set_link(cpuobj, OBJECT(s), "idau", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ "memory", &error_abort);
+ object_property_set_link(cpuobj, OBJECT(s), "idau", &error_abort);
sysbus_realize(SYS_BUS_DEVICE(cpuobj), &err);
if (err) {
error_propagate(errp, err);
@@ -699,11 +691,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
return;
}
object_property_set_link(OBJECT(&s->mpc[i]), OBJECT(&s->sram[i]),
- "downstream", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ "downstream", &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->mpc[i]), &err);
if (err) {
error_propagate(errp, err);
@@ -754,11 +742,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
armsse_get_common_irq_in(s, 3));
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
- object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]",
+ &error_abort);
qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
sysbus_realize(SYS_BUS_DEVICE(&s->timer1), &err);
@@ -769,12 +754,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
armsse_get_common_irq_in(s, 4));
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
- object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
+ object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]",
+ &error_abort);
qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), &err);
@@ -785,11 +766,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
armsse_get_common_irq_in(s, 5));
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
- object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]",
+ &error_abort);
if (info->has_mhus) {
/*
@@ -814,12 +792,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
port = g_strdup_printf("port[%d]", i + 3);
mr = sysbus_mmio_get_region(mhu_sbd, 0);
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr),
- port, &err);
+ port, &error_abort);
g_free(port);
- if (err) {
- error_propagate(errp, err);
- return;
- }
/*
* Each MHU has an irq line for each CPU:
@@ -966,11 +940,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
armsse_get_common_irq_in(s, 2));
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
- object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]",
+ &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc1), &err);
if (err) {
@@ -1019,13 +990,13 @@ static void armsse_realize(DeviceState *dev, Error **errp)
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
/* System control registers */
object_property_set_int(OBJECT(&s->sysctl), info->sys_version,
- "SYS_VERSION", &err);
+ "SYS_VERSION", &error_abort);
object_property_set_int(OBJECT(&s->sysctl), info->cpuwait_rst,
- "CPUWAIT_RST", &err);
+ "CPUWAIT_RST", &error_abort);
object_property_set_int(OBJECT(&s->sysctl), s->init_svtor,
- "INITSVTOR0_RST", &err);
+ "INITSVTOR0_RST", &error_abort);
object_property_set_int(OBJECT(&s->sysctl), s->init_svtor,
- "INITSVTOR1_RST", &err);
+ "INITSVTOR1_RST", &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->sysctl), &err);
if (err) {
error_propagate(errp, err);
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index ce83586..3308211 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -170,11 +170,8 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
object_property_set_link(OBJECT(s->cpu), OBJECT(&s->container), "memory",
&error_abort);
if (object_property_find(OBJECT(s->cpu), "idau", NULL)) {
- object_property_set_link(OBJECT(s->cpu), s->idau, "idau", &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
+ object_property_set_link(OBJECT(s->cpu), s->idau, "idau",
+ &error_abort);
}
if (object_property_find(OBJECT(s->cpu), "init-svtor", NULL)) {
object_property_set_uint(OBJECT(s->cpu), s->init_svtor,
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 6da6872..59a7a13 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -228,7 +228,7 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
int i;
AspeedSoCState *s = ASPEED_SOC(dev);
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
- Error *err = NULL, *local_err = NULL;
+ Error *err = NULL;
qemu_irq irq;
/* IO space */
@@ -341,11 +341,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
}
/* I2C */
- object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram",
+ &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->i2c), &err);
if (err) {
error_propagate(errp, err);
@@ -363,11 +360,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
}
/* FMC, The number of CS is set at the board level */
- object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram",
+ &error_abort);
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
"sdram-base", &err);
if (err) {
@@ -388,14 +382,10 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
/* SPI */
for (i = 0; i < sc->spis_num; i++) {
object_property_set_link(OBJECT(&s->spi[i]), OBJECT(s->dram_mr),
- "dram", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err);
- sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &local_err);
- error_propagate(&err, local_err);
+ "dram", &error_abort);
+ object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs",
+ &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &err);
if (err) {
error_propagate(errp, err);
return;
@@ -445,12 +435,11 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
/* Net */
for (i = 0; i < sc->macs_num; i++) {
object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "aspeed",
- &err);
- sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), &local_err);
- error_propagate(&err, local_err);
+ &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), &err);
if (err) {
error_propagate(errp, err);
- return;
+ return;
}
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
sc->memmap[ASPEED_ETH1 + i]);
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 810cf9b..311458a 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -218,7 +218,7 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
int i;
AspeedSoCState *s = ASPEED_SOC(dev);
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
- Error *err = NULL, *local_err = NULL;
+ Error *err = NULL;
/* IO space */
create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_IOMEM],
@@ -300,11 +300,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
}
/* I2C */
- object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram",
+ &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->i2c), &err);
if (err) {
error_propagate(errp, err);
@@ -315,11 +312,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
aspeed_soc_get_irq(s, ASPEED_I2C));
/* FMC, The number of CS is set at the board level */
- object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram",
+ &error_abort);
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
"sdram-base", &err);
if (err) {
@@ -339,9 +333,9 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
/* SPI */
for (i = 0; i < sc->spis_num; i++) {
- object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs", &err);
- sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &local_err);
- error_propagate(&err, local_err);
+ object_property_set_int(OBJECT(&s->spi[i]), 1, "num-cs",
+ &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), &err);
if (err) {
error_propagate(errp, err);
return;
@@ -391,12 +385,11 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
/* Net */
for (i = 0; i < sc->macs_num; i++) {
object_property_set_bool(OBJECT(&s->ftgmac100[i]), true, "aspeed",
- &err);
- sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), &local_err);
- error_propagate(&err, local_err);
+ &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), &err);
if (err) {
error_propagate(errp, err);
- return;
+ return;
}
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
sc->memmap[ASPEED_ETH1 + i]);
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 1e975d7..7ffdf62 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -283,16 +283,12 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
* For the exact details please refer to the Arasan documentation:
* SD3.0_Host_AHB_eMMC4.4_Usersguide_ver5.9_jan11_10.pdf
*/
- object_property_set_uint(OBJECT(&s->sdhci), 3, "sd-spec-version", &err);
+ object_property_set_uint(OBJECT(&s->sdhci), 3, "sd-spec-version",
+ &error_abort);
object_property_set_uint(OBJECT(&s->sdhci), BCM2835_SDHC_CAPAREG, "capareg",
- &err);
+ &error_abort);
object_property_set_bool(OBJECT(&s->sdhci), true, "pending-insert-quirk",
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
+ &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), &err);
if (err) {
error_propagate(errp, err);
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index f32f9bc..7ab5c98 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -260,15 +260,13 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
};
object_property_set_uint(OBJECT(&s->esdhc[i]), 2, "sd-spec-version",
- &err);
+ &error_abort);
object_property_set_uint(OBJECT(&s->esdhc[i]), IMX25_ESDHC_CAPABILITIES,
- "capareg", &err);
+ "capareg",
+ &error_abort);
object_property_set_uint(OBJECT(&s->esdhc[i]), SDHCI_VENDOR_IMX,
- "vendor", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ "vendor",
+ &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->esdhc[i]), &err);
if (err) {
error_propagate(errp, err);
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
index d4bc4fa..4ae3c3e 100644
--- a/hw/arm/fsl-imx6.c
+++ b/hw/arm/fsl-imx6.c
@@ -336,15 +336,13 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
/* UHS-I SDIO3.0 SDR104 1.8V ADMA */
object_property_set_uint(OBJECT(&s->esdhc[i]), 3, "sd-spec-version",
- &err);
+ &error_abort);
object_property_set_uint(OBJECT(&s->esdhc[i]), IMX6_ESDHC_CAPABILITIES,
- "capareg", &err);
+ "capareg",
+ &error_abort);
object_property_set_uint(OBJECT(&s->esdhc[i]), SDHCI_VENDOR_IMX,
- "vendor", &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ "vendor",
+ &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->esdhc[i]), &err);
if (err) {
error_propagate(errp, err);
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
index 6446034..51b2f25 100644
--- a/hw/arm/fsl-imx6ul.c
+++ b/hw/arm/fsl-imx6ul.c
@@ -428,6 +428,9 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
};
object_property_set_uint(OBJECT(&s->eth[i]),
+ s->phy_num[i],
+ "phy-num", &error_abort);
+ object_property_set_uint(OBJECT(&s->eth[i]),
FSL_IMX6UL_ETH_NUM_TX_RINGS,
"tx-ring-num", &error_abort);
qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
@@ -607,10 +610,17 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
FSL_IMX6UL_OCRAM_ALIAS_ADDR, &s->ocram_alias);
}
+static Property fsl_imx6ul_properties[] = {
+ DEFINE_PROP_UINT32("fec1-phy-num", FslIMX6ULState, phy_num[0], 0),
+ DEFINE_PROP_UINT32("fec2-phy-num", FslIMX6ULState, phy_num[1], 1),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void fsl_imx6ul_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
+ device_class_set_props(dc, fsl_imx6ul_properties);
dc->realize = fsl_imx6ul_realize;
dc->desc = "i.MX6UL SOC";
/* Reason: Uses serial_hds and nd_table in realize() directly */
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
index 2f845ce..9033d3f 100644
--- a/hw/arm/mcimx6ul-evk.c
+++ b/hw/arm/mcimx6ul-evk.c
@@ -40,6 +40,8 @@ static void mcimx6ul_evk_init(MachineState *machine)
s = FSL_IMX6UL(object_new(TYPE_FSL_IMX6UL));
object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
+ object_property_set_uint(OBJECT(s), 2, "fec1-phy-num", &error_fatal);
+ object_property_set_uint(OBJECT(s), 1, "fec2-phy-num", &error_fatal);
qdev_realize(DEVICE(s), NULL, &error_fatal);
memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_MMDC_ADDR,
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
index 5a8961d..20dd8b5 100644
--- a/hw/arm/nrf51_soc.c
+++ b/hw/arm/nrf51_soc.c
@@ -66,11 +66,7 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
}
object_property_set_link(OBJECT(&s->cpu), OBJECT(&s->container), "memory",
- &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->cpu), &err);
if (err) {
error_propagate(errp, err);
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
index 105c5e6..ceee6aa 100644
--- a/hw/arm/pxa2xx_pic.c
+++ b/hw/arm/pxa2xx_pic.c
@@ -11,6 +11,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
+#include "qemu/log.h"
#include "cpu.h"
#include "hw/arm/pxa.h"
#include "hw/sysbus.h"
@@ -166,7 +167,9 @@ static uint64_t pxa2xx_pic_mem_read(void *opaque, hwaddr offset,
case ICHP: /* Highest Priority register */
return pxa2xx_pic_highest(s);
default:
- printf("%s: Bad register offset " REG_FMT "\n", __func__, offset);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "pxa2xx_pic_mem_read: bad register offset 0x%" HWADDR_PRIx
+ "\n", offset);
return 0;
}
}
@@ -199,7 +202,9 @@ static void pxa2xx_pic_mem_write(void *opaque, hwaddr offset,
s->priority[32 + ((offset - IPR32) >> 2)] = value & 0x8000003f;
break;
default:
- printf("%s: Bad register offset " REG_FMT "\n", __func__, offset);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "pxa2xx_pic_mem_write: bad register offset 0x%"
+ HWADDR_PRIx "\n", offset);
return;
}
pxa2xx_pic_update(opaque);
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index fc18212..f020aff 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -23,36 +23,66 @@
#include "hw/ssi/ssi.h"
#include "hw/block/flash.h"
#include "qemu/timer.h"
+#include "qemu/log.h"
#include "hw/arm/sharpsl.h"
#include "ui/console.h"
#include "hw/audio/wm8750.h"
#include "audio/audio.h"
#include "hw/boards.h"
#include "hw/sysbus.h"
+#include "hw/misc/max111x.h"
#include "migration/vmstate.h"
#include "exec/address-spaces.h"
#include "cpu.h"
-#undef REG_FMT
-#define REG_FMT "0x%02lx"
+enum spitz_model_e { spitz, akita, borzoi, terrier };
+
+typedef struct {
+ MachineClass parent;
+ enum spitz_model_e model;
+ int arm_id;
+} SpitzMachineClass;
+
+typedef struct {
+ MachineState parent;
+ PXA2xxState *mpu;
+ DeviceState *mux;
+ DeviceState *lcdtg;
+ DeviceState *ads7846;
+ DeviceState *max1111;
+ DeviceState *scp0;
+ DeviceState *scp1;
+ DeviceState *misc_gpio;
+} SpitzMachineState;
+
+#define TYPE_SPITZ_MACHINE "spitz-common"
+#define SPITZ_MACHINE(obj) \
+ OBJECT_CHECK(SpitzMachineState, obj, TYPE_SPITZ_MACHINE)
+#define SPITZ_MACHINE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(SpitzMachineClass, obj, TYPE_SPITZ_MACHINE)
+#define SPITZ_MACHINE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(SpitzMachineClass, klass, TYPE_SPITZ_MACHINE)
+
+#define zaurus_printf(format, ...) \
+ fprintf(stderr, "%s: " format, __func__, ##__VA_ARGS__)
/* Spitz Flash */
-#define FLASH_BASE 0x0c000000
-#define FLASH_ECCLPLB 0x00 /* Line parity 7 - 0 bit */
-#define FLASH_ECCLPUB 0x04 /* Line parity 15 - 8 bit */
-#define FLASH_ECCCP 0x08 /* Column parity 5 - 0 bit */
-#define FLASH_ECCCNTR 0x0c /* ECC byte counter */
-#define FLASH_ECCCLRR 0x10 /* Clear ECC */
-#define FLASH_FLASHIO 0x14 /* Flash I/O */
-#define FLASH_FLASHCTL 0x18 /* Flash Control */
-
-#define FLASHCTL_CE0 (1 << 0)
-#define FLASHCTL_CLE (1 << 1)
-#define FLASHCTL_ALE (1 << 2)
-#define FLASHCTL_WP (1 << 3)
-#define FLASHCTL_CE1 (1 << 4)
-#define FLASHCTL_RYBY (1 << 5)
-#define FLASHCTL_NCE (FLASHCTL_CE0 | FLASHCTL_CE1)
+#define FLASH_BASE 0x0c000000
+#define FLASH_ECCLPLB 0x00 /* Line parity 7 - 0 bit */
+#define FLASH_ECCLPUB 0x04 /* Line parity 15 - 8 bit */
+#define FLASH_ECCCP 0x08 /* Column parity 5 - 0 bit */
+#define FLASH_ECCCNTR 0x0c /* ECC byte counter */
+#define FLASH_ECCCLRR 0x10 /* Clear ECC */
+#define FLASH_FLASHIO 0x14 /* Flash I/O */
+#define FLASH_FLASHCTL 0x18 /* Flash Control */
+
+#define FLASHCTL_CE0 (1 << 0)
+#define FLASHCTL_CLE (1 << 1)
+#define FLASHCTL_ALE (1 << 2)
+#define FLASHCTL_WP (1 << 3)
+#define FLASHCTL_CE1 (1 << 4)
+#define FLASHCTL_RYBY (1 << 5)
+#define FLASHCTL_NCE (FLASHCTL_CE0 | FLASHCTL_CE1)
#define TYPE_SL_NAND "sl-nand"
#define SL_NAND(obj) OBJECT_CHECK(SLNANDState, (obj), TYPE_SL_NAND)
@@ -74,12 +104,12 @@ static uint64_t sl_read(void *opaque, hwaddr addr, unsigned size)
int ryby;
switch (addr) {
-#define BSHR(byte, from, to) ((s->ecc.lp[byte] >> (from - to)) & (1 << to))
+#define BSHR(byte, from, to) ((s->ecc.lp[byte] >> (from - to)) & (1 << to))
case FLASH_ECCLPLB:
return BSHR(0, 4, 0) | BSHR(0, 5, 2) | BSHR(0, 6, 4) | BSHR(0, 7, 6) |
BSHR(1, 4, 1) | BSHR(1, 5, 3) | BSHR(1, 6, 5) | BSHR(1, 7, 7);
-#define BSHL(byte, from, to) ((s->ecc.lp[byte] << (to - from)) & (1 << to))
+#define BSHL(byte, from, to) ((s->ecc.lp[byte] << (to - from)) & (1 << to))
case FLASH_ECCLPUB:
return BSHL(0, 0, 0) | BSHL(0, 1, 2) | BSHL(0, 2, 4) | BSHL(0, 3, 6) |
BSHL(1, 0, 1) | BSHL(1, 1, 3) | BSHL(1, 2, 5) | BSHL(1, 3, 7);
@@ -105,7 +135,9 @@ static uint64_t sl_read(void *opaque, hwaddr addr, unsigned size)
return ecc_digest(&s->ecc, nand_getio(s->nand));
default:
- zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "sl_read: bad register offset 0x%02" HWADDR_PRIx "\n",
+ addr);
}
return 0;
}
@@ -136,7 +168,9 @@ static void sl_write(void *opaque, hwaddr addr,
break;
default:
- zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "sl_write: bad register offset 0x%02" HWADDR_PRIx "\n",
+ addr);
}
}
@@ -191,8 +225,8 @@ static void sl_nand_realize(DeviceState *dev, Error **errp)
/* Spitz Keyboard */
-#define SPITZ_KEY_STROBE_NUM 11
-#define SPITZ_KEY_SENSE_NUM 7
+#define SPITZ_KEY_STROBE_NUM 11
+#define SPITZ_KEY_SENSE_NUM 7
static const int spitz_gpio_key_sense[SPITZ_KEY_SENSE_NUM] = {
12, 17, 91, 34, 36, 38, 39
@@ -214,11 +248,11 @@ static int spitz_keymap[SPITZ_KEY_SENSE_NUM + 1][SPITZ_KEY_STROBE_NUM] = {
{ 0x52, 0x43, 0x01, 0x47, 0x49, -1 , -1 , -1 , -1 , -1 , -1 },
};
-#define SPITZ_GPIO_AK_INT 13 /* Remote control */
-#define SPITZ_GPIO_SYNC 16 /* Sync button */
-#define SPITZ_GPIO_ON_KEY 95 /* Power button */
-#define SPITZ_GPIO_SWA 97 /* Lid */
-#define SPITZ_GPIO_SWB 96 /* Tablet mode */
+#define SPITZ_GPIO_AK_INT 13 /* Remote control */
+#define SPITZ_GPIO_SYNC 16 /* Sync button */
+#define SPITZ_GPIO_ON_KEY 95 /* Power button */
+#define SPITZ_GPIO_SWA 97 /* Lid */
+#define SPITZ_GPIO_SWB 96 /* Tablet mode */
/* The special buttons are mapped to unused keys */
static const int spitz_gpiomap[5] = {
@@ -300,7 +334,7 @@ static void spitz_keyboard_keydown(SpitzKeyboardState *s, int keycode)
#define SPITZ_MOD_CTRL (1 << 8)
#define SPITZ_MOD_FN (1 << 9)
-#define QUEUE_KEY(c) s->fifo[(s->fifopos + s->fifolen ++) & 0xf] = c
+#define QUEUE_KEY(c) s->fifo[(s->fifopos + s->fifolen ++) & 0xf] = c
static void spitz_keyboard_handler(void *opaque, int keycode)
{
@@ -308,25 +342,25 @@ static void spitz_keyboard_handler(void *opaque, int keycode)
uint16_t code;
int mapcode;
switch (keycode) {
- case 0x2a: /* Left Shift */
+ case 0x2a: /* Left Shift */
s->modifiers |= 1;
break;
case 0xaa:
s->modifiers &= ~1;
break;
- case 0x36: /* Right Shift */
+ case 0x36: /* Right Shift */
s->modifiers |= 2;
break;
case 0xb6:
s->modifiers &= ~2;
break;
- case 0x1d: /* Control */
+ case 0x1d: /* Control */
s->modifiers |= 4;
break;
case 0x9d:
s->modifiers &= ~4;
break;
- case 0x38: /* Alt */
+ case 0x38: /* Alt */
s->modifiers |= 8;
break;
case 0xb8:
@@ -536,14 +570,17 @@ static void spitz_keyboard_realize(DeviceState *dev, Error **errp)
/* LCD backlight controller */
-#define LCDTG_RESCTL 0x00
-#define LCDTG_PHACTRL 0x01
-#define LCDTG_DUTYCTRL 0x02
-#define LCDTG_POWERREG0 0x03
-#define LCDTG_POWERREG1 0x04
-#define LCDTG_GPOR3 0x05
-#define LCDTG_PICTRL 0x06
-#define LCDTG_POLCTRL 0x07
+#define LCDTG_RESCTL 0x00
+#define LCDTG_PHACTRL 0x01
+#define LCDTG_DUTYCTRL 0x02
+#define LCDTG_POWERREG0 0x03
+#define LCDTG_POWERREG1 0x04
+#define LCDTG_GPOR3 0x05
+#define LCDTG_PICTRL 0x06
+#define LCDTG_POLCTRL 0x07
+
+#define TYPE_SPITZ_LCDTG "spitz-lcdtg"
+#define SPITZ_LCDTG(obj) OBJECT_CHECK(SpitzLCDTG, (obj), TYPE_SPITZ_LCDTG)
typedef struct {
SSISlave ssidev;
@@ -559,12 +596,9 @@ static void spitz_bl_update(SpitzLCDTG *s)
zaurus_printf("LCD Backlight now off\n");
}
-/* FIXME: Implement GPIO properly and remove this hack. */
-static SpitzLCDTG *spitz_lcdtg;
-
static inline void spitz_bl_bit5(void *opaque, int line, int level)
{
- SpitzLCDTG *s = spitz_lcdtg;
+ SpitzLCDTG *s = opaque;
int prev = s->bl_intensity;
if (level)
@@ -578,14 +612,14 @@ static inline void spitz_bl_bit5(void *opaque, int line, int level)
static inline void spitz_bl_power(void *opaque, int line, int level)
{
- SpitzLCDTG *s = spitz_lcdtg;
+ SpitzLCDTG *s = opaque;
s->bl_power = !!level;
spitz_bl_update(s);
}
static uint32_t spitz_lcdtg_transfer(SSISlave *dev, uint32_t value)
{
- SpitzLCDTG *s = FROM_SSI_SLAVE(SpitzLCDTG, dev);
+ SpitzLCDTG *s = SPITZ_LCDTG(dev);
int addr;
addr = value >> 5;
value &= 0x1f;
@@ -612,25 +646,29 @@ static uint32_t spitz_lcdtg_transfer(SSISlave *dev, uint32_t value)
return 0;
}
-static void spitz_lcdtg_realize(SSISlave *dev, Error **errp)
+static void spitz_lcdtg_realize(SSISlave *ssi, Error **errp)
{
- SpitzLCDTG *s = FROM_SSI_SLAVE(SpitzLCDTG, dev);
+ SpitzLCDTG *s = SPITZ_LCDTG(ssi);
+ DeviceState *dev = DEVICE(s);
- spitz_lcdtg = s;
s->bl_power = 0;
s->bl_intensity = 0x20;
+
+ qdev_init_gpio_in_named(dev, spitz_bl_bit5, "bl_bit5", 1);
+ qdev_init_gpio_in_named(dev, spitz_bl_power, "bl_power", 1);
}
/* SSP devices */
-#define CORGI_SSP_PORT 2
+#define CORGI_SSP_PORT 2
-#define SPITZ_GPIO_LCDCON_CS 53
-#define SPITZ_GPIO_ADS7846_CS 14
-#define SPITZ_GPIO_MAX1111_CS 20
-#define SPITZ_GPIO_TP_INT 11
+#define SPITZ_GPIO_LCDCON_CS 53
+#define SPITZ_GPIO_ADS7846_CS 14
+#define SPITZ_GPIO_MAX1111_CS 20
+#define SPITZ_GPIO_TP_INT 11
-static DeviceState *max1111;
+#define TYPE_CORGI_SSP "corgi-ssp"
+#define CORGI_SSP(obj) OBJECT_CHECK(CorgiSSPState, (obj), TYPE_CORGI_SSP)
/* "Demux" the signal based on current chipselect */
typedef struct {
@@ -641,7 +679,7 @@ typedef struct {
static uint32_t corgi_ssp_transfer(SSISlave *dev, uint32_t value)
{
- CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, dev);
+ CorgiSSPState *s = CORGI_SSP(dev);
int i;
for (i = 0; i < 3; i++) {
@@ -659,29 +697,18 @@ static void corgi_ssp_gpio_cs(void *opaque, int line, int level)
s->enable[line] = !level;
}
-#define MAX1111_BATT_VOLT 1
-#define MAX1111_BATT_TEMP 2
-#define MAX1111_ACIN_VOLT 3
-
-#define SPITZ_BATTERY_TEMP 0xe0 /* About 2.9V */
-#define SPITZ_BATTERY_VOLT 0xd0 /* About 4.0V */
-#define SPITZ_CHARGEON_ACIN 0x80 /* About 5.0V */
+#define MAX1111_BATT_VOLT 1
+#define MAX1111_BATT_TEMP 2
+#define MAX1111_ACIN_VOLT 3
-static void spitz_adc_temp_on(void *opaque, int line, int level)
-{
- if (!max1111)
- return;
-
- if (level)
- max111x_set_input(max1111, MAX1111_BATT_TEMP, SPITZ_BATTERY_TEMP);
- else
- max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
-}
+#define SPITZ_BATTERY_TEMP 0xe0 /* About 2.9V */
+#define SPITZ_BATTERY_VOLT 0xd0 /* About 4.0V */
+#define SPITZ_CHARGEON_ACIN 0x80 /* About 5.0V */
static void corgi_ssp_realize(SSISlave *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
- CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, d);
+ CorgiSSPState *s = CORGI_SSP(d);
qdev_init_gpio_in(dev, corgi_ssp_gpio_cs, 3);
s->bus[0] = ssi_create_bus(dev, "ssi0");
@@ -689,34 +716,36 @@ static void corgi_ssp_realize(SSISlave *d, Error **errp)
s->bus[2] = ssi_create_bus(dev, "ssi2");
}
-static void spitz_ssp_attach(PXA2xxState *cpu)
+static void spitz_ssp_attach(SpitzMachineState *sms)
{
- DeviceState *mux;
- DeviceState *dev;
void *bus;
- mux = ssi_create_slave(cpu->ssp[CORGI_SSP_PORT - 1], "corgi-ssp");
-
- bus = qdev_get_child_bus(mux, "ssi0");
- ssi_create_slave(bus, "spitz-lcdtg");
-
- bus = qdev_get_child_bus(mux, "ssi1");
- dev = ssi_create_slave(bus, "ads7846");
- qdev_connect_gpio_out(dev, 0,
- qdev_get_gpio_in(cpu->gpio, SPITZ_GPIO_TP_INT));
-
- bus = qdev_get_child_bus(mux, "ssi2");
- max1111 = ssi_create_slave(bus, "max1111");
- max111x_set_input(max1111, MAX1111_BATT_VOLT, SPITZ_BATTERY_VOLT);
- max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
- max111x_set_input(max1111, MAX1111_ACIN_VOLT, SPITZ_CHARGEON_ACIN);
-
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_LCDCON_CS,
- qdev_get_gpio_in(mux, 0));
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_ADS7846_CS,
- qdev_get_gpio_in(mux, 1));
- qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_MAX1111_CS,
- qdev_get_gpio_in(mux, 2));
+ sms->mux = ssi_create_slave(sms->mpu->ssp[CORGI_SSP_PORT - 1],
+ TYPE_CORGI_SSP);
+
+ bus = qdev_get_child_bus(sms->mux, "ssi0");
+ sms->lcdtg = ssi_create_slave(bus, TYPE_SPITZ_LCDTG);
+
+ bus = qdev_get_child_bus(sms->mux, "ssi1");
+ sms->ads7846 = ssi_create_slave(bus, "ads7846");
+ qdev_connect_gpio_out(sms->ads7846, 0,
+ qdev_get_gpio_in(sms->mpu->gpio, SPITZ_GPIO_TP_INT));
+
+ bus = qdev_get_child_bus(sms->mux, "ssi2");
+ sms->max1111 = qdev_new(TYPE_MAX_1111);
+ qdev_prop_set_uint8(sms->max1111, "input1" /* BATT_VOLT */,
+ SPITZ_BATTERY_VOLT);
+ qdev_prop_set_uint8(sms->max1111, "input2" /* BATT_TEMP */, 0);
+ qdev_prop_set_uint8(sms->max1111, "input3" /* ACIN_VOLT */,
+ SPITZ_CHARGEON_ACIN);
+ ssi_realize_and_unref(sms->max1111, bus, &error_fatal);
+
+ qdev_connect_gpio_out(sms->mpu->gpio, SPITZ_GPIO_LCDCON_CS,
+ qdev_get_gpio_in(sms->mux, 0));
+ qdev_connect_gpio_out(sms->mpu->gpio, SPITZ_GPIO_ADS7846_CS,
+ qdev_get_gpio_in(sms->mux, 1));
+ qdev_connect_gpio_out(sms->mpu->gpio, SPITZ_GPIO_MAX1111_CS,
+ qdev_get_gpio_in(sms->mux, 2));
}
/* CF Microdrive */
@@ -735,11 +764,11 @@ static void spitz_microdrive_attach(PXA2xxState *cpu, int slot)
/* Wm8750 and Max7310 on I2C */
-#define AKITA_MAX_ADDR 0x18
-#define SPITZ_WM_ADDRL 0x1b
-#define SPITZ_WM_ADDRH 0x1a
+#define AKITA_MAX_ADDR 0x18
+#define SPITZ_WM_ADDRL 0x1b
+#define SPITZ_WM_ADDRH 0x1a
-#define SPITZ_GPIO_WM 5
+#define SPITZ_GPIO_WM 5
static void spitz_wm8750_addr(void *opaque, int line, int level)
{
@@ -779,75 +808,119 @@ static void spitz_akita_i2c_setup(PXA2xxState *cpu)
/* Other peripherals */
-static void spitz_out_switch(void *opaque, int line, int level)
+/*
+ * Encapsulation of some miscellaneous GPIO line behaviour for the Spitz boards.
+ *
+ * QEMU interface:
+ * + named GPIO inputs "green-led", "orange-led", "charging", "discharging":
+ * these currently just print messages that the line has been signalled
+ * + named GPIO input "adc-temp-on": set to cause the battery-temperature
+ * value to be passed to the max111x ADC
+ * + named GPIO output "adc-temp": the ADC value, to be wired up to the max111x
+ */
+#define TYPE_SPITZ_MISC_GPIO "spitz-misc-gpio"
+#define SPITZ_MISC_GPIO(obj) \
+ OBJECT_CHECK(SpitzMiscGPIOState, (obj), TYPE_SPITZ_MISC_GPIO)
+
+typedef struct SpitzMiscGPIOState {
+ SysBusDevice parent_obj;
+
+ qemu_irq adc_value;
+} SpitzMiscGPIOState;
+
+static void spitz_misc_charging(void *opaque, int n, int level)
{
- switch (line) {
- case 0:
- zaurus_printf("Charging %s.\n", level ? "off" : "on");
- break;
- case 1:
- zaurus_printf("Discharging %s.\n", level ? "on" : "off");
- break;
- case 2:
- zaurus_printf("Green LED %s.\n", level ? "on" : "off");
- break;
- case 3:
- zaurus_printf("Orange LED %s.\n", level ? "on" : "off");
- break;
- case 4:
- spitz_bl_bit5(opaque, line, level);
- break;
- case 5:
- spitz_bl_power(opaque, line, level);
- break;
- case 6:
- spitz_adc_temp_on(opaque, line, level);
- break;
- }
+ zaurus_printf("Charging %s.\n", level ? "off" : "on");
}
-#define SPITZ_SCP_LED_GREEN 1
-#define SPITZ_SCP_JK_B 2
-#define SPITZ_SCP_CHRG_ON 3
-#define SPITZ_SCP_MUTE_L 4
-#define SPITZ_SCP_MUTE_R 5
-#define SPITZ_SCP_CF_POWER 6
-#define SPITZ_SCP_LED_ORANGE 7
-#define SPITZ_SCP_JK_A 8
-#define SPITZ_SCP_ADC_TEMP_ON 9
-#define SPITZ_SCP2_IR_ON 1
-#define SPITZ_SCP2_AKIN_PULLUP 2
-#define SPITZ_SCP2_BACKLIGHT_CONT 7
-#define SPITZ_SCP2_BACKLIGHT_ON 8
-#define SPITZ_SCP2_MIC_BIAS 9
-
-static void spitz_scoop_gpio_setup(PXA2xxState *cpu,
- DeviceState *scp0, DeviceState *scp1)
+static void spitz_misc_discharging(void *opaque, int n, int level)
{
- qemu_irq *outsignals = qemu_allocate_irqs(spitz_out_switch, cpu, 8);
+ zaurus_printf("Discharging %s.\n", level ? "off" : "on");
+}
- qdev_connect_gpio_out(scp0, SPITZ_SCP_CHRG_ON, outsignals[0]);
- qdev_connect_gpio_out(scp0, SPITZ_SCP_JK_B, outsignals[1]);
- qdev_connect_gpio_out(scp0, SPITZ_SCP_LED_GREEN, outsignals[2]);
- qdev_connect_gpio_out(scp0, SPITZ_SCP_LED_ORANGE, outsignals[3]);
+static void spitz_misc_green_led(void *opaque, int n, int level)
+{
+ zaurus_printf("Green LED %s.\n", level ? "off" : "on");
+}
- if (scp1) {
- qdev_connect_gpio_out(scp1, SPITZ_SCP2_BACKLIGHT_CONT, outsignals[4]);
- qdev_connect_gpio_out(scp1, SPITZ_SCP2_BACKLIGHT_ON, outsignals[5]);
- }
+static void spitz_misc_orange_led(void *opaque, int n, int level)
+{
+ zaurus_printf("Orange LED %s.\n", level ? "off" : "on");
+}
+
+static void spitz_misc_adc_temp(void *opaque, int n, int level)
+{
+ SpitzMiscGPIOState *s = SPITZ_MISC_GPIO(opaque);
+ int batt_temp = level ? SPITZ_BATTERY_TEMP : 0;
- qdev_connect_gpio_out(scp0, SPITZ_SCP_ADC_TEMP_ON, outsignals[6]);
+ qemu_set_irq(s->adc_value, batt_temp);
}
-#define SPITZ_GPIO_HSYNC 22
-#define SPITZ_GPIO_SD_DETECT 9
-#define SPITZ_GPIO_SD_WP 81
-#define SPITZ_GPIO_ON_RESET 89
-#define SPITZ_GPIO_BAT_COVER 90
-#define SPITZ_GPIO_CF1_IRQ 105
-#define SPITZ_GPIO_CF1_CD 94
-#define SPITZ_GPIO_CF2_IRQ 106
-#define SPITZ_GPIO_CF2_CD 93
+static void spitz_misc_gpio_init(Object *obj)
+{
+ SpitzMiscGPIOState *s = SPITZ_MISC_GPIO(obj);
+ DeviceState *dev = DEVICE(obj);
+
+ qdev_init_gpio_in_named(dev, spitz_misc_charging, "charging", 1);
+ qdev_init_gpio_in_named(dev, spitz_misc_discharging, "discharging", 1);
+ qdev_init_gpio_in_named(dev, spitz_misc_green_led, "green-led", 1);
+ qdev_init_gpio_in_named(dev, spitz_misc_orange_led, "orange-led", 1);
+ qdev_init_gpio_in_named(dev, spitz_misc_adc_temp, "adc-temp-on", 1);
+
+ qdev_init_gpio_out_named(dev, &s->adc_value, "adc-temp", 1);
+}
+
+#define SPITZ_SCP_LED_GREEN 1
+#define SPITZ_SCP_JK_B 2
+#define SPITZ_SCP_CHRG_ON 3
+#define SPITZ_SCP_MUTE_L 4
+#define SPITZ_SCP_MUTE_R 5
+#define SPITZ_SCP_CF_POWER 6
+#define SPITZ_SCP_LED_ORANGE 7
+#define SPITZ_SCP_JK_A 8
+#define SPITZ_SCP_ADC_TEMP_ON 9
+#define SPITZ_SCP2_IR_ON 1
+#define SPITZ_SCP2_AKIN_PULLUP 2
+#define SPITZ_SCP2_BACKLIGHT_CONT 7
+#define SPITZ_SCP2_BACKLIGHT_ON 8
+#define SPITZ_SCP2_MIC_BIAS 9
+
+static void spitz_scoop_gpio_setup(SpitzMachineState *sms)
+{
+ DeviceState *miscdev = sysbus_create_simple(TYPE_SPITZ_MISC_GPIO, -1, NULL);
+
+ sms->misc_gpio = miscdev;
+
+ qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_CHRG_ON,
+ qdev_get_gpio_in_named(miscdev, "charging", 0));
+ qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_JK_B,
+ qdev_get_gpio_in_named(miscdev, "discharging", 0));
+ qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_LED_GREEN,
+ qdev_get_gpio_in_named(miscdev, "green-led", 0));
+ qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_LED_ORANGE,
+ qdev_get_gpio_in_named(miscdev, "orange-led", 0));
+ qdev_connect_gpio_out(sms->scp0, SPITZ_SCP_ADC_TEMP_ON,
+ qdev_get_gpio_in_named(miscdev, "adc-temp-on", 0));
+ qdev_connect_gpio_out_named(miscdev, "adc-temp", 0,
+ qdev_get_gpio_in(sms->max1111, MAX1111_BATT_TEMP));
+
+ if (sms->scp1) {
+ qdev_connect_gpio_out(sms->scp1, SPITZ_SCP2_BACKLIGHT_CONT,
+ qdev_get_gpio_in_named(sms->lcdtg, "bl_bit5", 0));
+ qdev_connect_gpio_out(sms->scp1, SPITZ_SCP2_BACKLIGHT_ON,
+ qdev_get_gpio_in_named(sms->lcdtg, "bl_power", 0));
+ }
+}
+
+#define SPITZ_GPIO_HSYNC 22
+#define SPITZ_GPIO_SD_DETECT 9
+#define SPITZ_GPIO_SD_WP 81
+#define SPITZ_GPIO_ON_RESET 89
+#define SPITZ_GPIO_BAT_COVER 90
+#define SPITZ_GPIO_CF1_IRQ 105
+#define SPITZ_GPIO_CF1_CD 94
+#define SPITZ_GPIO_CF2_IRQ 106
+#define SPITZ_GPIO_CF2_CD 93
static int spitz_hsync;
@@ -905,27 +978,27 @@ static void spitz_gpio_setup(PXA2xxState *cpu, int slots)
}
/* Board init. */
-enum spitz_model_e { spitz, akita, borzoi, terrier };
-
-#define SPITZ_RAM 0x04000000
-#define SPITZ_ROM 0x00800000
+#define SPITZ_RAM 0x04000000
+#define SPITZ_ROM 0x00800000
static struct arm_boot_info spitz_binfo = {
.loader_start = PXA2XX_SDRAM_BASE,
.ram_size = 0x04000000,
};
-static void spitz_common_init(MachineState *machine,
- enum spitz_model_e model, int arm_id)
+static void spitz_common_init(MachineState *machine)
{
+ SpitzMachineClass *smc = SPITZ_MACHINE_GET_CLASS(machine);
+ SpitzMachineState *sms = SPITZ_MACHINE(machine);
+ enum spitz_model_e model = smc->model;
PXA2xxState *mpu;
- DeviceState *scp0, *scp1 = NULL;
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *rom = g_new(MemoryRegion, 1);
/* Setup CPU & memory */
mpu = pxa270_init(address_space_mem, spitz_binfo.ram_size,
machine->cpu_type);
+ sms->mpu = mpu;
sl_flash_register(mpu, (model == spitz) ? FLASH_128M : FLASH_1024M);
@@ -935,14 +1008,16 @@ static void spitz_common_init(MachineState *machine,
/* Setup peripherals */
spitz_keyboard_register(mpu);
- spitz_ssp_attach(mpu);
+ spitz_ssp_attach(sms);
- scp0 = sysbus_create_simple("scoop", 0x10800000, NULL);
+ sms->scp0 = sysbus_create_simple("scoop", 0x10800000, NULL);
if (model != akita) {
- scp1 = sysbus_create_simple("scoop", 0x08800040, NULL);
+ sms->scp1 = sysbus_create_simple("scoop", 0x08800040, NULL);
+ } else {
+ sms->scp1 = NULL;
}
- spitz_scoop_gpio_setup(mpu, scp0, scp1);
+ spitz_scoop_gpio_setup(sms);
spitz_gpio_setup(mpu, (model == akita) ? 1 : 2);
@@ -958,100 +1033,100 @@ static void spitz_common_init(MachineState *machine,
/* A 4.0 GB microdrive is permanently sitting in CF slot 0. */
spitz_microdrive_attach(mpu, 0);
- spitz_binfo.board_id = arm_id;
+ spitz_binfo.board_id = smc->arm_id;
arm_load_kernel(mpu->cpu, machine, &spitz_binfo);
sl_bootparam_write(SL_PXA_PARAM_BASE);
}
-static void spitz_init(MachineState *machine)
-{
- spitz_common_init(machine, spitz, 0x2c9);
-}
-
-static void borzoi_init(MachineState *machine)
+static void spitz_common_class_init(ObjectClass *oc, void *data)
{
- spitz_common_init(machine, borzoi, 0x33f);
-}
+ MachineClass *mc = MACHINE_CLASS(oc);
-static void akita_init(MachineState *machine)
-{
- spitz_common_init(machine, akita, 0x2e8);
+ mc->block_default_type = IF_IDE;
+ mc->ignore_memory_transaction_failures = true;
+ mc->init = spitz_common_init;
}
-static void terrier_init(MachineState *machine)
-{
- spitz_common_init(machine, terrier, 0x33f);
-}
+static const TypeInfo spitz_common_info = {
+ .name = TYPE_SPITZ_MACHINE,
+ .parent = TYPE_MACHINE,
+ .abstract = true,
+ .instance_size = sizeof(SpitzMachineState),
+ .class_size = sizeof(SpitzMachineClass),
+ .class_init = spitz_common_class_init,
+};
static void akitapda_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
+ SpitzMachineClass *smc = SPITZ_MACHINE_CLASS(oc);
mc->desc = "Sharp SL-C1000 (Akita) PDA (PXA270)";
- mc->init = akita_init;
- mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
+ smc->model = akita;
+ smc->arm_id = 0x2e8;
}
static const TypeInfo akitapda_type = {
.name = MACHINE_TYPE_NAME("akita"),
- .parent = TYPE_MACHINE,
+ .parent = TYPE_SPITZ_MACHINE,
.class_init = akitapda_class_init,
};
static void spitzpda_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
+ SpitzMachineClass *smc = SPITZ_MACHINE_CLASS(oc);
mc->desc = "Sharp SL-C3000 (Spitz) PDA (PXA270)";
- mc->init = spitz_init;
- mc->block_default_type = IF_IDE;
- mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
+ smc->model = spitz;
+ smc->arm_id = 0x2c9;
}
static const TypeInfo spitzpda_type = {
.name = MACHINE_TYPE_NAME("spitz"),
- .parent = TYPE_MACHINE,
+ .parent = TYPE_SPITZ_MACHINE,
.class_init = spitzpda_class_init,
};
static void borzoipda_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
+ SpitzMachineClass *smc = SPITZ_MACHINE_CLASS(oc);
mc->desc = "Sharp SL-C3100 (Borzoi) PDA (PXA270)";
- mc->init = borzoi_init;
- mc->block_default_type = IF_IDE;
- mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
+ smc->model = borzoi;
+ smc->arm_id = 0x33f;
}
static const TypeInfo borzoipda_type = {
.name = MACHINE_TYPE_NAME("borzoi"),
- .parent = TYPE_MACHINE,
+ .parent = TYPE_SPITZ_MACHINE,
.class_init = borzoipda_class_init,
};
static void terrierpda_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
+ SpitzMachineClass *smc = SPITZ_MACHINE_CLASS(oc);
mc->desc = "Sharp SL-C3200 (Terrier) PDA (PXA270)";
- mc->init = terrier_init;
- mc->block_default_type = IF_IDE;
- mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c5");
+ smc->model = terrier;
+ smc->arm_id = 0x33f;
}
static const TypeInfo terrierpda_type = {
.name = MACHINE_TYPE_NAME("terrier"),
- .parent = TYPE_MACHINE,
+ .parent = TYPE_SPITZ_MACHINE,
.class_init = terrierpda_class_init,
};
static void spitz_machine_init(void)
{
+ type_register_static(&spitz_common_info);
type_register_static(&akitapda_type);
type_register_static(&spitzpda_type);
type_register_static(&borzoipda_type);
@@ -1152,7 +1227,7 @@ static void corgi_ssp_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo corgi_ssp_info = {
- .name = "corgi-ssp",
+ .name = TYPE_CORGI_SSP,
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(CorgiSSPState),
.class_init = corgi_ssp_class_init,
@@ -1181,18 +1256,30 @@ static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo spitz_lcdtg_info = {
- .name = "spitz-lcdtg",
+ .name = TYPE_SPITZ_LCDTG,
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(SpitzLCDTG),
.class_init = spitz_lcdtg_class_init,
};
+static const TypeInfo spitz_misc_gpio_info = {
+ .name = TYPE_SPITZ_MISC_GPIO,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(SpitzMiscGPIOState),
+ .instance_init = spitz_misc_gpio_init,
+ /*
+ * No class_init required: device has no internal state so does not
+ * need to set up reset or vmstate, and does not have a realize method.
+ */
+};
+
static void spitz_register_types(void)
{
type_register_static(&corgi_ssp_info);
type_register_static(&spitz_lcdtg_info);
type_register_static(&spitz_keyboard_info);
type_register_static(&sl_nand_info);
+ type_register_static(&spitz_misc_gpio_info);
}
type_init(spitz_register_types)
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
index 1948754..56aef68 100644
--- a/hw/arm/stm32f205_soc.c
+++ b/hw/arm/stm32f205_soc.c
@@ -154,7 +154,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
/* ADC 1 to 3 */
object_property_set_int(OBJECT(s->adc_irqs), STM_NUM_ADCS,
- "num-lines", &err);
+ "num-lines", &error_abort);
qdev_realize(DEVICE(s->adc_irqs), NULL, &err);
if (err != NULL) {
error_propagate(errp, err);
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
index c12d9f9..cf9228d 100644
--- a/hw/arm/stm32f405_soc.c
+++ b/hw/arm/stm32f405_soc.c
@@ -172,7 +172,7 @@ static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
return;
}
object_property_set_int(OBJECT(&s->adc_irqs), STM_NUM_ADCS,
- "num-lines", &err);
+ "num-lines", &error_abort);
qdev_realize(DEVICE(&s->adc_irqs), NULL, &err);
if (err != NULL) {
error_propagate(errp, err);
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 1384a2c..91f0df7 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -749,6 +749,7 @@ static void build_fadt_rev5(GArray *table_data, BIOSLinker *linker,
static void
build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
{
+ VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
Aml *scope, *dsdt;
MachineState *ms = MACHINE(vms);
const MemMapEntry *memmap = vms->memmap;
@@ -767,7 +768,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
acpi_dsdt_add_cpus(scope, vms->smp_cpus);
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
- acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
+ if (vmc->acpi_expose_flash) {
+ acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
+ }
acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]);
acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
(irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f97be80..7d9f715 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -217,11 +217,9 @@ static bool cpu_type_valid(const char *cpu)
static void create_kaslr_seed(VirtMachineState *vms, const char *node)
{
- Error *err = NULL;
uint64_t seed;
- if (qemu_guest_getrandom(&seed, sizeof(seed), &err)) {
- error_free(err);
+ if (qemu_guest_getrandom(&seed, sizeof(seed), NULL)) {
return;
}
qemu_fdt_setprop_u64(vms->fdt, node, "kaslr-seed", seed);
@@ -602,6 +600,7 @@ static void create_its(VirtMachineState *vms)
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_ITS].base);
fdt_add_its_gic_node(vms);
+ vms->msi_controller = VIRT_MSI_CTRL_ITS;
}
static void create_v2m(VirtMachineState *vms)
@@ -622,6 +621,7 @@ static void create_v2m(VirtMachineState *vms)
}
fdt_add_v2m_gic_node(vms);
+ vms->msi_controller = VIRT_MSI_CTRL_GICV2M;
}
static void create_gic(VirtMachineState *vms)
@@ -2200,8 +2200,36 @@ out:
static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
+
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
virt_memory_pre_plug(hotplug_dev, dev, errp);
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
+ hwaddr db_start = 0, db_end = 0;
+ char *resv_prop_str;
+
+ switch (vms->msi_controller) {
+ case VIRT_MSI_CTRL_NONE:
+ return;
+ case VIRT_MSI_CTRL_ITS:
+ /* GITS_TRANSLATER page */
+ db_start = base_memmap[VIRT_GIC_ITS].base + 0x10000;
+ db_end = base_memmap[VIRT_GIC_ITS].base +
+ base_memmap[VIRT_GIC_ITS].size - 1;
+ break;
+ case VIRT_MSI_CTRL_GICV2M:
+ /* MSI_SETSPI_NS page */
+ db_start = base_memmap[VIRT_GIC_V2M].base;
+ db_end = db_start + base_memmap[VIRT_GIC_V2M].size - 1;
+ break;
+ }
+ resv_prop_str = g_strdup_printf("0x%"PRIx64":0x%"PRIx64":%u",
+ db_start, db_end,
+ VIRTIO_IOMMU_RESV_MEM_T_MSI);
+
+ qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
+ qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
+ g_free(resv_prop_str);
}
}
@@ -2483,9 +2511,12 @@ DEFINE_VIRT_MACHINE_AS_LATEST(5, 1)
static void virt_machine_5_0_options(MachineClass *mc)
{
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
+
virt_machine_5_1_options(mc);
compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
mc->numa_mem_supported = true;
+ vmc->acpi_expose_flash = true;
mc->auto_enable_numa_with_memdev = false;
}
DEFINE_VIRT_MACHINE(5, 0)
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index a0f4095..e1f22f5 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -111,9 +111,12 @@ typedef struct {
int pos;
} ZipitLCD;
+#define TYPE_ZIPIT_LCD "zipit-lcd"
+#define ZIPIT_LCD(obj) OBJECT_CHECK(ZipitLCD, (obj), TYPE_ZIPIT_LCD)
+
static uint32_t zipit_lcd_transfer(SSISlave *dev, uint32_t value)
{
- ZipitLCD *z = FROM_SSI_SLAVE(ZipitLCD, dev);
+ ZipitLCD *z = ZIPIT_LCD(dev);
uint16_t val;
if (z->selected) {
z->buf[z->pos] = value & 0xff;
@@ -153,7 +156,7 @@ static void z2_lcd_cs(void *opaque, int line, int level)
static void zipit_lcd_realize(SSISlave *dev, Error **errp)
{
- ZipitLCD *z = FROM_SSI_SLAVE(ZipitLCD, dev);
+ ZipitLCD *z = ZIPIT_LCD(dev);
z->selected = 0;
z->enabled = 0;
z->pos = 0;
@@ -185,7 +188,7 @@ static void zipit_lcd_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo zipit_lcd_info = {
- .name = "zipit-lcd",
+ .name = TYPE_ZIPIT_LCD,
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(ZipitLCD),
.class_init = zipit_lcd_class_init,
@@ -325,7 +328,7 @@ static void z2_init(MachineState *machine)
type_register_static(&zipit_lcd_info);
type_register_static(&aer915_info);
- z2_lcd = ssi_create_slave(mpu->ssp[1], "zipit-lcd");
+ z2_lcd = ssi_create_slave(mpu->ssp[1], TYPE_ZIPIT_LCD);
bus = pxa2xx_i2c_bus(mpu->i2c[0]);
i2c_create_slave(bus, TYPE_AER915, 0x55);
wm = i2c_create_slave(bus, TYPE_WM8750, 0x1b);
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 262089c..f9a4428 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -1056,7 +1056,7 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
/* Spawn a new virtio-serial bus on which the ports will ride as devices */
qbus_create_inplace(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
dev, vdev->bus_name);
- qbus_set_hotplug_handler(BUS(&vser->bus), OBJECT(vser), errp);
+ qbus_set_hotplug_handler(BUS(&vser->bus), OBJECT(vser));
vser->bus.vser = vser;
QTAILQ_INIT(&vser->ports);
@@ -1147,7 +1147,7 @@ static void virtio_serial_device_unrealize(DeviceState *dev)
g_free(vser->post_load);
}
- qbus_set_hotplug_handler(BUS(&vser->bus), NULL, &error_abort);
+ qbus_set_hotplug_handler(BUS(&vser->bus), NULL);
virtio_cleanup(vdev);
}
diff --git a/hw/core/bus.c b/hw/core/bus.c
index 6cc28b3..544dd8a 100644
--- a/hw/core/bus.c
+++ b/hw/core/bus.c
@@ -23,15 +23,15 @@
#include "qemu/module.h"
#include "qapi/error.h"
-void qbus_set_hotplug_handler(BusState *bus, Object *handler, Error **errp)
+void qbus_set_hotplug_handler(BusState *bus, Object *handler)
{
object_property_set_link(OBJECT(bus), handler,
- QDEV_HOTPLUG_HANDLER_PROPERTY, errp);
+ QDEV_HOTPLUG_HANDLER_PROPERTY, &error_abort);
}
-void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp)
+void qbus_set_bus_hotplug_handler(BusState *bus)
{
- qbus_set_hotplug_handler(bus, OBJECT(bus), errp);
+ qbus_set_hotplug_handler(bus, OBJECT(bus));
}
int qbus_walk_children(BusState *bus,
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 71f8aca..ca7771f 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -15,6 +15,7 @@
#include "chardev/char.h"
#include "qemu/uuid.h"
#include "qemu/units.h"
+#include "qemu/cutils.h"
void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
Error **errp)
@@ -578,6 +579,94 @@ const PropertyInfo qdev_prop_macaddr = {
.set = set_mac,
};
+/* --- Reserved Region --- */
+
+/*
+ * Accepted syntax:
+ * <low address>:<high address>:<type>
+ * where low/high addresses are uint64_t in hexadecimal
+ * and type is a non-negative decimal integer
+ */
+static void get_reserved_region(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
+ char buffer[64];
+ char *p = buffer;
+ int rc;
+
+ rc = snprintf(buffer, sizeof(buffer), "0x%"PRIx64":0x%"PRIx64":%u",
+ rr->low, rr->high, rr->type);
+ assert(rc < sizeof(buffer));
+
+ visit_type_str(v, name, &p, errp);
+}
+
+static void set_reserved_region(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ ReservedRegion *rr = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
+ const char *endptr;
+ char *str;
+ int ret;
+
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
+ }
+
+ visit_type_str(v, name, &str, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ ret = qemu_strtou64(str, &endptr, 16, &rr->low);
+ if (ret) {
+ error_setg(errp, "start address of '%s'"
+ " must be a hexadecimal integer", name);
+ goto out;
+ }
+ if (*endptr != ':') {
+ goto separator_error;
+ }
+
+ ret = qemu_strtou64(endptr + 1, &endptr, 16, &rr->high);
+ if (ret) {
+ error_setg(errp, "end address of '%s'"
+ " must be a hexadecimal integer", name);
+ goto out;
+ }
+ if (*endptr != ':') {
+ goto separator_error;
+ }
+
+ ret = qemu_strtoui(endptr + 1, &endptr, 10, &rr->type);
+ if (ret) {
+ error_setg(errp, "type of '%s'"
+ " must be a non-negative decimal integer", name);
+ }
+ goto out;
+
+separator_error:
+ error_setg(errp, "reserved region fields must be separated with ':'");
+out:
+ g_free(str);
+ return;
+}
+
+const PropertyInfo qdev_prop_reserved_region = {
+ .name = "reserved_region",
+ .description = "Reserved Region, example: 0xFEE00000:0xFEEFFFFF:0",
+ .get = get_reserved_region,
+ .set = set_reserved_region,
+};
+
/* --- on/off/auto --- */
const PropertyInfo qdev_prop_on_off_auto = {
diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c
index 9228b40..56bf82f 100644
--- a/hw/display/ads7846.c
+++ b/hw/display/ads7846.c
@@ -29,6 +29,9 @@ typedef struct {
int output;
} ADS7846State;
+#define TYPE_ADS7846 "ads7846"
+#define ADS7846(obj) OBJECT_CHECK(ADS7846State, (obj), TYPE_ADS7846)
+
/* Control-byte bitfields */
#define CB_PD0 (1 << 0)
#define CB_PD1 (1 << 1)
@@ -61,7 +64,7 @@ static void ads7846_int_update(ADS7846State *s)
static uint32_t ads7846_transfer(SSISlave *dev, uint32_t value)
{
- ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
+ ADS7846State *s = ADS7846(dev);
switch (s->cycle ++) {
case 0:
@@ -139,7 +142,7 @@ static const VMStateDescription vmstate_ads7846 = {
static void ads7846_realize(SSISlave *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
- ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, d);
+ ADS7846State *s = ADS7846(d);
qdev_init_gpio_out(dev, &s->interrupt, 1);
@@ -166,7 +169,7 @@ static void ads7846_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo ads7846_info = {
- .name = "ads7846",
+ .name = TYPE_ADS7846,
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(ADS7846State),
.class_init = ads7846_class_init,
diff --git a/hw/display/ati.c b/hw/display/ati.c
index 7216f7e..4c3ad8f 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -86,8 +86,8 @@ static void ati_vga_switch_mode(ATIVGAState *s)
break;
default:
qemu_log_mask(LOG_UNIMP, "Unsupported bpp value\n");
+ return;
}
- assert(bpp != 0);
DPRINTF("Switching to %dx%d %d %d @ %x\n", h, v, stride, bpp, offs);
vbe_ioport_write_index(&s->vga, 0, VBE_DISPI_INDEX_ENABLE);
vbe_ioport_write_data(&s->vga, 0, VBE_DISPI_DISABLED);
@@ -361,6 +361,11 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
case MC_STATUS:
val = 5;
break;
+ case MEM_SDRAM_MODE_REG:
+ if (s->dev_id != PCI_DEVICE_ID_ATI_RAGE128_PF) {
+ val = BIT(28) | BIT(20);
+ }
+ break;
case RBBM_STATUS:
case GUI_STAT:
val = 64; /* free CMDFIFO entries */
@@ -389,22 +394,28 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, unsigned int size)
case 0xf00 ... 0xfff:
val = pci_default_read_config(&s->dev, addr - 0xf00, size);
break;
- case CUR_OFFSET:
- val = s->regs.cur_offset;
+ case CUR_OFFSET ... CUR_OFFSET + 3:
+ val = ati_reg_read_offs(s->regs.cur_offset, addr - CUR_OFFSET, size);
break;
- case CUR_HORZ_VERT_POSN:
- val = s->regs.cur_hv_pos;
- val |= s->regs.cur_offset & BIT(31);
+ case CUR_HORZ_VERT_POSN ... CUR_HORZ_VERT_POSN + 3:
+ val = ati_reg_read_offs(s->regs.cur_hv_pos,
+ addr - CUR_HORZ_VERT_POSN, size);
+ if (addr + size > CUR_HORZ_VERT_POSN + 3) {
+ val |= (s->regs.cur_offset & BIT(31)) >> (4 - size);
+ }
break;
- case CUR_HORZ_VERT_OFF:
- val = s->regs.cur_hv_offs;
- val |= s->regs.cur_offset & BIT(31);
+ case CUR_HORZ_VERT_OFF ... CUR_HORZ_VERT_OFF + 3:
+ val = ati_reg_read_offs(s->regs.cur_hv_offs,
+ addr - CUR_HORZ_VERT_OFF, size);
+ if (addr + size > CUR_HORZ_VERT_OFF + 3) {
+ val |= (s->regs.cur_offset & BIT(31)) >> (4 - size);
+ }
break;
- case CUR_CLR0:
- val = s->regs.cur_color0;
+ case CUR_CLR0 ... CUR_CLR0 + 3:
+ val = ati_reg_read_offs(s->regs.cur_color0, addr - CUR_CLR0, size);
break;
- case CUR_CLR1:
- val = s->regs.cur_color1;
+ case CUR_CLR1 ... CUR_CLR1 + 3:
+ val = ati_reg_read_offs(s->regs.cur_color1, addr - CUR_CLR1, size);
break;
case DST_OFFSET:
val = s->regs.dst_offset;
@@ -679,48 +690,71 @@ static void ati_mm_write(void *opaque, hwaddr addr,
case 0xf00 ... 0xfff:
/* read-only copy of PCI config space so ignore writes */
break;
- case CUR_OFFSET:
- if (s->regs.cur_offset != (data & 0x87fffff0)) {
- s->regs.cur_offset = data & 0x87fffff0;
+ case CUR_OFFSET ... CUR_OFFSET + 3:
+ {
+ uint32_t t = s->regs.cur_offset;
+
+ ati_reg_write_offs(&t, addr - CUR_OFFSET, data, size);
+ t &= 0x87fffff0;
+ if (s->regs.cur_offset != t) {
+ s->regs.cur_offset = t;
ati_cursor_define(s);
}
break;
- case CUR_HORZ_VERT_POSN:
- s->regs.cur_hv_pos = data & 0x3fff0fff;
- if (data & BIT(31)) {
- s->regs.cur_offset |= data & BIT(31);
+ }
+ case CUR_HORZ_VERT_POSN ... CUR_HORZ_VERT_POSN + 3:
+ {
+ uint32_t t = s->regs.cur_hv_pos | (s->regs.cur_offset & BIT(31));
+
+ ati_reg_write_offs(&t, addr - CUR_HORZ_VERT_POSN, data, size);
+ s->regs.cur_hv_pos = t & 0x3fff0fff;
+ if (t & BIT(31)) {
+ s->regs.cur_offset |= t & BIT(31);
} else if (s->regs.cur_offset & BIT(31)) {
s->regs.cur_offset &= ~BIT(31);
ati_cursor_define(s);
}
if (!s->cursor_guest_mode &&
- (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) && !(data & BIT(31))) {
+ (s->regs.crtc_gen_cntl & CRTC2_CUR_EN) && !(t & BIT(31))) {
dpy_mouse_set(s->vga.con, s->regs.cur_hv_pos >> 16,
s->regs.cur_hv_pos & 0xffff, 1);
}
break;
+ }
case CUR_HORZ_VERT_OFF:
- s->regs.cur_hv_offs = data & 0x3f003f;
- if (data & BIT(31)) {
- s->regs.cur_offset |= data & BIT(31);
+ {
+ uint32_t t = s->regs.cur_hv_offs | (s->regs.cur_offset & BIT(31));
+
+ ati_reg_write_offs(&t, addr - CUR_HORZ_VERT_OFF, data, size);
+ s->regs.cur_hv_offs = t & 0x3f003f;
+ if (t & BIT(31)) {
+ s->regs.cur_offset |= t & BIT(31);
} else if (s->regs.cur_offset & BIT(31)) {
s->regs.cur_offset &= ~BIT(31);
ati_cursor_define(s);
}
break;
- case CUR_CLR0:
- if (s->regs.cur_color0 != (data & 0xffffff)) {
- s->regs.cur_color0 = data & 0xffffff;
+ }
+ case CUR_CLR0 ... CUR_CLR0 + 3:
+ {
+ uint32_t t = s->regs.cur_color0;
+
+ ati_reg_write_offs(&t, addr - CUR_CLR0, data, size);
+ t &= 0xffffff;
+ if (s->regs.cur_color0 != t) {
+ s->regs.cur_color0 = t;
ati_cursor_define(s);
}
break;
- case CUR_CLR1:
+ }
+ case CUR_CLR1 ... CUR_CLR1 + 3:
/*
* Update cursor unconditionally here because some clients set up
* other registers before actually writing cursor data to memory at
* offset so we would miss cursor change unless always updating here
*/
- s->regs.cur_color1 = data & 0xffffff;
+ ati_reg_write_offs(&s->regs.cur_color1, addr - CUR_CLR1, data, size);
+ s->regs.cur_color1 &= 0xffffff;
ati_cursor_define(s);
break;
case DST_OFFSET:
diff --git a/hw/display/ati_dbg.c b/hw/display/ati_dbg.c
index 0ebbd36..bd0ecd4 100644
--- a/hw/display/ati_dbg.c
+++ b/hw/display/ati_dbg.c
@@ -42,6 +42,7 @@ static struct ati_regdesc ati_reg_names[] = {
{"MC_FB_LOCATION", 0x0148},
{"MC_AGP_LOCATION", 0x014C},
{"MC_STATUS", 0x0150},
+ {"MEM_SDRAM_MODE_REG", 0x0158},
{"MEM_POWER_MISC", 0x015c},
{"AGP_BASE", 0x0170},
{"AGP_CNTL", 0x0174},
diff --git a/hw/display/ati_regs.h b/hw/display/ati_regs.h
index ebd37ee..d6282b2 100644
--- a/hw/display/ati_regs.h
+++ b/hw/display/ati_regs.h
@@ -60,6 +60,7 @@
#define MC_FB_LOCATION 0x0148
#define MC_AGP_LOCATION 0x014C
#define MC_STATUS 0x0150
+#define MEM_SDRAM_MODE_REG 0x0158
#define MEM_POWER_MISC 0x015c
#define AGP_BASE 0x0170
#define AGP_CNTL 0x0174
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
index c626380..7c0e5ee 100644
--- a/hw/display/bcm2835_fb.c
+++ b/hw/display/bcm2835_fb.c
@@ -282,6 +282,10 @@ static void bcm2835_fb_mbox_push(BCM2835FBState *s, uint32_t value)
newconf.base = s->vcram_base | (value & 0xc0000000);
newconf.base += BCM2835_FB_OFFSET;
+ /* Copy fields which we don't want to change from the existing config */
+ newconf.pixo = s->config.pixo;
+ newconf.alpha = s->config.alpha;
+
bcm2835_fb_validate_config(&newconf);
pitch = bcm2835_fb_get_pitch(&newconf);
diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index a7fc08c..9cccc68 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -39,15 +39,7 @@
#include "qemu/range.h"
#include "ui/pixel_ops.h"
#include "qemu/bswap.h"
-
-/*#define DEBUG_SM501*/
-/*#define DEBUG_BITBLT*/
-
-#ifdef DEBUG_SM501
-#define SM501_DPRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
-#else
-#define SM501_DPRINTF(fmt, ...) do {} while (0)
-#endif
+#include "trace.h"
#define MMIO_BASE_OFFSET 0x3e00000
#define MMIO_SIZE 0x200000
@@ -684,10 +676,11 @@ static void sm501_2d_operation(SM501State *s)
{
int cmd = (s->twoD_control >> 16) & 0x1F;
int rtl = s->twoD_control & BIT(27);
- int format = (s->twoD_stretch >> 20) & 0x3;
- int rop_mode = (s->twoD_control >> 15) & 0x1; /* 1 for rop2, else rop3 */
+ int format = (s->twoD_stretch >> 20) & 3;
+ int bypp = 1 << format; /* bytes per pixel */
+ int rop_mode = (s->twoD_control >> 15) & 1; /* 1 for rop2, else rop3 */
/* 1 if rop2 source is the pattern, otherwise the source is the bitmap */
- int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1;
+ int rop2_source_is_pattern = (s->twoD_control >> 14) & 1;
int rop = s->twoD_control & 0xFF;
unsigned int dst_x = (s->twoD_destination >> 16) & 0x01FFF;
unsigned int dst_y = s->twoD_destination & 0xFFFF;
@@ -697,6 +690,7 @@ static void sm501_2d_operation(SM501State *s)
unsigned int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF;
int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt);
+ bool overlap = false;
if ((s->twoD_stretch >> 16) & 0xF) {
qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n");
@@ -723,9 +717,9 @@ static void sm501_2d_operation(SM501State *s)
dst_y -= height - 1;
}
- if (dst_base >= get_local_mem_size(s) || dst_base +
- (dst_x + width + (dst_y + height) * (dst_pitch + width)) *
- (1 << format) >= get_local_mem_size(s)) {
+ if (dst_base >= get_local_mem_size(s) ||
+ dst_base + (dst_x + width + (dst_y + height) * dst_pitch) * bypp >=
+ get_local_mem_size(s)) {
qemu_log_mask(LOG_GUEST_ERROR, "sm501: 2D op dest is outside vram.\n");
return;
}
@@ -749,9 +743,9 @@ static void sm501_2d_operation(SM501State *s)
src_y -= height - 1;
}
- if (src_base >= get_local_mem_size(s) || src_base +
- (src_x + width + (src_y + height) * (src_pitch + width)) *
- (1 << format) >= get_local_mem_size(s)) {
+ if (src_base >= get_local_mem_size(s) ||
+ src_base + (src_x + width + (src_y + height) * src_pitch) * bypp >=
+ get_local_mem_size(s)) {
qemu_log_mask(LOG_GUEST_ERROR,
"sm501: 2D op src is outside vram.\n");
return;
@@ -763,19 +757,9 @@ static void sm501_2d_operation(SM501State *s)
uint8_t *d = s->local_mem + dst_base;
for (y = 0; y < height; y++) {
- i = (dst_x + (dst_y + y) * dst_pitch) * (1 << format);
- for (x = 0; x < width; x++, i += (1 << format)) {
- switch (format) {
- case 0:
- d[i] = ~d[i];
- break;
- case 1:
- *(uint16_t *)&d[i] = ~*(uint16_t *)&d[i];
- break;
- case 2:
- *(uint32_t *)&d[i] = ~*(uint32_t *)&d[i];
- break;
- }
+ i = (dst_x + (dst_y + y) * dst_pitch) * bypp;
+ for (x = 0; x < width; x++, i += bypp) {
+ stn_he_p(&d[i], bypp, ~ldn_he_p(&d[i], bypp));
}
}
} else {
@@ -788,40 +772,57 @@ static void sm501_2d_operation(SM501State *s)
(rop2_source_is_pattern ?
" with pattern source" : ""));
}
- /* Check for overlaps, this could be made more exact */
- uint32_t sb, se, db, de;
- sb = src_base + src_x + src_y * (width + src_pitch);
- se = sb + width + height * (width + src_pitch);
- db = dst_base + dst_x + dst_y * (width + dst_pitch);
- de = db + width + height * (width + dst_pitch);
- if (rtl && ((db >= sb && db <= se) || (de >= sb && de <= se))) {
- /* regions may overlap: copy via temporary */
- int free_buf = 0, llb = width * (1 << format);
- int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t));
+ /* Ignore no-op blits, some guests seem to do this */
+ if (src_base == dst_base && src_pitch == dst_pitch &&
+ src_x == dst_x && src_y == dst_y) {
+ break;
+ }
+ /* Some clients also do 1 pixel blits, avoid overhead for these */
+ if (width == 1 && height == 1) {
+ unsigned int si = (src_x + src_y * src_pitch) * bypp;
+ unsigned int di = (dst_x + dst_y * dst_pitch) * bypp;
+ stn_he_p(&s->local_mem[dst_base + di], bypp,
+ ldn_he_p(&s->local_mem[src_base + si], bypp));
+ break;
+ }
+ /* If reverse blit do simple check for overlaps */
+ if (rtl && src_base == dst_base && src_pitch == dst_pitch) {
+ overlap = (src_x < dst_x + width && src_x + width > dst_x &&
+ src_y < dst_y + height && src_y + height > dst_y);
+ } else if (rtl) {
+ unsigned int sb, se, db, de;
+ sb = src_base + (src_x + src_y * src_pitch) * bypp;
+ se = sb + (width + (height - 1) * src_pitch) * bypp;
+ db = dst_base + (dst_x + dst_y * dst_pitch) * bypp;
+ de = db + (width + (height - 1) * dst_pitch) * bypp;
+ overlap = (db < se && sb < de);
+ }
+ if (overlap) {
+ /* pixman can't do reverse blit: copy via temporary */
+ int tmp_stride = DIV_ROUND_UP(width * bypp, sizeof(uint32_t));
uint32_t *tmp = tmp_buf;
if (tmp_stride * sizeof(uint32_t) * height > sizeof(tmp_buf)) {
tmp = g_malloc(tmp_stride * sizeof(uint32_t) * height);
- free_buf = 1;
}
pixman_blt((uint32_t *)&s->local_mem[src_base], tmp,
- src_pitch * (1 << format) / sizeof(uint32_t),
- tmp_stride, 8 * (1 << format), 8 * (1 << format),
+ src_pitch * bypp / sizeof(uint32_t),
+ tmp_stride, 8 * bypp, 8 * bypp,
src_x, src_y, 0, 0, width, height);
pixman_blt(tmp, (uint32_t *)&s->local_mem[dst_base],
tmp_stride,
- dst_pitch * (1 << format) / sizeof(uint32_t),
- 8 * (1 << format), 8 * (1 << format),
+ dst_pitch * bypp / sizeof(uint32_t),
+ 8 * bypp, 8 * bypp,
0, 0, dst_x, dst_y, width, height);
- if (free_buf) {
+ if (tmp != tmp_buf) {
g_free(tmp);
}
} else {
pixman_blt((uint32_t *)&s->local_mem[src_base],
(uint32_t *)&s->local_mem[dst_base],
- src_pitch * (1 << format) / sizeof(uint32_t),
- dst_pitch * (1 << format) / sizeof(uint32_t),
- 8 * (1 << format), 8 * (1 << format),
+ src_pitch * bypp / sizeof(uint32_t),
+ dst_pitch * bypp / sizeof(uint32_t),
+ 8 * bypp, 8 * bypp,
src_x, src_y, dst_x, dst_y, width, height);
}
}
@@ -837,9 +838,14 @@ static void sm501_2d_operation(SM501State *s)
color = cpu_to_le16(color);
}
- pixman_fill((uint32_t *)&s->local_mem[dst_base],
- dst_pitch * (1 << format) / sizeof(uint32_t),
- 8 * (1 << format), dst_x, dst_y, width, height, color);
+ if (width == 1 && height == 1) {
+ unsigned int i = (dst_x + dst_y * dst_pitch) * bypp;
+ stn_he_p(&s->local_mem[dst_base + i], bypp, color);
+ } else {
+ pixman_fill((uint32_t *)&s->local_mem[dst_base],
+ dst_pitch * bypp / sizeof(uint32_t),
+ 8 * bypp, dst_x, dst_y, width, height, color);
+ }
break;
}
default:
@@ -851,7 +857,7 @@ static void sm501_2d_operation(SM501State *s)
if (dst_base >= get_fb_addr(s, crt) &&
dst_base <= get_fb_addr(s, crt) + fb_len) {
int dst_len = MIN(fb_len, ((dst_y + height - 1) * dst_pitch +
- dst_x + width) * (1 << format));
+ dst_x + width) * bypp);
if (dst_len) {
memory_region_set_dirty(&s->local_mem_region, dst_base, dst_len);
}
@@ -863,7 +869,6 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
{
SM501State *s = (SM501State *)opaque;
uint32_t ret = 0;
- SM501_DPRINTF("sm501 system config regs : read addr=%x\n", (int)addr);
switch (addr) {
case SM501_SYSTEM_CONTROL:
@@ -915,7 +920,7 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
qemu_log_mask(LOG_UNIMP, "sm501: not implemented system config"
"register read. addr=%" HWADDR_PRIx "\n", addr);
}
-
+ trace_sm501_system_config_read(addr, ret);
return ret;
}
@@ -923,9 +928,8 @@ static void sm501_system_config_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 system config regs : write addr=%x, val=%x\n",
- (uint32_t)addr, (uint32_t)value);
+ trace_sm501_system_config_write((uint32_t)addr, (uint32_t)value);
switch (addr) {
case SM501_SYSTEM_CONTROL:
s->system_control &= 0x10DB0000;
@@ -1011,9 +1015,7 @@ static uint64_t sm501_i2c_read(void *opaque, hwaddr addr, unsigned size)
qemu_log_mask(LOG_UNIMP, "sm501 i2c : not implemented register read."
" addr=0x%" HWADDR_PRIx "\n", addr);
}
-
- SM501_DPRINTF("sm501 i2c regs : read addr=%" HWADDR_PRIx " val=%x\n",
- addr, ret);
+ trace_sm501_i2c_read((uint32_t)addr, ret);
return ret;
}
@@ -1021,9 +1023,8 @@ static void sm501_i2c_write(void *opaque, hwaddr addr, uint64_t value,
unsigned size)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 i2c regs : write addr=%" HWADDR_PRIx
- " val=%" PRIx64 "\n", addr, value);
+ trace_sm501_i2c_write((uint32_t)addr, (uint32_t)value);
switch (addr) {
case SM501_I2C_BYTE_COUNT:
s->i2c_byte_count = value & 0xf;
@@ -1037,25 +1038,19 @@ static void sm501_i2c_write(void *opaque, hwaddr addr, uint64_t value,
s->i2c_status |= (res ? SM501_I2C_STATUS_ERROR : 0);
if (!res) {
int i;
- SM501_DPRINTF("sm501 i2c : transferring %d bytes to 0x%x\n",
- s->i2c_byte_count + 1, s->i2c_addr >> 1);
for (i = 0; i <= s->i2c_byte_count; i++) {
res = i2c_send_recv(s->i2c_bus, &s->i2c_data[i],
!(s->i2c_addr & 1));
if (res) {
- SM501_DPRINTF("sm501 i2c : transfer failed"
- " i=%d, res=%d\n", i, res);
s->i2c_status |= SM501_I2C_STATUS_ERROR;
return;
}
}
if (i) {
- SM501_DPRINTF("sm501 i2c : transferred %d bytes\n", i);
s->i2c_status = SM501_I2C_STATUS_COMPLETE;
}
}
} else {
- SM501_DPRINTF("sm501 i2c : end transfer\n");
i2c_end_transfer(s->i2c_bus);
s->i2c_status &= ~SM501_I2C_STATUS_ERROR;
}
@@ -1095,7 +1090,8 @@ static const MemoryRegionOps sm501_i2c_ops = {
static uint32_t sm501_palette_read(void *opaque, hwaddr addr)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 palette read addr=%x\n", (int)addr);
+
+ trace_sm501_palette_read((uint32_t)addr);
/* TODO : consider BYTE/WORD access */
/* TODO : consider endian */
@@ -1108,8 +1104,8 @@ static void sm501_palette_write(void *opaque, hwaddr addr,
uint32_t value)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 palette write addr=%x, val=%x\n",
- (int)addr, value);
+
+ trace_sm501_palette_write((uint32_t)addr, value);
/* TODO : consider BYTE/WORD access */
/* TODO : consider endian */
@@ -1124,7 +1120,6 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr,
{
SM501State *s = (SM501State *)opaque;
uint32_t ret = 0;
- SM501_DPRINTF("sm501 disp ctrl regs : read addr=%x\n", (int)addr);
switch (addr) {
@@ -1229,7 +1224,7 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr,
qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register "
"read. addr=%" HWADDR_PRIx "\n", addr);
}
-
+ trace_sm501_disp_ctrl_read((uint32_t)addr, ret);
return ret;
}
@@ -1237,9 +1232,8 @@ static void sm501_disp_ctrl_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 disp ctrl regs : write addr=%x, val=%x\n",
- (unsigned)addr, (unsigned)value);
+ trace_sm501_disp_ctrl_write((uint32_t)addr, (uint32_t)value);
switch (addr) {
case SM501_DC_PANEL_CONTROL:
s->dc_panel_control = value & 0x0FFF73FF;
@@ -1384,7 +1378,6 @@ static uint64_t sm501_2d_engine_read(void *opaque, hwaddr addr,
{
SM501State *s = (SM501State *)opaque;
uint32_t ret = 0;
- SM501_DPRINTF("sm501 2d engine regs : read addr=%x\n", (int)addr);
switch (addr) {
case SM501_2D_SOURCE:
@@ -1454,7 +1447,7 @@ static uint64_t sm501_2d_engine_read(void *opaque, hwaddr addr,
qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register "
"read. addr=%" HWADDR_PRIx "\n", addr);
}
-
+ trace_sm501_2d_engine_read((uint32_t)addr, ret);
return ret;
}
@@ -1462,9 +1455,8 @@ static void sm501_2d_engine_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
SM501State *s = (SM501State *)opaque;
- SM501_DPRINTF("sm501 2d engine regs : write addr=%x, val=%x\n",
- (unsigned)addr, (unsigned)value);
+ trace_sm501_2d_engine_write((uint32_t)addr, (uint32_t)value);
switch (addr) {
case SM501_2D_SOURCE:
s->twoD_source = value;
@@ -1495,6 +1487,9 @@ static void sm501_2d_engine_write(void *opaque, hwaddr addr,
s->twoD_background = value;
break;
case SM501_2D_STRETCH:
+ if (((value >> 20) & 3) == 3) {
+ value &= ~BIT(20);
+ }
s->twoD_stretch = value;
break;
case SM501_2D_COLOR_COMPARE:
@@ -1819,8 +1814,6 @@ static void sm501_init(SM501State *s, DeviceState *dev,
uint32_t local_mem_bytes)
{
s->local_mem_size_index = get_local_mem_size_index(local_mem_bytes);
- SM501_DPRINTF("sm501 local mem size=%x. index=%d\n", get_local_mem_size(s),
- s->local_mem_size_index);
/* local memory */
memory_region_init_ram(&s->local_mem_region, OBJECT(dev), "sm501.local",
diff --git a/hw/display/ssd0323.c b/hw/display/ssd0323.c
index c3bdb18..32d27f0 100644
--- a/hw/display/ssd0323.c
+++ b/hw/display/ssd0323.c
@@ -66,9 +66,13 @@ typedef struct {
uint8_t framebuffer[128 * 80 / 2];
} ssd0323_state;
+#define TYPE_SSD0323 "ssd0323"
+#define SSD0323(obj) OBJECT_CHECK(ssd0323_state, (obj), TYPE_SSD0323)
+
+
static uint32_t ssd0323_transfer(SSISlave *dev, uint32_t data)
{
- ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
+ ssd0323_state *s = SSD0323(dev);
switch (s->mode) {
case SSD0323_DATA:
@@ -346,7 +350,7 @@ static const GraphicHwOps ssd0323_ops = {
static void ssd0323_realize(SSISlave *d, Error **errp)
{
DeviceState *dev = DEVICE(d);
- ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, d);
+ ssd0323_state *s = SSD0323(d);
s->col_end = 63;
s->row_end = 79;
@@ -368,7 +372,7 @@ static void ssd0323_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo ssd0323_info = {
- .name = "ssd0323",
+ .name = TYPE_SSD0323,
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(ssd0323_state),
.class_init = ssd0323_class_init,
diff --git a/hw/display/trace-events b/hw/display/trace-events
index 72d4c98..970d6ba 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -161,3 +161,15 @@ cg3_write(uint32_t addr, uint32_t val, unsigned size) "write addr:0x%06"PRIx32"
# dpcd.c
dpcd_read(uint32_t addr, uint8_t val) "read addr:0x%"PRIx32" val:0x%02x"
dpcd_write(uint32_t addr, uint8_t val) "write addr:0x%"PRIx32" val:0x%02x"
+
+# sm501.c
+sm501_system_config_read(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_system_config_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_i2c_read(uint32_t addr, uint8_t val) "addr=0x%x, val=0x%x"
+sm501_i2c_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_palette_read(uint32_t addr) "addr=0x%x"
+sm501_palette_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_disp_ctrl_read(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_disp_ctrl_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_2d_engine_read(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
+sm501_2d_engine_write(uint32_t addr, uint32_t val) "addr=0x%x, val=0x%x"
diff --git a/hw/display/virtio-gpu-pci.c b/hw/display/virtio-gpu-pci.c
index b532fe8..41b88b8 100644
--- a/hw/display/virtio-gpu-pci.c
+++ b/hw/display/virtio-gpu-pci.c
@@ -44,7 +44,7 @@ static void virtio_gpu_pci_base_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
for (i = 0; i < g->conf.max_outputs; i++) {
object_property_set_link(OBJECT(g->scanout[i].con),
OBJECT(vpci_dev),
- "device", errp);
+ "device", &error_abort);
}
}
diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
index 68a062e..67f409e 100644
--- a/hw/display/virtio-vga.c
+++ b/hw/display/virtio-vga.c
@@ -154,7 +154,7 @@ static void virtio_vga_base_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
for (i = 0; i < g->conf.max_outputs; i++) {
object_property_set_link(OBJECT(g->scanout[i].con),
OBJECT(vpci_dev),
- "device", errp);
+ "device", &error_abort);
}
}
diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c
index f02aca6..2d7dbbb 100644
--- a/hw/dma/sparc32_dma.c
+++ b/hw/dma/sparc32_dma.c
@@ -346,7 +346,7 @@ static void sparc32_ledma_device_realize(DeviceState *dev, Error **errp)
d = qdev_new(TYPE_LANCE);
object_property_add_child(OBJECT(dev), "lance", OBJECT(d));
qdev_set_nic_properties(d, nd);
- object_property_set_link(OBJECT(d), OBJECT(dev), "dma", errp);
+ object_property_set_link(OBJECT(d), OBJECT(dev), "dma", &error_abort);
sysbus_realize_and_unref(SYS_BUS_DEVICE(d), &error_fatal);
}
@@ -379,7 +379,7 @@ static void sparc32_dma_realize(DeviceState *dev, Error **errp)
}
espdma = qdev_new(TYPE_SPARC32_ESPDMA_DEVICE);
- object_property_set_link(OBJECT(espdma), iommu, "iommu", errp);
+ object_property_set_link(OBJECT(espdma), iommu, "iommu", &error_abort);
object_property_add_child(OBJECT(s), "espdma", OBJECT(espdma));
sysbus_realize_and_unref(SYS_BUS_DEVICE(espdma), &error_fatal);
@@ -394,7 +394,7 @@ static void sparc32_dma_realize(DeviceState *dev, Error **errp)
sysbus_mmio_get_region(sbd, 0));
ledma = qdev_new(TYPE_SPARC32_LEDMA_DEVICE);
- object_property_set_link(OBJECT(ledma), iommu, "iommu", errp);
+ object_property_set_link(OBJECT(ledma), iommu, "iommu", &error_abort);
object_property_add_child(OBJECT(s), "ledma", OBJECT(ledma));
sysbus_realize_and_unref(SYS_BUS_DEVICE(ledma), &error_fatal);
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index 6a9df2c..a069637 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -537,7 +537,6 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(&s->rx_data_dev);
XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(
&s->rx_control_dev);
- Error *local_err = NULL;
int i;
object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
@@ -548,11 +547,8 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
(Object **)&cs->dma,
object_property_allow_set_link,
OBJ_PROP_LINK_STRONG);
- object_property_set_link(OBJECT(ds), OBJECT(s), "dma", &local_err);
- object_property_set_link(OBJECT(cs), OBJECT(s), "dma", &local_err);
- if (local_err) {
- goto xilinx_axidma_realize_fail;
- }
+ object_property_set_link(OBJECT(ds), OBJECT(s), "dma", &error_abort);
+ object_property_set_link(OBJECT(cs), OBJECT(s), "dma", &error_abort);
for (i = 0; i < 2; i++) {
struct Stream *st = &s->streams[i];
@@ -567,10 +563,6 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
address_space_init(&s->as,
s->dma_mr ? s->dma_mr : get_system_memory(), "dma");
- return;
-
-xilinx_axidma_realize_fail:
- error_propagate(errp, local_err);
}
static void xilinx_axidma_init(Object *obj)
diff --git a/hw/gpio/zaurus.c b/hw/gpio/zaurus.c
index 9a12c68..258e926 100644
--- a/hw/gpio/zaurus.c
+++ b/hw/gpio/zaurus.c
@@ -22,9 +22,7 @@
#include "hw/sysbus.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
-
-#undef REG_FMT
-#define REG_FMT "0x%02lx"
+#include "qemu/log.h"
/* SCOOP devices */
@@ -104,7 +102,9 @@ static uint64_t scoop_read(void *opaque, hwaddr addr,
case SCOOP_GPRR:
return s->gpio_level;
default:
- zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "scoop_read: bad register offset 0x%02" HWADDR_PRIx "\n",
+ addr);
}
return 0;
@@ -150,7 +150,9 @@ static void scoop_write(void *opaque, hwaddr addr,
scoop_gpio_handler_update(s);
break;
default:
- zaurus_printf("Bad register offset " REG_FMT "\n", (unsigned long)addr);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "scoop_write: bad register offset 0x%02" HWADDR_PRIx "\n",
+ addr);
}
}
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index b26d30d..087f601 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -1549,7 +1549,9 @@ static void amdvi_realize(DeviceState *dev, Error **errp)
/* This device should take care of IOMMU PCI properties */
x86_iommu->type = TYPE_AMD;
- qdev_realize(DEVICE(&s->pci), &bus->qbus, errp);
+ if (!qdev_realize(DEVICE(&s->pci), &bus->qbus, errp)) {
+ return;
+ }
ret = pci_add_capability(&s->pci.dev, AMDVI_CAPAB_ID_SEC, 0,
AMDVI_CAPAB_SIZE, errp);
if (ret < 0) {
@@ -1578,7 +1580,7 @@ static void amdvi_realize(DeviceState *dev, Error **errp)
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mmio);
sysbus_mmio_map(SYS_BUS_DEVICE(s), 0, AMDVI_BASE_ADDR);
pci_setup_iommu(bus, amdvi_host_dma_iommu, s);
- s->devid = object_property_get_int(OBJECT(&s->pci), "addr", errp);
+ s->devid = object_property_get_int(OBJECT(&s->pci), "addr", &error_abort);
msi_init(&s->pci.dev, 0, 1, true, false, errp);
amdvi_init(s);
}
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 34229b4..93f7371 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -118,14 +118,16 @@ uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms,
void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp)
{
- Object *cpu = NULL;
Error *local_err = NULL;
-
- cpu = object_new(MACHINE(x86ms)->cpu_type);
+ Object *cpu = object_new(MACHINE(x86ms)->cpu_type);
object_property_set_uint(cpu, apic_id, "apic-id", &local_err);
+ if (local_err) {
+ goto out;
+ }
qdev_realize(DEVICE(cpu), NULL, &local_err);
+out:
object_unref(cpu);
error_propagate(errp, local_err);
}
diff --git a/hw/m68k/mcf5206.c b/hw/m68k/mcf5206.c
index a2fef04..94a37a1 100644
--- a/hw/m68k/mcf5206.c
+++ b/hw/m68k/mcf5206.c
@@ -10,7 +10,6 @@
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "cpu.h"
-#include "hw/hw.h"
#include "hw/irq.h"
#include "hw/m68k/mcf.h"
#include "qemu/timer.h"
@@ -69,10 +68,16 @@ static void m5206_timer_recalibrate(m5206_timer_state *s)
if (mode == 2)
prescale *= 16;
- if (mode == 3 || mode == 0)
- hw_error("m5206_timer: mode %d not implemented\n", mode);
- if ((s->tmr & TMR_FRR) == 0)
- hw_error("m5206_timer: free running mode not implemented\n");
+ if (mode == 3 || mode == 0) {
+ qemu_log_mask(LOG_UNIMP, "m5206_timer: mode %d not implemented\n",
+ mode);
+ goto exit;
+ }
+ if ((s->tmr & TMR_FRR) == 0) {
+ qemu_log_mask(LOG_UNIMP,
+ "m5206_timer: free running mode not implemented\n");
+ goto exit;
+ }
/* Assume 66MHz system clock. */
ptimer_set_freq(s->timer, 66000000 / prescale);
@@ -391,7 +396,9 @@ static uint32_t m5206_mbar_readb(void *opaque, hwaddr offset)
m5206_mbar_state *s = (m5206_mbar_state *)opaque;
offset &= 0x3ff;
if (offset >= 0x200) {
- hw_error("Bad MBAR read offset 0x%x", (int)offset);
+ qemu_log_mask(LOG_GUEST_ERROR, "Bad MBAR read offset 0x%" HWADDR_PRIX,
+ offset);
+ return 0;
}
if (m5206_mbar_width[offset >> 2] > 1) {
uint16_t val;
@@ -410,7 +417,9 @@ static uint32_t m5206_mbar_readw(void *opaque, hwaddr offset)
int width;
offset &= 0x3ff;
if (offset >= 0x200) {
- hw_error("Bad MBAR read offset 0x%x", (int)offset);
+ qemu_log_mask(LOG_GUEST_ERROR, "Bad MBAR read offset 0x%" HWADDR_PRIX,
+ offset);
+ return 0;
}
width = m5206_mbar_width[offset >> 2];
if (width > 2) {
@@ -434,7 +443,9 @@ static uint32_t m5206_mbar_readl(void *opaque, hwaddr offset)
int width;
offset &= 0x3ff;
if (offset >= 0x200) {
- hw_error("Bad MBAR read offset 0x%x", (int)offset);
+ qemu_log_mask(LOG_GUEST_ERROR, "Bad MBAR read offset 0x%" HWADDR_PRIX,
+ offset);
+ return 0;
}
width = m5206_mbar_width[offset >> 2];
if (width < 4) {
@@ -458,7 +469,9 @@ static void m5206_mbar_writeb(void *opaque, hwaddr offset,
int width;
offset &= 0x3ff;
if (offset >= 0x200) {
- hw_error("Bad MBAR write offset 0x%x", (int)offset);
+ qemu_log_mask(LOG_GUEST_ERROR, "Bad MBAR write offset 0x%" HWADDR_PRIX,
+ offset);
+ return;
}
width = m5206_mbar_width[offset >> 2];
if (width > 1) {
@@ -482,7 +495,9 @@ static void m5206_mbar_writew(void *opaque, hwaddr offset,
int width;
offset &= 0x3ff;
if (offset >= 0x200) {
- hw_error("Bad MBAR write offset 0x%x", (int)offset);
+ qemu_log_mask(LOG_GUEST_ERROR, "Bad MBAR write offset 0x%" HWADDR_PRIX,
+ offset);
+ return;
}
width = m5206_mbar_width[offset >> 2];
if (width > 2) {
@@ -510,7 +525,9 @@ static void m5206_mbar_writel(void *opaque, hwaddr offset,
int width;
offset &= 0x3ff;
if (offset >= 0x200) {
- hw_error("Bad MBAR write offset 0x%x", (int)offset);
+ qemu_log_mask(LOG_GUEST_ERROR, "Bad MBAR write offset 0x%" HWADDR_PRIX,
+ offset);
+ return;
}
width = m5206_mbar_width[offset >> 2];
if (width < 4) {
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index cdfab19..0d7f3cf 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -100,10 +100,12 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
/* Inter-Thread Communication Unit */
if (itu_present) {
object_initialize_child(OBJECT(dev), "itu", &s->itu, TYPE_MIPS_ITU);
- object_property_set_int(OBJECT(&s->itu), 16, "num-fifo", &err);
- object_property_set_int(OBJECT(&s->itu), 16, "num-semaphores", &err);
+ object_property_set_int(OBJECT(&s->itu), 16, "num-fifo",
+ &error_abort);
+ object_property_set_int(OBJECT(&s->itu), 16, "num-semaphores",
+ &error_abort);
object_property_set_bool(OBJECT(&s->itu), saar_present, "saar-present",
- &err);
+ &error_abort);
if (saar_present) {
s->itu.saar = &env->CP0_SAAR;
}
@@ -119,8 +121,10 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
/* Cluster Power Controller */
object_initialize_child(OBJECT(dev), "cpc", &s->cpc, TYPE_MIPS_CPC);
- object_property_set_int(OBJECT(&s->cpc), s->num_vp, "num-vp", &err);
- object_property_set_int(OBJECT(&s->cpc), 1, "vp-start-running", &err);
+ object_property_set_int(OBJECT(&s->cpc), s->num_vp, "num-vp",
+ &error_abort);
+ object_property_set_int(OBJECT(&s->cpc), 1, "vp-start-running",
+ &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->cpc), &err);
if (err != NULL) {
error_propagate(errp, err);
@@ -132,8 +136,10 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
/* Global Interrupt Controller */
object_initialize_child(OBJECT(dev), "gic", &s->gic, TYPE_MIPS_GIC);
- object_property_set_int(OBJECT(&s->gic), s->num_vp, "num-vp", &err);
- object_property_set_int(OBJECT(&s->gic), 128, "num-irq", &err);
+ object_property_set_int(OBJECT(&s->gic), s->num_vp, "num-vp",
+ &error_abort);
+ object_property_set_int(OBJECT(&s->gic), 128, "num-irq",
+ &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->gic), &err);
if (err != NULL) {
error_propagate(errp, err);
@@ -147,11 +153,16 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
gcr_base = env->CP0_CMGCRBase << 4;
object_initialize_child(OBJECT(dev), "gcr", &s->gcr, TYPE_MIPS_GCR);
- object_property_set_int(OBJECT(&s->gcr), s->num_vp, "num-vp", &err);
- object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev", &err);
- object_property_set_int(OBJECT(&s->gcr), gcr_base, "gcr-base", &err);
- object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->gic.mr), "gic", &err);
- object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->cpc.mr), "cpc", &err);
+ object_property_set_int(OBJECT(&s->gcr), s->num_vp, "num-vp",
+ &error_abort);
+ object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev",
+ &error_abort);
+ object_property_set_int(OBJECT(&s->gcr), gcr_base, "gcr-base",
+ &error_abort);
+ object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->gic.mr), "gic",
+ &error_abort);
+ object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->cpc.mr), "cpc",
+ &error_abort);
sysbus_realize(SYS_BUS_DEVICE(&s->gcr), &err);
if (err != NULL) {
error_propagate(errp, err);
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index 8ba7af0..3251c79 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -136,7 +136,8 @@ static void macio_realize_ide(MacIOState *s, MACIOIDEState *ide,
sysbus_connect_irq(sysbus_dev, 0, irq0);
sysbus_connect_irq(sysbus_dev, 1, irq1);
qdev_prop_set_uint32(DEVICE(ide), "channel", dmaid);
- object_property_set_link(OBJECT(ide), OBJECT(&s->dbdma), "dbdma", errp);
+ object_property_set_link(OBJECT(ide), OBJECT(&s->dbdma), "dbdma",
+ &error_abort);
macio_ide_register_dma(ide);
qdev_realize(DEVICE(ide), BUS(&s->macio_bus), errp);
diff --git a/hw/misc/max111x.c b/hw/misc/max111x.c
index 2b87bde..7e6723f 100644
--- a/hw/misc/max111x.c
+++ b/hw/misc/max111x.c
@@ -11,29 +11,11 @@
*/
#include "qemu/osdep.h"
+#include "hw/misc/max111x.h"
#include "hw/irq.h"
-#include "hw/ssi/ssi.h"
#include "migration/vmstate.h"
#include "qemu/module.h"
-
-typedef struct {
- SSISlave parent_obj;
-
- qemu_irq interrupt;
- uint8_t tb1, rb2, rb3;
- int cycle;
-
- uint8_t input[8];
- int inputs, com;
-} MAX111xState;
-
-#define TYPE_MAX_111X "max111x"
-
-#define MAX_111X(obj) \
- OBJECT_CHECK(MAX111xState, (obj), TYPE_MAX_111X)
-
-#define TYPE_MAX_1110 "max1110"
-#define TYPE_MAX_1111 "max1111"
+#include "hw/qdev-properties.h"
/* Control-byte bitfields */
#define CB_PD0 (1 << 0)
@@ -127,27 +109,24 @@ static const VMStateDescription vmstate_max111x = {
}
};
+static void max111x_input_set(void *opaque, int line, int value)
+{
+ MAX111xState *s = MAX_111X(opaque);
+
+ assert(line >= 0 && line < s->inputs);
+ s->input[line] = value;
+}
+
static int max111x_init(SSISlave *d, int inputs)
{
DeviceState *dev = DEVICE(d);
MAX111xState *s = MAX_111X(dev);
qdev_init_gpio_out(dev, &s->interrupt, 1);
+ qdev_init_gpio_in(dev, max111x_input_set, inputs);
s->inputs = inputs;
- /* TODO: add a user interface for setting these */
- s->input[0] = 0xf0;
- s->input[1] = 0xe0;
- s->input[2] = 0xd0;
- s->input[3] = 0xc0;
- s->input[4] = 0xb0;
- s->input[5] = 0xa0;
- s->input[6] = 0x90;
- s->input[7] = 0x80;
- s->com = 0;
- vmstate_register(VMSTATE_IF(dev), VMSTATE_INSTANCE_ID_ANY,
- &vmstate_max111x, s);
return 0;
}
@@ -161,18 +140,51 @@ static void max1111_realize(SSISlave *dev, Error **errp)
max111x_init(dev, 4);
}
-void max111x_set_input(DeviceState *dev, int line, uint8_t value)
+static void max111x_reset(DeviceState *dev)
{
MAX111xState *s = MAX_111X(dev);
- assert(line >= 0 && line < s->inputs);
- s->input[line] = value;
+ int i;
+
+ for (i = 0; i < s->inputs; i++) {
+ s->input[i] = s->reset_input[i];
+ }
+ s->com = 0;
+ s->tb1 = 0;
+ s->rb2 = 0;
+ s->rb3 = 0;
+ s->cycle = 0;
}
+static Property max1110_properties[] = {
+ /* Reset values for ADC inputs */
+ DEFINE_PROP_UINT8("input0", MAX111xState, reset_input[0], 0xf0),
+ DEFINE_PROP_UINT8("input1", MAX111xState, reset_input[1], 0xe0),
+ DEFINE_PROP_UINT8("input2", MAX111xState, reset_input[2], 0xd0),
+ DEFINE_PROP_UINT8("input3", MAX111xState, reset_input[3], 0xc0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static Property max1111_properties[] = {
+ /* Reset values for ADC inputs */
+ DEFINE_PROP_UINT8("input0", MAX111xState, reset_input[0], 0xf0),
+ DEFINE_PROP_UINT8("input1", MAX111xState, reset_input[1], 0xe0),
+ DEFINE_PROP_UINT8("input2", MAX111xState, reset_input[2], 0xd0),
+ DEFINE_PROP_UINT8("input3", MAX111xState, reset_input[3], 0xc0),
+ DEFINE_PROP_UINT8("input4", MAX111xState, reset_input[4], 0xb0),
+ DEFINE_PROP_UINT8("input5", MAX111xState, reset_input[5], 0xa0),
+ DEFINE_PROP_UINT8("input6", MAX111xState, reset_input[6], 0x90),
+ DEFINE_PROP_UINT8("input7", MAX111xState, reset_input[7], 0x80),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void max111x_class_init(ObjectClass *klass, void *data)
{
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
k->transfer = max111x_transfer;
+ dc->reset = max111x_reset;
+ dc->vmsd = &vmstate_max111x;
}
static const TypeInfo max111x_info = {
@@ -186,8 +198,10 @@ static const TypeInfo max111x_info = {
static void max1110_class_init(ObjectClass *klass, void *data)
{
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
k->realize = max1110_realize;
+ device_class_set_props(dc, max1110_properties);
}
static const TypeInfo max1110_info = {
@@ -199,8 +213,10 @@ static const TypeInfo max1110_info = {
static void max1111_class_init(ObjectClass *klass, void *data)
{
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
k->realize = max1111_realize;
+ device_class_set_props(dc, max1111_properties);
}
static const TypeInfo max1111_info = {
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index eefedc2..2c14804 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -280,12 +280,16 @@ static void imx_phy_reset(IMXFECState *s)
static uint32_t imx_phy_read(IMXFECState *s, int reg)
{
uint32_t val;
+ uint32_t phy = reg / 32;
- if (reg > 31) {
- /* we only advertise one phy */
+ if (phy != s->phy_num) {
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad phy num %u\n",
+ TYPE_IMX_FEC, __func__, phy);
return 0;
}
+ reg %= 32;
+
switch (reg) {
case 0: /* Basic Control */
val = s->phy_control;
@@ -331,20 +335,25 @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
break;
}
- trace_imx_phy_read(val, reg);
+ trace_imx_phy_read(val, phy, reg);
return val;
}
static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
{
- trace_imx_phy_write(val, reg);
+ uint32_t phy = reg / 32;
- if (reg > 31) {
- /* we only advertise one phy */
+ if (phy != s->phy_num) {
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad phy num %u\n",
+ TYPE_IMX_FEC, __func__, phy);
return;
}
+ reg %= 32;
+
+ trace_imx_phy_write(val, phy, reg);
+
switch (reg) {
case 0: /* Basic Control */
if (val & 0x8000) {
@@ -926,7 +935,7 @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
extract32(value,
18, 10)));
} else {
- /* This a write operation */
+ /* This is a write operation */
imx_phy_write(s, extract32(value, 18, 10), extract32(value, 0, 16));
}
/* raise the interrupt as the PHY operation is done */
@@ -1315,6 +1324,7 @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
static Property imx_eth_properties[] = {
DEFINE_NIC_PROPERTIES(IMXFECState, conf),
DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1),
+ DEFINE_PROP_UINT32("phy-num", IMXFECState, phy_num, 0),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/net/trace-events b/hw/net/trace-events
index e6875c4..5db4545 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -413,8 +413,8 @@ i82596_set_multicast(uint16_t count) "Added %d multicast entries"
i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
# imx_fec.c
-imx_phy_read(uint32_t val, int reg) "0x%04"PRIx32" <= reg[%d]"
-imx_phy_write(uint32_t val, int reg) "0x%04"PRIx32" => reg[%d]"
+imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
+imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => phy[%d].reg[%d]"
imx_phy_update_link(const char *s) "%s"
imx_phy_reset(void) ""
imx_fec_read_bd(uint64_t addr, int flags, int len, int data) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x"
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 0a54b19..1596cb1 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -3148,7 +3148,7 @@ static bool failover_replug_primary(VirtIONet *n, Error **errp)
if (err) {
goto out;
}
- hotplug_handler_plug(hotplug_ctrl, n->primary_dev, errp);
+ hotplug_handler_plug(hotplug_ctrl, n->primary_dev, &err);
}
out:
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index c2f40b8..679a359 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -980,7 +980,6 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(&s->rx_data_dev);
XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(
&s->rx_control_dev);
- Error *local_err = NULL;
object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
(Object **) &ds->enet,
@@ -990,11 +989,8 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
(Object **) &cs->enet,
object_property_allow_set_link,
OBJ_PROP_LINK_STRONG);
- object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &local_err);
- object_property_set_link(OBJECT(cs), OBJECT(s), "enet", &local_err);
- if (local_err) {
- goto xilinx_enet_realize_fail;
- }
+ object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &error_abort);
+ object_property_set_link(OBJECT(cs), OBJECT(s), "enet", &error_abort);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&net_xilinx_enet_info, &s->conf,
@@ -1008,10 +1004,6 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
s->rxmem = g_malloc(s->c_rxmem);
s->txmem = g_malloc(s->c_txmem);
- return;
-
-xilinx_enet_realize_fail:
- error_propagate(errp, local_err);
}
static void xilinx_enet_init(Object *obj)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index b22dedc..de0fae1 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2123,7 +2123,6 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
if (!pci_bus_is_express(pci_get_bus(pci_dev))) {
error_setg(errp, "failover primary device must be on "
"PCIExpress bus");
- error_propagate(errp, local_err);
pci_qdev_unrealize(DEVICE(pci_dev));
return;
}
@@ -2131,7 +2130,6 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
if (class_id != PCI_CLASS_NETWORK_ETHERNET) {
error_setg(errp, "failover primary device is not an "
"Ethernet device");
- error_propagate(errp, local_err);
pci_qdev_unrealize(DEVICE(pci_dev));
return;
}
@@ -2141,7 +2139,6 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
} else {
error_setg(errp, "failover: primary device must be in its own "
"PCI slot");
- error_propagate(errp, local_err);
pci_qdev_unrealize(DEVICE(pci_dev));
return;
}
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 086d0df..5b48bae 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -574,7 +574,7 @@ void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
dev->exp.hpev_notified = false;
qbus_set_hotplug_handler(BUS(pci_bridge_get_sec_bus(PCI_BRIDGE(dev))),
- OBJECT(dev), NULL);
+ OBJECT(dev));
}
void pcie_cap_slot_reset(PCIDevice *dev)
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index 99d65d5..b00dce6 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -649,7 +649,7 @@ int shpc_init(PCIDevice *d, PCIBus *sec_bus, MemoryRegion *bar,
shpc_cap_update_dword(d);
memory_region_add_subregion(bar, offset, &shpc->mmio);
- qbus_set_hotplug_handler(BUS(sec_bus), OBJECT(d), NULL);
+ qbus_set_hotplug_handler(BUS(sec_bus), OBJECT(d));
d->cap_present |= QEMU_PCI_CAP_SHPC;
return 0;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 4c185bc..f6f034d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2731,6 +2731,7 @@ static void spapr_machine_init(MachineState *machine)
error_report_err(resize_hpt_err);
exit(1);
}
+ error_free(resize_hpt_err);
spapr->rma_size = spapr_rma_size(spapr, &error_fatal);
@@ -3032,8 +3033,7 @@ static void spapr_machine_init(MachineState *machine)
register_savevm_live("spapr/htab", VMSTATE_INSTANCE_ID_ANY, 1,
&savevm_htab_handlers, spapr);
- qbus_set_hotplug_handler(sysbus_get_default(), OBJECT(machine),
- &error_fatal);
+ qbus_set_hotplug_handler(sysbus_get_default(), OBJECT(machine));
qemu_register_boot_set(spapr_boot_set, spapr);
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 2689104..951bcdf 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -1163,16 +1163,14 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
if (!drc->fdt) {
- Error *local_err = NULL;
void *fdt;
int fdt_size;
fdt = create_device_tree(&fdt_size);
if (drck->dt_populate(drc, spapr, fdt, &drc->fdt_start_offset,
- &local_err)) {
+ NULL)) {
g_free(fdt);
- error_free(local_err);
rc = SPAPR_DR_CC_RESPONSE_ERROR;
goto out;
}
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 329002a..0f00e24 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1719,7 +1719,7 @@ static void spapr_phb_unrealize(DeviceState *dev)
address_space_remove_listeners(&sphb->iommu_as);
address_space_destroy(&sphb->iommu_as);
- qbus_set_hotplug_handler(BUS(phb->bus), NULL, &error_abort);
+ qbus_set_hotplug_handler(BUS(phb->bus), NULL);
pci_unregister_root_bus(phb->bus);
memory_region_del_subregion(get_system_memory(), &sphb->iowindow);
@@ -1868,7 +1868,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE;
}
phb->bus = bus;
- qbus_set_hotplug_handler(BUS(phb->bus), OBJECT(sphb), NULL);
+ qbus_set_hotplug_handler(BUS(phb->bus), OBJECT(sphb));
/*
* Initialize PHB address space.
diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index e26c382..f59fe52 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -40,19 +40,13 @@ static void riscv_harts_cpu_reset(void *opaque)
cpu_reset(CPU(cpu));
}
-static void riscv_hart_realize(RISCVHartArrayState *s, int idx,
+static bool riscv_hart_realize(RISCVHartArrayState *s, int idx,
char *cpu_type, Error **errp)
{
- Error *err = NULL;
-
object_initialize_child(OBJECT(s), "harts[*]", &s->harts[idx], cpu_type);
s->harts[idx].env.mhartid = s->hartid_base + idx;
qemu_register_reset(riscv_harts_cpu_reset, &s->harts[idx]);
- qdev_realize(DEVICE(&s->harts[idx]), NULL, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
+ return qdev_realize(DEVICE(&s->harts[idx]), NULL, errp);
}
static void riscv_harts_realize(DeviceState *dev, Error **errp)
@@ -63,7 +57,9 @@ static void riscv_harts_realize(DeviceState *dev, Error **errp)
s->harts = g_new0(RISCVCPU, s->num_harts);
for (n = 0; n < s->num_harts; n++) {
- riscv_hart_realize(s, n, s->cpu_type, errp);
+ if (!riscv_hart_realize(s, n, s->cpu_type, errp)) {
+ return;
+ }
}
}
diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c
index b11ffa0..669c21a 100644
--- a/hw/riscv/sifive_clint.c
+++ b/hw/riscv/sifive_clint.c
@@ -181,7 +181,7 @@ static const MemoryRegionOps sifive_clint_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4,
- .max_access_size = 4
+ .max_access_size = 8
}
};
diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index 4f216c5..c20c192 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -166,6 +166,9 @@ static void sifive_plic_update(SiFivePLICState *plic)
static uint32_t sifive_plic_claim(SiFivePLICState *plic, uint32_t addrid)
{
int i, j;
+ uint32_t max_irq = 0;
+ uint32_t max_prio = plic->target_priority[addrid];
+
for (i = 0; i < plic->bitfield_words; i++) {
uint32_t pending_enabled_not_claimed =
(plic->pending[i] & ~plic->claimed[i]) &
@@ -177,14 +180,18 @@ static uint32_t sifive_plic_claim(SiFivePLICState *plic, uint32_t addrid)
int irq = (i << 5) + j;
uint32_t prio = plic->source_priority[irq];
int enabled = pending_enabled_not_claimed & (1 << j);
- if (enabled && prio > plic->target_priority[addrid]) {
- sifive_plic_set_pending(plic, irq, false);
- sifive_plic_set_claimed(plic, irq, true);
- return irq;
+ if (enabled && prio > max_prio) {
+ max_irq = irq;
+ max_prio = prio;
}
}
}
- return 0;
+
+ if (max_irq) {
+ sifive_plic_set_pending(plic, max_irq, false);
+ sifive_plic_set_claimed(plic, max_irq, true);
+ }
+ return max_irq;
}
static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
@@ -248,8 +255,8 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
plic->addr_config[addrid].hartid,
mode_to_char(plic->addr_config[addrid].mode),
value);
- sifive_plic_print_state(plic);
}
+ sifive_plic_update(plic);
return value;
}
}
@@ -280,6 +287,7 @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
qemu_log("plic: write priority: irq=%d priority=%d\n",
irq, plic->source_priority[irq]);
}
+ sifive_plic_update(plic);
return;
} else if (addr >= plic->pending_base && /* 1 bit per source */
addr < plic->pending_base + (plic->num_sources >> 3))
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 7d051e7..a1d2edf 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -677,11 +677,15 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
memmap[SIFIVE_U_CLINT].size, ms->smp.cpus,
SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false);
- sysbus_realize(SYS_BUS_DEVICE(&s->prci), &err);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->prci), errp)) {
+ return;
+ }
sysbus_mmio_map(SYS_BUS_DEVICE(&s->prci), 0, memmap[SIFIVE_U_PRCI].base);
qdev_prop_set_uint32(DEVICE(&s->gpio), "ngpio", 16);
- sysbus_realize(SYS_BUS_DEVICE(&s->gpio), &err);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
+ return;
+ }
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, memmap[SIFIVE_U_GPIO].base);
/* Pass all GPIOs to the SOC layer so they are available to the board */
@@ -695,7 +699,9 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
}
qdev_prop_set_uint32(DEVICE(&s->otp), "serial", s->serial);
- sysbus_realize(SYS_BUS_DEVICE(&s->otp), &err);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->otp), errp)) {
+ return;
+ }
sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base);
if (nd->used) {
diff --git a/hw/s390x/ap-bridge.c b/hw/s390x/ap-bridge.c
index c4e3188..8bcf8ec 100644
--- a/hw/s390x/ap-bridge.c
+++ b/hw/s390x/ap-bridge.c
@@ -58,7 +58,7 @@ void s390_init_ap(void)
bus = qbus_create(TYPE_AP_BUS, dev, TYPE_AP_BUS);
/* Enable hotplugging */
- qbus_set_hotplug_handler(bus, OBJECT(dev), &error_abort);
+ qbus_set_hotplug_handler(bus, OBJECT(dev));
}
static void ap_bridge_class_init(ObjectClass *oc, void *data)
diff --git a/hw/s390x/css-bridge.c b/hw/s390x/css-bridge.c
index e37a54d..9d793d6 100644
--- a/hw/s390x/css-bridge.c
+++ b/hw/s390x/css-bridge.c
@@ -111,7 +111,7 @@ VirtualCssBus *virtual_css_bus_init(void)
cbus = VIRTUAL_CSS_BUS(bus);
/* Enable hotplugging */
- qbus_set_hotplug_handler(bus, OBJECT(dev), &error_abort);
+ qbus_set_hotplug_handler(bus, OBJECT(dev));
css_register_io_adapters(CSS_IO_ADAPTER_VIRTIO, true, false,
0, &error_abort);
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index a13978b..736965c 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -637,22 +637,24 @@ static AddressSpace *s390_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
static uint8_t set_ind_atomic(uint64_t ind_loc, uint8_t to_be_set)
{
- uint8_t ind_old, ind_new;
+ uint8_t expected, actual;
hwaddr len = 1;
- uint8_t *ind_addr;
+ /* avoid multiple fetches */
+ uint8_t volatile *ind_addr;
ind_addr = cpu_physical_memory_map(ind_loc, &len, true);
if (!ind_addr) {
s390_pci_generate_error_event(ERR_EVENT_AIRERR, 0, 0, 0, 0);
return -1;
}
+ actual = *ind_addr;
do {
- ind_old = *ind_addr;
- ind_new = ind_old | to_be_set;
- } while (atomic_cmpxchg(ind_addr, ind_old, ind_new) != ind_old);
- cpu_physical_memory_unmap(ind_addr, len, 1, len);
+ expected = actual;
+ actual = atomic_cmpxchg(ind_addr, expected, expected | to_be_set);
+ } while (actual != expected);
+ cpu_physical_memory_unmap((void *)ind_addr, len, 1, len);
- return ind_old;
+ return actual;
}
static void s390_msi_ctrl_write(void *opaque, hwaddr addr, uint64_t data,
@@ -751,19 +753,11 @@ static void s390_pcihost_realize(DeviceState *dev, Error **errp)
pci_setup_iommu(b, s390_pci_dma_iommu, s);
bus = BUS(b);
- qbus_set_hotplug_handler(bus, OBJECT(dev), &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ qbus_set_hotplug_handler(bus, OBJECT(dev));
phb->bus = b;
s->bus = S390_PCI_BUS(qbus_create(TYPE_S390_PCI_BUS, dev, NULL));
- qbus_set_hotplug_handler(BUS(s->bus), OBJECT(dev), &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ qbus_set_hotplug_handler(BUS(s->bus), OBJECT(dev));
s->iommu_table = g_hash_table_new_full(g_int64_hash, g_int64_equal,
NULL, g_free);
@@ -921,7 +915,7 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
pci_bridge_map_irq(pb, dev->id, s390_pci_map_irq);
pci_setup_iommu(&pb->sec_bus, s390_pci_dma_iommu, s);
- qbus_set_hotplug_handler(BUS(&pb->sec_bus), OBJECT(s), errp);
+ qbus_set_hotplug_handler(BUS(&pb->sec_bus), OBJECT(s));
if (dev->hotplugged) {
pci_default_write_config(pdev, PCI_PRIMARY_BUS,
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index c1f4bb1..3c988a0 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -786,9 +786,10 @@ static inline VirtioCcwDevice *to_virtio_ccw_dev_fast(DeviceState *d)
static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc,
uint8_t to_be_set)
{
- uint8_t ind_old, ind_new;
+ uint8_t expected, actual;
hwaddr len = 1;
- uint8_t *ind_addr;
+ /* avoid multiple fetches */
+ uint8_t volatile *ind_addr;
ind_addr = cpu_physical_memory_map(ind_loc, &len, true);
if (!ind_addr) {
@@ -796,14 +797,15 @@ static uint8_t virtio_set_ind_atomic(SubchDev *sch, uint64_t ind_loc,
__func__, sch->cssid, sch->ssid, sch->schid);
return -1;
}
+ actual = *ind_addr;
do {
- ind_old = *ind_addr;
- ind_new = ind_old | to_be_set;
- } while (atomic_cmpxchg(ind_addr, ind_old, ind_new) != ind_old);
- trace_virtio_ccw_set_ind(ind_loc, ind_old, ind_new);
- cpu_physical_memory_unmap(ind_addr, len, 1, len);
+ expected = actual;
+ actual = atomic_cmpxchg(ind_addr, expected, expected | to_be_set);
+ } while (actual != expected);
+ trace_virtio_ccw_set_ind(ind_loc, actual, actual | to_be_set);
+ cpu_physical_memory_unmap((void *)ind_addr, len, 1, len);
- return ind_old;
+ return actual;
}
static void virtio_ccw_notify(DeviceState *d, uint16_t vector)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 27843bb..b878a08 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -107,7 +107,7 @@ void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
qbus_create_inplace(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
bus->busnr = next_scsi_bus++;
bus->info = info;
- qbus_set_bus_hotplug_handler(BUS(bus), &error_abort);
+ qbus_set_bus_hotplug_handler(BUS(bus));
}
static void scsi_dma_restart_bh(void *opaque)
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 9b72094..b497752 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -934,7 +934,7 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
scsi_bus_new(&s->bus, sizeof(s->bus), dev,
&virtio_scsi_scsi_info, vdev->bus_name);
/* override default SCSI bus hotplug-handler, with virtio-scsi's one */
- qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev), &error_abort);
+ qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev));
virtio_scsi_dataplane_setup(s, errp);
}
@@ -958,7 +958,7 @@ static void virtio_scsi_device_unrealize(DeviceState *dev)
{
VirtIOSCSI *s = VIRTIO_SCSI(dev);
- qbus_set_hotplug_handler(BUS(&s->bus), NULL, &error_abort);
+ qbus_set_hotplug_handler(BUS(&s->bus), NULL);
virtio_scsi_common_unrealize(dev);
}
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index ec5bf9e..df07ab6 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1147,7 +1147,7 @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
&pvscsi_scsi_info, NULL);
/* override default SCSI bus hotplug-handler, with pvscsi's one */
- qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(s), &error_abort);
+ qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(s));
pvscsi_reset_state(s);
}
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
index 482e971..afdb8aa 100644
--- a/hw/sd/milkymist-memcard.c
+++ b/hw/sd/milkymist-memcard.c
@@ -280,9 +280,8 @@ static void milkymist_memcard_realize(DeviceState *dev, Error **errp)
blk = dinfo ? blk_by_legacy_dinfo(dinfo) : NULL;
carddev = qdev_new(TYPE_SD_CARD);
qdev_prop_set_drive(carddev, "drive", blk);
- qdev_realize_and_unref(carddev, BUS(&s->sdbus), &err);
- if (err) {
- error_setg(errp, "failed to init SD card: %s", error_get_pretty(err));
+ if (!qdev_realize_and_unref(carddev, BUS(&s->sdbus), &err)) {
+ error_propagate_prepend(errp, err, "failed to init SD card: %s");
return;
}
s->enabled = blk && blk_is_inserted(blk);
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 25cec2d..25cdf4c 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -74,7 +74,7 @@ typedef struct {
static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
{
- ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, dev);
+ ssi_sd_state *s = SSI_SD(dev);
/* Special case: allow CMD12 (STOP TRANSMISSION) while reading data. */
if (s->mode == SSI_SD_DATA_READ && val == 0x4d) {
@@ -241,7 +241,7 @@ static const VMStateDescription vmstate_ssi_sd = {
static void ssi_sd_realize(SSISlave *d, Error **errp)
{
- ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
+ ssi_sd_state *s = SSI_SD(d);
DeviceState *carddev;
DriveInfo *dinfo;
Error *err = NULL;
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
index 67b48c3..a35d7eb 100644
--- a/hw/ssi/ssi.c
+++ b/hw/ssi/ssi.c
@@ -90,11 +90,16 @@ static const TypeInfo ssi_slave_info = {
.abstract = true,
};
+bool ssi_realize_and_unref(DeviceState *dev, SSIBus *bus, Error **errp)
+{
+ return qdev_realize_and_unref(dev, &bus->parent_obj, errp);
+}
+
DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
{
DeviceState *dev = qdev_new(name);
- qdev_realize_and_unref(dev, &bus->parent_obj, &error_fatal);
+ ssi_realize_and_unref(dev, bus, &error_fatal);
return dev;
}
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index a81aee2..957559b 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -84,7 +84,7 @@ void usb_bus_new(USBBus *bus, size_t bus_size,
USBBusOps *ops, DeviceState *host)
{
qbus_create_inplace(bus, bus_size, TYPE_USB_BUS, host, NULL);
- qbus_set_bus_hotplug_handler(BUS(bus), &error_abort);
+ qbus_set_bus_hotplug_handler(BUS(bus));
bus->ops = ops;
bus->busnr = next_usb_bus++;
QTAILQ_INIT(&bus->free);
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 1684281..15a2243 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -634,7 +634,6 @@ static void usb_mtp_object_readdir(MTPState *s, MTPObject *o)
error_reportf_err(err,
"usb-mtp: failed to add watch for %s: ",
o->path);
- error_free(err);
} else {
trace_usb_mtp_file_monitor_event(s->dev.addr, o->path,
"Watch Added");
@@ -1279,7 +1278,6 @@ static void usb_mtp_command(MTPState *s, MTPControl *c)
if (err) {
error_reportf_err(err,
"usb-mtp: file monitoring init failed: ");
- error_free(err);
} else {
QTAILQ_INIT(&s->events);
}
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index ada18c1..fcfe216 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1320,7 +1320,7 @@ static void ccid_realize(USBDevice *dev, Error **errp)
usb_desc_init(dev);
qbus_create_inplace(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev),
NULL);
- qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev), &error_abort);
+ qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev));
s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
s->bulk = usb_ep_get(dev, USB_TOKEN_IN, CCID_BULK_IN_EP);
s->card = NULL;
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 292fc15..045e89c 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -74,6 +74,7 @@ virtio_iommu_get_domain(uint32_t domain_id) "Alloc domain=%d"
virtio_iommu_put_domain(uint32_t domain_id) "Free domain=%d"
virtio_iommu_translate_out(uint64_t virt_addr, uint64_t phys_addr, uint32_t sid) "0x%"PRIx64" -> 0x%"PRIx64 " for sid=%d"
virtio_iommu_report_fault(uint8_t reason, uint32_t flags, uint32_t endpoint, uint64_t addr) "FAULT reason=%d flags=%d endpoint=%d address =0x%"PRIx64
+virtio_iommu_fill_resv_property(uint32_t devid, uint8_t subtype, uint64_t start, uint64_t end) "dev= %d, type=%d start=0x%"PRIx64" end=0x%"PRIx64
# virtio-mem.c
virtio_mem_send_response(uint16_t type) "type=%" PRIu16
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
index 632533a..592abc9 100644
--- a/hw/virtio/virtio-iommu-pci.c
+++ b/hw/virtio/virtio-iommu-pci.c
@@ -33,6 +33,9 @@ struct VirtIOIOMMUPCI {
static Property virtio_iommu_pci_properties[] = {
DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
+ DEFINE_PROP_ARRAY("reserved-regions", VirtIOIOMMUPCI,
+ vdev.nb_reserved_regions, vdev.reserved_regions,
+ qdev_prop_reserved_region, ReservedRegion),
DEFINE_PROP_END_OF_LIST(),
};
@@ -40,6 +43,7 @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{
VirtIOIOMMUPCI *dev = VIRTIO_IOMMU_PCI(vpci_dev);
DeviceState *vdev = DEVICE(&dev->vdev);
+ VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
if (!qdev_get_machine_hotplug_handler(DEVICE(vpci_dev))) {
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
@@ -48,15 +52,22 @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
"%s machine fails to create iommu-map device tree bindings",
mc->name);
error_append_hint(errp,
- "Check you machine implements a hotplug handler "
+ "Check your machine implements a hotplug handler "
"for the virtio-iommu-pci device\n");
error_append_hint(errp, "Check the guest is booted without FW or with "
"-no-acpi\n");
return;
}
+ for (int i = 0; i < s->nb_reserved_regions; i++) {
+ if (s->reserved_regions[i].type != VIRTIO_IOMMU_RESV_MEM_T_RESERVED &&
+ s->reserved_regions[i].type != VIRTIO_IOMMU_RESV_MEM_T_MSI) {
+ error_setg(errp, "reserved region %d has an invalid type", i);
+ error_append_hint(errp, "Valid values are 0 and 1\n");
+ }
+ }
object_property_set_link(OBJECT(dev),
OBJECT(pci_get_bus(&vpci_dev->pci_dev)),
- "primary-bus", errp);
+ "primary-bus", &error_abort);
qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
}
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
index 483883e..b39e836 100644
--- a/hw/virtio/virtio-iommu.c
+++ b/hw/virtio/virtio-iommu.c
@@ -38,6 +38,7 @@
/* Max size */
#define VIOMMU_DEFAULT_QUEUE_SIZE 256
+#define VIOMMU_PROBE_SIZE 512
typedef struct VirtIOIOMMUDomain {
uint32_t id;
@@ -378,6 +379,65 @@ static int virtio_iommu_unmap(VirtIOIOMMU *s,
return ret;
}
+static ssize_t virtio_iommu_fill_resv_mem_prop(VirtIOIOMMU *s, uint32_t ep,
+ uint8_t *buf, size_t free)
+{
+ struct virtio_iommu_probe_resv_mem prop = {};
+ size_t size = sizeof(prop), length = size - sizeof(prop.head), total;
+ int i;
+
+ total = size * s->nb_reserved_regions;
+
+ if (total > free) {
+ return -ENOSPC;
+ }
+
+ for (i = 0; i < s->nb_reserved_regions; i++) {
+ unsigned subtype = s->reserved_regions[i].type;
+
+ assert(subtype == VIRTIO_IOMMU_RESV_MEM_T_RESERVED ||
+ subtype == VIRTIO_IOMMU_RESV_MEM_T_MSI);
+ prop.head.type = cpu_to_le16(VIRTIO_IOMMU_PROBE_T_RESV_MEM);
+ prop.head.length = cpu_to_le16(length);
+ prop.subtype = subtype;
+ prop.start = cpu_to_le64(s->reserved_regions[i].low);
+ prop.end = cpu_to_le64(s->reserved_regions[i].high);
+
+ memcpy(buf, &prop, size);
+
+ trace_virtio_iommu_fill_resv_property(ep, prop.subtype,
+ prop.start, prop.end);
+ buf += size;
+ }
+ return total;
+}
+
+/**
+ * virtio_iommu_probe - Fill the probe request buffer with
+ * the properties the device is able to return
+ */
+static int virtio_iommu_probe(VirtIOIOMMU *s,
+ struct virtio_iommu_req_probe *req,
+ uint8_t *buf)
+{
+ uint32_t ep_id = le32_to_cpu(req->endpoint);
+ size_t free = VIOMMU_PROBE_SIZE;
+ ssize_t count;
+
+ if (!virtio_iommu_mr(s, ep_id)) {
+ return VIRTIO_IOMMU_S_NOENT;
+ }
+
+ count = virtio_iommu_fill_resv_mem_prop(s, ep_id, buf, free);
+ if (count < 0) {
+ return VIRTIO_IOMMU_S_INVAL;
+ }
+ buf += count;
+ free -= count;
+
+ return VIRTIO_IOMMU_S_OK;
+}
+
static int virtio_iommu_iov_to_req(struct iovec *iov,
unsigned int iov_cnt,
void *req, size_t req_sz)
@@ -407,15 +467,27 @@ virtio_iommu_handle_req(detach)
virtio_iommu_handle_req(map)
virtio_iommu_handle_req(unmap)
+static int virtio_iommu_handle_probe(VirtIOIOMMU *s,
+ struct iovec *iov,
+ unsigned int iov_cnt,
+ uint8_t *buf)
+{
+ struct virtio_iommu_req_probe req;
+ int ret = virtio_iommu_iov_to_req(iov, iov_cnt, &req, sizeof(req));
+
+ return ret ? ret : virtio_iommu_probe(s, &req, buf);
+}
+
static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
struct virtio_iommu_req_head head;
struct virtio_iommu_req_tail tail = {};
+ size_t output_size = sizeof(tail), sz;
VirtQueueElement *elem;
unsigned int iov_cnt;
struct iovec *iov;
- size_t sz;
+ void *buf = NULL;
for (;;) {
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
@@ -452,6 +524,17 @@ static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
case VIRTIO_IOMMU_T_UNMAP:
tail.status = virtio_iommu_handle_unmap(s, iov, iov_cnt);
break;
+ case VIRTIO_IOMMU_T_PROBE:
+ {
+ struct virtio_iommu_req_tail *ptail;
+
+ output_size = s->config.probe_size + sizeof(tail);
+ buf = g_malloc0(output_size);
+
+ ptail = (struct virtio_iommu_req_tail *)
+ (buf + s->config.probe_size);
+ ptail->status = virtio_iommu_handle_probe(s, iov, iov_cnt, buf);
+ }
default:
tail.status = VIRTIO_IOMMU_S_UNSUPP;
}
@@ -459,12 +542,13 @@ static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)
out:
sz = iov_from_buf(elem->in_sg, elem->in_num, 0,
- &tail, sizeof(tail));
- assert(sz == sizeof(tail));
+ buf ? buf : &tail, output_size);
+ assert(sz == output_size);
- virtqueue_push(vq, elem, sizeof(tail));
+ virtqueue_push(vq, elem, sz);
virtio_notify(vdev, vq);
g_free(elem);
+ g_free(buf);
}
}
@@ -523,6 +607,7 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
uint32_t sid, flags;
bool bypass_allowed;
bool found;
+ int i;
interval.low = addr;
interval.high = addr + 1;
@@ -556,6 +641,25 @@ static IOMMUTLBEntry virtio_iommu_translate(IOMMUMemoryRegion *mr, hwaddr addr,
goto unlock;
}
+ for (i = 0; i < s->nb_reserved_regions; i++) {
+ ReservedRegion *reg = &s->reserved_regions[i];
+
+ if (addr >= reg->low && addr <= reg->high) {
+ switch (reg->type) {
+ case VIRTIO_IOMMU_RESV_MEM_T_MSI:
+ entry.perm = flag;
+ break;
+ case VIRTIO_IOMMU_RESV_MEM_T_RESERVED:
+ default:
+ virtio_iommu_report_fault(s, VIRTIO_IOMMU_FAULT_R_MAPPING,
+ VIRTIO_IOMMU_FAULT_F_ADDRESS,
+ sid, addr);
+ break;
+ }
+ goto unlock;
+ }
+ }
+
if (!ep->domain) {
if (!bypass_allowed) {
error_report_once("%s %02x:%02x.%01x not attached to any domain",
@@ -667,6 +771,7 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
s->config.page_size_mask = TARGET_PAGE_MASK;
s->config.input_range.end = -1UL;
s->config.domain_range.end = 32;
+ s->config.probe_size = VIOMMU_PROBE_SIZE;
virtio_add_feature(&s->features, VIRTIO_RING_F_EVENT_IDX);
virtio_add_feature(&s->features, VIRTIO_RING_F_INDIRECT_DESC);
@@ -676,6 +781,7 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MAP_UNMAP);
virtio_add_feature(&s->features, VIRTIO_IOMMU_F_BYPASS);
virtio_add_feature(&s->features, VIRTIO_IOMMU_F_MMIO);
+ virtio_add_feature(&s->features, VIRTIO_IOMMU_F_PROBE);
qemu_mutex_init(&s->mutex);
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 4b00320..c4e2162 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -1391,5 +1391,5 @@ void xen_bus_init(void)
BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- qbus_set_bus_hotplug_handler(bus, &error_abort);
+ qbus_set_bus_hotplug_handler(bus);
}
diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c
index 2335ee2..7d4b133 100644
--- a/hw/xen/xen-legacy-backend.c
+++ b/hw/xen/xen-legacy-backend.c
@@ -705,7 +705,7 @@ int xen_be_init(void)
xen_sysdev = qdev_new(TYPE_XENSYSDEV);
sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal);
xen_sysbus = qbus_create(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
- qbus_set_bus_hotplug_handler(xen_sysbus, &error_abort);
+ qbus_set_bus_hotplug_handler(xen_sysbus);
return 0;