summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/acpi/nvdimm.c7
-rw-r--r--hw/acpi/pcihp.c4
-rw-r--r--hw/acpi/piix4.c7
-rw-r--r--hw/acpi/vmgenid.c30
-rw-r--r--hw/adc/stm32f2xx_adc.c2
-rw-r--r--hw/alpha/typhoon.c8
-rw-r--r--hw/arm/nseries.c2
-rw-r--r--hw/arm/omap1.c46
-rw-r--r--hw/arm/omap2.c12
-rw-r--r--hw/arm/palm.c14
-rw-r--r--hw/arm/pxa2xx.c46
-rw-r--r--hw/arm/pxa2xx_gpio.c6
-rw-r--r--hw/arm/pxa2xx_pic.c4
-rw-r--r--hw/arm/tosa.c10
-rw-r--r--hw/arm/virt.c27
-rw-r--r--hw/audio/hda-codec.c10
-rw-r--r--hw/audio/intel-hda.c28
-rw-r--r--hw/audio/wm8750.c4
-rw-r--r--hw/block/Makefile.objs3
-rw-r--r--hw/block/m25p80.c2
-rw-r--r--hw/block/nand.c4
-rw-r--r--hw/block/onenand.c8
-rw-r--r--hw/block/vhost-user-blk.c359
-rw-r--r--hw/bt/core.c15
-rw-r--r--hw/bt/hci-csr.c21
-rw-r--r--hw/bt/hci.c46
-rw-r--r--hw/bt/hid.c4
-rw-r--r--hw/bt/l2cap.c49
-rw-r--r--hw/bt/sdp.c11
-rw-r--r--hw/char/cadence_uart.c2
-rw-r--r--hw/char/stm32f2xx_usart.c2
-rw-r--r--hw/char/terminal3270.c28
-rw-r--r--hw/core/machine.c55
-rw-r--r--hw/core/qdev-properties.c61
-rw-r--r--hw/core/qdev.c28
-rw-r--r--hw/display/blizzard.c18
-rw-r--r--hw/display/cg3.c2
-rw-r--r--hw/display/dpcd.c2
-rw-r--r--hw/display/omap_dss.c6
-rw-r--r--hw/display/pxa2xx_lcd.c14
-rw-r--r--hw/display/qxl-render.c6
-rw-r--r--hw/display/qxl.c1
-rw-r--r--hw/display/qxl.h2
-rw-r--r--hw/display/sm501.c1
-rw-r--r--hw/display/tc6393xb.c2
-rw-r--r--hw/display/xenfb.c2
-rw-r--r--hw/display/xlnx_dp.c2
-rw-r--r--hw/dma/omap_dma.c26
-rw-r--r--hw/dma/pl330.c2
-rw-r--r--hw/dma/pxa2xx_dma.c14
-rw-r--r--hw/dma/xlnx-zynq-devcfg.c2
-rw-r--r--hw/dma/xlnx_dpdma.c2
-rw-r--r--hw/gpio/max7310.c8
-rw-r--r--hw/gpio/omap_gpio.c2
-rw-r--r--hw/i2c/i2c-ddc.c2
-rw-r--r--hw/i2c/omap_i2c.c6
-rw-r--r--hw/i2c/pm_smbus.c16
-rw-r--r--hw/i386/acpi-build.c5
-rw-r--r--hw/i386/amd_iommu.c13
-rw-r--r--hw/i386/intel_iommu.c148
-rw-r--r--hw/i386/intel_iommu_internal.h43
-rw-r--r--hw/i386/pc.c22
-rw-r--r--hw/i386/pc_piix.c23
-rw-r--r--hw/i386/pc_q35.c18
-rw-r--r--hw/i386/x86-iommu.c13
-rw-r--r--hw/i386/xen/xen_platform.c12
-rw-r--r--hw/ide/ahci.c2
-rw-r--r--hw/ide/ahci_internal.h4
-rw-r--r--hw/ide/core.c53
-rw-r--r--hw/ide/microdrive.c4
-rw-r--r--hw/ide/sii3112.c10
-rw-r--r--hw/input/lm832x.c6
-rw-r--r--hw/input/pxa2xx_keypad.c6
-rw-r--r--hw/input/tsc2005.c8
-rw-r--r--hw/input/tsc210x.c4
-rw-r--r--hw/intc/armv7m_nvic.c38
-rw-r--r--hw/intc/omap_intc.c2
-rw-r--r--hw/ipmi/ipmi_bmc_extern.c5
-rw-r--r--hw/isa/isa-bus.c7
-rw-r--r--hw/isa/lpc_ich9.c10
-rw-r--r--hw/isa/vt82c686.c2
-rw-r--r--hw/mem/nvdimm.c28
-rw-r--r--hw/mips/gt64xxx_pci.c14
-rw-r--r--hw/misc/auxbus.c2
-rw-r--r--hw/misc/cbus.c12
-rw-r--r--hw/misc/macio/mac_dbdma.c4
-rw-r--r--hw/misc/mmio_interface.c2
-rw-r--r--hw/misc/omap_clk.c4
-rw-r--r--hw/misc/omap_gpmc.c6
-rw-r--r--hw/misc/omap_l4.c4
-rw-r--r--hw/misc/omap_sdrc.c2
-rw-r--r--hw/misc/omap_tap.c6
-rw-r--r--hw/misc/stm32f2xx_syscfg.c2
-rw-r--r--hw/misc/tmp105.c2
-rw-r--r--hw/misc/zynq_slcr.c2
-rw-r--r--hw/net/cadence_gem.c2
-rw-r--r--hw/net/pcnet.c20
-rw-r--r--hw/net/vmxnet3.c2
-rw-r--r--hw/nvram/ds1225y.c4
-rw-r--r--hw/nvram/fw_cfg.c6
-rw-r--r--hw/pci-bridge/gen_pcie_root_port.c7
-rw-r--r--hw/pci-bridge/pci_expander_bridge.c21
-rw-r--r--hw/pci-host/apb.c10
-rw-r--r--hw/pci-host/bonito.c10
-rw-r--r--hw/pci-host/gpex.c6
-rw-r--r--hw/pci-host/grackle.c14
-rw-r--r--hw/pci-host/piix.c59
-rw-r--r--hw/pci-host/ppce500.c6
-rw-r--r--hw/pci-host/prep.c4
-rw-r--r--hw/pci-host/q35.c7
-rw-r--r--hw/pci-host/uninorth.c24
-rw-r--r--hw/pci-host/versatile.c8
-rw-r--r--hw/pci-host/xilinx-pcie.c27
-rw-r--r--hw/pci/pci.c141
-rw-r--r--hw/pci/pci_bridge.c6
-rw-r--r--hw/pci/pcie.c5
-rw-r--r--hw/pci/pcie_aer.c4
-rw-r--r--hw/pci/shpc.c13
-rw-r--r--hw/ppc/Makefile.objs6
-rw-r--r--hw/ppc/e500plat.c4
-rw-r--r--hw/ppc/pnv.c23
-rw-r--r--hw/ppc/pnv_core.c2
-rw-r--r--hw/ppc/pnv_xscom.c8
-rw-r--r--hw/ppc/ppc4xx_pci.c6
-rw-r--r--hw/ppc/spapr.c152
-rw-r--r--hw/ppc/spapr_caps.c315
-rw-r--r--hw/ppc/spapr_cpu_core.c7
-rw-r--r--hw/ppc/spapr_pci.c10
-rw-r--r--hw/ppc/spapr_rtas.c9
-rw-r--r--hw/s390x/s390-pci-bus.c18
-rw-r--r--hw/s390x/s390-stattrib-kvm.c4
-rw-r--r--hw/s390x/s390-virtio-ccw.c1
-rw-r--r--hw/s390x/sclp.c6
-rw-r--r--hw/s390x/virtio-ccw.c5
-rw-r--r--hw/scsi/megasas.c2
-rw-r--r--hw/scsi/mptsas.c2
-rw-r--r--hw/scsi/scsi-disk.c1
-rw-r--r--hw/scsi/scsi-generic.c9
-rw-r--r--hw/scsi/vmw_pvscsi.c2
-rw-r--r--hw/sd/milkymist-memcard.c4
-rw-r--r--hw/sd/omap_mmc.c14
-rw-r--r--hw/sd/pl181.c4
-rw-r--r--hw/sd/sdhci-internal.h7
-rw-r--r--hw/sd/sdhci.c266
-rw-r--r--hw/sd/ssi-sd.c25
-rw-r--r--hw/sd/trace-events14
-rw-r--r--hw/sh4/sh_pci.c12
-rw-r--r--hw/smbios/smbios.c72
-rw-r--r--hw/smbios/smbios_build.h12
-rw-r--r--hw/ssi/mss-spi.c2
-rw-r--r--hw/ssi/omap_spi.c6
-rw-r--r--hw/ssi/stm32f2xx_spi.c2
-rw-r--r--hw/ssi/xilinx_spi.c2
-rw-r--r--hw/ssi/xilinx_spips.c2
-rw-r--r--hw/timer/a9gtimer.c2
-rw-r--r--hw/timer/cadence_ttc.c2
-rw-r--r--hw/timer/hpet.c30
-rw-r--r--hw/timer/mss-timer.c2
-rw-r--r--hw/timer/omap_gptimer.c6
-rw-r--r--hw/timer/stm32f2xx_timer.c2
-rw-r--r--hw/timer/twl92230.c6
-rw-r--r--hw/tpm/tpm_passthrough.c2
-rw-r--r--hw/tpm/tpm_tis.c2
-rw-r--r--hw/usb/desc.c2
-rw-r--r--hw/usb/dev-bluetooth.c4
-rw-r--r--hw/usb/hcd-musb.c4
-rw-r--r--hw/usb/hcd-xhci.c2
-rw-r--r--hw/usb/tusb6010.c14
-rw-r--r--hw/vfio/pci.c10
-rw-r--r--hw/virtio/vhost-user.c318
-rw-r--r--hw/virtio/vhost.c32
-rw-r--r--hw/virtio/virtio-bus.c19
-rw-r--r--hw/virtio/virtio-pci.c67
-rw-r--r--hw/virtio/virtio-pci.h18
-rw-r--r--hw/virtio/virtio.c7
-rw-r--r--hw/xen/xen_backend.c2
-rw-r--r--hw/xen/xen_pt.c10
-rw-r--r--hw/xenpv/xen_domainbuild.c16
-rw-r--r--hw/xenpv/xen_machine_pv.c2
179 files changed, 2549 insertions, 1125 deletions
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 6ceea196e7..59d6e4254c 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -138,6 +138,8 @@ struct NvdimmNfitMemDev {
} QEMU_PACKED;
typedef struct NvdimmNfitMemDev NvdimmNfitMemDev;
+#define ACPI_NFIT_MEM_NOT_ARMED (1 << 3)
+
/*
* NVDIMM Control Region Structure
*
@@ -284,6 +286,7 @@ static void
nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev)
{
NvdimmNfitMemDev *nfit_memdev;
+ NVDIMMDevice *nvdimm = NVDIMM(OBJECT(dev));
uint64_t size = object_property_get_uint(OBJECT(dev), PC_DIMM_SIZE_PROP,
NULL);
int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
@@ -312,6 +315,10 @@ nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev)
/* Only one interleave for PMEM. */
nfit_memdev->interleave_ways = cpu_to_le16(1);
+
+ if (nvdimm->unarmed) {
+ nfit_memdev->flags |= cpu_to_le16(ACPI_NFIT_MEM_NOT_ARMED);
+ }
}
/*
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 7da51c0569..91c82fdc7a 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -223,7 +223,7 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
{
PCIDevice *pdev = PCI_DEVICE(dev);
int slot = PCI_SLOT(pdev->devfn);
- int bsel = acpi_pcihp_get_bsel(pdev->bus);
+ int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
if (bsel < 0) {
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
ACPI_PCIHP_PROP_BSEL "' set");
@@ -246,7 +246,7 @@ void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
{
PCIDevice *pdev = PCI_DEVICE(dev);
int slot = PCI_SLOT(pdev->devfn);
- int bsel = acpi_pcihp_get_bsel(pdev->bus);
+ int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
if (bsel < 0) {
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
ACPI_PCIHP_PROP_BSEL "' set");
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index a0fb1ce037..8b703455b7 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -460,9 +460,9 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque)
(memory_region_present(io_as, 0x2f8) ? 0x90 : 0);
if (s->use_acpi_pci_hotplug) {
- pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s);
+ pci_for_each_bus(pci_get_bus(d), piix4_update_bus_hotplug, s);
} else {
- piix4_update_bus_hotplug(d->bus, s);
+ piix4_update_bus_hotplug(pci_get_bus(d), s);
}
}
@@ -535,7 +535,8 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
qemu_add_machine_init_done_notifier(&s->machine_ready);
qemu_register_reset(piix4_reset, s);
- piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s);
+ piix4_acpi_system_hot_add_init(pci_address_space_io(dev),
+ pci_get_bus(dev), s);
piix4_pm_add_propeties(s);
}
diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c
index 105044f666..ba6f47b67b 100644
--- a/hw/acpi/vmgenid.c
+++ b/hw/acpi/vmgenid.c
@@ -162,21 +162,6 @@ static void vmgenid_update_guest(VmGenIdState *vms)
}
}
-static void vmgenid_set_guid(Object *obj, const char *value, Error **errp)
-{
- VmGenIdState *vms = VMGENID(obj);
-
- if (!strcmp(value, "auto")) {
- qemu_uuid_generate(&vms->guid);
- } else if (qemu_uuid_parse(value, &vms->guid) < 0) {
- error_setg(errp, "'%s. %s': Failed to parse GUID string: %s",
- object_get_typename(OBJECT(vms)), VMGENID_GUID, value);
- return;
- }
-
- vmgenid_update_guest(vms);
-}
-
/* After restoring an image, we need to update the guest memory and notify
* it of a potential change to VM Generation ID
*/
@@ -224,23 +209,24 @@ static void vmgenid_realize(DeviceState *dev, Error **errp)
}
qemu_register_reset(vmgenid_handle_reset, vms);
+
+ vmgenid_update_guest(vms);
}
+static Property vmgenid_device_properties[] = {
+ DEFINE_PROP_UUID(VMGENID_GUID, VmGenIdState, guid),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void vmgenid_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->vmsd = &vmstate_vmgenid;
dc->realize = vmgenid_realize;
+ dc->props = vmgenid_device_properties;
dc->hotpluggable = false;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
-
- object_class_property_add_str(klass, VMGENID_GUID, NULL,
- vmgenid_set_guid, NULL);
- object_class_property_set_description(klass, VMGENID_GUID,
- "Set Global Unique Identifier "
- "(big-endian) or auto for random value",
- NULL);
}
static const TypeInfo vmgenid_device_info = {
diff --git a/hw/adc/stm32f2xx_adc.c b/hw/adc/stm32f2xx_adc.c
index 90fe9de299..13f31ad2f7 100644
--- a/hw/adc/stm32f2xx_adc.c
+++ b/hw/adc/stm32f2xx_adc.c
@@ -37,7 +37,7 @@
if (STM_ADC_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index ae11e012c7..6a40869488 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -881,10 +881,10 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
memory_region_add_subregion(addr_space, 0x801fc000000ULL,
&s->pchip.reg_io);
- b = pci_register_bus(dev, "pci",
- typhoon_set_irq, sys_map_irq, s,
- &s->pchip.reg_mem, &s->pchip.reg_io,
- 0, 64, TYPE_PCI_BUS);
+ b = pci_register_root_bus(dev, "pci",
+ typhoon_set_irq, sys_map_irq, s,
+ &s->pchip.reg_mem, &s->pchip.reg_io,
+ 0, 64, TYPE_PCI_BUS);
phb->bus = b;
qdev_init_nofail(dev);
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 58005b6619..32687afced 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -463,7 +463,7 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
uint8_t ret;
if (len > 9) {
- hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
+ hw_error("%s: FIXME: bad SPI word width %i\n", __func__, len);
}
if (s->p >= ARRAY_SIZE(s->resp)) {
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index b3e7625130..92e58f09c8 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -999,7 +999,7 @@ static uint64_t omap_id_read(void *opaque, hwaddr addr,
case omap1510:
return 0x03310115;
default:
- hw_error("%s: bad mpu model\n", __FUNCTION__);
+ hw_error("%s: bad mpu model\n", __func__);
}
break;
@@ -1010,7 +1010,7 @@ static uint64_t omap_id_read(void *opaque, hwaddr addr,
case omap1510:
return 0xfb47002f;
default:
- hw_error("%s: bad mpu model\n", __FUNCTION__);
+ hw_error("%s: bad mpu model\n", __func__);
}
break;
}
@@ -1716,8 +1716,8 @@ static void omap_clkm_write(void *opaque, hwaddr addr,
case 0x18: /* ARM_SYSST */
if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
s->clkm.clocking_scheme = (value >> 11) & 7;
- printf("%s: clocking scheme set to %s\n", __FUNCTION__,
- clkschemename[s->clkm.clocking_scheme]);
+ printf("%s: clocking scheme set to %s\n", __func__,
+ clkschemename[s->clkm.clocking_scheme]);
}
s->clkm.cold_start &= value & 0x3f;
return;
@@ -2129,14 +2129,14 @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s)
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler)
{
if (line >= 16 || line < 0)
- hw_error("%s: No GPIO line %i\n", __FUNCTION__, line);
+ hw_error("%s: No GPIO line %i\n", __func__, line);
s->handler[line] = handler;
}
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down)
{
if (row >= 5 || row < 0)
- hw_error("%s: No key %i-%i\n", __FUNCTION__, col, row);
+ hw_error("%s: No key %i-%i\n", __func__, col, row);
if (down)
s->buttons[row] |= 1 << col;
@@ -2313,7 +2313,7 @@ void omap_uwire_attach(struct omap_uwire_s *s,
uWireSlave *slave, int chipselect)
{
if (chipselect < 0 || chipselect > 3) {
- fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
+ fprintf(stderr, "%s: Bad chipselect %i\n", __func__, chipselect);
exit(-1);
}
@@ -2335,7 +2335,7 @@ static void omap_pwl_update(struct omap_pwl_s *s)
if (output != s->output) {
s->output = output;
- printf("%s: Backlight now at %i/256\n", __FUNCTION__, output);
+ printf("%s: Backlight now at %i/256\n", __func__, output);
}
}
@@ -2473,7 +2473,7 @@ static void omap_pwt_write(void *opaque, hwaddr addr,
case 0x04: /* VRC */
if ((value ^ s->vrc) & 1) {
if (value & 1)
- printf("%s: %iHz buzz on\n", __FUNCTION__, (int)
+ printf("%s: %iHz buzz on\n", __func__, (int)
/* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
((omap_clk_getrate(s->clk) >> 3) /
/* Pre-multiplexer divider */
@@ -2490,7 +2490,7 @@ static void omap_pwt_write(void *opaque, hwaddr addr,
((value & (1 << 5)) ? 80 : 127) /
(107 * 55 * 63 * 127)));
else
- printf("%s: silence!\n", __FUNCTION__);
+ printf("%s: silence!\n", __func__);
}
s->vrc = value & 0x7f;
break;
@@ -2562,7 +2562,7 @@ static void omap_rtc_alarm_update(struct omap_rtc_s *s)
{
s->alarm_ti = mktimegm(&s->alarm_tm);
if (s->alarm_ti == -1)
- printf("%s: conversion failed\n", __FUNCTION__);
+ printf("%s: conversion failed\n", __func__);
}
static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
@@ -3028,7 +3028,7 @@ static void omap_mcbsp_source_tick(void *opaque)
if (!s->rx_rate)
return;
if (s->rx_req)
- printf("%s: Rx FIFO overrun\n", __FUNCTION__);
+ printf("%s: Rx FIFO overrun\n", __func__);
s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
@@ -3074,7 +3074,7 @@ static void omap_mcbsp_sink_tick(void *opaque)
if (!s->tx_rate)
return;
if (s->tx_req)
- printf("%s: Tx FIFO underrun\n", __FUNCTION__);
+ printf("%s: Tx FIFO underrun\n", __func__);
s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
@@ -3176,7 +3176,7 @@ static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
/* Fall through. */
case 0x02: /* DRR1 */
if (s->rx_req < 2) {
- printf("%s: Rx FIFO underrun\n", __FUNCTION__);
+ printf("%s: Rx FIFO underrun\n", __func__);
omap_mcbsp_rx_done(s);
} else {
s->tx_req -= 2;
@@ -3282,7 +3282,7 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
if (s->tx_req < 2)
omap_mcbsp_tx_done(s);
} else
- printf("%s: Tx FIFO overrun\n", __FUNCTION__);
+ printf("%s: Tx FIFO overrun\n", __func__);
return;
case 0x08: /* SPCR2 */
@@ -3297,7 +3297,7 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
s->spcr[0] &= 0x0006;
s->spcr[0] |= 0xf8f9 & value;
if (value & (1 << 15)) /* DLB */
- printf("%s: Digital Loopback mode enable attempt\n", __FUNCTION__);
+ printf("%s: Digital Loopback mode enable attempt\n", __func__);
if (~value & 1) { /* RRST */
s->spcr[0] &= ~6;
s->rx_req = 0;
@@ -3329,14 +3329,12 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
case 0x18: /* MCR2 */
s->mcr[1] = value & 0x03e3;
if (value & 3) /* XMCM */
- printf("%s: Tx channel selection mode enable attempt\n",
- __FUNCTION__);
+ printf("%s: Tx channel selection mode enable attempt\n", __func__);
return;
case 0x1a: /* MCR1 */
s->mcr[0] = value & 0x03e1;
if (value & 1) /* RMCM */
- printf("%s: Rx channel selection mode enable attempt\n",
- __FUNCTION__);
+ printf("%s: Rx channel selection mode enable attempt\n", __func__);
return;
case 0x1c: /* RCERA */
s->rcer[0] = value & 0xffff;
@@ -3418,7 +3416,7 @@ static void omap_mcbsp_writew(void *opaque, hwaddr addr,
if (s->tx_req < 4)
omap_mcbsp_tx_done(s);
} else
- printf("%s: Tx FIFO overrun\n", __FUNCTION__);
+ printf("%s: Tx FIFO overrun\n", __func__);
return;
}
@@ -3536,7 +3534,7 @@ static void omap_lpg_tick(void *opaque)
timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
s->cycle = !s->cycle;
- printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
+ printf("%s: LED is %s\n", __func__, s->cycle ? "on" : "off");
}
static void omap_lpg_update(struct omap_lpg_s *s)
@@ -3557,9 +3555,9 @@ static void omap_lpg_update(struct omap_lpg_s *s)
timer_del(s->tm);
if (on == period && s->on < s->period)
- printf("%s: LED is on\n", __FUNCTION__);
+ printf("%s: LED is on\n", __func__);
else if (on == 0 && s->on)
- printf("%s: LED is off\n", __FUNCTION__);
+ printf("%s: LED is off\n", __func__);
else if (on && (on != s->on || period != s->period)) {
s->cycle = 0;
s->on = on;
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index f5b148881c..b53878b8b9 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -1312,7 +1312,7 @@ static void omap_prcm_apll_update(struct omap_prcm_s *s)
if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[1] == 2)
fprintf(stderr, "%s: bad EN_54M_PLL or bad EN_96M_PLL\n",
- __FUNCTION__);
+ __func__);
}
static void omap_prcm_dpll_update(struct omap_prcm_s *s)
@@ -1331,7 +1331,7 @@ static void omap_prcm_dpll_update(struct omap_prcm_s *s)
s->dpll_lock = 0;
switch (mode) {
case 0:
- fprintf(stderr, "%s: bad EN_DPLL\n", __FUNCTION__);
+ fprintf(stderr, "%s: bad EN_DPLL\n", __func__);
break;
case 1: /* Low-power bypass mode (Default) */
case 2: /* Fast-relock bypass mode */
@@ -1358,7 +1358,7 @@ static void omap_prcm_dpll_update(struct omap_prcm_s *s)
omap_clk_reparent(core, dpll_x2);
break;
case 3:
- fprintf(stderr, "%s: bad CORE_CLK_SRC\n", __FUNCTION__);
+ fprintf(stderr, "%s: bad CORE_CLK_SRC\n", __func__);
break;
}
}
@@ -1628,7 +1628,7 @@ static void omap_prcm_write(void *opaque, hwaddr addr,
case 0x500: /* CM_CLKEN_PLL */
if (value & 0xffffff30)
fprintf(stderr, "%s: write 0s in CM_CLKEN_PLL for "
- "future compatibility\n", __FUNCTION__);
+ "future compatibility\n", __func__);
if ((s->clken[9] ^ value) & 0xcc) {
s->clken[9] &= ~0xcc;
s->clken[9] |= value & 0xcc;
@@ -1647,7 +1647,7 @@ static void omap_prcm_write(void *opaque, hwaddr addr,
case 0x540: /* CM_CLKSEL1_PLL */
if (value & 0xfc4000d7)
fprintf(stderr, "%s: write 0s in CM_CLKSEL1_PLL for "
- "future compatibility\n", __FUNCTION__);
+ "future compatibility\n", __func__);
if ((s->clksel[5] ^ value) & 0x003fff00) {
s->clksel[5] = value & 0x03bfff28;
omap_prcm_dpll_update(s);
@@ -1659,7 +1659,7 @@ static void omap_prcm_write(void *opaque, hwaddr addr,
case 0x544: /* CM_CLKSEL2_PLL */
if (value & ~3)
fprintf(stderr, "%s: write 0s in CM_CLKSEL2_PLL[31:2] for "
- "future compatibility\n", __FUNCTION__);
+ "future compatibility\n", __func__);
if (s->clksel[6] != (value & 3)) {
s->clksel[6] = value & 3;
omap_prcm_dpll_update(s);
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index a1f55d79b4..285f43709d 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -44,7 +44,7 @@ static void static_write(void *opaque, hwaddr offset, uint64_t value,
{
#ifdef SPY
printf("%s: value %08lx written at " PA_FMT "\n",
- __FUNCTION__, value, offset);
+ __func__, value, offset);
#endif
}
@@ -127,11 +127,11 @@ static void palmte_onoff_gpios(void *opaque, int line, int level)
switch (line) {
case 0:
printf("%s: current to MMC/SD card %sabled.\n",
- __FUNCTION__, level ? "dis" : "en");
+ __func__, level ? "dis" : "en");
break;
case 1:
printf("%s: internal speaker amplifier %s.\n",
- __FUNCTION__, level ? "down" : "on");
+ __func__, level ? "down" : "on");
break;
/* These LCD & Audio output signals have not been identified yet. */
@@ -139,12 +139,12 @@ static void palmte_onoff_gpios(void *opaque, int line, int level)
case 3:
case 4:
printf("%s: LCD GPIO%i %s.\n",
- __FUNCTION__, line - 1, level ? "high" : "low");
+ __func__, line - 1, level ? "high" : "low");
break;
case 5:
case 6:
printf("%s: Audio GPIO%i %s.\n",
- __FUNCTION__, line - 4, level ? "high" : "low");
+ __func__, line - 4, level ? "high" : "low");
break;
}
}
@@ -234,7 +234,7 @@ static void palmte_init(MachineState *machine)
rom_size = get_image_size(option_rom[0].name);
if (rom_size > flash_size) {
fprintf(stderr, "%s: ROM image too big (%x > %x)\n",
- __FUNCTION__, rom_size, flash_size);
+ __func__, rom_size, flash_size);
rom_size = 0;
}
if (rom_size > 0) {
@@ -244,7 +244,7 @@ static void palmte_init(MachineState *machine)
}
if (rom_size < 0) {
fprintf(stderr, "%s: error loading '%s'\n",
- __FUNCTION__, option_rom[0].name);
+ __func__, option_rom[0].name);
}
}
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index ab691a7985..db860c238e 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -107,7 +107,7 @@ static uint64_t pxa2xx_pm_read(void *opaque, hwaddr addr,
return s->pm_regs[addr >> 2];
default:
fail:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
return 0;
@@ -139,7 +139,7 @@ static void pxa2xx_pm_write(void *opaque, hwaddr addr,
break;
}
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
}
@@ -180,7 +180,7 @@ static uint64_t pxa2xx_cm_read(void *opaque, hwaddr addr,
return s->cm_regs[CCCR >> 2] | (3 << 28);
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
return 0;
@@ -205,7 +205,7 @@ static void pxa2xx_cm_write(void *opaque, hwaddr addr,
break;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
}
@@ -410,7 +410,7 @@ static uint64_t pxa2xx_mm_read(void *opaque, hwaddr addr,
return s->mm_regs[addr >> 2];
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
return 0;
@@ -429,7 +429,7 @@ static void pxa2xx_mm_write(void *opaque, hwaddr addr,
}
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
}
@@ -619,7 +619,7 @@ static uint64_t pxa2xx_ssp_read(void *opaque, hwaddr addr,
if (!s->enable)
return 0xffffffff;
if (s->rx_level < 1) {
- printf("%s: SSP Rx Underrun\n", __FUNCTION__);
+ printf("%s: SSP Rx Underrun\n", __func__);
return 0xffffffff;
}
s->rx_level --;
@@ -636,7 +636,7 @@ static uint64_t pxa2xx_ssp_read(void *opaque, hwaddr addr,
case SSACD:
return s->ssacd;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
return 0;
@@ -653,9 +653,9 @@ static void pxa2xx_ssp_write(void *opaque, hwaddr addr,
s->sscr[0] = value & 0xc7ffffff;
s->enable = value & SSCR0_SSE;
if (value & SSCR0_MOD)
- printf("%s: Attempt to use network mode\n", __FUNCTION__);
+ printf("%s: Attempt to use network mode\n", __func__);
if (s->enable && SSCR0_DSS(value) < 4)
- printf("%s: Wrong data size: %i bits\n", __FUNCTION__,
+ printf("%s: Wrong data size: %i bits\n", __func__,
SSCR0_DSS(value));
if (!(value & SSCR0_SSE)) {
s->sssr = 0;
@@ -668,7 +668,7 @@ static void pxa2xx_ssp_write(void *opaque, hwaddr addr,
case SSCR1:
s->sscr[1] = value;
if (value & (SSCR1_LBM | SSCR1_EFWR))
- printf("%s: Attempt to use SSP test mode\n", __FUNCTION__);
+ printf("%s: Attempt to use SSP test mode\n", __func__);
pxa2xx_ssp_fifo_update(s);
break;
@@ -728,7 +728,7 @@ static void pxa2xx_ssp_write(void *opaque, hwaddr addr,
break;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
}
@@ -990,7 +990,7 @@ static uint64_t pxa2xx_rtc_read(void *opaque, hwaddr addr,
else
return s->last_swcr;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
return 0;
@@ -1096,7 +1096,7 @@ static void pxa2xx_rtc_write(void *opaque, hwaddr addr,
break;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
}
}
@@ -1344,7 +1344,7 @@ static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr,
s->ibmr = 0;
return s->ibmr;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
return 0;
@@ -1417,7 +1417,7 @@ static void pxa2xx_i2c_write(void *opaque, hwaddr addr,
break;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
}
}
@@ -1618,7 +1618,7 @@ static uint64_t pxa2xx_i2s_read(void *opaque, hwaddr addr,
}
return 0;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
return 0;
@@ -1641,14 +1641,14 @@ static void pxa2xx_i2s_write(void *opaque, hwaddr addr,
s->status &= ~(1 << 7); /* I2SOFF */
}
if (value & (1 << 4)) /* EFWR */
- printf("%s: Attempt to use special function\n", __FUNCTION__);
+ printf("%s: Attempt to use special function\n", __func__);
s->enable = (value & 9) == 1; /* ENB && !RST*/
pxa2xx_i2s_update(s);
break;
case SACR1:
s->control[1] = value & 0x0039;
if (value & (1 << 5)) /* ENLBF */
- printf("%s: Attempt to use loopback function\n", __FUNCTION__);
+ printf("%s: Attempt to use loopback function\n", __func__);
if (value & (1 << 4)) /* DPRL */
s->fifo_len = 0;
pxa2xx_i2s_update(s);
@@ -1675,7 +1675,7 @@ static void pxa2xx_i2s_write(void *opaque, hwaddr addr,
}
break;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
}
}
@@ -1851,7 +1851,7 @@ static uint64_t pxa2xx_fir_read(void *opaque, hwaddr addr,
pxa2xx_fir_update(s);
return ret;
}
- printf("%s: Rx FIFO underrun.\n", __FUNCTION__);
+ printf("%s: Rx FIFO underrun.\n", __func__);
break;
case ICSR0:
return s->status[0];
@@ -1860,7 +1860,7 @@ static uint64_t pxa2xx_fir_read(void *opaque, hwaddr addr,
case ICFOR:
return s->rx_len;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
break;
}
return 0;
@@ -1912,7 +1912,7 @@ static void pxa2xx_fir_write(void *opaque, hwaddr addr,
case ICFOR:
break;
default:
- printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);
+ printf("%s: Bad register " REG_FMT "\n", __func__, addr);
}
}
diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c
index 521dbad039..e15070188e 100644
--- a/hw/arm/pxa2xx_gpio.c
+++ b/hw/arm/pxa2xx_gpio.c
@@ -107,7 +107,7 @@ static void pxa2xx_gpio_set(void *opaque, int line, int level)
uint32_t mask;
if (line >= s->lines) {
- printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
+ printf("%s: No GPIO pin %i\n", __func__, line);
return;
}
@@ -195,7 +195,7 @@ static uint64_t pxa2xx_gpio_read(void *opaque, hwaddr offset,
return s->status[bank];
default:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
+ hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
}
return 0;
@@ -248,7 +248,7 @@ static void pxa2xx_gpio_write(void *opaque, hwaddr offset,
break;
default:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
+ hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
}
}
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
index b516ced8c0..61275fa040 100644
--- a/hw/arm/pxa2xx_pic.c
+++ b/hw/arm/pxa2xx_pic.c
@@ -165,7 +165,7 @@ 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", __FUNCTION__, offset);
+ printf("%s: Bad register offset " REG_FMT "\n", __func__, offset);
return 0;
}
}
@@ -198,7 +198,7 @@ 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", __FUNCTION__, offset);
+ printf("%s: Bad register offset " REG_FMT "\n", __func__, offset);
return;
}
pxa2xx_pic_update(opaque);
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 044796350a..a55b1a369c 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -159,7 +159,7 @@ static int tosa_dac_send(I2CSlave *i2c, uint8_t data)
s->buf[s->len] = data;
if (s->len ++ > 2) {
#ifdef VERBOSE
- fprintf(stderr, "%s: message too long (%i bytes)\n", __FUNCTION__, s->len);
+ fprintf(stderr, "%s: message too long (%i bytes)\n", __func__, s->len);
#endif
return 1;
}
@@ -181,14 +181,14 @@ static int tosa_dac_event(I2CSlave *i2c, enum i2c_event event)
case I2C_START_SEND:
break;
case I2C_START_RECV:
- printf("%s: recv not supported!!!\n", __FUNCTION__);
+ printf("%s: recv not supported!!!\n", __func__);
break;
case I2C_FINISH:
#ifdef VERBOSE
if (s->len < 2)
- printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len);
+ printf("%s: message too short (%i bytes)\n", __func__, s->len);
if (s->len > 2)
- printf("%s: message too long\n", __FUNCTION__);
+ printf("%s: message too long\n", __func__);
#endif
break;
default:
@@ -200,7 +200,7 @@ static int tosa_dac_event(I2CSlave *i2c, enum i2c_event event)
static int tosa_dac_recv(I2CSlave *s)
{
- printf("%s: recv not supported!!!\n", __FUNCTION__);
+ printf("%s: recv not supported!!!\n", __func__);
return -1;
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 151592b1e5..a4537af400 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -34,6 +34,8 @@
#include "hw/arm/arm.h"
#include "hw/arm/primecell.h"
#include "hw/arm/virt.h"
+#include "hw/vfio/vfio-calxeda-xgmac.h"
+#include "hw/vfio/vfio-amd-xgbe.h"
#include "hw/devices.h"
#include "net/net.h"
#include "sysemu/block-backend.h"
@@ -1357,7 +1359,7 @@ static void machvirt_init(MachineState *machine)
break;
}
- cpuobj = object_new(machine->cpu_type);
+ cpuobj = object_new(possible_cpus->cpus[n].type);
object_property_set_int(cpuobj, possible_cpus->cpus[n].arch_id,
"mp-affinity", NULL);
@@ -1573,6 +1575,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
sizeof(CPUArchId) * max_cpus);
ms->possible_cpus->len = max_cpus;
for (n = 0; n < ms->possible_cpus->len; n++) {
+ ms->possible_cpus->cpus[n].type = ms->cpu_type;
ms->possible_cpus->cpus[n].arch_id =
virt_cpu_mp_affinity(vms, n);
ms->possible_cpus->cpus[n].props.has_thread_id = true;
@@ -1591,7 +1594,8 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
* configuration of the particular instance.
*/
mc->max_cpus = 255;
- mc->has_dynamic_sysbus = true;
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC);
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
mc->block_default_type = IF_VIRTIO;
mc->no_cdrom = 1;
mc->pci_allow_0_address = true;
@@ -1618,7 +1622,7 @@ static void machvirt_machine_init(void)
}
type_init(machvirt_machine_init);
-static void virt_2_11_instance_init(Object *obj)
+static void virt_2_12_instance_init(Object *obj)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
@@ -1678,10 +1682,25 @@ static void virt_2_11_instance_init(Object *obj)
vms->irqmap = a15irqmap;
}
+static void virt_machine_2_12_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(2, 12)
+
+#define VIRT_COMPAT_2_11 \
+ HW_COMPAT_2_11
+
+static void virt_2_11_instance_init(Object *obj)
+{
+ virt_2_12_instance_init(obj);
+}
+
static void virt_machine_2_11_options(MachineClass *mc)
{
+ virt_machine_2_12_options(mc);
+ SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_11);
}
-DEFINE_VIRT_MACHINE_AS_LATEST(2, 11)
+DEFINE_VIRT_MACHINE(2, 11)
#define VIRT_COMPAT_2_10 \
HW_COMPAT_2_10
diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
index 5402cd196c..e8aa7842e6 100644
--- a/hw/audio/hda-codec.c
+++ b/hw/audio/hda-codec.c
@@ -316,7 +316,7 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
goto fail;
}
dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n",
- __FUNCTION__, nid, node->name, verb, payload);
+ __func__, nid, node->name, verb, payload);
switch (verb) {
/* all nodes */
@@ -449,7 +449,7 @@ static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)
fail:
dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n",
- __FUNCTION__, nid, node ? node->name : "?", verb, payload);
+ __func__, nid, node ? node->name : "?", verb, payload);
hda_codec_response(hda, true, 0);
}
@@ -484,7 +484,7 @@ static int hda_audio_init(HDACodecDevice *hda, const struct desc_codec *desc)
a->desc = desc;
a->name = object_get_typename(OBJECT(a));
- dprint(a, 1, "%s: cad %d\n", __FUNCTION__, a->hda.cad);
+ dprint(a, 1, "%s: cad %d\n", __func__, a->hda.cad);
AUD_register_card("hda", &a->card);
for (i = 0; i < a->desc->nnodes; i++) {
@@ -526,7 +526,7 @@ static void hda_audio_exit(HDACodecDevice *hda)
HDAAudioStream *st;
int i;
- dprint(a, 1, "%s\n", __FUNCTION__);
+ dprint(a, 1, "%s\n", __func__);
for (i = 0; i < ARRAY_SIZE(a->st); i++) {
st = a->st + i;
if (st->node == NULL) {
@@ -547,7 +547,7 @@ static int hda_audio_post_load(void *opaque, int version)
HDAAudioStream *st;
int i;
- dprint(a, 1, "%s\n", __FUNCTION__);
+ dprint(a, 1, "%s\n", __func__);
if (version == 1) {
/* assume running_compat[] is for output streams */
for (i = 0; i < ARRAY_SIZE(a->running_compat); i++)
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index a3e670c188..948268afd8 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -265,7 +265,7 @@ static void intel_hda_update_irq(IntelHDAState *d)
} else {
level = 0;
}
- dprint(d, 2, "%s: level %d [%s]\n", __FUNCTION__,
+ dprint(d, 2, "%s: level %d [%s]\n", __func__,
level, msi ? "msi" : "intx");
if (msi) {
if (level) {
@@ -285,7 +285,7 @@ static int intel_hda_send_command(IntelHDAState *d, uint32_t verb)
cad = (verb >> 28) & 0x0f;
if (verb & (1 << 27)) {
/* indirect node addressing, not specified in HDA 1.0 */
- dprint(d, 1, "%s: indirect node addressing (guest bug?)\n", __FUNCTION__);
+ dprint(d, 1, "%s: indirect node addressing (guest bug?)\n", __func__);
return -1;
}
nid = (verb >> 20) & 0x7f;
@@ -293,7 +293,7 @@ static int intel_hda_send_command(IntelHDAState *d, uint32_t verb)
codec = hda_codec_find(&d->codecs, cad);
if (codec == NULL) {
- dprint(d, 1, "%s: addressed non-existing codec\n", __FUNCTION__);
+ dprint(d, 1, "%s: addressed non-existing codec\n", __func__);
return -1;
}
cdc = HDA_CODEC_DEVICE_GET_CLASS(codec);
@@ -307,22 +307,22 @@ static void intel_hda_corb_run(IntelHDAState *d)
uint32_t rp, verb;
if (d->ics & ICH6_IRS_BUSY) {
- dprint(d, 2, "%s: [icw] verb 0x%08x\n", __FUNCTION__, d->icw);
+ dprint(d, 2, "%s: [icw] verb 0x%08x\n", __func__, d->icw);
intel_hda_send_command(d, d->icw);
return;
}
for (;;) {
if (!(d->corb_ctl & ICH6_CORBCTL_RUN)) {
- dprint(d, 2, "%s: !run\n", __FUNCTION__);
+ dprint(d, 2, "%s: !run\n", __func__);
return;
}
if ((d->corb_rp & 0xff) == d->corb_wp) {
- dprint(d, 2, "%s: corb ring empty\n", __FUNCTION__);
+ dprint(d, 2, "%s: corb ring empty\n", __func__);
return;
}
if (d->rirb_count == d->rirb_cnt) {
- dprint(d, 2, "%s: rirb count reached\n", __FUNCTION__);
+ dprint(d, 2, "%s: rirb count reached\n", __func__);
return;
}
@@ -331,7 +331,7 @@ static void intel_hda_corb_run(IntelHDAState *d)
verb = ldl_le_pci_dma(&d->pci, addr + 4*rp);
d->corb_rp = rp;
- dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __FUNCTION__, rp, verb);
+ dprint(d, 2, "%s: [rp 0x%x] verb 0x%08x\n", __func__, rp, verb);
intel_hda_send_command(d, verb);
}
}
@@ -345,7 +345,7 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
if (d->ics & ICH6_IRS_BUSY) {
dprint(d, 2, "%s: [irr] response 0x%x, cad 0x%x\n",
- __FUNCTION__, response, dev->cad);
+ __func__, response, dev->cad);
d->irr = response;
d->ics &= ~(ICH6_IRS_BUSY | 0xf0);
d->ics |= (ICH6_IRS_VALID | (dev->cad << 4));
@@ -353,7 +353,7 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
}
if (!(d->rirb_ctl & ICH6_RBCTL_DMA_EN)) {
- dprint(d, 1, "%s: rirb dma disabled, drop codec response\n", __FUNCTION__);
+ dprint(d, 1, "%s: rirb dma disabled, drop codec response\n", __func__);
return;
}
@@ -365,17 +365,17 @@ static void intel_hda_response(HDACodecDevice *dev, bool solicited, uint32_t res
d->rirb_wp = wp;
dprint(d, 2, "%s: [wp 0x%x] response 0x%x, extra 0x%x\n",
- __FUNCTION__, wp, response, ex);
+ __func__, wp, response, ex);
d->rirb_count++;
if (d->rirb_count == d->rirb_cnt) {
- dprint(d, 2, "%s: rirb count reached (%d)\n", __FUNCTION__, d->rirb_count);
+ dprint(d, 2, "%s: rirb count reached (%d)\n", __func__, d->rirb_count);
if (d->rirb_ctl & ICH6_RBCTL_IRQ_EN) {
d->rirb_sts |= ICH6_RBSTS_IRQ;
intel_hda_update_irq(d);
}
} else if ((d->corb_rp & 0xff) == d->corb_wp) {
- dprint(d, 2, "%s: corb ring empty (%d/%d)\n", __FUNCTION__,
+ dprint(d, 2, "%s: corb ring empty (%d/%d)\n", __func__,
d->rirb_count, d->rirb_cnt);
if (d->rirb_ctl & ICH6_RBCTL_IRQ_EN) {
d->rirb_sts |= ICH6_RBSTS_IRQ;
@@ -1144,7 +1144,7 @@ static int intel_hda_post_load(void *opaque, int version)
IntelHDAState* d = opaque;
int i;
- dprint(d, 1, "%s\n", __FUNCTION__);
+ dprint(d, 1, "%s\n", __func__);
for (i = 0; i < ARRAY_SIZE(d->st); i++) {
if (d->st[i].ctl & 0x02) {
intel_hda_parse_bdl(d, &d->st[i]);
diff --git a/hw/audio/wm8750.c b/hw/audio/wm8750.c
index 8bb44a7cc1..6d8b728923 100644
--- a/hw/audio/wm8750.c
+++ b/hw/audio/wm8750.c
@@ -315,7 +315,7 @@ static int wm8750_event(I2CSlave *i2c, enum i2c_event event)
#ifdef VERBOSE
if (s->i2c_len < 2)
printf("%s: message too short (%i bytes)\n",
- __FUNCTION__, s->i2c_len);
+ __func__, s->i2c_len);
#endif
break;
default:
@@ -555,7 +555,7 @@ static int wm8750_tx(I2CSlave *i2c, uint8_t data)
#ifdef VERBOSE
default:
- printf("%s: unknown register %02x\n", __FUNCTION__, cmd);
+ printf("%s: unknown register %02x\n", __func__, cmd);
#endif
}
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index e0ed980c90..4c19a583c8 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -13,3 +13,6 @@ obj-$(CONFIG_SH4) += tc58128.o
obj-$(CONFIG_VIRTIO) += virtio-blk.o
obj-$(CONFIG_VIRTIO) += dataplane/
+ifeq ($(CONFIG_VIRTIO),y)
+obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk.o
+endif
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index ea142160b3..b49c8e9caa 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -40,7 +40,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/* Fields for FlashPartInfo->flags */
diff --git a/hw/block/nand.c b/hw/block/nand.c
index 76dcd3f76e..919cb9b803 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -321,7 +321,7 @@ static void nand_command(NANDFlashState *s)
break;
default:
- printf("%s: Unknown NAND command 0x%02x\n", __FUNCTION__, s->cmd);
+ printf("%s: Unknown NAND command 0x%02x\n", __func__, s->cmd);
}
}
@@ -640,7 +640,7 @@ DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id)
DeviceState *dev;
if (nand_flash_ids[chip_id].size == 0) {
- hw_error("%s: Unsupported NAND chip ID.\n", __FUNCTION__);
+ hw_error("%s: Unsupported NAND chip ID.\n", __func__);
}
dev = DEVICE(object_new(TYPE_NAND));
qdev_prop_set_uint8(dev, "manufacturer_id", manf_id);
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
index de65c9ebb9..ed77f859e9 100644
--- a/hw/block/onenand.c
+++ b/hw/block/onenand.c
@@ -659,12 +659,12 @@ static uint64_t onenand_read(void *opaque, hwaddr addr,
case 0xff02: /* ECC Result of spare area data */
case 0xff03: /* ECC Result of main area data */
case 0xff04: /* ECC Result of spare area data */
- hw_error("%s: imeplement ECC\n", __FUNCTION__);
+ hw_error("%s: implement ECC\n", __func__);
return 0x0000;
}
fprintf(stderr, "%s: unknown OneNAND register %x\n",
- __FUNCTION__, offset);
+ __func__, offset);
return 0;
}
@@ -709,7 +709,7 @@ static void onenand_write(void *opaque, hwaddr addr,
default:
fprintf(stderr, "%s: unknown OneNAND boot command %"PRIx64"\n",
- __FUNCTION__, value);
+ __func__, value);
}
break;
@@ -760,7 +760,7 @@ static void onenand_write(void *opaque, hwaddr addr,
default:
fprintf(stderr, "%s: unknown OneNAND register %x\n",
- __FUNCTION__, offset);
+ __func__, offset);
}
}
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
new file mode 100644
index 0000000000..b53b4c9c57
--- /dev/null
+++ b/hw/block/vhost-user-blk.c
@@ -0,0 +1,359 @@
+/*
+ * vhost-user-blk host device
+ *
+ * Copyright(C) 2017 Intel Corporation.
+ *
+ * Authors:
+ * Changpeng Liu <changpeng.liu@intel.com>
+ *
+ * Largely based on the "vhost-user-scsi.c" and "vhost-scsi.c" implemented by:
+ * Felipe Franciosi <felipe@nutanix.com>
+ * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+ * Nicholas Bellinger <nab@risingtidesystems.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/typedefs.h"
+#include "qemu/cutils.h"
+#include "qom/object.h"
+#include "hw/qdev-core.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user-blk.h"
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/virtio-access.h"
+
+static const int user_feature_bits[] = {
+ VIRTIO_BLK_F_SIZE_MAX,
+ VIRTIO_BLK_F_SEG_MAX,
+ VIRTIO_BLK_F_GEOMETRY,
+ VIRTIO_BLK_F_BLK_SIZE,
+ VIRTIO_BLK_F_TOPOLOGY,
+ VIRTIO_BLK_F_MQ,
+ VIRTIO_BLK_F_RO,
+ VIRTIO_BLK_F_FLUSH,
+ VIRTIO_BLK_F_CONFIG_WCE,
+ VIRTIO_F_VERSION_1,
+ VIRTIO_RING_F_INDIRECT_DESC,
+ VIRTIO_RING_F_EVENT_IDX,
+ VIRTIO_F_NOTIFY_ON_EMPTY,
+ VHOST_INVALID_FEATURE_BIT
+};
+
+static void vhost_user_blk_update_config(VirtIODevice *vdev, uint8_t *config)
+{
+ VHostUserBlk *s = VHOST_USER_BLK(vdev);
+
+ memcpy(config, &s->blkcfg, sizeof(struct virtio_blk_config));
+}
+
+static void vhost_user_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
+{
+ VHostUserBlk *s = VHOST_USER_BLK(vdev);
+ struct virtio_blk_config *blkcfg = (struct virtio_blk_config *)config;
+ int ret;
+
+ if (blkcfg->wce == s->blkcfg.wce) {
+ return;
+ }
+
+ ret = vhost_dev_set_config(&s->dev, &blkcfg->wce,
+ offsetof(struct virtio_blk_config, wce),
+ sizeof(blkcfg->wce),
+ VHOST_SET_CONFIG_TYPE_MASTER);
+ if (ret) {
+ error_report("set device config space failed");
+ return;
+ }
+
+ s->blkcfg.wce = blkcfg->wce;
+}
+
+static int vhost_user_blk_handle_config_change(struct vhost_dev *dev)
+{
+ int ret;
+ struct virtio_blk_config blkcfg;
+ VHostUserBlk *s = VHOST_USER_BLK(dev->vdev);
+
+ ret = vhost_dev_get_config(dev, (uint8_t *)&blkcfg,
+ sizeof(struct virtio_blk_config));
+ if (ret < 0) {
+ error_report("get config space failed");
+ return -1;
+ }
+
+ /* valid for resize only */
+ if (blkcfg.capacity != s->blkcfg.capacity) {
+ s->blkcfg.capacity = blkcfg.capacity;
+ memcpy(dev->vdev->config, &s->blkcfg, sizeof(struct virtio_blk_config));
+ virtio_notify_config(dev->vdev);
+ }
+
+ return 0;
+}
+
+const VhostDevConfigOps blk_ops = {
+ .vhost_dev_config_notifier = vhost_user_blk_handle_config_change,
+};
+
+static void vhost_user_blk_start(VirtIODevice *vdev)
+{
+ VHostUserBlk *s = VHOST_USER_BLK(vdev);
+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+ int i, ret;
+
+ if (!k->set_guest_notifiers) {
+ error_report("binding does not support guest notifiers");
+ return;
+ }
+
+ ret = vhost_dev_enable_notifiers(&s->dev, vdev);
+ if (ret < 0) {
+ error_report("Error enabling host notifiers: %d", -ret);
+ return;
+ }
+
+ ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, true);
+ if (ret < 0) {
+ error_report("Error binding guest notifier: %d", -ret);
+ goto err_host_notifiers;
+ }
+
+ s->dev.acked_features = vdev->guest_features;
+ ret = vhost_dev_start(&s->dev, vdev);
+ if (ret < 0) {
+ error_report("Error starting vhost: %d", -ret);
+ goto err_guest_notifiers;
+ }
+
+ /* guest_notifier_mask/pending not used yet, so just unmask
+ * everything here. virtio-pci will do the right thing by
+ * enabling/disabling irqfd.
+ */
+ for (i = 0; i < s->dev.nvqs; i++) {
+ vhost_virtqueue_mask(&s->dev, vdev, i, false);
+ }
+
+ return;
+
+err_guest_notifiers:
+ k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
+err_host_notifiers:
+ vhost_dev_disable_notifiers(&s->dev, vdev);
+}
+
+static void vhost_user_blk_stop(VirtIODevice *vdev)
+{
+ VHostUserBlk *s = VHOST_USER_BLK(vdev);
+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+ int ret;
+
+ if (!k->set_guest_notifiers) {
+ return;
+ }
+
+ vhost_dev_stop(&s->dev, vdev);
+
+ ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
+ if (ret < 0) {
+ error_report("vhost guest notifier cleanup failed: %d", ret);
+ return;
+ }
+
+ vhost_dev_disable_notifiers(&s->dev, vdev);
+}
+
+static void vhost_user_blk_set_status(VirtIODevice *vdev, uint8_t status)
+{
+ VHostUserBlk *s = VHOST_USER_BLK(vdev);
+ bool should_start = status & VIRTIO_CONFIG_S_DRIVER_OK;
+
+ if (!vdev->vm_running) {
+ should_start = false;
+ }
+
+ if (s->dev.started == should_start) {
+ return;
+ }
+
+ if (should_start) {
+ vhost_user_blk_start(vdev);
+ } else {
+ vhost_user_blk_stop(vdev);
+ }
+
+}
+
+static uint64_t vhost_user_blk_get_features(VirtIODevice *vdev,
+ uint64_t features,
+ Error **errp)
+{
+ VHostUserBlk *s = VHOST_USER_BLK(vdev);
+ uint64_t get_features;
+
+ /* Turn on pre-defined features */
+ virtio_add_feature(&features, VIRTIO_BLK_F_SEG_MAX);
+ virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
+ virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
+ virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
+ virtio_add_feature(&features, VIRTIO_BLK_F_FLUSH);
+
+ if (s->config_wce) {
+ virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
+ }
+ if (s->config_ro) {
+ virtio_add_feature(&features, VIRTIO_BLK_F_RO);
+ }
+ if (s->num_queues > 1) {
+ virtio_add_feature(&features, VIRTIO_BLK_F_MQ);
+ }
+
+ get_features = vhost_get_features(&s->dev, user_feature_bits, features);
+
+ return get_features;
+}
+
+static void vhost_user_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+
+}
+
+static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VHostUserBlk *s = VHOST_USER_BLK(vdev);
+ int i, ret;
+
+ if (!s->chardev.chr) {
+ error_setg(errp, "vhost-user-blk: chardev is mandatory");
+ return;
+ }
+
+ if (!s->num_queues || s->num_queues > VIRTIO_QUEUE_MAX) {
+ error_setg(errp, "vhost-user-blk: invalid number of IO queues");
+ return;
+ }
+
+ if (!s->queue_size) {
+ error_setg(errp, "vhost-user-blk: queue size must be non-zero");
+ return;
+ }
+
+ virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
+ sizeof(struct virtio_blk_config));
+
+ for (i = 0; i < s->num_queues; i++) {
+ virtio_add_queue(vdev, s->queue_size,
+ vhost_user_blk_handle_output);
+ }
+
+ s->dev.nvqs = s->num_queues;
+ s->dev.vqs = g_new(struct vhost_virtqueue, s->dev.nvqs);
+ s->dev.vq_index = 0;
+ s->dev.backend_features = 0;
+
+ ret = vhost_dev_init(&s->dev, &s->chardev, VHOST_BACKEND_TYPE_USER, 0);
+ if (ret < 0) {
+ error_setg(errp, "vhost-user-blk: vhost initialization failed: %s",
+ strerror(-ret));
+ goto virtio_err;
+ }
+
+ ret = vhost_dev_get_config(&s->dev, (uint8_t *)&s->blkcfg,
+ sizeof(struct virtio_blk_config));
+ if (ret < 0) {
+ error_setg(errp, "vhost-user-blk: get block config failed");
+ goto vhost_err;
+ }
+
+ if (s->blkcfg.num_queues != s->num_queues) {
+ s->blkcfg.num_queues = s->num_queues;
+ }
+
+ vhost_dev_set_config_notifier(&s->dev, &blk_ops);
+
+ return;
+
+vhost_err:
+ vhost_dev_cleanup(&s->dev);
+virtio_err:
+ g_free(s->dev.vqs);
+ virtio_cleanup(vdev);
+}
+
+static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VHostUserBlk *s = VHOST_USER_BLK(dev);
+
+ vhost_user_blk_set_status(vdev, 0);
+ vhost_dev_cleanup(&s->dev);
+ g_free(s->dev.vqs);
+ virtio_cleanup(vdev);
+}
+
+static void vhost_user_blk_instance_init(Object *obj)
+{
+ VHostUserBlk *s = VHOST_USER_BLK(obj);
+
+ device_add_bootindex_property(obj, &s->bootindex, "bootindex",
+ "/disk@0,0", DEVICE(obj), NULL);
+}
+
+static const VMStateDescription vmstate_vhost_user_blk = {
+ .name = "vhost-user-blk",
+ .minimum_version_id = 1,
+ .version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_VIRTIO_DEVICE,
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static Property vhost_user_blk_properties[] = {
+ DEFINE_PROP_CHR("chardev", VHostUserBlk, chardev),
+ DEFINE_PROP_UINT16("num-queues", VHostUserBlk, num_queues, 1),
+ DEFINE_PROP_UINT32("queue-size", VHostUserBlk, queue_size, 128),
+ DEFINE_PROP_BIT("config-wce", VHostUserBlk, config_wce, 0, true),
+ DEFINE_PROP_BIT("config-ro", VHostUserBlk, config_ro, 0, false),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_user_blk_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+
+ dc->props = vhost_user_blk_properties;
+ dc->vmsd = &vmstate_vhost_user_blk;
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ vdc->realize = vhost_user_blk_device_realize;
+ vdc->unrealize = vhost_user_blk_device_unrealize;
+ vdc->get_config = vhost_user_blk_update_config;
+ vdc->set_config = vhost_user_blk_set_config;
+ vdc->get_features = vhost_user_blk_get_features;
+ vdc->set_status = vhost_user_blk_set_status;
+}
+
+static const TypeInfo vhost_user_blk_info = {
+ .name = TYPE_VHOST_USER_BLK,
+ .parent = TYPE_VIRTIO_DEVICE,
+ .instance_size = sizeof(VHostUserBlk),
+ .instance_init = vhost_user_blk_instance_init,
+ .class_init = vhost_user_blk_class_init,
+};
+
+static void virtio_register_types(void)
+{
+ type_register_static(&vhost_user_blk_info);
+}
+
+type_init(virtio_register_types)
diff --git a/hw/bt/core.c b/hw/bt/core.c
index 615f0af073..78370e64f5 100644
--- a/hw/bt/core.c
+++ b/hw/bt/core.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/error-report.h"
#include "qemu-common.h"
#include "sysemu/bt.h"
#include "hw/bt.h"
@@ -31,24 +32,22 @@ static void bt_dummy_lmp_mode_change(struct bt_link_s *link)
static void bt_dummy_lmp_connection_complete(struct bt_link_s *link)
{
if (link->slave->reject_reason)
- fprintf(stderr, "%s: stray LMP_not_accepted received, fixme\n",
- __FUNCTION__);
+ error_report("%s: stray LMP_not_accepted received, fixme", __func__);
else
- fprintf(stderr, "%s: stray LMP_accepted received, fixme\n",
- __FUNCTION__);
+ error_report("%s: stray LMP_accepted received, fixme", __func__);
exit(-1);
}
static void bt_dummy_lmp_disconnect_master(struct bt_link_s *link)
{
- fprintf(stderr, "%s: stray LMP_detach received, fixme\n", __FUNCTION__);
+ error_report("%s: stray LMP_detach received, fixme", __func__);
exit(-1);
}
static void bt_dummy_lmp_acl_resp(struct bt_link_s *link,
const uint8_t *data, int start, int len)
{
- fprintf(stderr, "%s: stray ACL response PDU, fixme\n", __FUNCTION__);
+ error_report("%s: stray ACL response PDU, fixme", __func__);
exit(-1);
}
@@ -113,8 +112,8 @@ void bt_device_done(struct bt_device_s *dev)
while (*p && *p != dev)
p = &(*p)->next;
if (*p != dev) {
- fprintf(stderr, "%s: bad bt device \"%s\"\n", __FUNCTION__,
- dev->lmp_name ?: "(null)");
+ error_report("%s: bad bt device \"%s\"", __func__,
+ dev->lmp_name ?: "(null)");
exit(-1);
}
diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c
index d13192b9b5..0341ded50c 100644
--- a/hw/bt/hci-csr.c
+++ b/hw/bt/hci-csr.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/error-report.h"
#include "qemu-common.h"
#include "chardev/char-serial.h"
#include "qemu/timer.h"
@@ -111,14 +112,14 @@ static uint8_t *csrhci_out_packet(struct csrhci_s *s, int len)
if (off < FIFO_LEN) {
if (off + len > FIFO_LEN && (s->out_size = off + len) > FIFO_LEN * 2) {
- fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
+ error_report("%s: can't alloc %i bytes", __func__, len);
exit(-1);
}
return s->outfifo + off;
}
if (s->out_len > s->out_size) {
- fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
+ error_report("%s: can't alloc %i bytes", __func__, len);
exit(-1);
}
@@ -168,10 +169,10 @@ static void csrhci_in_packet_vendor(struct csrhci_s *s, int ocf,
s->bd_addr.b[5] = data[offset + 2];
s->hci->bdaddr_set(s->hci, s->bd_addr.b);
- fprintf(stderr, "%s: bd_address loaded from firmware: "
- "%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
- s->bd_addr.b[0], s->bd_addr.b[1], s->bd_addr.b[2],
- s->bd_addr.b[3], s->bd_addr.b[4], s->bd_addr.b[5]);
+ error_report("%s: bd_address loaded from firmware: "
+ "%02x:%02x:%02x:%02x:%02x:%02x", __func__,
+ s->bd_addr.b[0], s->bd_addr.b[1], s->bd_addr.b[2],
+ s->bd_addr.b[3], s->bd_addr.b[4], s->bd_addr.b[5]);
}
rpkt = csrhci_out_packet_event(s, EVT_VENDOR, 11);
@@ -181,7 +182,7 @@ static void csrhci_in_packet_vendor(struct csrhci_s *s, int ocf,
break;
default:
- fprintf(stderr, "%s: got a bad CMD packet\n", __FUNCTION__);
+ error_report("%s: got a bad CMD packet", __func__);
return;
}
@@ -226,7 +227,7 @@ static void csrhci_in_packet(struct csrhci_s *s, uint8_t *pkt)
case H4_NEG_PKT:
if (s->in_hdr != sizeof(csrhci_neg_packet) ||
memcmp(pkt - 1, csrhci_neg_packet, s->in_hdr)) {
- fprintf(stderr, "%s: got a bad NEG packet\n", __FUNCTION__);
+ error_report("%s: got a bad NEG packet", __func__);
return;
}
pkt += 2;
@@ -241,7 +242,7 @@ static void csrhci_in_packet(struct csrhci_s *s, uint8_t *pkt)
case H4_ALIVE_PKT:
if (s->in_hdr != 4 || pkt[1] != 0x55 || pkt[2] != 0x00) {
- fprintf(stderr, "%s: got a bad ALIVE packet\n", __FUNCTION__);
+ error_report("%s: got a bad ALIVE packet", __func__);
return;
}
@@ -254,7 +255,7 @@ static void csrhci_in_packet(struct csrhci_s *s, uint8_t *pkt)
default:
bad_pkt:
/* TODO: error out */
- fprintf(stderr, "%s: got a bad packet\n", __FUNCTION__);
+ error_report("%s: got a bad packet", __func__);
break;
}
diff --git a/hw/bt/hci.c b/hw/bt/hci.c
index 476ebec0ab..c6b2cc1d48 100644
--- a/hw/bt/hci.c
+++ b/hw/bt/hci.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "qemu/timer.h"
@@ -457,8 +458,7 @@ static inline uint8_t *bt_hci_event_start(struct bt_hci_s *hci,
int mask_byte;
if (len > 255) {
- fprintf(stderr, "%s: HCI event params too long (%ib)\n",
- __FUNCTION__, len);
+ error_report("%s: HCI event params too long (%ib)", __func__, len);
exit(-1);
}
@@ -589,8 +589,8 @@ static void bt_hci_inquiry_result(struct bt_hci_s *hci,
bt_hci_inquiry_result_with_rssi(hci, slave);
return;
default:
- fprintf(stderr, "%s: bad inquiry mode %02x\n", __FUNCTION__,
- hci->lm.inquiry_mode);
+ error_report("%s: bad inquiry mode %02x", __func__,
+ hci->lm.inquiry_mode);
exit(-1);
}
}
@@ -1528,7 +1528,7 @@ static void bt_submit_hci(struct HCIInfo *info,
"the Inquiry command has been issued, a Command "
"Status event has been received for the Inquiry "
"command, and before the Inquiry Complete event "
- "occurs", __FUNCTION__);
+ "occurs", __func__);
bt_hci_event_complete_status(hci, HCI_COMMAND_DISALLOWED);
break;
}
@@ -1567,7 +1567,7 @@ static void bt_submit_hci(struct HCIInfo *info,
"the Inquiry command has been issued, a Command "
"Status event has been received for the Inquiry "
"command, and before the Inquiry Complete event "
- "occurs", __FUNCTION__);
+ "occurs", __func__);
bt_hci_event_complete_status(hci, HCI_COMMAND_DISALLOWED);
break;
}
@@ -1971,8 +1971,7 @@ static void bt_submit_hci(struct HCIInfo *info,
break;
short_hci:
- fprintf(stderr, "%s: HCI packet too short (%iB)\n",
- __FUNCTION__, length);
+ error_report("%s: HCI packet too short (%iB)", __func__, length);
bt_hci_event_status(hci, HCI_INVALID_PARAMETERS);
break;
}
@@ -1991,8 +1990,8 @@ static inline void bt_hci_lmp_acl_data(struct bt_hci_s *hci, uint16_t handle,
/* TODO: avoid memcpy'ing */
if (len + HCI_ACL_HDR_SIZE > sizeof(hci->acl_buf)) {
- fprintf(stderr, "%s: can't take ACL packets %i bytes long\n",
- __FUNCTION__, len);
+ error_report("%s: can't take ACL packets %i bytes long",
+ __func__, len);
return;
}
memcpy(hci->acl_buf + HCI_ACL_HDR_SIZE, data, len);
@@ -2029,8 +2028,7 @@ static void bt_submit_acl(struct HCIInfo *info,
struct bt_link_s *link;
if (length < HCI_ACL_HDR_SIZE) {
- fprintf(stderr, "%s: ACL packet too short (%iB)\n",
- __FUNCTION__, length);
+ error_report("%s: ACL packet too short (%iB)", __func__, length);
return;
}
@@ -2041,16 +2039,15 @@ static void bt_submit_acl(struct HCIInfo *info,
length -= HCI_ACL_HDR_SIZE;
if (bt_hci_handle_bad(hci, handle)) {
- fprintf(stderr, "%s: invalid ACL handle %03x\n",
- __FUNCTION__, handle);
+ error_report("%s: invalid ACL handle %03x", __func__, handle);
/* TODO: signal an error */
return;
}
handle &= ~HCI_HANDLE_OFFSET;
if (datalen > length) {
- fprintf(stderr, "%s: ACL packet too short (%iB < %iB)\n",
- __FUNCTION__, length, datalen);
+ error_report("%s: ACL packet too short (%iB < %iB)",
+ __func__, length, datalen);
return;
}
@@ -2060,8 +2057,8 @@ static void bt_submit_acl(struct HCIInfo *info,
if (!hci->asb_handle)
hci->asb_handle = handle;
else if (handle != hci->asb_handle) {
- fprintf(stderr, "%s: Bad handle %03x in Active Slave Broadcast\n",
- __FUNCTION__, handle);
+ error_report("%s: Bad handle %03x in Active Slave Broadcast",
+ __func__, handle);
/* TODO: signal an error */
return;
}
@@ -2073,8 +2070,8 @@ static void bt_submit_acl(struct HCIInfo *info,
if (!hci->psb_handle)
hci->psb_handle = handle;
else if (handle != hci->psb_handle) {
- fprintf(stderr, "%s: Bad handle %03x in Parked Slave Broadcast\n",
- __FUNCTION__, handle);
+ error_report("%s: Bad handle %03x in Parked Slave Broadcast",
+ __func__, handle);
/* TODO: signal an error */
return;
}
@@ -2105,14 +2102,13 @@ static void bt_submit_sco(struct HCIInfo *info,
length -= 3;
if (bt_hci_handle_bad(hci, handle)) {
- fprintf(stderr, "%s: invalid SCO handle %03x\n",
- __FUNCTION__, handle);
+ error_report("%s: invalid SCO handle %03x", __func__, handle);
return;
}
if (datalen > length) {
- fprintf(stderr, "%s: SCO packet too short (%iB < %iB)\n",
- __FUNCTION__, length, datalen);
+ error_report("%s: SCO packet too short (%iB < %iB)",
+ __func__, length, datalen);
return;
}
@@ -2223,7 +2219,7 @@ struct HCIInfo *hci_init(const char *str)
return bt_new_hci(vlan);
}
- fprintf(stderr, "qemu: Unknown bluetooth HCI `%s'.\n", str);
+ error_report("Unknown bluetooth HCI `%s'.", str);
return 0;
}
diff --git a/hw/bt/hid.c b/hw/bt/hid.c
index f6affbbb44..056291f9b5 100644
--- a/hw/bt/hid.c
+++ b/hw/bt/hid.c
@@ -419,8 +419,8 @@ static void bt_hid_interrupt_sdu(void *opaque, const uint8_t *data, int len)
return;
bad:
- fprintf(stderr, "%s: bad transaction on Interrupt channel.\n",
- __FUNCTION__);
+ error_report("%s: bad transaction on Interrupt channel.",
+ __func__);
}
/* "Virtual cable" plug/unplug event. */
diff --git a/hw/bt/l2cap.c b/hw/bt/l2cap.c
index e342045140..9cf27f0df6 100644
--- a/hw/bt/l2cap.c
+++ b/hw/bt/l2cap.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/error-report.h"
#include "qemu-common.h"
#include "qemu/timer.h"
#include "qemu/bswap.h"
@@ -467,8 +468,8 @@ static void l2cap_channel_close(struct l2cap_instance_s *l2cap,
if (likely(ch)) {
if (ch->remote_cid != source_cid) {
- fprintf(stderr, "%s: Ignoring a Disconnection Request with the "
- "invalid SCID %04x.\n", __FUNCTION__, source_cid);
+ error_report("%s: Ignoring a Disconnection Request with the "
+ "invalid SCID %04x.", __func__, source_cid);
return;
}
@@ -790,8 +791,8 @@ static void l2cap_command(struct l2cap_instance_s *l2cap, int code, int id,
#if 0
/* TODO: do the IDs really have to be in sequence? */
if (!id || (id != l2cap->last_id && id != l2cap->next_id)) {
- fprintf(stderr, "%s: out of sequence command packet ignored.\n",
- __FUNCTION__);
+ error_report("%s: out of sequence command packet ignored.",
+ __func__);
return;
}
#else
@@ -813,9 +814,9 @@ static void l2cap_command(struct l2cap_instance_s *l2cap, int code, int id,
}
/* We never issue commands other than Command Reject currently. */
- fprintf(stderr, "%s: stray Command Reject (%02x, %04x) "
- "packet, ignoring.\n", __FUNCTION__, id,
- le16_to_cpu(((l2cap_cmd_rej *) params)->reason));
+ error_report("%s: stray Command Reject (%02x, %04x) "
+ "packet, ignoring.", __func__, id,
+ le16_to_cpu(((l2cap_cmd_rej *) params)->reason));
break;
case L2CAP_CONN_REQ:
@@ -836,8 +837,8 @@ static void l2cap_command(struct l2cap_instance_s *l2cap, int code, int id,
}
/* We never issue Connection Requests currently. TODO */
- fprintf(stderr, "%s: unexpected Connection Response (%02x) "
- "packet, ignoring.\n", __FUNCTION__, id);
+ error_report("%s: unexpected Connection Response (%02x) "
+ "packet, ignoring.", __func__, id);
break;
case L2CAP_CONF_REQ:
@@ -865,8 +866,8 @@ static void l2cap_command(struct l2cap_instance_s *l2cap, int code, int id,
le16_to_cpu(((l2cap_conf_rsp *) params)->scid),
((l2cap_conf_rsp *) params)->data,
len - L2CAP_CONF_RSP_SIZE(0)))
- fprintf(stderr, "%s: unexpected Configure Response (%02x) "
- "packet, ignoring.\n", __FUNCTION__, id);
+ error_report("%s: unexpected Configure Response (%02x) "
+ "packet, ignoring.", __func__, id);
break;
case L2CAP_DISCONN_REQ:
@@ -887,8 +888,8 @@ static void l2cap_command(struct l2cap_instance_s *l2cap, int code, int id,
}
/* We never issue Disconnection Requests currently. TODO */
- fprintf(stderr, "%s: unexpected Disconnection Response (%02x) "
- "packet, ignoring.\n", __FUNCTION__, id);
+ error_report("%s: unexpected Disconnection Response (%02x) "
+ "packet, ignoring.", __func__, id);
break;
case L2CAP_ECHO_REQ:
@@ -897,8 +898,8 @@ static void l2cap_command(struct l2cap_instance_s *l2cap, int code, int id,
case L2CAP_ECHO_RSP:
/* We never issue Echo Requests currently. TODO */
- fprintf(stderr, "%s: unexpected Echo Response (%02x) "
- "packet, ignoring.\n", __FUNCTION__, id);
+ error_report("%s: unexpected Echo Response (%02x) "
+ "packet, ignoring.", __func__, id);
break;
case L2CAP_INFO_REQ:
@@ -917,8 +918,8 @@ static void l2cap_command(struct l2cap_instance_s *l2cap, int code, int id,
}
/* We never issue Information Requests currently. TODO */
- fprintf(stderr, "%s: unexpected Information Response (%02x) "
- "packet, ignoring.\n", __FUNCTION__, id);
+ error_report("%s: unexpected Information Response (%02x) "
+ "packet, ignoring.", __func__, id);
break;
default:
@@ -1066,8 +1067,8 @@ static void l2cap_frame_in(struct l2cap_instance_s *l2cap,
uint16_t len = le16_to_cpu(frame->len);
if (unlikely(cid >= L2CAP_CID_MAX || !l2cap->cid[cid])) {
- fprintf(stderr, "%s: frame addressed to a non-existent L2CAP "
- "channel %04x received.\n", __FUNCTION__, cid);
+ error_report("%s: frame addressed to a non-existent L2CAP "
+ "channel %04x received.", __func__, cid);
return;
}
@@ -1128,9 +1129,9 @@ static uint8_t *l2cap_bframe_out(struct bt_l2cap_conn_params_s *parm, int len)
struct l2cap_chan_s *chan = (struct l2cap_chan_s *) parm;
if (len > chan->params.remote_mtu) {
- fprintf(stderr, "%s: B-Frame for CID %04x longer than %i octets.\n",
- __FUNCTION__,
- chan->remote_cid, chan->params.remote_mtu);
+ error_report("%s: B-Frame for CID %04x longer than %i octets.",
+ __func__,
+ chan->remote_cid, chan->params.remote_mtu);
exit(-1);
}
@@ -1353,8 +1354,8 @@ void bt_l2cap_psm_register(struct bt_l2cap_device_s *dev, int psm, int min_mtu,
struct bt_l2cap_psm_s *new_psm = l2cap_psm(dev, psm);
if (new_psm) {
- fprintf(stderr, "%s: PSM %04x already registered for device `%s'.\n",
- __FUNCTION__, psm, dev->device.lmp_name);
+ error_report("%s: PSM %04x already registered for device `%s'.",
+ __func__, psm, dev->device.lmp_name);
exit(-1);
}
diff --git a/hw/bt/sdp.c b/hw/bt/sdp.c
index 3cb60b9495..f4aba9d74f 100644
--- a/hw/bt/sdp.c
+++ b/hw/bt/sdp.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/error-report.h"
#include "qemu-common.h"
#include "qemu/host-utils.h"
#include "hw/bt.h"
@@ -506,7 +507,7 @@ static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len)
int rsp_len = 0;
if (len < 5) {
- fprintf(stderr, "%s: short SDP PDU (%iB).\n", __FUNCTION__, len);
+ error_report("%s: short SDP PDU (%iB).", __func__, len);
return;
}
@@ -517,8 +518,8 @@ static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len)
len -= 5;
if (len != plen) {
- fprintf(stderr, "%s: wrong SDP PDU length (%iB != %iB).\n",
- __FUNCTION__, plen, len);
+ error_report("%s: wrong SDP PDU length (%iB != %iB).",
+ __func__, plen, len);
err = SDP_INVALID_PDU_SIZE;
goto respond;
}
@@ -544,8 +545,8 @@ static void bt_l2cap_sdp_sdu_in(void *opaque, const uint8_t *data, int len)
case SDP_SVC_SEARCH_RSP:
case SDP_SVC_SEARCH_ATTR_RSP:
default:
- fprintf(stderr, "%s: unexpected SDP PDU ID %02x.\n",
- __FUNCTION__, pdu_id);
+ error_report("%s: unexpected SDP PDU ID %02x.",
+ __func__, pdu_id);
err = SDP_INVALID_SYNTAX;
break;
}
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index 6143494060..fbdbd463bb 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -33,7 +33,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
- } while (0);
+ } while (0)
#else
#define DB_PRINT(...)
#endif
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
index 268e435338..07b462d4b6 100644
--- a/hw/char/stm32f2xx_usart.c
+++ b/hw/char/stm32f2xx_usart.c
@@ -34,7 +34,7 @@
if (STM_USART_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c
index a109ce5987..e9c45e55b1 100644
--- a/hw/char/terminal3270.c
+++ b/hw/char/terminal3270.c
@@ -31,7 +31,7 @@ typedef struct Terminal3270 {
uint8_t outv[OUTPUT_BUFFER_SIZE];
int in_len;
bool handshake_done;
- guint timer_tag;
+ GSource *timer_src;
} Terminal3270;
#define TYPE_TERMINAL_3270 "x-terminal3270"
@@ -45,6 +45,15 @@ static int terminal_can_read(void *opaque)
return INPUT_BUFFER_SIZE - t->in_len;
}
+static void terminal_timer_cancel(Terminal3270 *t)
+{
+ if (t->timer_src) {
+ g_source_destroy(t->timer_src);
+ g_source_unref(t->timer_src);
+ t->timer_src = NULL;
+ }
+}
+
/*
* Protocol handshake done,
* signal guest by an unsolicited DE irq.
@@ -90,12 +99,9 @@ static void terminal_read(void *opaque, const uint8_t *buf, int size)
assert(size <= (INPUT_BUFFER_SIZE - t->in_len));
- if (t->timer_tag) {
- g_source_remove(t->timer_tag);
- t->timer_tag = 0;
- }
- t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
-
+ terminal_timer_cancel(t);
+ t->timer_src = qemu_chr_timeout_add_ms(t->chr.chr, 600 * 1000,
+ send_timing_mark_cb, t);
memcpy(&t->inv[t->in_len], buf, size);
t->in_len += size;
if (t->in_len < 2) {
@@ -145,10 +151,7 @@ static void chr_event(void *opaque, int event)
/* Ensure the initial status correct, always reset them. */
t->in_len = 0;
t->handshake_done = false;
- if (t->timer_tag) {
- g_source_remove(t->timer_tag);
- t->timer_tag = 0;
- }
+ terminal_timer_cancel(t);
switch (event) {
case CHR_EVENT_OPENED:
@@ -157,7 +160,8 @@ static void chr_event(void *opaque, int event)
* char-socket.c. Once qemu receives the terminal-type of the
* client, mark handshake done and trigger everything rolling again.
*/
- t->timer_tag = g_timeout_add_seconds(600, send_timing_mark_cb, t);
+ t->timer_src = qemu_chr_timeout_add_ms(t->chr.chr, 600 * 1000,
+ send_timing_mark_cb, t);
break;
case CHR_EVENT_CLOSED:
sch->curr_status.scsw.dstat = SCSW_DSTAT_DEVICE_END;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index c857f3f934..cdc1163dc6 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -334,46 +334,61 @@ static bool machine_get_enforce_config_section(Object *obj, Error **errp)
return ms->enforce_config_section;
}
-static void error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
+void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type)
{
- error_report("Option '-device %s' cannot be handled by this machine",
- object_class_get_name(object_get_class(OBJECT(sbdev))));
- exit(1);
+ strList *item = g_new0(strList, 1);
+
+ item->value = g_strdup(type);
+ item->next = mc->allowed_dynamic_sysbus_devices;
+ mc->allowed_dynamic_sysbus_devices = item;
}
-static void machine_init_notify(Notifier *notifier, void *data)
+static void validate_sysbus_device(SysBusDevice *sbdev, void *opaque)
{
- Object *machine = qdev_get_machine();
- ObjectClass *oc = object_get_class(machine);
- MachineClass *mc = MACHINE_CLASS(oc);
+ MachineState *machine = opaque;
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ bool allowed = false;
+ strList *wl;
- if (mc->has_dynamic_sysbus) {
- /* Our machine can handle dynamic sysbus devices, we're all good */
- return;
+ for (wl = mc->allowed_dynamic_sysbus_devices;
+ !allowed && wl;
+ wl = wl->next) {
+ allowed |= !!object_dynamic_cast(OBJECT(sbdev), wl->value);
+ }
+
+ if (!allowed) {
+ error_report("Option '-device %s' cannot be handled by this machine",
+ object_class_get_name(object_get_class(OBJECT(sbdev))));
+ exit(1);
}
+}
+
+static void machine_init_notify(Notifier *notifier, void *data)
+{
+ MachineState *machine = MACHINE(qdev_get_machine());
/*
- * Loop through all dynamically created devices and check whether there
- * are sysbus devices among them. If there are, error out.
+ * Loop through all dynamically created sysbus devices and check if they are
+ * all allowed. If a device is not allowed, error out.
*/
- foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
+ foreach_dynamic_sysbus_device(validate_sysbus_device, machine);
}
HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
{
int i;
- Object *cpu;
HotpluggableCPUList *head = NULL;
- const char *cpu_type;
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+
+ /* force board to initialize possible_cpus if it hasn't been done yet */
+ mc->possible_cpu_arch_ids(machine);
- cpu = machine->possible_cpus->cpus[0].cpu;
- assert(cpu); /* Boot cpu is always present */
- cpu_type = object_get_typename(cpu);
for (i = 0; i < machine->possible_cpus->len; i++) {
+ Object *cpu;
HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1);
HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1);
- cpu_item->type = g_strdup(cpu_type);
+ cpu_item->type = g_strdup(machine->possible_cpus->cpus[i].type);
cpu_item->vcpus_count = machine->possible_cpus->cpus[i].vcpus_count;
cpu_item->props = g_memdup(&machine->possible_cpus->cpus[i].props,
sizeof(*cpu_item->props));
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 1dc80fcea2..24c17800e3 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -10,6 +10,7 @@
#include "net/hub.h"
#include "qapi/visitor.h"
#include "chardev/char.h"
+#include "qemu/uuid.h"
void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
Error **errp)
@@ -883,6 +884,66 @@ const PropertyInfo qdev_prop_pci_host_devaddr = {
.set = set_pci_host_devaddr,
};
+/* --- UUID --- */
+
+static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
+ Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
+ char buffer[UUID_FMT_LEN + 1];
+ char *p = buffer;
+
+ qemu_uuid_unparse(uuid, buffer);
+
+ visit_type_str(v, name, &p, errp);
+}
+
+#define UUID_VALUE_AUTO "auto"
+
+static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
+ Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
+ char *str;
+
+ 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;
+ }
+
+ if (!strcmp(str, UUID_VALUE_AUTO)) {
+ qemu_uuid_generate(uuid);
+ } else if (qemu_uuid_parse(str, uuid) < 0) {
+ error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+ }
+ g_free(str);
+}
+
+static void set_default_uuid_auto(Object *obj, const Property *prop)
+{
+ object_property_set_str(obj, UUID_VALUE_AUTO, prop->name, &error_abort);
+}
+
+const PropertyInfo qdev_prop_uuid = {
+ .name = "str",
+ .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
+ "\" for random value (default)",
+ .get = get_uuid,
+ .set = set_uuid,
+ .set_default_value = set_default_uuid_auto,
+};
+
/* --- support for array properties --- */
/* Used as an opaque for the object properties we add for each
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 11112951a5..f739753e3a 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -253,19 +253,31 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
dev->alias_required_for_version = required_for_version;
}
+HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
+{
+ MachineState *machine;
+ MachineClass *mc;
+ Object *m_obj = qdev_get_machine();
+
+ if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
+ machine = MACHINE(m_obj);
+ mc = MACHINE_GET_CLASS(machine);
+ if (mc->get_hotplug_handler) {
+ return mc->get_hotplug_handler(machine, dev);
+ }
+ }
+
+ return NULL;
+}
+
HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
{
- HotplugHandler *hotplug_ctrl = NULL;
+ HotplugHandler *hotplug_ctrl;
if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
hotplug_ctrl = dev->parent_bus->hotplug_handler;
- } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
- MachineState *machine = MACHINE(qdev_get_machine());
- MachineClass *mc = MACHINE_GET_CLASS(machine);
-
- if (mc->get_hotplug_handler) {
- hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
- }
+ } else {
+ hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
}
return hotplug_ctrl;
}
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
index cbf07d14d9..291abe6fca 100644
--- a/hw/display/blizzard.c
+++ b/hw/display/blizzard.c
@@ -474,7 +474,7 @@ static uint16_t blizzard_reg_read(void *opaque, uint8_t reg)
return s->gpio_pdown;
default:
- fprintf(stderr, "%s: unknown register %02x\n", __FUNCTION__, reg);
+ fprintf(stderr, "%s: unknown register %02x\n", __func__, reg);
return 0;
}
}
@@ -502,7 +502,7 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)
s->pll_mode = value & 0x77;
if ((value & 3) == 0 || (value & 3) == 3)
fprintf(stderr, "%s: wrong PLL Control bits (%i)\n",
- __FUNCTION__, value & 3);
+ __func__, value & 3);
break;
case 0x0e: /* Clock-Source Select */
@@ -541,7 +541,7 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)
case 0x28: /* LCD Panel Configuration */
s->lcd_config = value & 0xff;
if (value & (1 << 7))
- fprintf(stderr, "%s: data swap not supported!\n", __FUNCTION__);
+ fprintf(stderr, "%s: data swap not supported!\n", __func__);
break;
case 0x2a: /* LCD Horizontal Display Width */
@@ -586,7 +586,7 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)
s->hssi_config[1] = value;
if (((value >> 4) & 3) == 3)
fprintf(stderr, "%s: Illegal active-data-links value\n",
- __FUNCTION__);
+ __func__);
break;
case 0x42: /* High-speed Serial Interface Tx Mode */
s->hssi_config[2] = value & 0xbd;
@@ -641,7 +641,7 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)
s->enable = value & 1;
s->blank = (value >> 1) & 1;
if (value & (1 << 4))
- fprintf(stderr, "%s: Macrovision enable attempt!\n", __FUNCTION__);
+ fprintf(stderr, "%s: Macrovision enable attempt!\n", __func__);
break;
case 0x6a: /* Special Effects */
@@ -718,7 +718,7 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)
s->bpp = blizzard_iformat_bpp[s->iformat];
if (!s->bpp)
fprintf(stderr, "%s: Illegal or unsupported input format %x\n",
- __FUNCTION__, s->iformat);
+ __func__, s->iformat);
break;
case 0x8e: /* Data Source Select */
s->source = value & 7;
@@ -730,7 +730,7 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)
!((s->ix[1] - s->ix[0]) & (s->iy[1] - s->iy[0]) &
(s->ox[1] - s->ox[0]) & (s->oy[1] - s->oy[0]) & 1))
fprintf(stderr, "%s: Illegal input/output window positions\n",
- __FUNCTION__);
+ __func__);
blizzard_transfer_setup(s);
break;
@@ -784,7 +784,7 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)
s->pm = value & 0x83;
if (value & s->mode & 1)
fprintf(stderr, "%s: The display must be disabled before entering "
- "Standby Mode\n", __FUNCTION__);
+ "Standby Mode\n", __func__);
break;
case 0xe8: /* Non-display Period Control / Status */
s->status = value & 0x1b;
@@ -815,7 +815,7 @@ static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)
break;
default:
- fprintf(stderr, "%s: unknown register %02x\n", __FUNCTION__, reg);
+ fprintf(stderr, "%s: unknown register %02x\n", __func__, reg);
break;
}
}
diff --git a/hw/display/cg3.c b/hw/display/cg3.c
index e069c4484c..cafd9f47ef 100644
--- a/hw/display/cg3.c
+++ b/hw/display/cg3.c
@@ -63,7 +63,7 @@
if (DEBUG_CG3) { \
printf("CG3: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define TYPE_CG3 "cgthree"
#define CG3(obj) OBJECT_CHECK(CG3State, (obj), TYPE_CG3)
diff --git a/hw/display/dpcd.c b/hw/display/dpcd.c
index ce92ff6e2a..943002bee5 100644
--- a/hw/display/dpcd.c
+++ b/hw/display/dpcd.c
@@ -39,7 +39,7 @@
if (DEBUG_DPCD) { \
qemu_log("dpcd: " fmt, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define DPCD_READABLE_AREA 0x600
diff --git a/hw/display/omap_dss.c b/hw/display/omap_dss.c
index 783e9e1318..601f178fdd 100644
--- a/hw/display/omap_dss.c
+++ b/hw/display/omap_dss.c
@@ -526,7 +526,7 @@ static void omap_disc_write(void *opaque, hwaddr addr,
s->dispc.l[0].attr = value & 0x7ff;
if (value & (3 << 9))
fprintf(stderr, "%s: Big-endian pixel format not supported\n",
- __FUNCTION__);
+ __func__);
s->dispc.l[0].enable = value & 1;
s->dispc.l[0].bpp = (value >> 1) & 0xf;
s->dispc.invalidate = 1;
@@ -617,7 +617,7 @@ static void omap_rfbi_transfer_start(struct omap_dss_s *s)
if (s->rfbi.control & (1 << 1)) { /* BYPASS */
/* TODO: in non-Bypass mode we probably need to just assert the
* DRQ and wait for DMA to write the pixels. */
- fprintf(stderr, "%s: Bypass mode unimplemented\n", __FUNCTION__);
+ fprintf(stderr, "%s: Bypass mode unimplemented\n", __func__);
return;
}
@@ -1086,6 +1086,6 @@ struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip)
{
if (cs < 0 || cs > 1)
- hw_error("%s: wrong CS %i\n", __FUNCTION__, cs);
+ hw_error("%s: wrong CS %i\n", __func__, cs);
s->rfbi.chip[cs] = chip;
}
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
index 845521c5b2..b83f80753a 100644
--- a/hw/display/pxa2xx_lcd.c
+++ b/hw/display/pxa2xx_lcd.c
@@ -405,7 +405,7 @@ static uint64_t pxa2xx_lcdc_read(void *opaque, hwaddr offset,
default:
fail:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
+ hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
}
return 0;
@@ -424,7 +424,7 @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset,
s->status[0] |= LCSR0_QD;
if (!(s->control[0] & LCCR0_LCDT) && (value & LCCR0_LCDT))
- printf("%s: internal frame buffer unsupported\n", __FUNCTION__);
+ printf("%s: internal frame buffer unsupported\n", __func__);
if ((s->control[3] & LCCR3_API) &&
(value & LCCR0_ENB) && !(value & LCCR0_LCDT))
@@ -460,7 +460,7 @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset,
case OVL1C1:
if (!(s->ovl1c[0] & OVLC1_EN) && (value & OVLC1_EN))
- printf("%s: Overlay 1 not supported\n", __FUNCTION__);
+ printf("%s: Overlay 1 not supported\n", __func__);
s->ovl1c[0] = value & 0x80ffffff;
s->dma_ch[1].up = (value & OVLC1_EN) || (s->control[0] & LCCR0_SDS);
@@ -472,7 +472,7 @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset,
case OVL2C1:
if (!(s->ovl2c[0] & OVLC1_EN) && (value & OVLC1_EN))
- printf("%s: Overlay 2 not supported\n", __FUNCTION__);
+ printf("%s: Overlay 2 not supported\n", __func__);
s->ovl2c[0] = value & 0x80ffffff;
s->dma_ch[2].up = !!(value & OVLC1_EN);
@@ -486,7 +486,7 @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset,
case CCR:
if (!(s->ccr & CCR_CEN) && (value & CCR_CEN))
- printf("%s: Hardware cursor unimplemented\n", __FUNCTION__);
+ printf("%s: Hardware cursor unimplemented\n", __func__);
s->ccr = value & 0x81ffffe7;
s->dma_ch[5].up = !!(value & CCR_CEN);
@@ -560,7 +560,7 @@ static void pxa2xx_lcdc_write(void *opaque, hwaddr offset,
default:
fail:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
+ hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
}
}
@@ -1050,7 +1050,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
s->dest_width = 4;
break;
default:
- fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);
+ fprintf(stderr, "%s: Bad color depth\n", __func__);
exit(1);
}
diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
index 90e0865618..e7ac4f8789 100644
--- a/hw/display/qxl-render.c
+++ b/hw/display/qxl-render.c
@@ -78,7 +78,7 @@ void qxl_render_resize(PCIQXLDevice *qxl)
qxl->guest_primary.bits_pp = 32;
break;
default:
- fprintf(stderr, "%s: unhandled format: %x\n", __FUNCTION__,
+ fprintf(stderr, "%s: unhandled format: %x\n", __func__,
qxl->guest_primary.surface.format);
qxl->guest_primary.bytes_pp = 4;
qxl->guest_primary.bits_pp = 32;
@@ -248,7 +248,7 @@ static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor,
break;
default:
fprintf(stderr, "%s: not implemented: type %d\n",
- __FUNCTION__, cursor->header.type);
+ __func__, cursor->header.type);
goto fail;
}
return c;
@@ -275,7 +275,7 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
}
if (qxl->debug > 1 && cmd->type != QXL_CURSOR_MOVE) {
- fprintf(stderr, "%s", __FUNCTION__);
+ fprintf(stderr, "%s", __func__);
qxl_log_cmd_cursor(qxl, cmd, ext->group_id);
fprintf(stderr, "\n");
}
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 99365c3e8f..b9fa067f6e 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -518,7 +518,6 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
trace_qxl_interface_attach_worker(qxl->id);
- qxl->ssd.worker = qxl_worker;
}
static void interface_set_compression_level(QXLInstance *sin, int level)
diff --git a/hw/display/qxl.h b/hw/display/qxl.h
index 8668a8e05a..089696ef62 100644
--- a/hw/display/qxl.h
+++ b/hw/display/qxl.h
@@ -132,7 +132,7 @@ typedef struct PCIQXLDevice {
#define PCI_QXL(obj) OBJECT_CHECK(PCIQXLDevice, (obj), TYPE_PCI_QXL)
#define PANIC_ON(x) if ((x)) { \
- printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \
+ printf("%s: PANIC %s failed\n", __func__, #x); \
abort(); \
}
diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 4f7dc59b25..134cbed607 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -797,6 +797,7 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
break;
case SM501_COMMAND_LIST_STATUS:
ret = 0x00180002; /* FIFOs are empty, everything idle */
+ break;
case SM501_IRQ_MASK:
ret = s->irq_mask;
break;
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
index 0ae63605f0..464465b7c2 100644
--- a/hw/display/tc6393xb.c
+++ b/hw/display/tc6393xb.c
@@ -148,7 +148,7 @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
// TC6393xbState *s = opaque;
if (line > TC6393XB_GPIOS) {
- printf("%s: No GPIO pin %i\n", __FUNCTION__, line);
+ printf("%s: No GPIO pin %i\n", __func__, line);
return;
}
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index d4fc0fa5f2..f5afcc0358 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -662,7 +662,7 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
}
if (oops) /* should not happen */
xen_pv_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
- __FUNCTION__, xenfb->depth, bpp);
+ __func__, xenfb->depth, bpp);
dpy_gfx_update(xenfb->con, x, y, w, h);
}
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index 561f828e7a..ead4e1a0e4 100644
--- a/hw/display/xlnx_dp.c
+++ b/hw/display/xlnx_dp.c
@@ -34,7 +34,7 @@
if (DEBUG_DP) { \
qemu_log("xlnx_dp: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/*
* Register offset for DP.
diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
index 45dfe7aadd..abd18c67ea 100644
--- a/hw/dma/omap_dma.c
+++ b/hw/dma/omap_dma.c
@@ -161,7 +161,7 @@ static void omap_dma_channel_load(struct omap_dma_channel_s *ch)
a->pck_element = 0;
if (unlikely(!ch->elements || !ch->frames)) {
- printf("%s: bad DMA request\n", __FUNCTION__);
+ printf("%s: bad DMA request\n", __func__);
return;
}
@@ -519,7 +519,7 @@ static void omap_dma_transfer_setup(struct soc_dma_ch_s *dma)
continue;
#endif
printf("%s: Bus time-out in DMA%i operation\n",
- __FUNCTION__, dma->num);
+ __func__, dma->num);
}
min_elems = INT_MAX;
@@ -879,14 +879,14 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
ch->pack[0] = (value & 0x0040) >> 6;
ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
if (ch->port[0] >= __omap_dma_port_last)
- printf("%s: invalid DMA port %i\n", __FUNCTION__,
+ printf("%s: invalid DMA port %i\n", __func__,
ch->port[0]);
if (ch->port[1] >= __omap_dma_port_last)
- printf("%s: invalid DMA port %i\n", __FUNCTION__,
+ printf("%s: invalid DMA port %i\n", __func__,
ch->port[1]);
ch->data_type = 1 << (value & 3);
if ((value & 3) == 3) {
- printf("%s: bad data_type for DMA channel\n", __FUNCTION__);
+ printf("%s: bad data_type for DMA channel\n", __func__);
ch->data_type >>= 1;
}
break;
@@ -1440,7 +1440,7 @@ static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
case 0x482: /* DMA_PCh1_SR */
case 0x4c0: /* DMA_PChD_SR_0 */
printf("%s: Physical Channel Status Registers not implemented.\n",
- __FUNCTION__);
+ __func__);
*ret = 0xff;
break;
@@ -1898,13 +1898,13 @@ static void omap_dma4_write(void *opaque, hwaddr addr,
omap_dma_reset(s->dma);
s->ocp = value & 0x3321;
if (((s->ocp >> 12) & 3) == 3) /* MIDLEMODE */
- fprintf(stderr, "%s: invalid DMA power mode\n", __FUNCTION__);
+ fprintf(stderr, "%s: invalid DMA power mode\n", __func__);
return;
case 0x78: /* DMA4_GCR */
s->gcr = value & 0x00ff00ff;
if ((value & 0xff) == 0x00) /* MAX_CHANNEL_FIFO_DEPTH */
- fprintf(stderr, "%s: wrong FIFO depth in GCR\n", __FUNCTION__);
+ fprintf(stderr, "%s: wrong FIFO depth in GCR\n", __func__);
return;
case 0x80 ... 0xfff:
@@ -1935,7 +1935,7 @@ static void omap_dma4_write(void *opaque, hwaddr addr,
ch->src_sync = (value >> 24) & 1; /* XXX For CamDMA must be 1 */
if (ch->buf_disable && !ch->src_sync)
fprintf(stderr, "%s: Buffering disable is not allowed in "
- "destination synchronised mode\n", __FUNCTION__);
+ "destination synchronised mode\n", __func__);
ch->prefetch = (value >> 23) & 1;
ch->bs = (value >> 18) & 1;
ch->transparent_copy = (value >> 17) & 1;
@@ -1947,7 +1947,7 @@ static void omap_dma4_write(void *opaque, hwaddr addr,
ch->fs = (value & 0x0020) >> 5;
if (ch->fs && ch->bs && ch->mode[0] && ch->mode[1])
fprintf(stderr, "%s: For a packet transfer at least one port "
- "must be constant-addressed\n", __FUNCTION__);
+ "must be constant-addressed\n", __func__);
ch->sync = (value & 0x001f) | ((value >> 14) & 0x0060);
/* XXX must be 0x01 for CamDMA */
@@ -1978,7 +1978,7 @@ static void omap_dma4_write(void *opaque, hwaddr addr,
ch->endian_lock[1] =(value >> 18) & 1;
if (ch->endian[0] != ch->endian[1])
fprintf(stderr, "%s: DMA endianness conversion enable attempt\n",
- __FUNCTION__);
+ __func__);
ch->write_mode = (value >> 16) & 3;
ch->burst[1] = (value & 0xc000) >> 14;
ch->pack[1] = (value & 0x2000) >> 13;
@@ -1988,10 +1988,10 @@ static void omap_dma4_write(void *opaque, hwaddr addr,
ch->translate[0] = (value & 0x003c) >> 2;
if (ch->translate[0] | ch->translate[1])
fprintf(stderr, "%s: bad MReqAddressTranslate sideband signal\n",
- __FUNCTION__);
+ __func__);
ch->data_type = 1 << (value & 3);
if ((value & 3) == 3) {
- printf("%s: bad data_type for DMA channel\n", __FUNCTION__);
+ printf("%s: bad data_type for DMA channel\n", __func__);
ch->data_type >>= 1;
}
break;
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index 32cf8399b8..d071049233 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -29,7 +29,7 @@
if (PL330_ERR_DEBUG >= lvl) {\
fprintf(stderr, "PL330: %s:" fmt, __func__, ## args);\
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/dma/pxa2xx_dma.c b/hw/dma/pxa2xx_dma.c
index 634a4328f0..f4eb26cf17 100644
--- a/hw/dma/pxa2xx_dma.c
+++ b/hw/dma/pxa2xx_dma.c
@@ -169,7 +169,7 @@ static inline void pxa2xx_dma_descriptor_fetch(
s->chan[ch].dest &= ~3;
if (s->chan[ch].cmd & (DCMD_CMPEN | DCMD_FLYBYS | DCMD_FLYBYT))
- printf("%s: unsupported mode in channel %i\n", __FUNCTION__, ch);
+ printf("%s: unsupported mode in channel %i\n", __func__, ch);
if (s->chan[ch].cmd & DCMD_STARTIRQEN)
s->chan[ch].state |= DCSR_STARTINTR;
@@ -264,7 +264,7 @@ static uint64_t pxa2xx_dma_read(void *opaque, hwaddr offset,
unsigned int channel;
if (size != 4) {
- hw_error("%s: Bad access width\n", __FUNCTION__);
+ hw_error("%s: Bad access width\n", __func__);
return 5;
}
@@ -312,7 +312,7 @@ static uint64_t pxa2xx_dma_read(void *opaque, hwaddr offset,
}
}
- hw_error("%s: Bad offset 0x" TARGET_FMT_plx "\n", __FUNCTION__, offset);
+ hw_error("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);
return 7;
}
@@ -323,7 +323,7 @@ static void pxa2xx_dma_write(void *opaque, hwaddr offset,
unsigned int channel;
if (size != 4) {
- hw_error("%s: Bad access width\n", __FUNCTION__);
+ hw_error("%s: Bad access width\n", __func__);
return;
}
@@ -337,7 +337,7 @@ static void pxa2xx_dma_write(void *opaque, hwaddr offset,
if (value & DRCMR_MAPVLD)
if ((value & DRCMR_CHLNUM) > s->channels)
hw_error("%s: Bad DMA channel %i\n",
- __FUNCTION__, (unsigned)value & DRCMR_CHLNUM);
+ __func__, (unsigned)value & DRCMR_CHLNUM);
s->req[channel] = value;
break;
@@ -416,7 +416,7 @@ static void pxa2xx_dma_write(void *opaque, hwaddr offset,
break;
}
fail:
- hw_error("%s: Bad offset " TARGET_FMT_plx "\n", __FUNCTION__, offset);
+ hw_error("%s: Bad offset " TARGET_FMT_plx "\n", __func__, offset);
}
}
@@ -431,7 +431,7 @@ static void pxa2xx_dma_request(void *opaque, int req_num, int on)
PXA2xxDMAState *s = opaque;
int ch;
if (req_num < 0 || req_num >= PXA2XX_DMA_NUM_REQUESTS)
- hw_error("%s: Bad DMA request %i\n", __FUNCTION__, req_num);
+ hw_error("%s: Bad DMA request %i\n", __func__, req_num);
if (!(s->req[req_num] & DRCMR_MAPVLD))
return;
diff --git a/hw/dma/xlnx-zynq-devcfg.c b/hw/dma/xlnx-zynq-devcfg.c
index 3b10523430..12bb2e3716 100644
--- a/hw/dma/xlnx-zynq-devcfg.c
+++ b/hw/dma/xlnx-zynq-devcfg.c
@@ -43,7 +43,7 @@
if (XLNX_ZYNQ_DEVCFG_ERR_DEBUG) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
REG32(CTRL, 0x00)
FIELD(CTRL, FORCE_RST, 31, 1) /* Not supported, wr ignored */
diff --git a/hw/dma/xlnx_dpdma.c b/hw/dma/xlnx_dpdma.c
index 8ceb21ddb3..077c7da9cc 100644
--- a/hw/dma/xlnx_dpdma.c
+++ b/hw/dma/xlnx_dpdma.c
@@ -34,7 +34,7 @@
if (DEBUG_DPDMA) { \
qemu_log("xlnx_dpdma: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/*
* Registers offset for DPDMA.
diff --git a/hw/gpio/max7310.c b/hw/gpio/max7310.c
index f82e3e6555..4c203ef5c6 100644
--- a/hw/gpio/max7310.c
+++ b/hw/gpio/max7310.c
@@ -67,7 +67,7 @@ static int max7310_rx(I2CSlave *i2c)
default:
#ifdef VERBOSE
- printf("%s: unknown register %02x\n", __FUNCTION__, s->command);
+ printf("%s: unknown register %02x\n", __func__, s->command);
#endif
break;
}
@@ -82,7 +82,7 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data)
if (s->len ++ > 1) {
#ifdef VERBOSE
- printf("%s: message too long (%i bytes)\n", __FUNCTION__, s->len);
+ printf("%s: message too long (%i bytes)\n", __func__, s->len);
#endif
return 1;
}
@@ -121,7 +121,7 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data)
break;
default:
#ifdef VERBOSE
- printf("%s: unknown register %02x\n", __FUNCTION__, s->command);
+ printf("%s: unknown register %02x\n", __func__, s->command);
#endif
return 1;
}
@@ -141,7 +141,7 @@ static int max7310_event(I2CSlave *i2c, enum i2c_event event)
case I2C_FINISH:
#ifdef VERBOSE
if (s->len == 1)
- printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len);
+ printf("%s: message too short (%i bytes)\n", __func__, s->len);
#endif
break;
default:
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
index 17891e2d0f..08472193b5 100644
--- a/hw/gpio/omap_gpio.c
+++ b/hw/gpio/omap_gpio.c
@@ -399,7 +399,7 @@ static void omap2_gpio_module_write(void *opaque, hwaddr addr,
case 0x10: /* GPIO_SYSCONFIG */
if (((value >> 3) & 3) == 3)
- fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
+ fprintf(stderr, "%s: bad IDLEMODE value\n", __func__);
if (value & 2)
omap2_gpio_module_reset(s);
s->config[0] = value & 0x1d;
diff --git a/hw/i2c/i2c-ddc.c b/hw/i2c/i2c-ddc.c
index 6b92e95c73..199dac9e41 100644
--- a/hw/i2c/i2c-ddc.c
+++ b/hw/i2c/i2c-ddc.c
@@ -30,7 +30,7 @@
if (DEBUG_I2CDDC) { \
qemu_log("i2c-ddc: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/* Structure defining a monitor's characteristics in a
* readable format: this should be passed to build_edid_blob()
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
index 12264ee0f5..26e3e5ebf6 100644
--- a/hw/i2c/omap_i2c.c
+++ b/hw/i2c/omap_i2c.c
@@ -341,12 +341,12 @@ static void omap_i2c_write(void *opaque, hwaddr addr,
}
if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
fprintf(stderr, "%s: I^2C slave mode not supported\n",
- __FUNCTION__);
+ __func__);
break;
}
if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */
fprintf(stderr, "%s: 10-bit addressing mode not supported\n",
- __FUNCTION__);
+ __func__);
break;
}
if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */
@@ -393,7 +393,7 @@ static void omap_i2c_write(void *opaque, hwaddr addr,
omap_i2c_interrupts_update(s);
}
if (value & (1 << 15)) /* ST_EN */
- fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__);
+ fprintf(stderr, "%s: System Test not supported\n", __func__);
break;
default:
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index a044dd1b27..0d26e0f6b5 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -62,6 +62,9 @@ static void smb_transaction(PMSMBus *s)
I2CBus *bus = s->smbus;
int ret;
+ assert(s->smb_stat & STS_HOST_BUSY);
+ s->smb_stat &= ~STS_HOST_BUSY;
+
SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
/* Transaction isn't exec if STS_DEV_ERR bit set */
if ((s->smb_stat & STS_DEV_ERR) != 0) {
@@ -134,6 +137,13 @@ error:
}
+static void smb_transaction_start(PMSMBus *s)
+{
+ /* Do not execute immediately the command ; it will be
+ * executed when guest will read SMB_STAT register */
+ s->smb_stat |= STS_HOST_BUSY;
+}
+
static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
unsigned width)
{
@@ -149,7 +159,7 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
case SMBHSTCNT:
s->smb_ctl = val;
if (val & 0x40)
- smb_transaction(s);
+ smb_transaction_start(s);
break;
case SMBHSTCMD:
s->smb_cmd = val;
@@ -181,6 +191,10 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
switch(addr) {
case SMBHSTSTS:
val = s->smb_stat;
+ if (s->smb_stat & STS_HOST_BUSY) {
+ /* execute command now */
+ smb_transaction(s);
+ }
break;
case SMBHSTCNT:
s->smb_index = 0;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 18b939e469..dc4b2b9ffe 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2394,7 +2394,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
}
mem_base = 1ULL << 32;
mem_len = next_base - pcms->below_4g_mem_size;
- next_base += (1ULL << 32) - pcms->below_4g_mem_size;
+ next_base = mem_base + mem_len;
}
numamem = acpi_data_push(table_data, sizeof *numamem);
build_srat_memory(numamem, mem_base, mem_len, i - 1,
@@ -2473,6 +2473,7 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker)
AcpiDmarDeviceScope *scope = NULL;
/* Root complex IOAPIC use one path[0] only */
size_t ioapic_scope_size = sizeof(*scope) + sizeof(scope->path[0]);
+ IntelIOMMUState *intel_iommu = INTEL_IOMMU_DEVICE(iommu);
assert(iommu);
if (iommu->intr_supported) {
@@ -2480,7 +2481,7 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker)
}
dmar = acpi_data_push(table_data, sizeof(*dmar));
- dmar->host_address_width = VTD_HOST_ADDRESS_WIDTH - 1;
+ dmar->host_address_width = intel_iommu->aw_bits - 1;
dmar->flags = dmar_flags;
/* DMAR Remapping Hardware Unit Definition structure */
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index eeaf0e0aa8..63d46ff6ee 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -1144,18 +1144,9 @@ static void amdvi_realize(DeviceState *dev, Error **err)
AMDVIState *s = AMD_IOMMU_DEVICE(dev);
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
MachineState *ms = MACHINE(qdev_get_machine());
- MachineClass *mc = MACHINE_GET_CLASS(ms);
- PCMachineState *pcms =
- PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));
- PCIBus *bus;
-
- if (!pcms) {
- error_setg(err, "Machine-type '%s' not supported by amd-iommu",
- mc->name);
- return;
- }
+ PCMachineState *pcms = PC_MACHINE(ms);
+ PCIBus *bus = pcms->bus;
- bus = pcms->bus;
s->iotlb = g_hash_table_new_full(amdvi_uint64_hash,
amdvi_uint64_equal, g_free, g_free);
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 3a5bb0bc2e..2e841cde27 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -186,7 +186,7 @@ static void vtd_reset_context_cache(IntelIOMMUState *s)
g_hash_table_iter_init(&bus_it, s->vtd_as_by_busptr);
while (g_hash_table_iter_next (&bus_it, NULL, (void**)&vtd_bus)) {
- for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
+ for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
vtd_as = vtd_bus->dev_as[devfn_it];
if (!vtd_as) {
continue;
@@ -521,9 +521,9 @@ static inline dma_addr_t vtd_ce_get_slpt_base(VTDContextEntry *ce)
return ce->lo & VTD_CONTEXT_ENTRY_SLPTPTR;
}
-static inline uint64_t vtd_get_slpte_addr(uint64_t slpte)
+static inline uint64_t vtd_get_slpte_addr(uint64_t slpte, uint8_t aw)
{
- return slpte & VTD_SL_PT_BASE_ADDR_MASK;
+ return slpte & VTD_SL_PT_BASE_ADDR_MASK(aw);
}
/* Whether the pte indicates the address of the page frame */
@@ -608,35 +608,29 @@ static inline bool vtd_ce_type_check(X86IOMMUState *x86_iommu,
return true;
}
-static inline uint64_t vtd_iova_limit(VTDContextEntry *ce)
+static inline uint64_t vtd_iova_limit(VTDContextEntry *ce, uint8_t aw)
{
uint32_t ce_agaw = vtd_ce_get_agaw(ce);
- return 1ULL << MIN(ce_agaw, VTD_MGAW);
+ return 1ULL << MIN(ce_agaw, aw);
}
/* Return true if IOVA passes range check, otherwise false. */
-static inline bool vtd_iova_range_check(uint64_t iova, VTDContextEntry *ce)
+static inline bool vtd_iova_range_check(uint64_t iova, VTDContextEntry *ce,
+ uint8_t aw)
{
/*
* Check if @iova is above 2^X-1, where X is the minimum of MGAW
* in CAP_REG and AW in context-entry.
*/
- return !(iova & ~(vtd_iova_limit(ce) - 1));
-}
-
-static const uint64_t vtd_paging_entry_rsvd_field[] = {
- [0] = ~0ULL,
- /* For not large page */
- [1] = 0x800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM),
- [2] = 0x800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM),
- [3] = 0x800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM),
- [4] = 0x880ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM),
- /* For large page */
- [5] = 0x800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM),
- [6] = 0x1ff800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM),
- [7] = 0x3ffff800ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM),
- [8] = 0x880ULL | ~(VTD_HAW_MASK | VTD_SL_IGN_COM),
-};
+ return !(iova & ~(vtd_iova_limit(ce, aw) - 1));
+}
+
+/*
+ * Rsvd field masks for spte:
+ * Index [1] to [4] 4k pages
+ * Index [5] to [8] large pages
+ */
+static uint64_t vtd_paging_entry_rsvd_field[9];
static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level)
{
@@ -676,7 +670,7 @@ static VTDBus *vtd_find_as_from_bus_num(IntelIOMMUState *s, uint8_t bus_num)
*/
static int vtd_iova_to_slpte(VTDContextEntry *ce, uint64_t iova, bool is_write,
uint64_t *slptep, uint32_t *slpte_level,
- bool *reads, bool *writes)
+ bool *reads, bool *writes, uint8_t aw_bits)
{
dma_addr_t addr = vtd_ce_get_slpt_base(ce);
uint32_t level = vtd_ce_get_level(ce);
@@ -684,7 +678,7 @@ static int vtd_iova_to_slpte(VTDContextEntry *ce, uint64_t iova, bool is_write,
uint64_t slpte;
uint64_t access_right_check;
- if (!vtd_iova_range_check(iova, ce)) {
+ if (!vtd_iova_range_check(iova, ce, aw_bits)) {
trace_vtd_err_dmar_iova_overflow(iova);
return -VTD_FR_ADDR_BEYOND_MGAW;
}
@@ -721,7 +715,7 @@ static int vtd_iova_to_slpte(VTDContextEntry *ce, uint64_t iova, bool is_write,
*slpte_level = level;
return 0;
}
- addr = vtd_get_slpte_addr(slpte);
+ addr = vtd_get_slpte_addr(slpte, aw_bits);
level--;
}
}
@@ -739,11 +733,12 @@ typedef int (*vtd_page_walk_hook)(IOMMUTLBEntry *entry, void *private);
* @read: whether parent level has read permission
* @write: whether parent level has write permission
* @notify_unmap: whether we should notify invalid entries
+ * @aw: maximum address width
*/
static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
uint64_t end, vtd_page_walk_hook hook_fn,
- void *private, uint32_t level,
- bool read, bool write, bool notify_unmap)
+ void *private, uint32_t level, bool read,
+ bool write, bool notify_unmap, uint8_t aw)
{
bool read_cur, write_cur, entry_valid;
uint32_t offset;
@@ -790,7 +785,7 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
entry.target_as = &address_space_memory;
entry.iova = iova & subpage_mask;
/* NOTE: this is only meaningful if entry_valid == true */
- entry.translated_addr = vtd_get_slpte_addr(slpte);
+ entry.translated_addr = vtd_get_slpte_addr(slpte, aw);
entry.addr_mask = ~subpage_mask;
entry.perm = IOMMU_ACCESS_FLAG(read_cur, write_cur);
if (!entry_valid && !notify_unmap) {
@@ -810,10 +805,10 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
trace_vtd_page_walk_skip_perm(iova, iova_next);
goto next;
}
- ret = vtd_page_walk_level(vtd_get_slpte_addr(slpte), iova,
+ ret = vtd_page_walk_level(vtd_get_slpte_addr(slpte, aw), iova,
MIN(iova_next, end), hook_fn, private,
level - 1, read_cur, write_cur,
- notify_unmap);
+ notify_unmap, aw);
if (ret < 0) {
return ret;
}
@@ -834,25 +829,26 @@ next:
* @end: IOVA range end address (start <= addr < end)
* @hook_fn: the hook that to be called for each detected area
* @private: private data for the hook function
+ * @aw: maximum address width
*/
static int vtd_page_walk(VTDContextEntry *ce, uint64_t start, uint64_t end,
vtd_page_walk_hook hook_fn, void *private,
- bool notify_unmap)
+ bool notify_unmap, uint8_t aw)
{
dma_addr_t addr = vtd_ce_get_slpt_base(ce);
uint32_t level = vtd_ce_get_level(ce);
- if (!vtd_iova_range_check(start, ce)) {
+ if (!vtd_iova_range_check(start, ce, aw)) {
return -VTD_FR_ADDR_BEYOND_MGAW;
}
- if (!vtd_iova_range_check(end, ce)) {
+ if (!vtd_iova_range_check(end, ce, aw)) {
/* Fix end so that it reaches the maximum */
- end = vtd_iova_limit(ce);
+ end = vtd_iova_limit(ce, aw);
}
return vtd_page_walk_level(addr, start, end, hook_fn, private,
- level, true, true, notify_unmap);
+ level, true, true, notify_unmap, aw);
}
/* Map a device to its corresponding domain (context-entry) */
@@ -874,7 +870,7 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num,
return -VTD_FR_ROOT_ENTRY_P;
}
- if (re.rsvd || (re.val & VTD_ROOT_ENTRY_RSVD)) {
+ if (re.rsvd || (re.val & VTD_ROOT_ENTRY_RSVD(s->aw_bits))) {
trace_vtd_re_invalid(re.rsvd, re.val);
return -VTD_FR_ROOT_ENTRY_RSVD;
}
@@ -891,7 +887,7 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num,
}
if ((ce->hi & VTD_CONTEXT_ENTRY_RSVD_HI) ||
- (ce->lo & VTD_CONTEXT_ENTRY_RSVD_LO)) {
+ (ce->lo & VTD_CONTEXT_ENTRY_RSVD_LO(s->aw_bits))) {
trace_vtd_ce_invalid(ce->hi, ce->lo);
return -VTD_FR_CONTEXT_ENTRY_RSVD;
}
@@ -1002,7 +998,7 @@ static void vtd_switch_address_space_all(IntelIOMMUState *s)
g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
- for (i = 0; i < X86_IOMMU_PCI_DEVFN_MAX; i++) {
+ for (i = 0; i < PCI_DEVFN_MAX; i++) {
if (!vtd_bus->dev_as[i]) {
continue;
}
@@ -1173,7 +1169,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
}
ret_fr = vtd_iova_to_slpte(&ce, addr, is_write, &slpte, &level,
- &reads, &writes);
+ &reads, &writes, s->aw_bits);
if (ret_fr) {
ret_fr = -ret_fr;
if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) {
@@ -1190,7 +1186,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
access_flags, level);
out:
entry->iova = addr & page_mask;
- entry->translated_addr = vtd_get_slpte_addr(slpte) & page_mask;
+ entry->translated_addr = vtd_get_slpte_addr(slpte, s->aw_bits) & page_mask;
entry->addr_mask = ~page_mask;
entry->perm = access_flags;
return true;
@@ -1207,7 +1203,7 @@ static void vtd_root_table_setup(IntelIOMMUState *s)
{
s->root = vtd_get_quad_raw(s, DMAR_RTADDR_REG);
s->root_extended = s->root & VTD_RTADDR_RTT;
- s->root &= VTD_RTADDR_ADDR_MASK;
+ s->root &= VTD_RTADDR_ADDR_MASK(s->aw_bits);
trace_vtd_reg_dmar_root(s->root, s->root_extended);
}
@@ -1223,7 +1219,7 @@ static void vtd_interrupt_remap_table_setup(IntelIOMMUState *s)
uint64_t value = 0;
value = vtd_get_quad_raw(s, DMAR_IRTA_REG);
s->intr_size = 1UL << ((value & VTD_IRTA_SIZE_MASK) + 1);
- s->intr_root = value & VTD_IRTA_ADDR_MASK;
+ s->intr_root = value & VTD_IRTA_ADDR_MASK(s->aw_bits);
s->intr_eime = value & VTD_IRTA_EIME;
/* Notify global invalidation */
@@ -1294,7 +1290,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
vtd_bus = vtd_find_as_from_bus_num(s, bus_n);
if (vtd_bus) {
devfn = VTD_SID_TO_DEVFN(source_id);
- for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
+ for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
vtd_as = vtd_bus->dev_as[devfn_it];
if (vtd_as && ((devfn_it & mask) == (devfn & mask))) {
trace_vtd_inv_desc_cc_device(bus_n, VTD_PCI_SLOT(devfn_it),
@@ -1399,7 +1395,7 @@ static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
vtd_page_walk(&ce, addr, addr + (1 << am) * VTD_PAGE_SIZE,
vtd_page_invalidate_notify_hook,
- (void *)&vtd_as->iommu, true);
+ (void *)&vtd_as->iommu, true, s->aw_bits);
}
}
}
@@ -1479,7 +1475,7 @@ static void vtd_handle_gcmd_qie(IntelIOMMUState *s, bool en)
trace_vtd_inv_qi_enable(en);
if (en) {
- s->iq = iqa_val & VTD_IQA_IQA_MASK;
+ s->iq = iqa_val & VTD_IQA_IQA_MASK(s->aw_bits);
/* 2^(x+8) entries */
s->iq_size = 1UL << ((iqa_val & VTD_IQA_QS) + 8);
s->qi_enabled = true;
@@ -2327,7 +2323,7 @@ static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
IntelIOMMUNotifierNode *next_node = NULL;
if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
- error_report("We need to set cache_mode=1 for intel-iommu to enable "
+ error_report("We need to set caching-mode=1 for intel-iommu to enable "
"device assignment with IOMMU protection.");
exit(1);
}
@@ -2410,6 +2406,8 @@ static Property vtd_properties[] = {
DEFINE_PROP_ON_OFF_AUTO("eim", IntelIOMMUState, intr_eim,
ON_OFF_AUTO_AUTO),
DEFINE_PROP_BOOL("x-buggy-eim", IntelIOMMUState, buggy_eim, false),
+ DEFINE_PROP_UINT8("x-aw-bits", IntelIOMMUState, aw_bits,
+ VTD_HOST_ADDRESS_WIDTH),
DEFINE_PROP_BOOL("caching-mode", IntelIOMMUState, caching_mode, FALSE),
DEFINE_PROP_END_OF_LIST(),
};
@@ -2699,7 +2697,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
*new_key = (uintptr_t)bus;
/* No corresponding free() */
vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * \
- X86_IOMMU_PCI_DEVFN_MAX);
+ PCI_DEVFN_MAX);
vtd_bus->bus = bus;
g_hash_table_insert(s->vtd_as_by_busptr, new_key, vtd_bus);
}
@@ -2765,6 +2763,7 @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
hwaddr size;
hwaddr start = n->start;
hwaddr end = n->end;
+ IntelIOMMUState *s = as->iommu_state;
/*
* Note: all the codes in this function has a assumption that IOVA
@@ -2772,12 +2771,12 @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
* VT-d spec), otherwise we need to consider overflow of 64 bits.
*/
- if (end > VTD_ADDRESS_SIZE) {
+ if (end > VTD_ADDRESS_SIZE(s->aw_bits)) {
/*
* Don't need to unmap regions that is bigger than the whole
* VT-d supported address space size
*/
- end = VTD_ADDRESS_SIZE;
+ end = VTD_ADDRESS_SIZE(s->aw_bits);
}
assert(start <= end);
@@ -2789,9 +2788,9 @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
* suite the minimum available mask.
*/
int n = 64 - clz64(size);
- if (n > VTD_MGAW) {
+ if (n > s->aw_bits) {
/* should not happen, but in case it happens, limit it */
- n = VTD_MGAW;
+ n = s->aw_bits;
}
size = 1ULL << n;
}
@@ -2851,7 +2850,8 @@ static void vtd_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n)
PCI_FUNC(vtd_as->devfn),
VTD_CONTEXT_ENTRY_DID(ce.hi),
ce.hi, ce.lo);
- vtd_page_walk(&ce, 0, ~0ULL, vtd_replay_hook, (void *)n, false);
+ vtd_page_walk(&ce, 0, ~0ULL, vtd_replay_hook, (void *)n, false,
+ s->aw_bits);
} else {
trace_vtd_replay_ce_invalid(bus_n, PCI_SLOT(vtd_as->devfn),
PCI_FUNC(vtd_as->devfn));
@@ -2882,10 +2882,27 @@ static void vtd_init(IntelIOMMUState *s)
s->qi_enabled = false;
s->iq_last_desc_type = VTD_INV_DESC_NONE;
s->next_frcd_reg = 0;
- s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_CAP_MGAW |
- VTD_CAP_SAGAW | VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS;
+ s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND |
+ VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS |
+ VTD_CAP_SAGAW_39bit | VTD_CAP_MGAW(s->aw_bits);
+ if (s->aw_bits == VTD_HOST_AW_48BIT) {
+ s->cap |= VTD_CAP_SAGAW_48bit;
+ }
s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO;
+ /*
+ * Rsvd field masks for spte
+ */
+ vtd_paging_entry_rsvd_field[0] = ~0ULL;
+ vtd_paging_entry_rsvd_field[1] = VTD_SPTE_PAGE_L1_RSVD_MASK(s->aw_bits);
+ vtd_paging_entry_rsvd_field[2] = VTD_SPTE_PAGE_L2_RSVD_MASK(s->aw_bits);
+ vtd_paging_entry_rsvd_field[3] = VTD_SPTE_PAGE_L3_RSVD_MASK(s->aw_bits);
+ vtd_paging_entry_rsvd_field[4] = VTD_SPTE_PAGE_L4_RSVD_MASK(s->aw_bits);
+ vtd_paging_entry_rsvd_field[5] = VTD_SPTE_LPAGE_L1_RSVD_MASK(s->aw_bits);
+ vtd_paging_entry_rsvd_field[6] = VTD_SPTE_LPAGE_L2_RSVD_MASK(s->aw_bits);
+ vtd_paging_entry_rsvd_field[7] = VTD_SPTE_LPAGE_L3_RSVD_MASK(s->aw_bits);
+ vtd_paging_entry_rsvd_field[8] = VTD_SPTE_LPAGE_L4_RSVD_MASK(s->aw_bits);
+
if (x86_iommu->intr_supported) {
s->ecap |= VTD_ECAP_IR | VTD_ECAP_MHMV;
if (s->intr_eim == ON_OFF_AUTO_ON) {
@@ -2982,7 +2999,7 @@ static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
IntelIOMMUState *s = opaque;
VTDAddressSpace *vtd_as;
- assert(0 <= devfn && devfn < X86_IOMMU_PCI_DEVFN_MAX);
+ assert(0 <= devfn && devfn < PCI_DEVFN_MAX);
vtd_as = vtd_find_add_as(s, bus, devfn);
return &vtd_as->as;
@@ -3021,26 +3038,25 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp)
}
}
+ /* Currently only address widths supported are 39 and 48 bits */
+ if ((s->aw_bits != VTD_HOST_AW_39BIT) &&
+ (s->aw_bits != VTD_HOST_AW_48BIT)) {
+ error_setg(errp, "Supported values for x-aw-bits are: %d, %d",
+ VTD_HOST_AW_39BIT, VTD_HOST_AW_48BIT);
+ return false;
+ }
+
return true;
}
static void vtd_realize(DeviceState *dev, Error **errp)
{
MachineState *ms = MACHINE(qdev_get_machine());
- MachineClass *mc = MACHINE_GET_CLASS(ms);
- PCMachineState *pcms =
- PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));
- PCIBus *bus;
+ PCMachineState *pcms = PC_MACHINE(ms);
+ PCIBus *bus = pcms->bus;
IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev);
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
- if (!pcms) {
- error_setg(errp, "Machine-type '%s' not supported by intel-iommu",
- mc->name);
- return;
- }
-
- bus = pcms->bus;
x86_iommu->type = TYPE_INTEL;
if (!vtd_decide_config(s, errp)) {
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 0e73a65bf2..d084099ed9 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -131,7 +131,7 @@
#define VTD_TLB_DID(val) (((val) >> 32) & VTD_DOMAIN_ID_MASK)
/* IVA_REG */
-#define VTD_IVA_ADDR(val) ((val) & ~0xfffULL & ((1ULL << VTD_MGAW) - 1))
+#define VTD_IVA_ADDR(val) ((val) & ~0xfffULL)
#define VTD_IVA_AM(val) ((val) & 0x3fULL)
/* GCMD_REG */
@@ -172,10 +172,10 @@
/* RTADDR_REG */
#define VTD_RTADDR_RTT (1ULL << 11)
-#define VTD_RTADDR_ADDR_MASK (VTD_HAW_MASK ^ 0xfffULL)
+#define VTD_RTADDR_ADDR_MASK(aw) (VTD_HAW_MASK(aw) ^ 0xfffULL)
/* IRTA_REG */
-#define VTD_IRTA_ADDR_MASK (VTD_HAW_MASK ^ 0xfffULL)
+#define VTD_IRTA_ADDR_MASK(aw) (VTD_HAW_MASK(aw) ^ 0xfffULL)
#define VTD_IRTA_EIME (1ULL << 11)
#define VTD_IRTA_SIZE_MASK (0xfULL)
@@ -197,9 +197,8 @@
#define VTD_DOMAIN_ID_SHIFT 16 /* 16-bit domain id for 64K domains */
#define VTD_DOMAIN_ID_MASK ((1UL << VTD_DOMAIN_ID_SHIFT) - 1)
#define VTD_CAP_ND (((VTD_DOMAIN_ID_SHIFT - 4) / 2) & 7ULL)
-#define VTD_MGAW 39 /* Maximum Guest Address Width */
-#define VTD_ADDRESS_SIZE (1ULL << VTD_MGAW)
-#define VTD_CAP_MGAW (((VTD_MGAW - 1) & 0x3fULL) << 16)
+#define VTD_ADDRESS_SIZE(aw) (1ULL << (aw))
+#define VTD_CAP_MGAW(aw) ((((aw) - 1) & 0x3fULL) << 16)
#define VTD_MAMV 18ULL
#define VTD_CAP_MAMV (VTD_MAMV << 48)
#define VTD_CAP_PSI (1ULL << 39)
@@ -213,13 +212,12 @@
#define VTD_CAP_SAGAW_39bit (0x2ULL << VTD_CAP_SAGAW_SHIFT)
/* 48-bit AGAW, 4-level page-table */
#define VTD_CAP_SAGAW_48bit (0x4ULL << VTD_CAP_SAGAW_SHIFT)
-#define VTD_CAP_SAGAW VTD_CAP_SAGAW_39bit
/* IQT_REG */
#define VTD_IQT_QT(val) (((val) >> 4) & 0x7fffULL)
/* IQA_REG */
-#define VTD_IQA_IQA_MASK (VTD_HAW_MASK ^ 0xfffULL)
+#define VTD_IQA_IQA_MASK(aw) (VTD_HAW_MASK(aw) ^ 0xfffULL)
#define VTD_IQA_QS 0x7ULL
/* IQH_REG */
@@ -252,7 +250,7 @@
#define VTD_FRCD_SID_MASK 0xffffULL
#define VTD_FRCD_SID(val) ((val) & VTD_FRCD_SID_MASK)
/* For the low 64-bit of 128-bit */
-#define VTD_FRCD_FI(val) ((val) & (((1ULL << VTD_MGAW) - 1) ^ 0xfffULL))
+#define VTD_FRCD_FI(val) ((val) & ~0xfffULL)
/* DMA Remapping Fault Conditions */
typedef enum VTDFaultReason {
@@ -360,8 +358,7 @@ typedef union VTDInvDesc VTDInvDesc;
#define VTD_INV_DESC_IOTLB_DOMAIN (2ULL << 4)
#define VTD_INV_DESC_IOTLB_PAGE (3ULL << 4)
#define VTD_INV_DESC_IOTLB_DID(val) (((val) >> 16) & VTD_DOMAIN_ID_MASK)
-#define VTD_INV_DESC_IOTLB_ADDR(val) ((val) & ~0xfffULL & \
- ((1ULL << VTD_MGAW) - 1))
+#define VTD_INV_DESC_IOTLB_ADDR(val) ((val) & ~0xfffULL)
#define VTD_INV_DESC_IOTLB_AM(val) ((val) & 0x3fULL)
#define VTD_INV_DESC_IOTLB_RSVD_LO 0xffffffff0000ff00ULL
#define VTD_INV_DESC_IOTLB_RSVD_HI 0xf80ULL
@@ -373,6 +370,24 @@ typedef union VTDInvDesc VTDInvDesc;
#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_HI 0xffeULL
#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
+/* Rsvd field masks for spte */
+#define VTD_SPTE_PAGE_L1_RSVD_MASK(aw) \
+ (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
+#define VTD_SPTE_PAGE_L2_RSVD_MASK(aw) \
+ (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
+#define VTD_SPTE_PAGE_L3_RSVD_MASK(aw) \
+ (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
+#define VTD_SPTE_PAGE_L4_RSVD_MASK(aw) \
+ (0x880ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
+#define VTD_SPTE_LPAGE_L1_RSVD_MASK(aw) \
+ (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
+#define VTD_SPTE_LPAGE_L2_RSVD_MASK(aw) \
+ (0x1ff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
+#define VTD_SPTE_LPAGE_L3_RSVD_MASK(aw) \
+ (0x3ffff800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
+#define VTD_SPTE_LPAGE_L4_RSVD_MASK(aw) \
+ (0x880ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM))
+
/* Information about page-selective IOTLB invalidate */
struct VTDIOTLBPageInvInfo {
uint16_t domain_id;
@@ -403,7 +418,7 @@ typedef struct VTDRootEntry VTDRootEntry;
#define VTD_ROOT_ENTRY_CTP (~0xfffULL)
#define VTD_ROOT_ENTRY_NR (VTD_PAGE_SIZE / sizeof(VTDRootEntry))
-#define VTD_ROOT_ENTRY_RSVD (0xffeULL | ~VTD_HAW_MASK)
+#define VTD_ROOT_ENTRY_RSVD(aw) (0xffeULL | ~VTD_HAW_MASK(aw))
/* Masks for struct VTDContextEntry */
/* lo */
@@ -415,7 +430,7 @@ typedef struct VTDRootEntry VTDRootEntry;
#define VTD_CONTEXT_TT_PASS_THROUGH (2ULL << 2)
/* Second Level Page Translation Pointer*/
#define VTD_CONTEXT_ENTRY_SLPTPTR (~0xfffULL)
-#define VTD_CONTEXT_ENTRY_RSVD_LO (0xff0ULL | ~VTD_HAW_MASK)
+#define VTD_CONTEXT_ENTRY_RSVD_LO(aw) (0xff0ULL | ~VTD_HAW_MASK(aw))
/* hi */
#define VTD_CONTEXT_ENTRY_AW 7ULL /* Adjusted guest-address-width */
#define VTD_CONTEXT_ENTRY_DID(val) (((val) >> 8) & VTD_DOMAIN_ID_MASK)
@@ -439,7 +454,7 @@ typedef struct VTDRootEntry VTDRootEntry;
#define VTD_SL_RW_MASK 3ULL
#define VTD_SL_R 1ULL
#define VTD_SL_W (1ULL << 1)
-#define VTD_SL_PT_BASE_ADDR_MASK (~(VTD_PAGE_SIZE - 1) & VTD_HAW_MASK)
+#define VTD_SL_PT_BASE_ADDR_MASK(aw) (~(VTD_PAGE_SIZE - 1) & VTD_HAW_MASK(aw))
#define VTD_SL_IGN_COM 0xbff0000000000000ULL
#endif
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3fcf318a95..ccc50baa85 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1148,7 +1148,8 @@ void pc_cpus_init(PCMachineState *pcms)
pcms->apic_id_limit = x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
possible_cpus = mc->possible_cpu_arch_ids(ms);
for (i = 0; i < smp_cpus; i++) {
- pc_new_cpu(ms->cpu_type, possible_cpus->cpus[i].arch_id, &error_fatal);
+ pc_new_cpu(possible_cpus->cpus[i].type, possible_cpus->cpus[i].arch_id,
+ &error_fatal);
}
}
@@ -1695,9 +1696,14 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
align = memory_region_get_alignment(mr);
}
- if (!pcms->acpi_dev) {
+ /*
+ * When -no-acpi is used with Q35 machine type, no ACPI is built,
+ * but pcms->acpi_dev is still created. Check !acpi_enabled in
+ * addition to cover this case.
+ */
+ if (!pcms->acpi_dev || !acpi_enabled) {
error_setg(&local_err,
- "memory hotplug is not enabled: missing acpi device");
+ "memory hotplug is not enabled: missing acpi device or acpi disabled");
goto out;
}
@@ -1729,9 +1735,14 @@ static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev,
Error *local_err = NULL;
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
- if (!pcms->acpi_dev) {
+ /*
+ * When -no-acpi is used with Q35 machine type, no ACPI is built,
+ * but pcms->acpi_dev is still created. Check !acpi_enabled in
+ * addition to cover this case.
+ */
+ if (!pcms->acpi_dev || !acpi_enabled) {
error_setg(&local_err,
- "memory hotplug is not enabled: missing acpi device");
+ "memory hotplug is not enabled: missing acpi device or acpi disabled");
goto out;
}
@@ -2297,6 +2308,7 @@ static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms)
for (i = 0; i < ms->possible_cpus->len; i++) {
X86CPUTopoInfo topo;
+ ms->possible_cpus->cpus[i].type = ms->cpu_type;
ms->possible_cpus->cpus[i].vcpus_count = 1;
ms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(i);
x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 5e47528993..a25619dfbf 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -394,7 +394,7 @@ static void pc_xen_hvm_init_pci(MachineState *machine)
static void pc_xen_hvm_init(MachineState *machine)
{
- PCIBus *bus;
+ PCMachineState *pcms = PC_MACHINE(machine);
if (!xen_enabled()) {
error_report("xenfv machine requires the xen accelerator");
@@ -402,11 +402,7 @@ static void pc_xen_hvm_init(MachineState *machine)
}
pc_xen_hvm_init_pci(machine);
-
- bus = pci_find_primary_bus();
- if (bus != NULL) {
- pci_create_simple(bus, -1, "xen-platform");
- }
+ pci_create_simple(pcms->bus, -1, "xen-platform");
}
#endif
@@ -430,21 +426,30 @@ static void pc_i440fx_machine_options(MachineClass *m)
m->default_display = "std";
}
-static void pc_i440fx_2_11_machine_options(MachineClass *m)
+static void pc_i440fx_2_12_machine_options(MachineClass *m)
{
pc_i440fx_machine_options(m);
m->alias = "pc";
m->is_default = 1;
}
+DEFINE_I440FX_MACHINE(v2_12, "pc-i440fx-2.12", NULL,
+ pc_i440fx_2_12_machine_options);
+
+static void pc_i440fx_2_11_machine_options(MachineClass *m)
+{
+ pc_i440fx_2_12_machine_options(m);
+ m->is_default = 0;
+ m->alias = NULL;
+ SET_MACHINE_COMPAT(m, PC_COMPAT_2_11);
+}
+
DEFINE_I440FX_MACHINE(v2_11, "pc-i440fx-2.11", NULL,
pc_i440fx_2_11_machine_options);
static void pc_i440fx_2_10_machine_options(MachineClass *m)
{
pc_i440fx_2_11_machine_options(m);
- m->is_default = 0;
- m->alias = NULL;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
m->auto_enable_numa_with_memhp = false;
}
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index d6060043ac..ed3a0b8ff7 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -42,6 +42,8 @@
#include "exec/address-spaces.h"
#include "hw/i386/pc.h"
#include "hw/i386/ich9.h"
+#include "hw/i386/amd_iommu.h"
+#include "hw/i386/intel_iommu.h"
#include "hw/smbios/smbios.h"
#include "hw/ide/pci.h"
#include "hw/ide/ahci.h"
@@ -299,23 +301,33 @@ static void pc_q35_machine_options(MachineClass *m)
m->default_machine_opts = "firmware=bios-256k.bin";
m->default_display = "std";
m->no_floppy = 1;
- m->has_dynamic_sysbus = true;
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE);
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE);
m->max_cpus = 288;
}
-static void pc_q35_2_11_machine_options(MachineClass *m)
+static void pc_q35_2_12_machine_options(MachineClass *m)
{
pc_q35_machine_options(m);
m->alias = "q35";
}
+DEFINE_Q35_MACHINE(v2_12, "pc-q35-2.12", NULL,
+ pc_q35_2_12_machine_options);
+
+static void pc_q35_2_11_machine_options(MachineClass *m)
+{
+ pc_q35_2_12_machine_options(m);
+ m->alias = NULL;
+ SET_MACHINE_COMPAT(m, PC_COMPAT_2_11);
+}
+
DEFINE_Q35_MACHINE(v2_11, "pc-q35-2.11", NULL,
pc_q35_2_11_machine_options);
static void pc_q35_2_10_machine_options(MachineClass *m)
{
pc_q35_2_11_machine_options(m);
- m->alias = NULL;
SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
m->auto_enable_numa_with_memhp = false;
diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c
index 293caf83ef..8a01a2dd25 100644
--- a/hw/i386/x86-iommu.c
+++ b/hw/i386/x86-iommu.c
@@ -21,6 +21,8 @@
#include "hw/sysbus.h"
#include "hw/boards.h"
#include "hw/i386/x86-iommu.h"
+#include "hw/i386/pc.h"
+#include "qapi/error.h"
#include "qemu/error-report.h"
#include "trace.h"
@@ -80,7 +82,18 @@ static void x86_iommu_realize(DeviceState *dev, Error **errp)
{
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
X86IOMMUClass *x86_class = X86_IOMMU_GET_CLASS(dev);
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ PCMachineState *pcms =
+ PC_MACHINE(object_dynamic_cast(OBJECT(ms), TYPE_PC_MACHINE));
QLIST_INIT(&x86_iommu->iec_notifiers);
+
+ if (!pcms || !pcms->bus) {
+ error_setg(errp, "Machine-type '%s' not supported by IOMMU",
+ mc->name);
+ return;
+ }
+
if (x86_class->realize) {
x86_class->realize(dev, errp);
}
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index fc8623c90b..deb7a0c374 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -185,11 +185,11 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v
if (val & (UNPLUG_IDE_SCSI_DISKS | UNPLUG_AUX_IDE_DISKS |
UNPLUG_NVME_DISKS)) {
DPRINTF("unplug disks\n");
- pci_unplug_disks(pci_dev->bus, val);
+ pci_unplug_disks(pci_get_bus(pci_dev), val);
}
if (val & UNPLUG_ALL_NICS) {
DPRINTF("unplug nics\n");
- pci_unplug_nics(pci_dev->bus);
+ pci_unplug_nics(pci_get_bus(pci_dev));
}
break;
}
@@ -371,17 +371,17 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
* If VMDP was to control both disk and LAN it would use 4.
* If it controlled just disk or just LAN, it would use 8 below.
*/
- pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
- pci_unplug_nics(pci_dev->bus);
+ pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS);
+ pci_unplug_nics(pci_get_bus(pci_dev));
}
break;
case 8:
switch (val) {
case 1:
- pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
+ pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS);
break;
case 2:
- pci_unplug_nics(pci_dev->bus);
+ pci_unplug_nics(pci_get_bus(pci_dev));
break;
default:
log_writeb(s, (uint32_t)val);
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 451b18b419..e22d7be05f 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1052,7 +1052,7 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
g_assert(is_ncq(ncq_fis->command));
if (ncq_tfs->used) {
/* error - already in use */
- fprintf(stderr, "%s: tag %d already used\n", __FUNCTION__, tag);
+ fprintf(stderr, "%s: tag %d already used\n", __func__, tag);
return;
}
diff --git a/hw/ide/ahci_internal.h b/hw/ide/ahci_internal.h
index ce2e818c8c..8c755d4ca1 100644
--- a/hw/ide/ahci_internal.h
+++ b/hw/ide/ahci_internal.h
@@ -311,8 +311,6 @@ struct AHCIPCIState {
AHCIState ahci;
};
-#define TYPE_ICH9_AHCI "ich9-ahci"
-
#define ICH_AHCI(obj) \
OBJECT_CHECK(AHCIPCIState, (obj), TYPE_ICH9_AHCI)
@@ -375,10 +373,8 @@ void ahci_uninit(AHCIState *s);
void ahci_reset(AHCIState *s);
-#define TYPE_SYSBUS_AHCI "sysbus-ahci"
#define SYSBUS_AHCI(obj) OBJECT_CHECK(SysbusAHCIState, (obj), TYPE_SYSBUS_AHCI)
-#define TYPE_ALLWINNER_AHCI "allwinner-ahci"
#define ALLWINNER_AHCI(obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \
TYPE_ALLWINNER_AHCI)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 1ea5812b7e..5be72d41dc 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -380,14 +380,27 @@ static void ide_set_signature(IDEState *s)
}
}
+static bool ide_sect_range_ok(IDEState *s,
+ uint64_t sector, uint64_t nb_sectors)
+{
+ uint64_t total_sectors;
+
+ blk_get_geometry(s->blk, &total_sectors);
+ if (sector > total_sectors || nb_sectors > total_sectors - sector) {
+ return false;
+ }
+ return true;
+}
+
typedef struct TrimAIOCB {
BlockAIOCB common;
- BlockBackend *blk;
+ IDEState *s;
QEMUBH *bh;
int ret;
QEMUIOVector *qiov;
BlockAIOCB *aiocb;
int i, j;
+ bool is_invalid;
} TrimAIOCB;
static void trim_aio_cancel(BlockAIOCB *acb)
@@ -415,8 +428,11 @@ static void ide_trim_bh_cb(void *opaque)
{
TrimAIOCB *iocb = opaque;
- iocb->common.cb(iocb->common.opaque, iocb->ret);
-
+ if (iocb->is_invalid) {
+ ide_dma_error(iocb->s);
+ } else {
+ iocb->common.cb(iocb->common.opaque, iocb->ret);
+ }
qemu_bh_delete(iocb->bh);
iocb->bh = NULL;
qemu_aio_unref(iocb);
@@ -425,6 +441,8 @@ static void ide_trim_bh_cb(void *opaque)
static void ide_issue_trim_cb(void *opaque, int ret)
{
TrimAIOCB *iocb = opaque;
+ IDEState *s = iocb->s;
+
if (ret >= 0) {
while (iocb->j < iocb->qiov->niov) {
int j = iocb->j;
@@ -441,8 +459,13 @@ static void ide_issue_trim_cb(void *opaque, int ret)
continue;
}
+ if (!ide_sect_range_ok(s, sector, count)) {
+ iocb->is_invalid = true;
+ goto done;
+ }
+
/* Got an entry! Submit and exit. */
- iocb->aiocb = blk_aio_pdiscard(iocb->blk,
+ iocb->aiocb = blk_aio_pdiscard(s->blk,
sector << BDRV_SECTOR_BITS,
count << BDRV_SECTOR_BITS,
ide_issue_trim_cb, opaque);
@@ -456,6 +479,7 @@ static void ide_issue_trim_cb(void *opaque, int ret)
iocb->ret = ret;
}
+done:
iocb->aiocb = NULL;
if (iocb->bh) {
qemu_bh_schedule(iocb->bh);
@@ -466,16 +490,17 @@ BlockAIOCB *ide_issue_trim(
int64_t offset, QEMUIOVector *qiov,
BlockCompletionFunc *cb, void *cb_opaque, void *opaque)
{
- BlockBackend *blk = opaque;
+ IDEState *s = opaque;
TrimAIOCB *iocb;
- iocb = blk_aio_get(&trim_aiocb_info, blk, cb, cb_opaque);
- iocb->blk = blk;
+ iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque);
+ iocb->s = s;
iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
iocb->ret = 0;
iocb->qiov = qiov;
iocb->i = -1;
iocb->j = 0;
+ iocb->is_invalid = false;
ide_issue_trim_cb(iocb, 0);
return &iocb->common;
}
@@ -601,18 +626,6 @@ static void ide_rw_error(IDEState *s) {
ide_set_irq(s->bus);
}
-static bool ide_sect_range_ok(IDEState *s,
- uint64_t sector, uint64_t nb_sectors)
-{
- uint64_t total_sectors;
-
- blk_get_geometry(s->blk, &total_sectors);
- if (sector > total_sectors || nb_sectors > total_sectors - sector) {
- return false;
- }
- return true;
-}
-
static void ide_buffered_readv_cb(void *opaque, int ret)
{
IDEBufferedRequest *req = opaque;
@@ -900,7 +913,7 @@ static void ide_dma_cb(void *opaque, int ret)
case IDE_DMA_TRIM:
s->bus->dma->aiocb = dma_blk_io(blk_get_aio_context(s->blk),
&s->sg, offset, BDRV_SECTOR_SIZE,
- ide_issue_trim, s->blk, ide_dma_cb, s,
+ ide_issue_trim, s, ide_dma_cb, s,
DMA_DIRECTION_TO_DEVICE);
break;
default:
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
index fde4d4645e..58e4f52f7d 100644
--- a/hw/ide/microdrive.c
+++ b/hw/ide/microdrive.c
@@ -155,7 +155,7 @@ static uint8_t md_attr_read(PCMCIACardState *card, uint32_t at)
return 0x00;
#ifdef VERBOSE
default:
- printf("%s: Bad attribute space register %02x\n", __FUNCTION__, at);
+ printf("%s: Bad attribute space register %02x\n", __func__, at);
#endif
}
@@ -192,7 +192,7 @@ static void md_attr_write(PCMCIACardState *card, uint32_t at, uint8_t value)
case 0x06: /* Socket and Copy Register */
break;
default:
- printf("%s: Bad attribute space register %02x\n", __FUNCTION__, at);
+ printf("%s: Bad attribute space register %02x\n", __func__, at);
}
}
diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c
index e2f5562bb7..17aa930e39 100644
--- a/hw/ide/sii3112.c
+++ b/hw/ide/sii3112.c
@@ -79,13 +79,13 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
val |= (d->regs[0].confstat & (1UL << 11) ? (1 << 4) : 0); /*SATAINT0*/
val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 6) : 0); /*SATAINT1*/
val |= (d->i.bmdma[1].status & BM_STATUS_INT ? (1 << 14) : 0);
- val |= d->i.bmdma[0].status << 16;
- val |= d->i.bmdma[1].status << 24;
+ val |= (uint32_t)d->i.bmdma[0].status << 16;
+ val |= (uint32_t)d->i.bmdma[1].status << 24;
break;
case 0x18:
val = d->i.bmdma[1].cmd;
val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0);
- val |= d->i.bmdma[1].status << 16;
+ val |= (uint32_t)d->i.bmdma[1].status << 16;
break;
case 0x80 ... 0x87:
if (size == 1) {
@@ -128,7 +128,7 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
val = (d->i.bus[0].ifs[0].blk) ? 0x113 : 0;
break;
case 0x148:
- val = d->regs[0].sien << 16;
+ val = (uint32_t)d->regs[0].sien << 16;
break;
case 0x180:
val = d->regs[1].scontrol;
@@ -137,7 +137,7 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr,
val = (d->i.bus[1].ifs[0].blk) ? 0x113 : 0;
break;
case 0x1c8:
- val = d->regs[1].sien << 16;
+ val = (uint32_t)d->regs[1].sien << 16;
break;
default:
val = 0;
diff --git a/hw/input/lm832x.c b/hw/input/lm832x.c
index 2340523da0..d39953126b 100644
--- a/hw/input/lm832x.c
+++ b/hw/input/lm832x.c
@@ -239,7 +239,7 @@ static uint8_t lm_kbd_read(LM823KbdState *s, int reg, int byte)
default:
lm_kbd_error(s, ERR_CMDUNK);
- fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, reg);
+ fprintf(stderr, "%s: unknown command %02x\n", __func__, reg);
return 0x00;
}
@@ -331,7 +331,7 @@ static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
if ((value & 3) && (value & 3) != 3) {
lm_kbd_error(s, ERR_BADPAR);
fprintf(stderr, "%s: invalid clock setting in RCPWM\n",
- __FUNCTION__);
+ __func__);
}
/* TODO: Validate that the command is only issued once */
break;
@@ -378,7 +378,7 @@ static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
break;
default:
lm_kbd_error(s, ERR_CMDUNK);
- fprintf(stderr, "%s: unknown command %02x\n", __FUNCTION__, reg);
+ fprintf(stderr, "%s: unknown command %02x\n", __func__, reg);
break;
}
}
diff --git a/hw/input/pxa2xx_keypad.c b/hw/input/pxa2xx_keypad.c
index 2b70bbb95c..93db9ed25b 100644
--- a/hw/input/pxa2xx_keypad.c
+++ b/hw/input/pxa2xx_keypad.c
@@ -231,7 +231,7 @@ static uint64_t pxa2xx_keypad_read(void *opaque, hwaddr offset,
return s->kpkdi;
break;
default:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
+ hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
}
return 0;
@@ -278,7 +278,7 @@ static void pxa2xx_keypad_write(void *opaque, hwaddr offset,
break;
default:
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
+ hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
}
}
@@ -326,7 +326,7 @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp,
const struct keymap *map, int size)
{
if(!map || size < 0x80) {
- fprintf(stderr, "%s - No PXA keypad map defined\n", __FUNCTION__);
+ fprintf(stderr, "%s - No PXA keypad map defined\n", __func__);
exit(-1);
}
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
index eb5320af40..7990954b6c 100644
--- a/hw/input/tsc2005.c
+++ b/hw/input/tsc2005.c
@@ -201,7 +201,7 @@ static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
if (s->enabled != !(data & 0x4000)) {
s->enabled = !(data & 0x4000);
fprintf(stderr, "%s: touchscreen sense %sabled\n",
- __FUNCTION__, s->enabled ? "en" : "dis");
+ __func__, s->enabled ? "en" : "dis");
if (s->busy && !s->enabled)
timer_del(s->timer);
s->busy = s->busy && s->enabled;
@@ -210,7 +210,7 @@ static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
s->timing[0] = data & 0x1fff;
if ((s->timing[0] >> 11) == 3)
fprintf(stderr, "%s: illegal conversion clock setting\n",
- __FUNCTION__);
+ __func__);
break;
case 0xd: /* CFR1 */
s->timing[1] = data & 0xf07;
@@ -222,7 +222,7 @@ static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
default:
fprintf(stderr, "%s: write into read-only register %x\n",
- __FUNCTION__, reg);
+ __func__, reg);
}
}
@@ -338,7 +338,7 @@ static uint8_t tsc2005_txrx_word(void *opaque, uint8_t value)
if (s->enabled != !(value & 1)) {
s->enabled = !(value & 1);
fprintf(stderr, "%s: touchscreen sense %sabled\n",
- __FUNCTION__, s->enabled ? "en" : "dis");
+ __func__, s->enabled ? "en" : "dis");
if (s->busy && !s->enabled)
timer_del(s->timer);
s->busy = s->busy && s->enabled;
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
index 75ac8c2ab5..1cad57f644 100644
--- a/hw/input/tsc210x.c
+++ b/hw/input/tsc210x.c
@@ -287,7 +287,7 @@ static void tsc2102_audio_rate_update(TSC210xState *s)
rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
break;
if (!rate->rate) {
- printf("%s: unknown sampling rate configured\n", __FUNCTION__);
+ printf("%s: unknown sampling rate configured\n", __func__);
return;
}
@@ -913,7 +913,7 @@ uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
uint32_t ret = 0;
if (len != 16)
- hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
+ hw_error("%s: FIXME: bad SPI word width %i\n", __func__, len);
/* TODO: sequential reads etc - how do we make sure the host doesn't
* unintentionally read out a conversion result from a register while
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index dd49b6c335..8ca6ceeb9b 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -896,13 +896,6 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
val |= (1 << 8);
}
return val;
- case 0xd28: /* Configurable Fault Status. */
- /* The BFSR bits [15:8] are shared between security states
- * and we store them in the NS copy
- */
- val = cpu->env.v7m.cfsr[attrs.secure];
- val |= cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
- return val;
case 0xd2c: /* Hard Fault Status. */
return cpu->env.v7m.hfsr;
case 0xd30: /* Debug Fault Status. */
@@ -1280,15 +1273,6 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
s->vectors[ARMV7M_EXCP_DEBUG].active = (value & (1 << 8)) != 0;
nvic_irq_update(s);
break;
- case 0xd28: /* Configurable Fault Status. */
- cpu->env.v7m.cfsr[attrs.secure] &= ~value; /* W1C */
- if (attrs.secure) {
- /* The BFSR bits [15:8] are shared between security states
- * and we store them in the NS copy.
- */
- cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
- }
- break;
case 0xd2c: /* Hard Fault Status. */
cpu->env.v7m.hfsr &= ~value; /* W1C */
break;
@@ -1667,6 +1651,14 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
val = deposit32(val, i * 8, 8, get_prio(s, hdlidx, sbank));
}
break;
+ case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
+ /* The BFSR bits [15:8] are shared between security states
+ * and we store them in the NS copy
+ */
+ val = s->cpu->env.v7m.cfsr[attrs.secure];
+ val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
+ val = extract32(val, (offset - 0xd28) * 8, size * 8);
+ break;
case 0xfe0 ... 0xfff: /* ID. */
if (offset & 3) {
val = 0;
@@ -1765,6 +1757,20 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
}
nvic_irq_update(s);
return MEMTX_OK;
+ case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
+ /* All bits are W1C, so construct 32 bit value with 0s in
+ * the parts not written by the access size
+ */
+ value <<= ((offset - 0xd28) * 8);
+
+ s->cpu->env.v7m.cfsr[attrs.secure] &= ~value;
+ if (attrs.secure) {
+ /* The BFSR bits [15:8] are shared between security states
+ * and we store them in the NS copy.
+ */
+ s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
+ }
+ return MEMTX_OK;
}
if (size == 4) {
nvic_writel(s, offset, value, attrs);
diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
index ccdda89dab..6844c1aa83 100644
--- a/hw/intc/omap_intc.c
+++ b/hw/intc/omap_intc.c
@@ -540,7 +540,7 @@ static void omap2_inth_write(void *opaque, hwaddr addr,
* for every register, see Chapter 3 and 4 for privileged mode. */
if (value & 1)
fprintf(stderr, "%s: protection mode enable attempt\n",
- __FUNCTION__);
+ __func__);
return;
case 0x50: /* INTC_IDLE */
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index abab3bba4f..8c0535d3dd 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -28,6 +28,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qemu/timer.h"
#include "chardev/char-fe.h"
@@ -194,8 +195,8 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b,
if (ibe->outlen) {
/* We already have a command queued. Shouldn't ever happen. */
- fprintf(stderr, "IPMI KCS: Got command when not finished with the"
- " previous command\n");
+ error_report("IPMI KCS: Got command when not finished with the"
+ " previous command");
abort();
}
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 348e0eab9d..0f2e426d02 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -17,6 +17,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
+#include "qemu/error-report.h"
#include "qapi/error.h"
#include "hw/hw.h"
#include "monitor/monitor.h"
@@ -186,15 +187,15 @@ ISADevice *isa_vga_init(ISABus *bus)
case VGA_CIRRUS:
return isa_create_simple(bus, "isa-cirrus-vga");
case VGA_QXL:
- fprintf(stderr, "%s: qxl: no PCI bus\n", __func__);
+ error_report("%s: qxl: no PCI bus", __func__);
return NULL;
case VGA_STD:
return isa_create_simple(bus, "isa-vga");
case VGA_VMWARE:
- fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __func__);
+ error_report("%s: vmware_vga: no PCI bus", __func__);
return NULL;
case VGA_VIRTIO:
- fprintf(stderr, "%s: virtio-vga: no PCI bus\n", __func__);
+ error_report("%s: virtio-vga: no PCI bus", __func__);
return NULL;
case VGA_NONE:
default:
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index ec3c9f7d0b..adcf077fa5 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -162,7 +162,7 @@ static void ich9_cc_write(void *opaque, hwaddr addr,
ich9_cc_addr_len(&addr, &len);
memcpy(lpc->chip_config + addr, &val, len);
- pci_bus_fire_intx_routing_notifier(lpc->d.bus);
+ pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d));
ich9_cc_update(lpc);
}
@@ -218,7 +218,7 @@ static void ich9_lpc_update_pic(ICH9LPCState *lpc, int gsi)
int tmp_dis;
ich9_lpc_pic_irq(lpc, i, &tmp_irq, &tmp_dis);
if (!tmp_dis && tmp_irq == gsi) {
- pic_level |= pci_bus_get_irq_level(lpc->d.bus, i);
+ pic_level |= pci_bus_get_irq_level(pci_get_bus(&lpc->d), i);
}
}
if (gsi == lpc->sci_gsi) {
@@ -246,7 +246,7 @@ static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi)
assert(gsi >= ICH9_LPC_PIC_NUM_PINS);
- level |= pci_bus_get_irq_level(lpc->d.bus, ich9_gsi_to_pirq(gsi));
+ level |= pci_bus_get_irq_level(pci_get_bus(&lpc->d), ich9_gsi_to_pirq(gsi));
if (gsi == lpc->sci_gsi) {
level |= lpc->sci_level;
}
@@ -524,10 +524,10 @@ static void ich9_lpc_config_write(PCIDevice *d,
ich9_lpc_rcba_update(lpc, rcba_old);
}
if (ranges_overlap(addr, len, ICH9_LPC_PIRQA_ROUT, 4)) {
- pci_bus_fire_intx_routing_notifier(lpc->d.bus);
+ pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d));
}
if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) {
- pci_bus_fire_intx_routing_notifier(lpc->d.bus);
+ pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d));
}
if (ranges_overlap(addr, len, ICH9_LPC_GEN_PMCON_1, 8)) {
ich9_lpc_pmcon_update(lpc);
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 4084b32be9..070cc1889f 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -29,7 +29,7 @@
//#define DEBUG_VT82C686B
#ifdef DEBUG_VT82C686B
-#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__)
#else
#define DPRINTF(fmt, ...)
#endif
diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index 952fce5ec8..61e677f92f 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
+#include "qapi-visit.h"
#include "hw/mem/nvdimm.h"
static void nvdimm_get_label_size(Object *obj, Visitor *v, const char *name,
@@ -64,11 +65,36 @@ out:
error_propagate(errp, local_err);
}
+static bool nvdimm_get_unarmed(Object *obj, Error **errp)
+{
+ NVDIMMDevice *nvdimm = NVDIMM(obj);
+
+ return nvdimm->unarmed;
+}
+
+static void nvdimm_set_unarmed(Object *obj, bool value, Error **errp)
+{
+ NVDIMMDevice *nvdimm = NVDIMM(obj);
+ Error *local_err = NULL;
+
+ if (memory_region_size(&nvdimm->nvdimm_mr)) {
+ error_setg(&local_err, "cannot change property value");
+ goto out;
+ }
+
+ nvdimm->unarmed = value;
+
+ out:
+ error_propagate(errp, local_err);
+}
+
static void nvdimm_init(Object *obj)
{
- object_property_add(obj, "label-size", "int",
+ object_property_add(obj, NVDIMM_LABLE_SIZE_PROP, "int",
nvdimm_get_label_size, nvdimm_set_label_size, NULL,
NULL, NULL);
+ object_property_add_bool(obj, NVDIMM_UNARMED_PROP,
+ nvdimm_get_unarmed, nvdimm_set_unarmed, NULL);
}
static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 5a9dad9aae..24ad0ad024 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -33,7 +33,7 @@
//#define DEBUG
#ifdef DEBUG
-#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__)
#else
#define DPRINTF(fmt, ...)
#endif
@@ -1171,12 +1171,12 @@ PCIBus *gt64120_register(qemu_irq *pic)
phb = PCI_HOST_BRIDGE(dev);
memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", UINT32_MAX);
address_space_init(&d->pci0_mem_as, &d->pci0_mem, "pci0-mem");
- phb->bus = pci_register_bus(dev, "pci",
- gt64120_pci_set_irq, gt64120_pci_map_irq,
- pic,
- &d->pci0_mem,
- get_system_io(),
- PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS);
+ phb->bus = pci_register_root_bus(dev, "pci",
+ gt64120_pci_set_irq, gt64120_pci_map_irq,
+ pic,
+ &d->pci0_mem,
+ get_system_io(),
+ PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS);
qdev_init_nofail(dev);
memory_region_init_io(&d->ISD_mem, OBJECT(dev), &isd_mem_ops, d, "isd-mem", 0x1000);
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
index 1182745044..b4cacd664b 100644
--- a/hw/misc/auxbus.c
+++ b/hw/misc/auxbus.c
@@ -40,7 +40,7 @@
if (DEBUG_AUX) { \
qemu_log("aux: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define TYPE_AUXTOI2C "aux-to-i2c-bridge"
#define AUXTOI2C(obj) OBJECT_CHECK(AUXTOI2CState, (obj), TYPE_AUXTOI2C)
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
index 677274ce3e..25e337ea77 100644
--- a/hw/misc/cbus.c
+++ b/hw/misc/cbus.c
@@ -62,7 +62,7 @@ static void cbus_io(CBusPriv *s)
s->slave[s->addr]->io(s->slave[s->addr]->opaque,
s->rw, s->reg, &s->val);
else
- hw_error("%s: bad slave address %i\n", __FUNCTION__, s->addr);
+ hw_error("%s: bad slave address %i\n", __func__, s->addr);
}
static void cbus_cycle(CBusPriv *s)
@@ -299,7 +299,7 @@ static inline uint16_t retu_read(CBusRetu *s, int reg)
return 0x0000;
default:
- hw_error("%s: bad register %02x\n", __FUNCTION__, reg);
+ hw_error("%s: bad register %02x\n", __func__, reg);
}
}
@@ -372,7 +372,7 @@ static inline void retu_write(CBusRetu *s, int reg, uint16_t val)
break;
default:
- hw_error("%s: bad register %02x\n", __FUNCTION__, reg);
+ hw_error("%s: bad register %02x\n", __func__, reg);
}
}
@@ -538,7 +538,7 @@ static inline uint16_t tahvo_read(CBusTahvo *s, int reg)
return 0x0000;
default:
- hw_error("%s: bad register %02x\n", __FUNCTION__, reg);
+ hw_error("%s: bad register %02x\n", __func__, reg);
}
}
@@ -567,7 +567,7 @@ static inline void tahvo_write(CBusTahvo *s, int reg, uint16_t val)
if (s->backlight != (val & 0x7f)) {
s->backlight = val & 0x7f;
printf("%s: LCD backlight now at %i / 127\n",
- __FUNCTION__, s->backlight);
+ __func__, s->backlight);
}
break;
@@ -588,7 +588,7 @@ static inline void tahvo_write(CBusTahvo *s, int reg, uint16_t val)
break;
default:
- hw_error("%s: bad register %02x\n", __FUNCTION__, reg);
+ hw_error("%s: bad register %02x\n", __func__, reg);
}
}
diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c
index 0eddf2e700..1b2a69b3ef 100644
--- a/hw/misc/macio/mac_dbdma.c
+++ b/hw/misc/macio/mac_dbdma.c
@@ -52,7 +52,7 @@
if (DEBUG_DBDMA) { \
printf("DBDMA: " fmt , ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define DBDMA_DPRINTFCH(ch, fmt, ...) do { \
if (DEBUG_DBDMA) { \
@@ -60,7 +60,7 @@
printf("DBDMA[%02x]: " fmt , (ch)->channel, ## __VA_ARGS__); \
} \
} \
-} while (0);
+} while (0)
/*
*/
diff --git a/hw/misc/mmio_interface.c b/hw/misc/mmio_interface.c
index 894e9801cb..3b0e2039a3 100644
--- a/hw/misc/mmio_interface.c
+++ b/hw/misc/mmio_interface.c
@@ -39,7 +39,7 @@ static uint64_t mmio_interface_counter;
if (DEBUG_MMIO_INTERFACE) { \
qemu_log("mmio_interface: 0x%" PRIX64 ": " fmt, s->id, ## __VA_ARGS__);\
} \
-} while (0);
+} while (0)
static void mmio_interface_init(Object *obj)
{
diff --git a/hw/misc/omap_clk.c b/hw/misc/omap_clk.c
index 19151d07d6..9ea14186d4 100644
--- a/hw/misc/omap_clk.c
+++ b/hw/misc/omap_clk.c
@@ -1109,7 +1109,7 @@ struct clk *omap_findclk(struct omap_mpu_state_s *mpu, const char *name)
for (i = mpu->clks; i->name; i ++)
if (!strcmp(i->name, name) || (i->alias && !strcmp(i->alias, name)))
return i;
- hw_error("%s: %s not found\n", __FUNCTION__, name);
+ hw_error("%s: %s not found\n", __func__, name);
}
void omap_clk_get(struct clk *clk)
@@ -1120,7 +1120,7 @@ void omap_clk_get(struct clk *clk)
void omap_clk_put(struct clk *clk)
{
if (!(clk->usecount --))
- hw_error("%s: %s is not in use\n", __FUNCTION__, clk->name);
+ hw_error("%s: %s is not in use\n", __func__, clk->name);
}
static void omap_clk_update(struct clk *clk)
diff --git a/hw/misc/omap_gpmc.c b/hw/misc/omap_gpmc.c
index 67d8e2f023..84f9e4c612 100644
--- a/hw/misc/omap_gpmc.c
+++ b/hw/misc/omap_gpmc.c
@@ -643,7 +643,7 @@ static void omap_gpmc_write(void *opaque, hwaddr addr,
case 0x010: /* GPMC_SYSCONFIG */
if ((value >> 3) == 0x3)
fprintf(stderr, "%s: bad SDRAM idle mode %"PRIi64"\n",
- __FUNCTION__, value >> 3);
+ __func__, value >> 3);
if (value & 2)
omap_gpmc_reset(s);
s->sysconfig = value & 0x19;
@@ -806,7 +806,7 @@ static void omap_gpmc_write(void *opaque, hwaddr addr,
break;
case 0x230: /* GPMC_TESTMODE_CTRL */
if (value & 7)
- fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__);
+ fprintf(stderr, "%s: test mode enable attempt\n", __func__);
break;
default:
@@ -864,7 +864,7 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem)
assert(iomem);
if (cs < 0 || cs >= 8) {
- fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
+ fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs);
exit(-1);
}
f = &s->cs_file[cs];
diff --git a/hw/misc/omap_l4.c b/hw/misc/omap_l4.c
index 88c533a0fe..96fc057b4e 100644
--- a/hw/misc/omap_l4.c
+++ b/hw/misc/omap_l4.c
@@ -126,7 +126,7 @@ struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus,
break;
}
if (!ta) {
- fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs);
+ fprintf(stderr, "%s: bad target agent (%i)\n", __func__, cs);
exit(-1);
}
@@ -151,7 +151,7 @@ hwaddr omap_l4_attach(struct omap_target_agent_s *ta,
hwaddr base;
if (region < 0 || region >= ta->regions) {
- fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region);
+ fprintf(stderr, "%s: bad io region (%i)\n", __func__, region);
exit(-1);
}
diff --git a/hw/misc/omap_sdrc.c b/hw/misc/omap_sdrc.c
index dff37ecaf9..7b38c5568c 100644
--- a/hw/misc/omap_sdrc.c
+++ b/hw/misc/omap_sdrc.c
@@ -109,7 +109,7 @@ static void omap_sdrc_write(void *opaque, hwaddr addr,
case 0x10: /* SDRC_SYSCONFIG */
if ((value >> 3) != 0x2)
fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
- __FUNCTION__, (unsigned)value >> 3);
+ __func__, (unsigned)value >> 3);
if (value & 2)
omap_sdrc_reset(s);
s->config = value & 0x18;
diff --git a/hw/misc/omap_tap.c b/hw/misc/omap_tap.c
index e6ea8ee235..3f595e8df7 100644
--- a/hw/misc/omap_tap.c
+++ b/hw/misc/omap_tap.c
@@ -44,7 +44,7 @@ static uint64_t omap_tap_read(void *opaque, hwaddr addr,
case omap3430:
return 0x1b7ae02f; /* ES 2 */
default:
- hw_error("%s: Bad mpu model\n", __FUNCTION__);
+ hw_error("%s: Bad mpu model\n", __func__);
}
case 0x208: /* PRODUCTION_ID_reg for OMAP2 */
@@ -61,7 +61,7 @@ static uint64_t omap_tap_read(void *opaque, hwaddr addr,
case omap3430:
return 0x000000f0;
default:
- hw_error("%s: Bad mpu model\n", __FUNCTION__);
+ hw_error("%s: Bad mpu model\n", __func__);
}
case 0x20c:
@@ -75,7 +75,7 @@ static uint64_t omap_tap_read(void *opaque, hwaddr addr,
case omap3430:
return 0xcafeb7ae; /* ES 2 */
default:
- hw_error("%s: Bad mpu model\n", __FUNCTION__);
+ hw_error("%s: Bad mpu model\n", __func__);
}
case 0x218: /* DIE_ID_reg */
diff --git a/hw/misc/stm32f2xx_syscfg.c b/hw/misc/stm32f2xx_syscfg.c
index 7c45833d09..7f10195862 100644
--- a/hw/misc/stm32f2xx_syscfg.c
+++ b/hw/misc/stm32f2xx_syscfg.c
@@ -34,7 +34,7 @@
if (STM_SYSCFG_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/misc/tmp105.c b/hw/misc/tmp105.c
index 04e83787d4..9e22d64e36 100644
--- a/hw/misc/tmp105.c
+++ b/hw/misc/tmp105.c
@@ -131,7 +131,7 @@ static void tmp105_write(TMP105State *s)
case TMP105_REG_CONFIG:
if (s->buf[0] & ~s->config & (1 << 0)) /* SD */
- printf("%s: TMP105 shutdown\n", __FUNCTION__);
+ printf("%s: TMP105 shutdown\n", __func__);
s->config = s->buf[0];
s->faults = tmp105_faultq[(s->config >> 3) & 3]; /* F */
tmp105_alarm_update(s);
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index 44304d48be..d6bdd027ef 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -30,7 +30,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
- } while (0);
+ } while (0)
#define XILINX_LOCK_KEY 0x767b
#define XILINX_UNLOCK_KEY 0xdf0d
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 3943187572..0fa4b0dc44 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -34,7 +34,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
- } while (0);
+ } while (0)
#else
#define DB_PRINT(...)
#endif
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 39d5d93525..606b05c09f 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -456,32 +456,32 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
#define CHECK_RMD(ADDR,RES) do { \
switch (BCR_SWSTYLE(s)) { \
case 0x00: \
- do { \
+ { \
uint16_t rda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[2] & 0xf000)!=0xf000; \
(RES) |= (rda[3] & 0xf000)!=0x0000; \
- } while (0); \
+ } \
break; \
case 0x01: \
case 0x02: \
- do { \
+ { \
uint32_t rda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
(RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \
- } while (0); \
+ } \
break; \
case 0x03: \
- do { \
+ { \
uint32_t rda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&rda[0], sizeof(rda), 0); \
(RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \
(RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \
- } while (0); \
+ } \
break; \
} \
} while (0)
@@ -489,22 +489,22 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd,
#define CHECK_TMD(ADDR,RES) do { \
switch (BCR_SWSTYLE(s)) { \
case 0x00: \
- do { \
+ { \
uint16_t xda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&xda[0], sizeof(xda), 0); \
(RES) |= (xda[2] & 0xf000)!=0xf000; \
- } while (0); \
+ } \
break; \
case 0x01: \
case 0x02: \
case 0x03: \
- do { \
+ { \
uint32_t xda[4]; \
s->phys_mem_read(s->dma_opaque, (ADDR), \
(void *)&xda[0], sizeof(xda), 0); \
(RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \
- } while (0); \
+ } \
break; \
} \
} while (0)
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index b8404cb2e2..0654d594c1 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2356,7 +2356,7 @@ static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp)
vmxnet3_net_init(s);
if (pci_is_express(pci_dev)) {
- if (pci_bus_is_express(pci_dev->bus)) {
+ if (pci_bus_is_express(pci_get_bus(pci_dev))) {
pcie_endpoint_cap_init(pci_dev, VMXNET3_EXP_EP_OFFSET);
}
diff --git a/hw/nvram/ds1225y.c b/hw/nvram/ds1225y.c
index 57d5ab2154..ad7345f288 100644
--- a/hw/nvram/ds1225y.c
+++ b/hw/nvram/ds1225y.c
@@ -80,7 +80,7 @@ static int nvram_post_load(void *opaque, int version_id)
}
/* Write back nvram contents */
- s->file = fopen(s->filename, "wb");
+ s->file = s->filename ? fopen(s->filename, "wb") : NULL;
if (s->file) {
/* Write back contents, as 'wb' mode cleaned the file */
if (fwrite(s->contents, s->chip_size, 1, s->file) != 1) {
@@ -126,7 +126,7 @@ static int nvram_sysbus_initfn(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->iomem);
/* Read current file */
- file = fopen(s->filename, "rb");
+ file = s->filename ? fopen(s->filename, "rb") : NULL;
if (file) {
/* Read nvram contents */
if (fread(s->contents, s->chip_size, 1, file) != 1) {
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 753ac0e4ea..4313484b21 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -784,7 +784,7 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
* index and "i - 1" is the one being copied from, thus the
* unusual start and end in the for statement.
*/
- for (i = count + 1; i > index; i--) {
+ for (i = count; i > index; i--) {
s->files->f[i] = s->files->f[i - 1];
s->files->f[i].select = cpu_to_be16(FW_CFG_FILE_FIRST + i);
s->entries[0][FW_CFG_FILE_FIRST + i] =
@@ -833,7 +833,6 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
assert(s->files);
index = be32_to_cpu(s->files->count);
- assert(index < fw_cfg_file_slots(s));
for (i = 0; i < index; i++) {
if (strcmp(filename, s->files->f[i].name) == 0) {
@@ -843,6 +842,9 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
return ptr;
}
}
+
+ assert(index < fw_cfg_file_slots(s));
+
/* add new one */
fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, true);
return NULL;
diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
index ad4e6aa7ff..0e2f2e8bf1 100644
--- a/hw/pci-bridge/gen_pcie_root_port.c
+++ b/hw/pci-bridge/gen_pcie_root_port.c
@@ -74,8 +74,13 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
PCIDevice *d = PCI_DEVICE(dev);
GenPCIERootPort *grp = GEN_PCIE_ROOT_PORT(d);
PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
+ Error *local_err = NULL;
- rpc->parent_realize(dev, errp);
+ rpc->parent_realize(dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve,
grp->io_reserve, grp->mem_reserve, grp->pref32_reserve,
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index 9e799dc10f..e62de4218f 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -51,7 +51,8 @@ typedef struct PXBDev {
static PXBDev *convert_to_pxb(PCIDevice *dev)
{
- return pci_bus_is_express(dev->bus) ? PXB_PCIE_DEV(dev) : PXB_DEV(dev);
+ return pci_bus_is_express(pci_get_bus(dev))
+ ? PXB_PCIE_DEV(dev) : PXB_DEV(dev);
}
static GList *pxb_dev_list;
@@ -165,7 +166,7 @@ static const TypeInfo pxb_host_info = {
*/
static void pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus, Error **errp)
{
- PCIBus *bus = dev->bus;
+ PCIBus *bus = pci_get_bus(dev);
int pxb_bus_num = pci_bus_num(pxb_bus);
if (bus->parent_dev) {
@@ -179,12 +180,12 @@ static void pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus, Error **errp)
return;
}
}
- QLIST_INSERT_HEAD(&dev->bus->child, pxb_bus, sibling);
+ QLIST_INSERT_HEAD(&pci_get_bus(dev)->child, pxb_bus, sibling);
}
static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)
{
- PCIDevice *pxb = pci_dev->bus->parent_dev;
+ PCIDevice *pxb = pci_get_bus(pci_dev)->parent_dev;
/*
* The bios does not index the pxb slot number when
@@ -229,9 +230,9 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
ds = qdev_create(NULL, TYPE_PXB_HOST);
if (pcie) {
- bus = pci_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS);
+ bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS);
} else {
- bus = pci_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
+ bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
bds = qdev_create(BUS(bus), "pci-bridge");
bds->id = dev_name;
qdev_prop_set_uint8(bds, PCI_BRIDGE_DEV_PROP_CHASSIS_NR, pxb->bus_nr);
@@ -239,8 +240,8 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
}
bus->parent_dev = dev;
- bus->address_space_mem = dev->bus->address_space_mem;
- bus->address_space_io = dev->bus->address_space_io;
+ bus->address_space_mem = pci_get_bus(dev)->address_space_mem;
+ bus->address_space_io = pci_get_bus(dev)->address_space_io;
bus->map_irq = pxb_map_irq_fn;
PCI_HOST_BRIDGE(ds)->bus = bus;
@@ -271,7 +272,7 @@ err_register_bus:
static void pxb_dev_realize(PCIDevice *dev, Error **errp)
{
- if (pci_bus_is_express(dev->bus)) {
+ if (pci_bus_is_express(pci_get_bus(dev))) {
error_setg(errp, "pxb devices cannot reside on a PCIe bus");
return;
}
@@ -323,7 +324,7 @@ static const TypeInfo pxb_dev_info = {
static void pxb_pcie_dev_realize(PCIDevice *dev, Error **errp)
{
- if (!pci_bus_is_express(dev->bus)) {
+ if (!pci_bus_is_express(pci_get_bus(dev))) {
error_setg(errp, "pxb-pcie devices cannot reside on a PCI bus");
return;
}
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 3e796fb6fc..ec676f94b6 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -433,11 +433,11 @@ static void pci_pbm_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(get_system_memory(), s->mem_base,
&s->pci_mmio);
- phb->bus = pci_register_bus(dev, "pci",
- pci_apb_set_irq, pci_apb_map_irq, s,
- &s->pci_mmio,
- &s->pci_ioport,
- 0, 32, TYPE_PCI_BUS);
+ phb->bus = pci_register_root_bus(dev, "pci",
+ pci_apb_set_irq, pci_apb_map_irq, s,
+ &s->pci_mmio,
+ &s->pci_ioport,
+ 0, 32, TYPE_PCI_BUS);
pci_create_simple(phb->bus, 0, "pbm-pci");
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 9f61e27edc..0d8cacb884 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -50,7 +50,7 @@
//#define DEBUG_BONITO
#ifdef DEBUG_BONITO
-#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__)
#else
#define DPRINTF(fmt, ...)
#endif
@@ -714,10 +714,10 @@ static int bonito_pcihost_initfn(SysBusDevice *dev)
{
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
- phb->bus = pci_register_bus(DEVICE(dev), "pci",
- pci_bonito_set_irq, pci_bonito_map_irq, dev,
- get_system_memory(), get_system_io(),
- 0x28, 32, TYPE_PCI_BUS);
+ phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
+ pci_bonito_set_irq, pci_bonito_map_irq,
+ dev, get_system_memory(), get_system_io(),
+ 0x28, 32, TYPE_PCI_BUS);
return 0;
}
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
index edf305b1fd..2583b151a4 100644
--- a/hw/pci-host/gpex.c
+++ b/hw/pci-host/gpex.c
@@ -89,9 +89,9 @@ static void gpex_host_realize(DeviceState *dev, Error **errp)
s->irq_num[i] = -1;
}
- pci->bus = pci_register_bus(dev, "pcie.0", gpex_set_irq,
- pci_swizzle_map_irq_fn, s, &s->io_mmio,
- &s->io_ioport, 0, 4, TYPE_PCIE_BUS);
+ pci->bus = pci_register_root_bus(dev, "pcie.0", gpex_set_irq,
+ pci_swizzle_map_irq_fn, s, &s->io_mmio,
+ &s->io_ioport, 0, 4, TYPE_PCIE_BUS);
qdev_set_parent_bus(DEVICE(&s->gpex_root), BUS(pci->bus));
pci_bus_set_route_irq_fn(pci->bus, gpex_route_intx_pin_to_irq);
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index 38cd279b6b..3caf1ccb37 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -82,13 +82,13 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
- phb->bus = pci_register_bus(dev, NULL,
- pci_grackle_set_irq,
- pci_grackle_map_irq,
- pic,
- &d->pci_mmio,
- address_space_io,
- 0, 4, TYPE_PCI_BUS);
+ phb->bus = pci_register_root_bus(dev, NULL,
+ pci_grackle_set_irq,
+ pci_grackle_map_irq,
+ pic,
+ &d->pci_mmio,
+ address_space_io,
+ 0, 4, TYPE_PCI_BUS);
pci_create_simple(phb->bus, 0, "grackle");
qdev_init_nofail(dev);
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index a684a7cca9..0e608347c1 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -361,8 +361,8 @@ PCIBus *i440fx_init(const char *host_type, const char *pci_type,
dev = qdev_create(NULL, host_type);
s = PCI_HOST_BRIDGE(dev);
- b = pci_bus_new(dev, NULL, pci_address_space,
- address_space_io, 0, TYPE_PCI_BUS);
+ b = pci_root_bus_new(dev, NULL, pci_address_space,
+ address_space_io, 0, TYPE_PCI_BUS);
s->bus = b;
object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
qdev_init_nofail(dev);
@@ -512,12 +512,12 @@ static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin)
/* irq routing is changed. so rebuild bitmap */
static void piix3_update_irq_levels(PIIX3State *piix3)
{
+ PCIBus *bus = pci_get_bus(&piix3->dev);
int pirq;
piix3->pic_levels = 0;
for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
- piix3_set_irq_level(piix3, pirq,
- pci_bus_get_irq_level(piix3->dev.bus, pirq));
+ piix3_set_irq_level(piix3, pirq, pci_bus_get_irq_level(bus, pirq));
}
}
@@ -529,7 +529,7 @@ static void piix3_write_config(PCIDevice *dev,
PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev);
int pic_irq;
- pci_bus_fire_intx_routing_notifier(piix3->dev.bus);
+ pci_bus_fire_intx_routing_notifier(pci_get_bus(&piix3->dev));
piix3_update_irq_levels(piix3);
for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
piix3_set_irq_pic(piix3, pic_irq);
@@ -601,7 +601,7 @@ static int piix3_post_load(void *opaque, int version_id)
piix3->pic_levels = 0;
for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
piix3_set_irq_level_internal(piix3, pirq,
- pci_bus_get_irq_level(piix3->dev.bus, pirq));
+ pci_bus_get_irq_level(pci_get_bus(&piix3->dev), pirq));
}
return 0;
}
@@ -613,7 +613,7 @@ static int piix3_pre_save(void *opaque)
for (i = 0; i < ARRAY_SIZE(piix3->pci_irq_levels_vmstate); i++) {
piix3->pci_irq_levels_vmstate[i] =
- pci_bus_get_irq_level(piix3->dev.bus, i);
+ pci_bus_get_irq_level(pci_get_bus(&piix3->dev), i);
}
return 0;
@@ -804,60 +804,55 @@ static const IGDHostInfo igd_host_bridge_infos[] = {
{0xa8, 4}, /* SNB: base of GTT stolen memory */
};
-static int host_pci_config_read(int pos, int len, uint32_t *val)
+static void host_pci_config_read(int pos, int len, uint32_t *val, Error **errp)
{
- char path[PATH_MAX];
- int config_fd;
- ssize_t size = sizeof(path);
+ int rc, config_fd;
/* Access real host bridge. */
- int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
- 0, 0, 0, 0, "config");
- int ret = 0;
-
- if (rc >= size || rc < 0) {
- return -ENODEV;
- }
+ char *path = g_strdup_printf("/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
+ 0, 0, 0, 0, "config");
config_fd = open(path, O_RDWR);
if (config_fd < 0) {
- return -ENODEV;
+ error_setg_errno(errp, errno, "Failed to open: %s", path);
+ goto out;
}
if (lseek(config_fd, pos, SEEK_SET) != pos) {
- ret = -errno;
- goto out;
+ error_setg_errno(errp, errno, "Failed to seek: %s", path);
+ goto out_close_fd;
}
do {
rc = read(config_fd, (uint8_t *)val, len);
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
if (rc != len) {
- ret = -errno;
+ error_setg_errno(errp, errno, "Failed to read: %s", path);
}
-out:
+out_close_fd:
close(config_fd);
- return ret;
+out:
+ g_free(path);
}
-static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
+static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
{
uint32_t val = 0;
- int rc, i, num;
+ int i, num;
int pos, len;
+ Error *local_err = NULL;
num = ARRAY_SIZE(igd_host_bridge_infos);
for (i = 0; i < num; i++) {
pos = igd_host_bridge_infos[i].offset;
len = igd_host_bridge_infos[i].len;
- rc = host_pci_config_read(pos, len, &val);
- if (rc) {
- return -ENODEV;
+ host_pci_config_read(pos, len, &val, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
}
pci_default_write_config(pci_dev, pos, val, len);
}
-
- return 0;
}
static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
@@ -865,7 +860,7 @@ static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = igd_pt_i440fx_initfn;
+ k->realize = igd_pt_i440fx_realize;
dc->desc = "IGD Passthrough Host bridge";
}
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 279badc894..eb75e080fc 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -460,9 +460,9 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
/* PIO lives at the bottom of our bus space */
memory_region_add_subregion_overlap(&s->busmem, 0, &s->pio, -2);
- b = pci_register_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq,
- mpc85xx_pci_map_irq, s, &s->busmem, &s->pio,
- PCI_DEVFN(s->first_slot, 0), 4, TYPE_PCI_BUS);
+ b = pci_register_root_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq,
+ mpc85xx_pci_map_irq, s, &s->busmem, &s->pio,
+ PCI_DEVFN(s->first_slot, 0), 4, TYPE_PCI_BUS);
h->bus = b;
/* Set up PCI view of memory */
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 92eed0f3e1..01f67f9db1 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -269,8 +269,8 @@ static void raven_pcihost_initfn(Object *obj)
memory_region_add_subregion_overlap(address_space_mem, 0x80000000,
&s->pci_io_non_contiguous, 1);
memory_region_add_subregion(address_space_mem, 0xc0000000, &s->pci_memory);
- pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
- &s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
+ pci_root_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
+ &s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
/* Bus master address space */
memory_region_init(&s->bm, obj, "bm-raven", UINT32_MAX);
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 6cb9a8d121..a36a1195e4 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -51,9 +51,10 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
- pci->bus = pci_bus_new(DEVICE(s), "pcie.0",
- s->mch.pci_address_space, s->mch.address_space_io,
- 0, TYPE_PCIE_BUS);
+ pci->bus = pci_root_bus_new(DEVICE(s), "pcie.0",
+ s->mch.pci_address_space,
+ s->mch.address_space_io,
+ 0, TYPE_PCIE_BUS);
PC_MACHINE(qdev_get_machine())->bus = pci->bus;
qdev_set_parent_bus(DEVICE(&s->mch), BUS(pci->bus));
qdev_init_nofail(DEVICE(&s->mch));
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index ea5c265718..5d8ccaa711 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -233,12 +233,12 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
- h->bus = pci_register_bus(dev, NULL,
- pci_unin_set_irq, pci_unin_map_irq,
- pic,
- &d->pci_mmio,
- address_space_io,
- PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
+ h->bus = pci_register_root_bus(dev, NULL,
+ pci_unin_set_irq, pci_unin_map_irq,
+ pic,
+ &d->pci_mmio,
+ address_space_io,
+ PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
#if 0
pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north");
@@ -299,12 +299,12 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
- h->bus = pci_register_bus(dev, NULL,
- pci_unin_set_irq, pci_unin_map_irq,
- pic,
- &d->pci_mmio,
- address_space_io,
- PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
+ h->bus = pci_register_root_bus(dev, NULL,
+ pci_unin_set_irq, pci_unin_map_irq,
+ pic,
+ &d->pci_mmio,
+ address_space_io,
+ PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
sysbus_mmio_map(s, 0, 0xf0800000);
sysbus_mmio_map(s, 1, 0xf0c00000);
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 6394a520fc..d0b02bdc47 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -311,7 +311,7 @@ static const MemoryRegionOps pci_vpb_config_ops = {
static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
{
- PCIVPBState *s = container_of(d->bus, PCIVPBState, pci_bus);
+ PCIVPBState *s = container_of(pci_get_bus(d), PCIVPBState, pci_bus);
if (s->irq_mapping == PCI_VPB_IRQMAP_BROKEN) {
/* Legacy broken IRQ mapping for compatibility with old and
@@ -399,9 +399,9 @@ static void pci_vpb_realize(DeviceState *dev, Error **errp)
memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 1ULL << 32);
memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 1ULL << 32);
- pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
- &s->pci_mem_space, &s->pci_io_space,
- PCI_DEVFN(11, 0), TYPE_PCI_BUS);
+ pci_root_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
+ &s->pci_mem_space, &s->pci_io_space,
+ PCI_DEVFN(11, 0), TYPE_PCI_BUS);
h->bus = &s->pci_bus;
object_initialize(&s->pci_dev, sizeof(s->pci_dev), TYPE_VERSATILE_PCI_HOST);
diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c
index 7659253090..53b561f81f 100644
--- a/hw/pci-host/xilinx-pcie.c
+++ b/hw/pci-host/xilinx-pcie.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "hw/pci/pci_bridge.h"
#include "hw/pci-host/xilinx-pcie.h"
@@ -129,9 +130,9 @@ static void xilinx_pcie_host_realize(DeviceState *dev, Error **errp)
sysbus_init_mmio(sbd, &pex->mmio);
sysbus_init_mmio(sbd, &s->mmio);
- pci->bus = pci_register_bus(dev, s->name, xilinx_pcie_set_irq,
- pci_swizzle_map_irq_fn, s, &s->mmio,
- &s->io, 0, 4, TYPE_PCIE_BUS);
+ pci->bus = pci_register_root_bus(dev, s->name, xilinx_pcie_set_irq,
+ pci_swizzle_map_irq_fn, s, &s->mmio,
+ &s->io, 0, 4, TYPE_PCIE_BUS);
qdev_set_parent_bus(DEVICE(&s->root), BUS(pci->bus));
qdev_init_nofail(DEVICE(&s->root));
@@ -267,24 +268,22 @@ static void xilinx_pcie_root_config_write(PCIDevice *d, uint32_t address,
}
}
-static int xilinx_pcie_root_init(PCIDevice *dev)
+static void xilinx_pcie_root_realize(PCIDevice *pci_dev, Error **errp)
{
- BusState *bus = qdev_get_parent_bus(DEVICE(dev));
+ BusState *bus = qdev_get_parent_bus(DEVICE(pci_dev));
XilinxPCIEHost *s = XILINX_PCIE_HOST(bus->parent);
- pci_set_word(dev->config + PCI_COMMAND,
+ pci_set_word(pci_dev->config + PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
- pci_set_word(dev->config + PCI_MEMORY_BASE, s->mmio_base >> 16);
- pci_set_word(dev->config + PCI_MEMORY_LIMIT,
+ pci_set_word(pci_dev->config + PCI_MEMORY_BASE, s->mmio_base >> 16);
+ pci_set_word(pci_dev->config + PCI_MEMORY_LIMIT,
((s->mmio_base + s->mmio_size - 1) >> 16) & 0xfff0);
- pci_bridge_initfn(dev, TYPE_PCI_BUS);
+ pci_bridge_initfn(pci_dev, TYPE_PCI_BUS);
- if (pcie_endpoint_cap_v1_init(dev, 0x80) < 0) {
- hw_error("Failed to initialize PCIe capability");
+ if (pcie_endpoint_cap_v1_init(pci_dev, 0x80) < 0) {
+ error_setg(errp, "Failed to initialize PCIe capability");
}
-
- return 0;
}
static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data)
@@ -300,7 +299,7 @@ static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
k->is_express = true;
k->is_bridge = true;
- k->init = xilinx_pcie_root_init;
+ k->realize = xilinx_pcie_root_realize;
k->exit = pci_bridge_exitfn;
dc->reset = pci_bridge_reset;
k->config_read = xilinx_pcie_root_config_read;
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index b2d139bd9a..e8f9fc1c27 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -222,7 +222,7 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)
{
PCIBus *bus;
for (;;) {
- bus = pci_dev->bus;
+ bus = pci_get_bus(pci_dev);
irq_num = bus->map_irq(pci_dev, irq_num);
if (bus->set_irq)
break;
@@ -331,31 +331,15 @@ static void pci_host_bus_register(DeviceState *host)
QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next);
}
-PCIBus *pci_find_primary_bus(void)
-{
- PCIBus *primary_bus = NULL;
- PCIHostState *host;
-
- QLIST_FOREACH(host, &pci_host_bridges, next) {
- if (primary_bus) {
- /* We have multiple root buses, refuse to select a primary */
- return NULL;
- }
- primary_bus = host->bus;
- }
-
- return primary_bus;
-}
-
PCIBus *pci_device_root_bus(const PCIDevice *d)
{
- PCIBus *bus = d->bus;
+ PCIBus *bus = pci_get_bus(d);
while (!pci_bus_is_root(bus)) {
d = bus->parent_dev;
assert(d != NULL);
- bus = d->bus;
+ bus = pci_get_bus(d);
}
return bus;
@@ -376,10 +360,10 @@ const char *pci_root_bus_path(PCIDevice *dev)
return rootbus->qbus.name;
}
-static void pci_bus_init(PCIBus *bus, DeviceState *parent,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min)
+static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min)
{
assert(PCI_FUNC(devfn_min) == 0);
bus->devfn_min = devfn_min;
@@ -403,25 +387,27 @@ bool pci_bus_is_root(PCIBus *bus)
return PCI_BUS_GET_CLASS(bus)->is_root(bus);
}
-void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
- const char *name,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min, const char *typename)
+void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
+ const char *name,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min, const char *typename)
{
qbus_create_inplace(bus, bus_size, typename, parent, name);
- pci_bus_init(bus, parent, address_space_mem, address_space_io, devfn_min);
+ pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
+ devfn_min);
}
-PCIBus *pci_bus_new(DeviceState *parent, const char *name,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min, const char *typename)
+PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min, const char *typename)
{
PCIBus *bus;
bus = PCI_BUS(qbus_create(typename, parent, name));
- pci_bus_init(bus, parent, address_space_mem, address_space_io, devfn_min);
+ pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
+ devfn_min);
return bus;
}
@@ -435,17 +421,18 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
}
-PCIBus *pci_register_bus(DeviceState *parent, const char *name,
- pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- void *irq_opaque,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min, int nirq, const char *typename)
+PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
+ pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+ void *irq_opaque,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min, int nirq,
+ const char *typename)
{
PCIBus *bus;
- bus = pci_bus_new(parent, name, address_space_mem,
- address_space_io, devfn_min, typename);
+ bus = pci_root_bus_new(parent, name, address_space_mem,
+ address_space_io, devfn_min, typename);
pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
return bus;
}
@@ -879,7 +866,7 @@ static void pci_config_free(PCIDevice *pci_dev)
static void do_pci_unregister_device(PCIDevice *pci_dev)
{
- pci_dev->bus->devices[pci_dev->devfn] = NULL;
+ pci_get_bus(pci_dev)->devices[pci_dev->devfn] = NULL;
pci_config_free(pci_dev);
if (memory_region_is_mapped(&pci_dev->bus_master_enable_region)) {
@@ -900,7 +887,7 @@ static uint16_t pci_req_id_cache_extract(PCIReqIDCache *cache)
result = pci_get_bdf(cache->dev);
break;
case PCI_REQ_ID_SECONDARY_BUS:
- bus_n = pci_bus_num(cache->dev->bus);
+ bus_n = pci_dev_bus_num(cache->dev);
result = PCI_BUILD_BDF(bus_n, 0);
break;
default:
@@ -930,9 +917,9 @@ static PCIReqIDCache pci_req_id_cache_get(PCIDevice *dev)
.type = PCI_REQ_ID_BDF,
};
- while (!pci_bus_is_root(dev->bus)) {
+ while (!pci_bus_is_root(pci_get_bus(dev))) {
/* We are under PCI/PCIe bridges */
- parent = dev->bus->parent_dev;
+ parent = pci_get_bus(dev)->parent_dev;
if (pci_is_express(parent)) {
if (pcie_cap_get_type(parent) == PCI_EXP_TYPE_PCI_BRIDGE) {
/* When we pass through PCIe-to-PCI/PCIX bridges, we
@@ -975,7 +962,7 @@ static bool pci_bus_devfn_reserved(PCIBus *bus, int devfn)
}
/* -1 for devfn means auto assign */
-static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
+static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
const char *name, int devfn,
Error **errp)
{
@@ -984,8 +971,8 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
PCIConfigWriteFunc *config_write = pc->config_write;
Error *local_err = NULL;
DeviceState *dev = DEVICE(pci_dev);
+ PCIBus *bus = pci_get_bus(pci_dev);
- pci_dev->bus = bus;
/* Only pci bridges can be attached to extra PCI root buses */
if (pci_bus_is_root(bus) && bus->parent_dev && !pc->is_bridge) {
error_setg(errp,
@@ -1139,8 +1126,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
r->type = type;
r->memory = memory;
r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO
- ? pci_dev->bus->address_space_io
- : pci_dev->bus->address_space_mem;
+ ? pci_get_bus(pci_dev)->address_space_io
+ : pci_get_bus(pci_dev)->address_space_mem;
wmask = ~(size - 1);
if (region_num == PCI_ROM_SLOT) {
@@ -1182,21 +1169,23 @@ static void pci_update_vga(PCIDevice *pci_dev)
void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
MemoryRegion *io_lo, MemoryRegion *io_hi)
{
+ PCIBus *bus = pci_get_bus(pci_dev);
+
assert(!pci_dev->has_vga);
assert(memory_region_size(mem) == QEMU_PCI_VGA_MEM_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_MEM] = mem;
- memory_region_add_subregion_overlap(pci_dev->bus->address_space_mem,
+ memory_region_add_subregion_overlap(bus->address_space_mem,
QEMU_PCI_VGA_MEM_BASE, mem, 1);
assert(memory_region_size(io_lo) == QEMU_PCI_VGA_IO_LO_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO] = io_lo;
- memory_region_add_subregion_overlap(pci_dev->bus->address_space_io,
+ memory_region_add_subregion_overlap(bus->address_space_io,
QEMU_PCI_VGA_IO_LO_BASE, io_lo, 1);
assert(memory_region_size(io_hi) == QEMU_PCI_VGA_IO_HI_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI] = io_hi;
- memory_region_add_subregion_overlap(pci_dev->bus->address_space_io,
+ memory_region_add_subregion_overlap(bus->address_space_io,
QEMU_PCI_VGA_IO_HI_BASE, io_hi, 1);
pci_dev->has_vga = true;
@@ -1205,15 +1194,17 @@ void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
void pci_unregister_vga(PCIDevice *pci_dev)
{
+ PCIBus *bus = pci_get_bus(pci_dev);
+
if (!pci_dev->has_vga) {
return;
}
- memory_region_del_subregion(pci_dev->bus->address_space_mem,
+ memory_region_del_subregion(bus->address_space_mem,
pci_dev->vga_regions[QEMU_PCI_VGA_MEM]);
- memory_region_del_subregion(pci_dev->bus->address_space_io,
+ memory_region_del_subregion(bus->address_space_io,
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO]);
- memory_region_del_subregion(pci_dev->bus->address_space_io,
+ memory_region_del_subregion(bus->address_space_io,
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI]);
pci_dev->has_vga = false;
}
@@ -1316,7 +1307,7 @@ static void pci_update_mappings(PCIDevice *d)
/* now do the real mapping */
if (r->addr != PCI_BAR_UNMAPPED) {
- trace_pci_update_mappings_del(d, pci_bus_num(d->bus),
+ trace_pci_update_mappings_del(d, pci_dev_bus_num(d),
PCI_SLOT(d->devfn),
PCI_FUNC(d->devfn),
i, r->addr, r->size);
@@ -1324,7 +1315,7 @@ static void pci_update_mappings(PCIDevice *d)
}
r->addr = new_addr;
if (r->addr != PCI_BAR_UNMAPPED) {
- trace_pci_update_mappings_add(d, pci_bus_num(d->bus),
+ trace_pci_update_mappings_add(d, pci_dev_bus_num(d),
PCI_SLOT(d->devfn),
PCI_FUNC(d->devfn),
i, r->addr, r->size);
@@ -1443,9 +1434,9 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)
PCIBus *bus;
do {
- bus = dev->bus;
- pin = bus->map_irq(dev, pin);
- dev = bus->parent_dev;
+ bus = pci_get_bus(dev);
+ pin = bus->map_irq(dev, pin);
+ dev = bus->parent_dev;
} while (dev);
if (!bus->route_intx_to_irq) {
@@ -2015,7 +2006,6 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
PCIDevice *pci_dev = (PCIDevice *)qdev;
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
Error *local_err = NULL;
- PCIBus *bus;
bool is_default_rom;
/* initialize cap_present for pci_is_express() and pci_config_size() */
@@ -2023,8 +2013,7 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
}
- bus = PCI_BUS(qdev_get_parent_bus(qdev));
- pci_dev = do_pci_register_device(pci_dev, bus,
+ pci_dev = do_pci_register_device(pci_dev,
object_get_typename(OBJECT(qdev)),
pci_dev->devfn, errp);
if (pci_dev == NULL)
@@ -2317,7 +2306,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
error_setg(errp, "%s:%02x:%02x.%x "
"Attempt to add PCI capability %x at offset "
"%x overlaps existing capability %x at offset %x",
- pci_root_bus_path(pdev), pci_bus_num(pdev->bus),
+ pci_root_bus_path(pdev), pci_dev_bus_num(pdev),
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
cap_id, offset, overlapping_cap, i);
return -EINVAL;
@@ -2381,7 +2370,7 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
"pci id %04x:%04x (sub %04x:%04x)\n",
- indent, "", ctxt, pci_bus_num(d->bus),
+ indent, "", ctxt, pci_dev_bus_num(d),
PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
pci_get_word(d->config + PCI_VENDOR_ID),
pci_get_word(d->config + PCI_DEVICE_ID),
@@ -2464,7 +2453,7 @@ static char *pcibus_get_dev_path(DeviceState *dev)
/* Calculate # of slots on path between device and root. */;
slot_depth = 0;
- for (t = d; t; t = t->bus->parent_dev) {
+ for (t = d; t; t = pci_get_bus(t)->parent_dev) {
++slot_depth;
}
@@ -2479,7 +2468,7 @@ static char *pcibus_get_dev_path(DeviceState *dev)
/* Fill in slot numbers. We walk up from device to root, so need to print
* them in the reverse order, last to first. */
p = path + path_len;
- for (t = d; t; t = t->bus->parent_dev) {
+ for (t = d; t; t = pci_get_bus(t)->parent_dev) {
p -= slot_len;
s = snprintf(slot, sizeof slot, ":%02x.%x",
PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
@@ -2527,12 +2516,12 @@ int pci_qdev_find_device(const char *id, PCIDevice **pdev)
MemoryRegion *pci_address_space(PCIDevice *dev)
{
- return dev->bus->address_space_mem;
+ return pci_get_bus(dev)->address_space_mem;
}
MemoryRegion *pci_address_space_io(PCIDevice *dev)
{
- return dev->bus->address_space_io;
+ return pci_get_bus(dev)->address_space_io;
}
static void pci_device_class_init(ObjectClass *klass, void *data)
@@ -2560,11 +2549,11 @@ static void pci_device_class_base_init(ObjectClass *klass, void *data)
AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
{
- PCIBus *bus = PCI_BUS(dev->bus);
+ PCIBus *bus = pci_get_bus(dev);
PCIBus *iommu_bus = bus;
while(iommu_bus && !iommu_bus->iommu_fn && iommu_bus->parent_dev) {
- iommu_bus = PCI_BUS(iommu_bus->parent_dev->bus);
+ iommu_bus = pci_get_bus(iommu_bus->parent_dev);
}
if (iommu_bus && iommu_bus->iommu_fn) {
return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, dev->devfn);
@@ -2635,7 +2624,7 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range)
static bool pcie_has_upstream_port(PCIDevice *dev)
{
- PCIDevice *parent_dev = pci_bridge_get_device(dev->bus);
+ PCIDevice *parent_dev = pci_bridge_get_device(pci_get_bus(dev));
/* Device associated with an upstream port.
* As there are several types of these, it's easier to check the
@@ -2651,12 +2640,14 @@ static bool pcie_has_upstream_port(PCIDevice *dev)
PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
{
+ PCIBus *bus = pci_get_bus(pci_dev);
+
if(pcie_has_upstream_port(pci_dev)) {
/* With an upstream PCIe port, we only support 1 device at slot 0 */
- return pci_dev->bus->devices[0];
+ return bus->devices[0];
} else {
/* Other bus types might support multiple devices at slots 0-31 */
- return pci_dev->bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
+ return bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
}
}
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index a47d257149..b2e50c36a0 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -183,7 +183,7 @@ static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
{
PCIDevice *pd = PCI_DEVICE(br);
- PCIBus *parent = pd->bus;
+ PCIBus *parent = pci_get_bus(pd);
PCIBridgeWindows *w = g_new(PCIBridgeWindows, 1);
uint16_t cmd = pci_get_word(pd->config + PCI_COMMAND);
@@ -214,7 +214,7 @@ static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
static void pci_bridge_region_del(PCIBridge *br, PCIBridgeWindows *w)
{
PCIDevice *pd = PCI_DEVICE(br);
- PCIBus *parent = pd->bus;
+ PCIBus *parent = pci_get_bus(pd);
memory_region_del_subregion(parent->address_space_io, &w->alias_io);
memory_region_del_subregion(parent->address_space_mem, &w->alias_mem);
@@ -339,7 +339,7 @@ void pci_bridge_reset(DeviceState *qdev)
/* default qdev initialization function for PCI-to-PCI bridge */
void pci_bridge_initfn(PCIDevice *dev, const char *typename)
{
- PCIBus *parent = dev->bus;
+ PCIBus *parent = pci_get_bus(dev);
PCIBridge *br = PCI_BRIDGE(dev);
PCIBus *sec_bus = &br->sec_bus;
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 32191f2a55..6c91bd44a0 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -155,7 +155,8 @@ pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size)
* a regular Endpoint type is exposed on a root complex. These
* should instead be Root Complex Integrated Endpoints.
*/
- if (pci_bus_is_express(dev->bus) && pci_bus_is_root(dev->bus)) {
+ if (pci_bus_is_express(pci_get_bus(dev))
+ && pci_bus_is_root(pci_get_bus(dev))) {
type = PCI_EXP_TYPE_RC_END;
}
@@ -369,7 +370,7 @@ void pcie_cap_slot_hot_unplug_request_cb(HotplugHandler *hotplug_dev,
{
uint8_t *exp_cap;
PCIDevice *pci_dev = PCI_DEVICE(dev);
- PCIBus *bus = pci_dev->bus;
+ PCIBus *bus = pci_get_bus(pci_dev);
pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index 97200742b4..b009be7f17 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -409,7 +409,7 @@ static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
*/
return;
}
- dev = pci_bridge_get_device(dev->bus);
+ dev = pci_bridge_get_device(pci_get_bus(dev));
}
}
@@ -1025,7 +1025,7 @@ static int do_pcie_aer_inject_error(Monitor *mon,
}
details->id = id;
details->root_bus = pci_root_bus_path(dev);
- details->bus = pci_bus_num(dev->bus);
+ details->bus = pci_dev_bus_num(dev);
details->devfn = dev->devfn;
return 0;
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index 69fc14b218..a8462d48bb 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -1,6 +1,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
+#include "qemu/host-utils.h"
#include "qemu/range.h"
#include "qemu/error-report.h"
#include "hw/pci/shpc.h"
@@ -122,16 +123,6 @@
#define SHPC_PCI_TO_IDX(pci_slot) ((pci_slot) - 1)
#define SHPC_IDX_TO_PHYSICAL(slot) ((slot) + 1)
-static int roundup_pow_of_two(int x)
-{
- x |= (x >> 1);
- x |= (x >> 2);
- x |= (x >> 4);
- x |= (x >> 8);
- x |= (x >> 16);
- return x + 1;
-}
-
static uint16_t shpc_get_status(SHPCDevice *shpc, int slot, uint16_t msk)
{
uint8_t *status = shpc->config + SHPC_SLOT_STATUS(slot);
@@ -656,7 +647,7 @@ int shpc_init(PCIDevice *d, PCIBus *sec_bus, MemoryRegion *bar,
int shpc_bar_size(PCIDevice *d)
{
- return roundup_pow_of_two(SHPC_SLOT_REG(SHPC_MAX_SLOTS));
+ return pow2roundup32(SHPC_SLOT_REG(SHPC_MAX_SLOTS));
}
void shpc_cleanup(PCIDevice *d, MemoryRegion *bar)
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 7efc686748..ad1928c5d8 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -1,7 +1,7 @@
# shared objects
obj-y += ppc.o ppc_booke.o fdt.o
# IBM pSeries (sPAPR)
-obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
+obj-$(CONFIG_PSERIES) += spapr.o spapr_caps.o spapr_vio.o spapr_events.o
obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o
obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o
@@ -12,8 +12,8 @@ obj-y += spapr_pci_vfio.o
endif
obj-$(CONFIG_PSERIES) += spapr_rtas_ddw.o
# PowerPC 4xx boards
-obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o
-obj-y += ppc4xx_pci.o
+obj-y += ppc4xx_devs.o ppc405_uc.o
+obj-$(CONFIG_PPC4XX) += ppc4xx_pci.o ppc405_boards.o ppc440_bamboo.o
# PReP
obj-$(CONFIG_PREP) += prep.o
obj-$(CONFIG_PREP) += prep_systemio.o
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index e59e80fb9e..81d03e1038 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -12,9 +12,11 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "e500.h"
+#include "hw/net/fsl_etsec/etsec.h"
#include "hw/boards.h"
#include "sysemu/device_tree.h"
#include "sysemu/kvm.h"
+#include "hw/sysbus.h"
#include "hw/pci/pci.h"
#include "hw/ppc/openpic.h"
#include "kvm_ppc.h"
@@ -63,7 +65,7 @@ static void e500plat_machine_init(MachineClass *mc)
mc->desc = "generic paravirt e500 platform";
mc->init = e500plat_init;
mc->max_cpus = 32;
- mc->has_dynamic_sysbus = true;
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_ETSEC_COMMON);
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("e500v2_v30");
}
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 9475e8479c..98ee3c607a 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -53,7 +53,7 @@
#define FW_MAX_SIZE 0x00400000
#define KERNEL_LOAD_ADDR 0x20000000
-#define INITRD_LOAD_ADDR 0x40000000
+#define INITRD_LOAD_ADDR 0x60000000
static const char *pnv_chip_core_typename(const PnvChip *o)
{
@@ -707,9 +707,9 @@ static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
#define POWER8_CORE_MASK (0x7e7eull)
/*
- * POWER9 has 24 cores, ids starting at 0x20
+ * POWER9 has 24 cores, ids starting at 0x0
*/
-#define POWER9_CORE_MASK (0xffffff00000000ull)
+#define POWER9_CORE_MASK (0xffffffffffffffull)
static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
{
@@ -721,7 +721,6 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data)
k->cores_mask = POWER8E_CORE_MASK;
k->core_pir = pnv_chip_core_pir_p8;
k->xscom_base = 0x003fc0000000000ull;
- k->xscom_core_base = 0x10000000ull;
dc->desc = "PowerNV Chip POWER8E";
}
@@ -735,7 +734,6 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data)
k->cores_mask = POWER8_CORE_MASK;
k->core_pir = pnv_chip_core_pir_p8;
k->xscom_base = 0x003fc0000000000ull;
- k->xscom_core_base = 0x10000000ull;
dc->desc = "PowerNV Chip POWER8";
}
@@ -749,7 +747,6 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data)
k->cores_mask = POWER8_CORE_MASK;
k->core_pir = pnv_chip_core_pir_p8;
k->xscom_base = 0x003fc0000000000ull;
- k->xscom_core_base = 0x10000000ull;
dc->desc = "PowerNV Chip POWER8NVL";
}
@@ -759,11 +756,10 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data)
PnvChipClass *k = PNV_CHIP_CLASS(klass);
k->chip_type = PNV_CHIP_POWER9;
- k->chip_cfam_id = 0x100d104980000000ull; /* P9 Nimbus DD1.0 */
+ k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */
k->cores_mask = POWER9_CORE_MASK;
k->core_pir = pnv_chip_core_pir_p9;
k->xscom_base = 0x00603fc00000000ull;
- k->xscom_core_base = 0x0ull;
dc->desc = "PowerNV Chip POWER9";
}
@@ -887,6 +883,7 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
&& (i < chip->nr_cores); core_hwid++) {
char core_name[32];
void *pnv_core = chip->cores + i * typesize;
+ uint64_t xscom_core_base;
if (!(chip->cores_mask & (1ull << core_hwid))) {
continue;
@@ -910,9 +907,13 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
object_unref(OBJECT(pnv_core));
/* Each core has an XSCOM MMIO region */
- pnv_xscom_add_subregion(chip,
- PNV_XSCOM_EX_CORE_BASE(pcc->xscom_core_base,
- core_hwid),
+ if (!pnv_chip_is_power9(chip)) {
+ xscom_core_base = PNV_XSCOM_EX_BASE(core_hwid);
+ } else {
+ xscom_core_base = PNV_XSCOM_P9_EC_BASE(core_hwid);
+ }
+
+ pnv_xscom_add_subregion(chip, xscom_core_base,
&PNV_CORE(pnv_core)->xscom_regs);
i++;
}
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 7e8a76df44..cbb64ad9e7 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -192,7 +192,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id);
pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), &pnv_core_xscom_ops,
- pc, name, PNV_XSCOM_EX_CORE_SIZE);
+ pc, name, PNV_XSCOM_EX_SIZE);
return;
err:
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index e51d634f40..99c40efecd 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -51,10 +51,9 @@ static void xscom_complete(CPUState *cs, uint64_t hmer_bits)
static uint32_t pnv_xscom_pcba(PnvChip *chip, uint64_t addr)
{
- PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
-
addr &= (PNV_XSCOM_SIZE - 1);
- if (pcc->chip_type == PNV_CHIP_POWER9) {
+
+ if (pnv_chip_is_power9(chip)) {
return addr >> 3;
} else {
return ((addr >> 4) & ~0xfull) | ((addr >> 3) & 0xf);
@@ -231,7 +230,6 @@ int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
int xscom_offset;
ForeachPopulateArgs args;
char *name;
- PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip);
name = g_strdup_printf("xscom@%" PRIx64, be64_to_cpu(reg[0]));
xscom_offset = fdt_add_subnode(fdt, root_offset, name);
@@ -242,7 +240,7 @@ int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset)
_FDT((fdt_setprop_cell(fdt, xscom_offset, "#size-cells", 1)));
_FDT((fdt_setprop(fdt, xscom_offset, "reg", reg, sizeof(reg))));
- if (pcc->chip_type == PNV_CHIP_POWER9) {
+ if (pnv_chip_is_power9(chip)) {
_FDT((fdt_setprop(fdt, xscom_offset, "compatible", compat_p9,
sizeof(compat_p9))));
} else {
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 4765dcecca..b7642bac01 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -314,9 +314,9 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq[i]);
}
- b = pci_register_bus(DEVICE(dev), NULL, ppc4xx_pci_set_irq,
- ppc4xx_pci_map_irq, s->irq, get_system_memory(),
- get_system_io(), 0, 4, TYPE_PCI_BUS);
+ b = pci_register_root_bus(DEVICE(dev), NULL, ppc4xx_pci_set_irq,
+ ppc4xx_pci_map_irq, s->irq, get_system_memory(),
+ get_system_io(), 0, 4, TYPE_PCI_BUS);
h->bus = b;
pci_create_simple(b, 0, "ppc4xx-host-bridge");
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index dfd352c473..88a78d31eb 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -253,7 +253,9 @@ static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
}
/* Populate the "ibm,pa-features" property */
-static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
+static void spapr_populate_pa_features(sPAPRMachineState *spapr,
+ PowerPCCPU *cpu,
+ void *fdt, int offset,
bool legacy_guest)
{
CPUPPCState *env = &cpu->env;
@@ -318,7 +320,7 @@ static void spapr_populate_pa_features(PowerPCCPU *cpu, void *fdt, int offset,
*/
pa_features[3] |= 0x20;
}
- if (kvmppc_has_cap_htm() && pa_size > 24) {
+ if ((spapr_get_cap(spapr, SPAPR_CAP_HTM) != 0) && pa_size > 24) {
pa_features[24] |= 0x80; /* Transactional memory support */
}
if (legacy_guest && pa_size > 40) {
@@ -343,7 +345,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
PowerPCCPU *cpu = POWERPC_CPU(cs);
DeviceClass *dc = DEVICE_GET_CLASS(cs);
int index = spapr_vcpu_id(cpu);
- int compat_smt = MIN(smp_threads, ppc_compat_max_threads(cpu));
+ int compat_smt = MIN(smp_threads, ppc_compat_max_vthreads(cpu));
if ((index % smt) != 0) {
continue;
@@ -384,8 +386,8 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
return ret;
}
- spapr_populate_pa_features(cpu, fdt, offset,
- spapr->cas_legacy_guest_workaround);
+ spapr_populate_pa_features(spapr, cpu, fdt, offset,
+ spapr->cas_legacy_guest_workaround);
}
return ret;
}
@@ -501,7 +503,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
size_t page_sizes_prop_size;
uint32_t vcpus_per_socket = smp_threads * smp_cores;
uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};
- int compat_smt = MIN(smp_threads, ppc_compat_max_threads(cpu));
+ int compat_smt = MIN(smp_threads, ppc_compat_max_vthreads(cpu));
sPAPRDRConnector *drc;
int drc_index;
uint32_t radix_AP_encodings[PPC_PAGE_SIZES_MAX_SZ];
@@ -555,20 +557,22 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
segs, sizeof(segs))));
}
- /* Advertise VMX/VSX (vector extensions) if available
- * 0 / no property == no vector extensions
+ /* Advertise VSX (vector extensions) if available
* 1 == VMX / Altivec available
- * 2 == VSX available */
- if (env->insns_flags & PPC_ALTIVEC) {
- uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
-
- _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));
+ * 2 == VSX available
+ *
+ * Only CPUs for which we create core types in spapr_cpu_core.c
+ * are possible, and all of those have VMX */
+ if (spapr_get_cap(spapr, SPAPR_CAP_VSX) != 0) {
+ _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 2)));
+ } else {
+ _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", 1)));
}
/* Advertise DFP (Decimal Floating Point) if available
* 0 / no property == no DFP
* 1 == DFP available */
- if (env->insns_flags2 & PPC2_DFP) {
+ if (spapr_get_cap(spapr, SPAPR_CAP_DFP) != 0) {
_FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
}
@@ -579,7 +583,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
page_sizes_prop, page_sizes_prop_size)));
}
- spapr_populate_pa_features(cpu, fdt, offset, false);
+ spapr_populate_pa_features(spapr, cpu, fdt, offset, false);
_FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",
cs->cpu_index / vcpus_per_socket)));
@@ -1466,6 +1470,8 @@ static void spapr_machine_reset(void)
/* Check for unknown sysbus devices */
foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL);
+ spapr_caps_reset(spapr);
+
first_ppc_cpu = POWERPC_CPU(first_cpu);
if (kvm_enabled() && kvmppc_has_cap_mmu_radix() &&
ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0,
@@ -1478,6 +1484,15 @@ static void spapr_machine_reset(void)
spapr_setup_hpt_and_vrma(spapr);
}
+ /* if this reset wasn't generated by CAS, we should reset our
+ * negotiated options and start from scratch */
+ if (!spapr->cas_reboot) {
+ spapr_ovec_cleanup(spapr->ov5_cas);
+ spapr->ov5_cas = spapr_ovec_new();
+
+ ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
+ }
+
qemu_devices_reset();
/* DRC reset may cause a device to be unplugged. This will cause troubles
@@ -1498,15 +1513,6 @@ static void spapr_machine_reset(void)
rtas_addr = rtas_limit - RTAS_MAX_SIZE;
fdt_addr = rtas_addr - FDT_MAX_SIZE;
- /* if this reset wasn't generated by CAS, we should reset our
- * negotiated options and start from scratch */
- if (!spapr->cas_reboot) {
- spapr_ovec_cleanup(spapr->ov5_cas);
- spapr->ov5_cas = spapr_ovec_new();
-
- ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal);
- }
-
fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size);
spapr_load_rtas(spapr, fdt, rtas_addr);
@@ -1580,11 +1586,28 @@ static bool spapr_vga_init(PCIBus *pci_bus, Error **errp)
}
}
+static int spapr_pre_load(void *opaque)
+{
+ int rc;
+
+ rc = spapr_caps_pre_load(opaque);
+ if (rc) {
+ return rc;
+ }
+
+ return 0;
+}
+
static int spapr_post_load(void *opaque, int version_id)
{
sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
int err = 0;
+ err = spapr_caps_post_migration(spapr);
+ if (err) {
+ return err;
+ }
+
if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) {
CPUState *cs;
CPU_FOREACH(cs) {
@@ -1616,6 +1639,18 @@ static int spapr_post_load(void *opaque, int version_id)
return err;
}
+static int spapr_pre_save(void *opaque)
+{
+ int rc;
+
+ rc = spapr_caps_pre_save(opaque);
+ if (rc) {
+ return rc;
+ }
+
+ return 0;
+}
+
static bool version_before_3(void *opaque, int version_id)
{
return version_id < 3;
@@ -1736,7 +1771,9 @@ static const VMStateDescription vmstate_spapr = {
.name = "spapr",
.version_id = 3,
.minimum_version_id = 1,
+ .pre_load = spapr_pre_load,
.post_load = spapr_post_load,
+ .pre_save = spapr_pre_save,
.fields = (VMStateField[]) {
/* used to be @next_irq */
VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4),
@@ -1751,6 +1788,9 @@ static const VMStateDescription vmstate_spapr = {
&vmstate_spapr_ov5_cas,
&vmstate_spapr_patb_entry,
&vmstate_spapr_pending_events,
+ &vmstate_spapr_cap_htm,
+ &vmstate_spapr_cap_vsx,
+ &vmstate_spapr_cap_dfp,
NULL
}
};
@@ -2186,11 +2226,6 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
int boot_cores_nr = smp_cpus / smp_threads;
int i;
- if (!type) {
- error_report("Unable to find sPAPR CPU Core definition");
- exit(1);
- }
-
possible_cpus = mc->possible_cpu_arch_ids(machine);
if (mc->has_hotpluggable_cpus) {
if (smp_cpus % smp_threads) {
@@ -2265,26 +2300,43 @@ static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp)
}
/* In this case, spapr->vsmt has been set by the command line */
} else {
- /* Choose a VSMT mode that may be higher than necessary but is
- * likely to be compatible with hosts that don't have VSMT. */
- spapr->vsmt = MAX(kvm_smt, smp_threads);
+ /*
+ * Default VSMT value is tricky, because we need it to be as
+ * consistent as possible (for migration), but this requires
+ * changing it for at least some existing cases. We pick 8 as
+ * the value that we'd get with KVM on POWER8, the
+ * overwhelmingly common case in production systems.
+ */
+ spapr->vsmt = 8;
}
/* KVM: If necessary, set the SMT mode: */
if (kvm_enabled() && (spapr->vsmt != kvm_smt)) {
ret = kvmppc_set_smt_threads(spapr->vsmt);
if (ret) {
+ /* Looks like KVM isn't able to change VSMT mode */
error_setg(&local_err,
"Failed to set KVM's VSMT mode to %d (errno %d)",
spapr->vsmt, ret);
- if (!vsmt_user) {
- error_append_hint(&local_err, "On PPC, a VM with %d threads/"
- "core on a host with %d threads/core requires "
- " the use of VSMT mode %d.\n",
- smp_threads, kvm_smt, spapr->vsmt);
+ /* We can live with that if the default one is big enough
+ * for the number of threads, and a submultiple of the one
+ * we want. In this case we'll waste some vcpu ids, but
+ * behaviour will be correct */
+ if ((kvm_smt >= smp_threads) && ((spapr->vsmt % kvm_smt) == 0)) {
+ warn_report_err(local_err);
+ local_err = NULL;
+ goto out;
+ } else {
+ if (!vsmt_user) {
+ error_append_hint(&local_err,
+ "On PPC, a VM with %d threads/core"
+ " on a host with %d threads/core"
+ " requires the use of VSMT mode %d.\n",
+ smp_threads, kvm_smt, spapr->vsmt);
+ }
+ kvmppc_hint_smt_possible(&local_err);
+ goto out;
}
- kvmppc_hint_smt_possible(&local_err);
- goto out;
}
}
/* else TCG: nothing to do currently */
@@ -3305,9 +3357,7 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
int i;
for (i = 0; i < cc->nr_threads; i++) {
- sPAPRCPUCore *sc = SPAPR_CPU_CORE(dev);
-
- cs = CPU(sc->threads[i]);
+ cs = CPU(core->threads[i]);
pre_2_10_vmstate_unregister_dummy_icp(cs->cpu_index);
}
}
@@ -3488,6 +3538,7 @@ static int64_t spapr_get_default_cpu_node_id(const MachineState *ms, int idx)
static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
{
int i;
+ const char *core_type;
int spapr_max_cores = max_cpus / smp_threads;
MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -3499,12 +3550,19 @@ static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine)
return machine->possible_cpus;
}
+ core_type = spapr_get_cpu_core_type(machine->cpu_type);
+ if (!core_type) {
+ error_report("Unable to find sPAPR CPU Core definition");
+ exit(1);
+ }
+
machine->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
sizeof(CPUArchId) * spapr_max_cores);
machine->possible_cpus->len = spapr_max_cores;
for (i = 0; i < machine->possible_cpus->len; i++) {
int core_id = i * smp_threads;
+ machine->possible_cpus->cpus[i].type = core_type;
machine->possible_cpus->cpus[i].vcpus_count = smp_threads;
machine->possible_cpus->cpus[i].arch_id = core_id;
machine->possible_cpus->cpus[i].props.has_core_id = true;
@@ -3786,7 +3844,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
mc->default_boot_order = "";
mc->default_ram_size = 512 * M_BYTE;
mc->kvm_type = spapr_kvm_type;
- mc->has_dynamic_sysbus = true;
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_SPAPR_PCI_HOST_BRIDGE);
mc->pci_allow_0_address = true;
mc->get_hotplug_handler = spapr_get_hotplug_handler;
hc->pre_plug = spapr_machine_device_pre_plug;
@@ -3819,6 +3877,11 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
* in which LMBs are represented and hot-added
*/
mc->numa_mem_align_shift = 28;
+
+ smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
+ smc->default_caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_ON;
+ smc->default_caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_ON;
+ spapr_caps_add_properties(smc, &error_abort);
}
static const TypeInfo spapr_machine_info = {
@@ -3896,7 +3959,10 @@ static void spapr_machine_2_11_instance_options(MachineState *machine)
static void spapr_machine_2_11_class_options(MachineClass *mc)
{
+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
spapr_machine_2_12_class_options(mc);
+ smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON;
SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_11);
}
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
new file mode 100644
index 0000000000..5d52969bd5
--- /dev/null
+++ b/hw/ppc/spapr_caps.c
@@ -0,0 +1,315 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition capabilities handling
+ *
+ * Copyright (c) 2017 David Gibson, Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "sysemu/hw_accel.h"
+#include "target/ppc/cpu.h"
+#include "cpu-models.h"
+#include "kvm_ppc.h"
+
+#include "hw/ppc/spapr.h"
+
+typedef struct sPAPRCapabilityInfo {
+ const char *name;
+ const char *description;
+ int index;
+
+ /* Getter and Setter Function Pointers */
+ ObjectPropertyAccessor *get;
+ ObjectPropertyAccessor *set;
+ const char *type;
+ /* Make sure the virtual hardware can support this capability */
+ void (*apply)(sPAPRMachineState *spapr, uint8_t val, Error **errp);
+} sPAPRCapabilityInfo;
+
+static void spapr_cap_get_bool(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ sPAPRCapabilityInfo *cap = opaque;
+ sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ bool value = spapr_get_cap(spapr, cap->index) == SPAPR_CAP_ON;
+
+ visit_type_bool(v, name, &value, errp);
+}
+
+static void spapr_cap_set_bool(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ sPAPRCapabilityInfo *cap = opaque;
+ sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
+ bool value;
+ Error *local_err = NULL;
+
+ visit_type_bool(v, name, &value, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ spapr->cmd_line_caps[cap->index] = true;
+ spapr->eff.caps[cap->index] = value ? SPAPR_CAP_ON : SPAPR_CAP_OFF;
+}
+
+static void cap_htm_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+{
+ if (!val) {
+ /* TODO: We don't support disabling htm yet */
+ return;
+ }
+ if (tcg_enabled()) {
+ error_setg(errp,
+ "No Transactional Memory support in TCG, try cap-htm=off");
+ } else if (kvm_enabled() && !kvmppc_has_cap_htm()) {
+ error_setg(errp,
+"KVM implementation does not support Transactional Memory, try cap-htm=off"
+ );
+ }
+}
+
+static void cap_vsx_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+ CPUPPCState *env = &cpu->env;
+
+ if (!val) {
+ /* TODO: We don't support disabling vsx yet */
+ return;
+ }
+ /* Allowable CPUs in spapr_cpu_core.c should already have gotten
+ * rid of anything that doesn't do VMX */
+ g_assert(env->insns_flags & PPC_ALTIVEC);
+ if (!(env->insns_flags2 & PPC2_VSX)) {
+ error_setg(errp, "VSX support not available, try cap-vsx=off");
+ }
+}
+
+static void cap_dfp_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
+ CPUPPCState *env = &cpu->env;
+
+ if (!val) {
+ /* TODO: We don't support disabling dfp yet */
+ return;
+ }
+ if (!(env->insns_flags2 & PPC2_DFP)) {
+ error_setg(errp, "DFP support not available, try cap-dfp=off");
+ }
+}
+
+
+sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
+ [SPAPR_CAP_HTM] = {
+ .name = "htm",
+ .description = "Allow Hardware Transactional Memory (HTM)",
+ .index = SPAPR_CAP_HTM,
+ .get = spapr_cap_get_bool,
+ .set = spapr_cap_set_bool,
+ .type = "bool",
+ .apply = cap_htm_apply,
+ },
+ [SPAPR_CAP_VSX] = {
+ .name = "vsx",
+ .description = "Allow Vector Scalar Extensions (VSX)",
+ .index = SPAPR_CAP_VSX,
+ .get = spapr_cap_get_bool,
+ .set = spapr_cap_set_bool,
+ .type = "bool",
+ .apply = cap_vsx_apply,
+ },
+ [SPAPR_CAP_DFP] = {
+ .name = "dfp",
+ .description = "Allow Decimal Floating Point (DFP)",
+ .index = SPAPR_CAP_DFP,
+ .get = spapr_cap_get_bool,
+ .set = spapr_cap_set_bool,
+ .type = "bool",
+ .apply = cap_dfp_apply,
+ },
+};
+
+static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr,
+ CPUState *cs)
+{
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ sPAPRCapabilities caps;
+
+ caps = smc->default_caps;
+
+ if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07,
+ 0, spapr->max_compat_pvr)) {
+ caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF;
+ }
+
+ if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06,
+ 0, spapr->max_compat_pvr)) {
+ caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_OFF;
+ caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_OFF;
+ }
+
+ return caps;
+}
+
+int spapr_caps_pre_load(void *opaque)
+{
+ sPAPRMachineState *spapr = opaque;
+
+ /* Set to default so we can tell if this came in with the migration */
+ spapr->mig = spapr->def;
+ return 0;
+}
+
+int spapr_caps_pre_save(void *opaque)
+{
+ sPAPRMachineState *spapr = opaque;
+
+ spapr->mig = spapr->eff;
+ return 0;
+}
+
+/* This has to be called from the top-level spapr post_load, not the
+ * caps specific one. Otherwise it wouldn't be called when the source
+ * caps are all defaults, which could still conflict with overridden
+ * caps on the destination */
+int spapr_caps_post_migration(sPAPRMachineState *spapr)
+{
+ int i;
+ bool ok = true;
+ sPAPRCapabilities dstcaps = spapr->eff;
+ sPAPRCapabilities srccaps;
+
+ srccaps = default_caps_with_cpu(spapr, first_cpu);
+ for (i = 0; i < SPAPR_CAP_NUM; i++) {
+ /* If not default value then assume came in with the migration */
+ if (spapr->mig.caps[i] != spapr->def.caps[i]) {
+ srccaps.caps[i] = spapr->mig.caps[i];
+ }
+ }
+
+ for (i = 0; i < SPAPR_CAP_NUM; i++) {
+ sPAPRCapabilityInfo *info = &capability_table[i];
+
+ if (srccaps.caps[i] > dstcaps.caps[i]) {
+ error_report("cap-%s higher level (%d) in incoming stream than on destination (%d)",
+ info->name, srccaps.caps[i], dstcaps.caps[i]);
+ ok = false;
+ }
+
+ if (srccaps.caps[i] < dstcaps.caps[i]) {
+ warn_report("cap-%s lower level (%d) in incoming stream than on destination (%d)",
+ info->name, srccaps.caps[i], dstcaps.caps[i]);
+ }
+ }
+
+ return ok ? 0 : -EINVAL;
+}
+
+/* Used to generate the migration field and needed function for a spapr cap */
+#define SPAPR_CAP_MIG_STATE(cap, ccap) \
+static bool spapr_cap_##cap##_needed(void *opaque) \
+{ \
+ sPAPRMachineState *spapr = opaque; \
+ \
+ return spapr->cmd_line_caps[SPAPR_CAP_##ccap] && \
+ (spapr->eff.caps[SPAPR_CAP_##ccap] != \
+ spapr->def.caps[SPAPR_CAP_##ccap]); \
+} \
+ \
+const VMStateDescription vmstate_spapr_cap_##cap = { \
+ .name = "spapr/cap/" #cap, \
+ .version_id = 1, \
+ .minimum_version_id = 1, \
+ .needed = spapr_cap_##cap##_needed, \
+ .fields = (VMStateField[]) { \
+ VMSTATE_UINT8(mig.caps[SPAPR_CAP_##ccap], \
+ sPAPRMachineState), \
+ VMSTATE_END_OF_LIST() \
+ }, \
+}
+
+SPAPR_CAP_MIG_STATE(htm, HTM);
+SPAPR_CAP_MIG_STATE(vsx, VSX);
+SPAPR_CAP_MIG_STATE(dfp, DFP);
+
+void spapr_caps_reset(sPAPRMachineState *spapr)
+{
+ sPAPRCapabilities default_caps;
+ int i;
+
+ /* First compute the actual set of caps we're running with.. */
+ default_caps = default_caps_with_cpu(spapr, first_cpu);
+
+ for (i = 0; i < SPAPR_CAP_NUM; i++) {
+ /* Store the defaults */
+ spapr->def.caps[i] = default_caps.caps[i];
+ /* If not set on the command line then apply the default value */
+ if (!spapr->cmd_line_caps[i]) {
+ spapr->eff.caps[i] = default_caps.caps[i];
+ }
+ }
+
+ /* .. then apply those caps to the virtual hardware */
+
+ for (i = 0; i < SPAPR_CAP_NUM; i++) {
+ sPAPRCapabilityInfo *info = &capability_table[i];
+
+ /*
+ * If the apply function can't set the desired level and thinks it's
+ * fatal, it should cause that.
+ */
+ info->apply(spapr, spapr->eff.caps[i], &error_fatal);
+ }
+}
+
+void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp)
+{
+ Error *local_err = NULL;
+ ObjectClass *klass = OBJECT_CLASS(smc);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(capability_table); i++) {
+ sPAPRCapabilityInfo *cap = &capability_table[i];
+ const char *name = g_strdup_printf("cap-%s", cap->name);
+ char *desc;
+
+ object_class_property_add(klass, name, cap->type,
+ cap->get, cap->set,
+ NULL, cap, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ desc = g_strdup_printf("%s", cap->description);
+ object_class_property_set_description(klass, name, desc, &local_err);
+ g_free(desc);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ }
+}
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index ac19b2e0b7..590d167b04 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -44,6 +44,13 @@ static void spapr_cpu_reset(void *opaque)
if (cs != first_cpu) {
env->spr[SPR_LPCR] &= ~pcc->lpcr_pm;
}
+
+ /* Set compatibility mode to match the boot CPU, which was either set
+ * by the machine reset code or by CAS. This should never fail.
+ */
+ if (cs != first_cpu) {
+ ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort);
+ }
}
static void spapr_cpu_destroy(PowerPCCPU *cpu)
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 695c820911..37f18b3d32 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -505,7 +505,7 @@ static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
goto param_error_exit;
}
- rtas_st(rets, 1, (pci_bus_num(pdev->bus) << 16) + 1);
+ rtas_st(rets, 1, (pci_bus_num(pci_get_bus(pdev)) << 16) + 1);
break;
case RTAS_GET_PE_MODE:
rtas_st(rets, 1, RTAS_PE_MODE_SHARED);
@@ -1621,10 +1621,10 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
&sphb->iowindow);
- bus = pci_register_bus(dev, NULL,
- pci_spapr_set_irq, pci_spapr_map_irq, sphb,
- &sphb->memspace, &sphb->iospace,
- PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
+ bus = pci_register_root_bus(dev, NULL,
+ pci_spapr_set_irq, pci_spapr_map_irq, sphb,
+ &sphb->memspace, &sphb->iospace,
+ PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
phb->bus = bus;
qbus_set_hotplug_handler(BUS(phb->bus), DEVICE(sphb), NULL);
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 2b89e1d448..4bb939d3d1 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -163,7 +163,6 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
- Error *local_err = NULL;
if (!cs->halted) {
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
@@ -175,14 +174,6 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
* new cpu enters */
kvm_cpu_synchronize_state(cs);
- /* Set compatibility mode to match existing cpus */
- ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &local_err);
- if (local_err) {
- error_report_err(local_err);
- rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
- return;
- }
-
env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
/* Enable Power-saving mode Exit Cause exceptions for the new CPU */
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 2b1e1409bf..7d9c65e719 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -554,10 +554,10 @@ static int s390_pcihost_init(SysBusDevice *dev)
DPRINTF("host_init\n");
- b = pci_register_bus(DEVICE(dev), NULL,
- s390_pci_set_irq, s390_pci_map_irq, NULL,
- get_system_memory(), get_system_io(), 0, 64,
- TYPE_PCI_BUS);
+ b = pci_register_root_bus(DEVICE(dev), NULL,
+ s390_pci_set_irq, s390_pci_map_irq, NULL,
+ get_system_memory(), get_system_io(), 0, 64,
+ TYPE_PCI_BUS);
pci_setup_iommu(b, s390_pci_dma_iommu, s);
bus = BUS(b);
@@ -680,10 +680,10 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
s->bus_no += 1;
pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1);
do {
- pdev = pdev->bus->parent_dev;
+ pdev = pci_get_bus(pdev)->parent_dev;
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS,
s->bus_no, 1);
- } while (pdev->bus && pci_bus_num(pdev->bus));
+ } while (pci_get_bus(pdev) && pci_dev_bus_num(pdev));
}
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
pdev = PCI_DEVICE(dev);
@@ -692,7 +692,7 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
/* In the case the PCI device does not define an id */
/* we generate one based on the PCI address */
dev->id = g_strdup_printf("auto_%02x:%02x.%01x",
- pci_bus_num(pdev->bus),
+ pci_dev_bus_num(pdev),
PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn));
}
@@ -713,7 +713,7 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
}
pbdev->pdev = pdev;
- pbdev->iommu = s390_pci_get_iommu(s, pdev->bus, pdev->devfn);
+ pbdev->iommu = s390_pci_get_iommu(s, pci_get_bus(pdev), pdev->devfn);
pbdev->iommu->pbdev = pbdev;
pbdev->state = ZPCI_FS_DISABLED;
@@ -807,7 +807,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
pbdev->fh, pbdev->fid);
- bus = pci_dev->bus;
+ bus = pci_get_bus(pci_dev);
devfn = pci_dev->devfn;
object_unparent(OBJECT(pci_dev));
s390_pci_msix_free(pbdev);
diff --git a/hw/s390x/s390-stattrib-kvm.c b/hw/s390x/s390-stattrib-kvm.c
index 41770a7dec..480551c3db 100644
--- a/hw/s390x/s390-stattrib-kvm.c
+++ b/hw/s390x/s390-stattrib-kvm.c
@@ -116,7 +116,7 @@ static void kvm_s390_stattrib_synchronize(S390StAttribState *sa)
for (cx = 0; cx + len <= max; cx += len) {
clog.start_gfn = cx;
clog.count = len;
- clog.values = (uint64_t)(sas->incoming_buffer + cx * len);
+ clog.values = (uint64_t)(sas->incoming_buffer + cx);
r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog);
if (r) {
error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r));
@@ -126,7 +126,7 @@ static void kvm_s390_stattrib_synchronize(S390StAttribState *sa)
if (cx < max) {
clog.start_gfn = cx;
clog.count = max - cx;
- clog.values = (uint64_t)(sas->incoming_buffer + cx * len);
+ clog.values = (uint64_t)(sas->incoming_buffer + cx);
r = kvm_vm_ioctl(kvm_state, KVM_S390_SET_CMMA_BITS, &clog);
if (r) {
error_report("KVM_S390_SET_CMMA_BITS failed: %s", strerror(-r));
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 35df7e19c5..3807dcb097 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -414,6 +414,7 @@ static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
sizeof(CPUArchId) * max_cpus);
ms->possible_cpus->len = max_cpus;
for (i = 0; i < ms->possible_cpus->len; i++) {
+ ms->possible_cpus->cpus[i].type = ms->cpu_type;
ms->possible_cpus->cpus[i].vcpus_count = 1;
ms->possible_cpus->cpus[i].arch_id = i;
ms->possible_cpus->cpus[i].props.has_core_id = true;
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 9be0cb80ad..276972b59f 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -67,7 +67,7 @@ static void read_SCP_info(SCLPDevice *sclp, SCCB *sccb)
prepare_cpu_entries(sclp, read_info->entries, &cpu_count);
read_info->entries_cpu = cpu_to_be16(cpu_count);
read_info->offset_cpu = cpu_to_be16(offsetof(ReadInfo, entries));
- read_info->highest_cpu = cpu_to_be16(max_cpus);
+ read_info->highest_cpu = cpu_to_be16(max_cpus - 1);
read_info->ibc_val = cpu_to_be32(s390_get_ibc_val());
@@ -233,7 +233,7 @@ static void assign_storage(SCLPDevice *sclp, SCCB *sccb)
sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
return;
}
- assign_addr = (assign_info->rn - 1) * mhd->rzm;
+ assign_addr = (be16_to_cpu(assign_info->rn) - 1) * mhd->rzm;
if ((assign_addr % MEM_SECTION_SIZE == 0) &&
(assign_addr >= mhd->padded_ram_size)) {
@@ -292,7 +292,7 @@ static void unassign_storage(SCLPDevice *sclp, SCCB *sccb)
sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);
return;
}
- unassign_addr = (assign_info->rn - 1) * mhd->rzm;
+ unassign_addr = (be16_to_cpu(assign_info->rn) - 1) * mhd->rzm;
/* if the addr is a multiple of 256 MB */
if ((unassign_addr % MEM_SECTION_SIZE == 0) &&
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 38f6a8afc9..3d8f26949b 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -426,8 +426,9 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
* passes us zeroes for those we don't support.
*/
if (features.features) {
- fprintf(stderr, "Guest bug: features[%i]=%x (expected 0)\n",
- features.index, features.features);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Guest bug: features[%i]=%x (expected 0)",
+ features.index, features.features);
/* XXX: do a unit check here? */
}
}
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index d5eae6239a..3e38e9e8aa 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2372,7 +2372,7 @@ static void megasas_scsi_realize(PCIDevice *dev, Error **errp)
if (!s->sas_addr) {
s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
- s->sas_addr |= (pci_bus_num(dev->bus) << 16);
+ s->sas_addr |= (pci_dev_bus_num(dev) << 16);
s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
s->sas_addr |= PCI_FUNC(dev->devfn);
}
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
index f6db1b0103..3f061f3f68 100644
--- a/hw/scsi/mptsas.c
+++ b/hw/scsi/mptsas.c
@@ -1312,7 +1312,7 @@ static void mptsas_scsi_realize(PCIDevice *dev, Error **errp)
if (!s->sas_addr) {
s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
- s->sas_addr |= (pci_bus_num(dev->bus) << 16);
+ s->sas_addr |= (pci_dev_bus_num(dev) << 16);
s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
s->sas_addr |= PCI_FUNC(dev->devfn);
}
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index e58833a087..49d2559d93 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -1755,6 +1755,7 @@ static void scsi_write_same_complete(void *opaque, int ret)
data->sector << BDRV_SECTOR_BITS,
&data->qiov, 0,
scsi_write_same_complete, data);
+ aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
return;
}
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index bd0d9ff355..ba70c0dc19 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -482,6 +482,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
int rc;
int sg_version;
struct sg_scsi_id scsiid;
+ Error *local_err = NULL;
if (!s->conf.blk) {
error_setg(errp, "drive property not set");
@@ -515,6 +516,13 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
return;
}
+ blkconf_apply_backend_options(&s->conf,
+ blk_is_read_only(s->conf.blk),
+ true, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
/* define device state */
s->type = scsiid.scsi_type;
@@ -565,6 +573,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
static Property scsi_generic_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
+ DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index d564e5caff..27749c0e42 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1133,7 +1133,7 @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
pvscsi_init_msi(s);
- if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus)) {
+ if (pci_is_express(pci_dev) && pci_bus_is_express(pci_get_bus(pci_dev))) {
pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET);
}
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
index 4008c81002..341da88552 100644
--- a/hw/sd/milkymist-memcard.c
+++ b/hw/sd/milkymist-memcard.c
@@ -248,6 +248,10 @@ static void milkymist_memcard_reset(DeviceState *d)
for (i = 0; i < R_MAX; i++) {
s->regs[i] = 0;
}
+ /* Since we're still using the legacy SD API the card is not plugged
+ * into any bus, and we must reset it manually.
+ */
+ device_reset(DEVICE(s->card));
}
static int milkymist_memcard_init(SysBusDevice *dev)
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
index e934cd3656..5b47cadf11 100644
--- a/hw/sd/omap_mmc.c
+++ b/hw/sd/omap_mmc.c
@@ -305,6 +305,12 @@ void omap_mmc_reset(struct omap_mmc_s *host)
host->cdet_enable = 0;
qemu_set_irq(host->coverswitch, host->cdet_state);
host->clkdiv = 0;
+
+ /* Since we're still using the legacy SD API the card is not plugged
+ * into any bus, and we must reset it manually. When omap_mmc is
+ * QOMified this must move into the QOM reset function.
+ */
+ device_reset(DEVICE(host->card));
}
static uint64_t omap_mmc_read(void *opaque, hwaddr offset,
@@ -587,8 +593,6 @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
s->lines = 1; /* TODO: needs to be settable per-board */
s->rev = 1;
- omap_mmc_reset(s);
-
memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc", 0x800);
memory_region_add_subregion(sysmem, base, &s->iomem);
@@ -598,6 +602,8 @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
exit(1);
}
+ omap_mmc_reset(s);
+
return s;
}
@@ -613,8 +619,6 @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
s->lines = 4;
s->rev = 2;
- omap_mmc_reset(s);
-
memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc",
omap_l4_region_size(ta, 0));
omap_l4_attach(ta, 0, &s->iomem);
@@ -628,6 +632,8 @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
s->cdet = qemu_allocate_irq(omap_mmc_cover_cb, s, 0);
sd_set_cb(s->card, NULL, s->cdet);
+ omap_mmc_reset(s);
+
return s;
}
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index 55c8098ecd..3ba1f7dd23 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -480,6 +480,10 @@ static void pl181_reset(DeviceState *d)
/* We can assume our GPIO outputs have been wired up now */
sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]);
+ /* Since we're still using the legacy SD API the card is not plugged
+ * into any bus, and we must reset it manually.
+ */
+ device_reset(DEVICE(s->card));
}
static void pl181_init(Object *obj)
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index 161177cf39..fc807f08f3 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -24,8 +24,6 @@
#ifndef SDHCI_INTERNAL_H
#define SDHCI_INTERNAL_H
-#include "hw/sd/sdhci.h"
-
/* R/W SDMA System Address register 0x0 */
#define SDHC_SYSAD 0x00
@@ -45,6 +43,7 @@
#define SDHC_TRNS_ACMD12 0x0004
#define SDHC_TRNS_READ 0x0010
#define SDHC_TRNS_MULTI 0x0020
+#define SDHC_TRNMOD_MASK 0x0037
/* R/W Command Register 0x0 */
#define SDHC_CMDREG 0x0E
@@ -175,7 +174,7 @@
#define SDHC_ACMD12ERRSTS 0x3C
/* HWInit Capabilities Register 0x05E80080 */
-#define SDHC_CAPAREG 0x40
+#define SDHC_CAPAB 0x40
#define SDHC_CAN_DO_DMA 0x00400000
#define SDHC_CAN_DO_ADMA2 0x00080000
#define SDHC_CAN_DO_ADMA1 0x00100000
@@ -227,6 +226,4 @@ enum {
sdhc_gap_write = 2 /* SDHC stopped at block gap during write operation */
};
-extern const VMStateDescription sdhci_vmstate;
-
#endif
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index b064a087c9..f9264d3be5 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -23,38 +23,18 @@
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "hw/hw.h"
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "sysemu/dma.h"
#include "qemu/timer.h"
#include "qemu/bitops.h"
+#include "hw/sd/sdhci.h"
#include "sdhci-internal.h"
+#include "qapi/error.h"
#include "qemu/log.h"
-
-/* host controller debug messages */
-#ifndef SDHC_DEBUG
-#define SDHC_DEBUG 0
-#endif
-
-#define DPRINT_L1(fmt, args...) \
- do { \
- if (SDHC_DEBUG) { \
- fprintf(stderr, "QEMU SDHC: " fmt, ## args); \
- } \
- } while (0)
-#define DPRINT_L2(fmt, args...) \
- do { \
- if (SDHC_DEBUG > 1) { \
- fprintf(stderr, "QEMU SDHC: " fmt, ## args); \
- } \
- } while (0)
-#define ERRPRINT(fmt, args...) \
- do { \
- if (SDHC_DEBUG) { \
- fprintf(stderr, "QEMU SDHC ERROR: " fmt, ## args); \
- } \
- } while (0)
+#include "trace.h"
#define TYPE_SDHCI_BUS "sdhci-bus"
#define SDHCI_BUS(obj) OBJECT_CHECK(SDBus, (obj), TYPE_SDHCI_BUS)
@@ -119,7 +99,6 @@
(SDHC_CAPAB_BASECLKFREQ << 8) | (SDHC_CAPAB_TOUNIT << 7) | \
(SDHC_CAPAB_TOCLKFREQ))
-#define MASK_TRNMOD 0x0037
#define MASKED_WRITE(reg, mask, val) (reg = (reg & (mask)) | (val))
static uint8_t sdhci_slotint(SDHCIState *s)
@@ -153,8 +132,8 @@ static void sdhci_raise_insertion_irq(void *opaque)
static void sdhci_set_inserted(DeviceState *dev, bool level)
{
SDHCIState *s = (SDHCIState *)dev;
- DPRINT_L1("Card state changed: %s!\n", level ? "insert" : "eject");
+ trace_sdhci_set_inserted(level ? "insert" : "eject");
if ((s->norintsts & SDHC_NIS_REMOVE) && level) {
/* Give target some time to notice card ejection */
timer_mod(s->insert_timer,
@@ -236,7 +215,8 @@ static void sdhci_send_command(SDHCIState *s)
s->acmd12errsts = 0;
request.cmd = s->cmdreg >> 8;
request.arg = s->argument;
- DPRINT_L1("sending CMD%u ARG[0x%08x]\n", request.cmd, request.arg);
+
+ trace_sdhci_send_command(request.cmd, request.arg);
rlen = sdbus_do_command(&s->sdbus, &request, response);
if (s->cmdreg & SDHC_CMD_RESPONSE) {
@@ -244,7 +224,7 @@ static void sdhci_send_command(SDHCIState *s)
s->rspreg[0] = (response[0] << 24) | (response[1] << 16) |
(response[2] << 8) | response[3];
s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
- DPRINT_L1("Response: RSPREG[31..0]=0x%08x\n", s->rspreg[0]);
+ trace_sdhci_response4(s->rspreg[0]);
} else if (rlen == 16) {
s->rspreg[0] = (response[11] << 24) | (response[12] << 16) |
(response[13] << 8) | response[14];
@@ -254,11 +234,10 @@ static void sdhci_send_command(SDHCIState *s)
(response[5] << 8) | response[6];
s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |
response[2];
- DPRINT_L1("Response received:\n RSPREG[127..96]=0x%08x, RSPREG[95.."
- "64]=0x%08x,\n RSPREG[63..32]=0x%08x, RSPREG[31..0]=0x%08x\n",
- s->rspreg[3], s->rspreg[2], s->rspreg[1], s->rspreg[0]);
+ trace_sdhci_response16(s->rspreg[3], s->rspreg[2],
+ s->rspreg[1], s->rspreg[0]);
} else {
- ERRPRINT("Timeout waiting for command response\n");
+ trace_sdhci_error("timeout waiting for command response");
if (s->errintstsen & SDHC_EISEN_CMDTIMEOUT) {
s->errintsts |= SDHC_EIS_CMDTIMEOUT;
s->norintsts |= SDHC_NIS_ERR;
@@ -292,7 +271,7 @@ static void sdhci_end_transfer(SDHCIState *s)
request.cmd = 0x0C;
request.arg = 0;
- DPRINT_L1("Automatically issue CMD%d %08x\n", request.cmd, request.arg);
+ trace_sdhci_end_transfer(request.cmd, request.arg);
sdbus_do_command(&s->sdbus, &request, response);
/* Auto CMD12 response goes to the upper Response register */
s->rspreg[3] = (response[0] << 24) | (response[1] << 16) |
@@ -361,7 +340,7 @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
/* first check that a valid data exists in host controller input buffer */
if ((s->prnsts & SDHC_DATA_AVAILABLE) == 0) {
- ERRPRINT("Trying to read from empty buffer\n");
+ trace_sdhci_error("read from empty buffer");
return 0;
}
@@ -370,8 +349,7 @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
s->data_count++;
/* check if we've read all valid data (blksize bytes) from buffer */
if ((s->data_count) >= (s->blksize & 0x0fff)) {
- DPRINT_L2("All %u bytes of data have been read from input buffer\n",
- s->data_count);
+ trace_sdhci_read_dataport(s->data_count);
s->prnsts &= ~SDHC_DATA_AVAILABLE; /* no more data in a buffer */
s->data_count = 0; /* next buff read must start at position [0] */
@@ -454,7 +432,7 @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
/* Check that there is free space left in a buffer */
if (!(s->prnsts & SDHC_SPACE_AVAILABLE)) {
- ERRPRINT("Can't write to data buffer: buffer full\n");
+ trace_sdhci_error("Can't write to data buffer: buffer full");
return;
}
@@ -463,8 +441,7 @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
s->data_count++;
value >>= 8;
if (s->data_count >= (s->blksize & 0x0fff)) {
- DPRINT_L2("write buffer filled with %u bytes of data\n",
- s->data_count);
+ trace_sdhci_write_dataport(s->data_count);
s->data_count = 0;
s->prnsts &= ~SDHC_SPACE_AVAILABLE;
if (s->prnsts & SDHC_DOING_WRITE) {
@@ -519,7 +496,7 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
s->blkcnt--;
}
}
- dma_memory_write(&address_space_memory, s->sdmasysad,
+ dma_memory_write(s->dma_as, s->sdmasysad,
&s->fifo_buffer[begin], s->data_count - begin);
s->sdmasysad += s->data_count - begin;
if (s->data_count == block_size) {
@@ -541,7 +518,7 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
s->data_count = block_size;
boundary_count -= block_size - begin;
}
- dma_memory_read(&address_space_memory, s->sdmasysad,
+ dma_memory_read(s->dma_as, s->sdmasysad,
&s->fifo_buffer[begin], s->data_count - begin);
s->sdmasysad += s->data_count - begin;
if (s->data_count == block_size) {
@@ -579,11 +556,9 @@ static void sdhci_sdma_transfer_single_block(SDHCIState *s)
for (n = 0; n < datacnt; n++) {
s->fifo_buffer[n] = sdbus_read_data(&s->sdbus);
}
- dma_memory_write(&address_space_memory, s->sdmasysad, s->fifo_buffer,
- datacnt);
+ dma_memory_write(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt);
} else {
- dma_memory_read(&address_space_memory, s->sdmasysad, s->fifo_buffer,
- datacnt);
+ dma_memory_read(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt);
for (n = 0; n < datacnt; n++) {
sdbus_write_data(&s->sdbus, s->fifo_buffer[n]);
}
@@ -607,7 +582,7 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
hwaddr entry_addr = (hwaddr)s->admasysaddr;
switch (SDHC_DMA_TYPE(s->hostctl)) {
case SDHC_CTRL_ADMA2_32:
- dma_memory_read(&address_space_memory, entry_addr, (uint8_t *)&adma2,
+ dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma2,
sizeof(adma2));
adma2 = le64_to_cpu(adma2);
/* The spec does not specify endianness of descriptor table.
@@ -619,7 +594,7 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
dscr->incr = 8;
break;
case SDHC_CTRL_ADMA1_32:
- dma_memory_read(&address_space_memory, entry_addr, (uint8_t *)&adma1,
+ dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma1,
sizeof(adma1));
adma1 = le32_to_cpu(adma1);
dscr->addr = (hwaddr)(adma1 & 0xFFFFF000);
@@ -632,12 +607,12 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
}
break;
case SDHC_CTRL_ADMA2_64:
- dma_memory_read(&address_space_memory, entry_addr,
+ dma_memory_read(s->dma_as, entry_addr,
(uint8_t *)(&dscr->attr), 1);
- dma_memory_read(&address_space_memory, entry_addr + 2,
+ dma_memory_read(s->dma_as, entry_addr + 2,
(uint8_t *)(&dscr->length), 2);
dscr->length = le16_to_cpu(dscr->length);
- dma_memory_read(&address_space_memory, entry_addr + 4,
+ dma_memory_read(s->dma_as, entry_addr + 4,
(uint8_t *)(&dscr->addr), 8);
dscr->attr = le64_to_cpu(dscr->attr);
dscr->attr &= 0xfffffff8;
@@ -652,15 +627,14 @@ static void sdhci_do_adma(SDHCIState *s)
{
unsigned int n, begin, length;
const uint16_t block_size = s->blksize & 0x0fff;
- ADMADescr dscr;
+ ADMADescr dscr = {};
int i;
for (i = 0; i < SDHC_ADMA_DESCS_PER_DELAY; ++i) {
s->admaerr &= ~SDHC_ADMAERR_LENGTH_MISMATCH;
get_adma_description(s, &dscr);
- DPRINT_L2("ADMA loop: addr=" TARGET_FMT_plx ", len=%d, attr=%x\n",
- dscr.addr, dscr.length, dscr.attr);
+ trace_sdhci_adma_loop(dscr.addr, dscr.length, dscr.attr);
if ((dscr.attr & SDHC_ADMA_ATTR_VALID) == 0) {
/* Indicate that error occurred in ST_FDS state */
@@ -697,7 +671,7 @@ static void sdhci_do_adma(SDHCIState *s)
s->data_count = block_size;
length -= block_size - begin;
}
- dma_memory_write(&address_space_memory, dscr.addr,
+ dma_memory_write(s->dma_as, dscr.addr,
&s->fifo_buffer[begin],
s->data_count - begin);
dscr.addr += s->data_count - begin;
@@ -721,7 +695,7 @@ static void sdhci_do_adma(SDHCIState *s)
s->data_count = block_size;
length -= block_size - begin;
}
- dma_memory_read(&address_space_memory, dscr.addr,
+ dma_memory_read(s->dma_as, dscr.addr,
&s->fifo_buffer[begin],
s->data_count - begin);
dscr.addr += s->data_count - begin;
@@ -743,8 +717,7 @@ static void sdhci_do_adma(SDHCIState *s)
break;
case SDHC_ADMA_ATTR_ACT_LINK: /* link to next descriptor table */
s->admasysaddr = dscr.addr;
- DPRINT_L1("ADMA link: admasysaddr=0x%" PRIx64 "\n",
- s->admasysaddr);
+ trace_sdhci_adma("link", s->admasysaddr);
break;
default:
s->admasysaddr += dscr.incr;
@@ -752,8 +725,7 @@ static void sdhci_do_adma(SDHCIState *s)
}
if (dscr.attr & SDHC_ADMA_ATTR_INT) {
- DPRINT_L1("ADMA interrupt: admasysaddr=0x%" PRIx64 "\n",
- s->admasysaddr);
+ trace_sdhci_adma("interrupt", s->admasysaddr);
if (s->norintstsen & SDHC_NISEN_DMA) {
s->norintsts |= SDHC_NIS_DMA;
}
@@ -764,15 +736,15 @@ static void sdhci_do_adma(SDHCIState *s)
/* ADMA transfer terminates if blkcnt == 0 or by END attribute */
if (((s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
(s->blkcnt == 0)) || (dscr.attr & SDHC_ADMA_ATTR_END)) {
- DPRINT_L2("ADMA transfer completed\n");
+ trace_sdhci_adma_transfer_completed();
if (length || ((dscr.attr & SDHC_ADMA_ATTR_END) &&
(s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
s->blkcnt != 0)) {
- ERRPRINT("SD/MMC host ADMA length mismatch\n");
+ trace_sdhci_error("SD/MMC host ADMA length mismatch");
s->admaerr |= SDHC_ADMAERR_LENGTH_MISMATCH |
SDHC_ADMAERR_STATE_ST_TFR;
if (s->errintstsen & SDHC_EISEN_ADMAERR) {
- ERRPRINT("Set ADMA error flag\n");
+ trace_sdhci_error("Set ADMA error flag");
s->errintsts |= SDHC_EIS_ADMAERR;
s->norintsts |= SDHC_NIS_ERR;
}
@@ -808,7 +780,7 @@ static void sdhci_data_transfer(void *opaque)
break;
case SDHC_CTRL_ADMA1_32:
if (!(s->capareg & SDHC_CAN_DO_ADMA1)) {
- ERRPRINT("ADMA1 not supported\n");
+ trace_sdhci_error("ADMA1 not supported");
break;
}
@@ -816,7 +788,7 @@ static void sdhci_data_transfer(void *opaque)
break;
case SDHC_CTRL_ADMA2_32:
if (!(s->capareg & SDHC_CAN_DO_ADMA2)) {
- ERRPRINT("ADMA2 not supported\n");
+ trace_sdhci_error("ADMA2 not supported");
break;
}
@@ -825,14 +797,14 @@ static void sdhci_data_transfer(void *opaque)
case SDHC_CTRL_ADMA2_64:
if (!(s->capareg & SDHC_CAN_DO_ADMA2) ||
!(s->capareg & SDHC_64_BIT_BUS_SUPPORT)) {
- ERRPRINT("64 bit ADMA not supported\n");
+ trace_sdhci_error("64 bit ADMA not supported");
break;
}
sdhci_do_adma(s);
break;
default:
- ERRPRINT("Unsupported DMA type\n");
+ trace_sdhci_error("Unsupported DMA type");
break;
}
} else {
@@ -867,8 +839,8 @@ static inline bool
sdhci_buff_access_is_sequential(SDHCIState *s, unsigned byte_num)
{
if ((s->data_count & 0x3) != byte_num) {
- ERRPRINT("Non-sequential access to Buffer Data Port register"
- "is prohibited\n");
+ trace_sdhci_error("Non-sequential access to Buffer Data Port register"
+ "is prohibited\n");
return false;
}
return true;
@@ -898,8 +870,7 @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
case SDHC_BDATA:
if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {
ret = sdhci_read_dataport(s, size);
- DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, (int)offset,
- ret, ret);
+ trace_sdhci_access("rd", size << 3, offset, "->", ret, ret);
return ret;
}
break;
@@ -925,11 +896,17 @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
case SDHC_ACMD12ERRSTS:
ret = s->acmd12errsts;
break;
- case SDHC_CAPAREG:
- ret = s->capareg;
+ case SDHC_CAPAB:
+ ret = (uint32_t)s->capareg;
+ break;
+ case SDHC_CAPAB + 4:
+ ret = (uint32_t)(s->capareg >> 32);
break;
case SDHC_MAXCURR:
- ret = s->maxcurr;
+ ret = (uint32_t)s->maxcurr;
+ break;
+ case SDHC_MAXCURR + 4:
+ ret = (uint32_t)(s->maxcurr >> 32);
break;
case SDHC_ADMAERR:
ret = s->admaerr;
@@ -944,13 +921,14 @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
ret = (SD_HOST_SPECv2_VERS << 16) | sdhci_slotint(s);
break;
default:
- ERRPRINT("bad %ub read: addr[0x%04x]\n", size, (int)offset);
+ qemu_log_mask(LOG_UNIMP, "SDHC rd_%ub @0x%02" HWADDR_PRIx " "
+ "not implemented\n", size, offset);
break;
}
ret >>= (offset & 0x3) * 8;
ret &= (1ULL << (size * 8)) - 1;
- DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, (int)offset, ret, ret);
+ trace_sdhci_access("rd", size << 3, offset, "->", ret, ret);
return ret;
}
@@ -1051,7 +1029,7 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
if (!(s->capareg & SDHC_CAN_DO_DMA)) {
value &= ~SDHC_TRNS_DMA;
}
- MASKED_WRITE(s->trnmod, mask, value & MASK_TRNMOD);
+ MASKED_WRITE(s->trnmod, mask, value & SDHC_TRNMOD_MASK);
MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);
/* Writing to the upper byte of CMDREG triggers SD command generation */
@@ -1149,13 +1127,25 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
}
sdhci_update_irq(s);
break;
+ case SDHC_ACMD12ERRSTS:
+ MASKED_WRITE(s->acmd12errsts, mask, value);
+ break;
+
+ case SDHC_CAPAB:
+ case SDHC_CAPAB + 4:
+ case SDHC_MAXCURR:
+ case SDHC_MAXCURR + 4:
+ qemu_log_mask(LOG_GUEST_ERROR, "SDHC wr_%ub @0x%02" HWADDR_PRIx
+ " <- 0x%08x read-only\n", size, offset, value >> shift);
+ break;
+
default:
- ERRPRINT("bad %ub write offset: addr[0x%04x] <- %u(0x%x)\n",
- size, (int)offset, value >> shift, value >> shift);
+ qemu_log_mask(LOG_UNIMP, "SDHC wr_%ub @0x%02" HWADDR_PRIx " <- 0x%08x "
+ "not implemented\n", size, offset, value >> shift);
break;
}
- DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",
- size, (int)offset, value >> shift, value >> shift);
+ trace_sdhci_access("wr", size << 3, offset, "<-",
+ value >> shift, value >> shift);
}
static const MemoryRegionOps sdhci_mmio_ops = {
@@ -1184,6 +1174,14 @@ static inline unsigned int sdhci_get_fifolen(SDHCIState *s)
}
}
+/* --- qdev common --- */
+
+#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \
+ /* Capabilities registers provide information on supported features
+ * of this specific host controller implementation */ \
+ DEFINE_PROP_UINT64("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \
+ DEFINE_PROP_UINT64("maxcurr", _state, maxcurr, 0)
+
static void sdhci_initfn(SDHCIState *s)
{
qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
@@ -1199,13 +1197,31 @@ static void sdhci_uninitfn(SDHCIState *s)
timer_free(s->insert_timer);
timer_del(s->transfer_timer);
timer_free(s->transfer_timer);
- qemu_free_irq(s->eject_cb);
- qemu_free_irq(s->ro_cb);
g_free(s->fifo_buffer);
s->fifo_buffer = NULL;
}
+static void sdhci_common_realize(SDHCIState *s, Error **errp)
+{
+ s->buf_maxsz = sdhci_get_fifolen(s);
+ s->fifo_buffer = g_malloc0(s->buf_maxsz);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
+ SDHC_REGISTERS_MAP_SIZE);
+}
+
+static void sdhci_common_unrealize(SDHCIState *s, Error **errp)
+{
+ /* This function is expected to be called only once for each class:
+ * - SysBus: via DeviceClass->unrealize(),
+ * - PCI: via PCIDeviceClass->exit().
+ * However to avoid double-free and/or use-after-free we still nullify
+ * this variable (better safe than sorry!). */
+ g_free(s->fifo_buffer);
+ s->fifo_buffer = NULL;
+}
+
static bool sdhci_pending_insert_vmstate_needed(void *opaque)
{
SDHCIState *s = opaque;
@@ -1265,32 +1281,44 @@ const VMStateDescription sdhci_vmstate = {
},
};
-/* Capabilities registers provide information on supported features of this
- * specific host controller implementation */
+static void sdhci_common_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ dc->vmsd = &sdhci_vmstate;
+ dc->reset = sdhci_poweron_reset;
+}
+
+/* --- qdev PCI --- */
+
static Property sdhci_pci_properties[] = {
- DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
- SDHC_CAPAB_REG_DEFAULT),
- DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
+ DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState),
DEFINE_PROP_END_OF_LIST(),
};
static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
{
SDHCIState *s = PCI_SDHCI(dev);
+
+ sdhci_initfn(s);
+ sdhci_common_realize(s, errp);
+ if (errp && *errp) {
+ return;
+ }
+
dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */
dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
- sdhci_initfn(s);
- s->buf_maxsz = sdhci_get_fifolen(s);
- s->fifo_buffer = g_malloc0(s->buf_maxsz);
s->irq = pci_allocate_irq(dev);
- memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
- SDHC_REGISTERS_MAP_SIZE);
- pci_register_bar(dev, 0, 0, &s->iomem);
+ s->dma_as = pci_get_address_space(dev);
+ pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->iomem);
}
static void sdhci_pci_exit(PCIDevice *dev)
{
SDHCIState *s = PCI_SDHCI(dev);
+
+ sdhci_common_unrealize(s, &error_abort);
sdhci_uninitfn(s);
}
@@ -1304,10 +1332,9 @@ static void sdhci_pci_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_REDHAT;
k->device_id = PCI_DEVICE_ID_REDHAT_SDHCI;
k->class_id = PCI_CLASS_SYSTEM_SDHCI;
- set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
- dc->vmsd = &sdhci_vmstate;
dc->props = sdhci_pci_properties;
- dc->reset = sdhci_poweron_reset;
+
+ sdhci_common_class_init(klass, data);
}
static const TypeInfo sdhci_pci_info = {
@@ -1321,12 +1348,14 @@ static const TypeInfo sdhci_pci_info = {
},
};
+/* --- qdev SysBus --- */
+
static Property sdhci_sysbus_properties[] = {
- DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
- SDHC_CAPAB_REG_DEFAULT),
- DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
+ DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState),
DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk,
false),
+ DEFINE_PROP_LINK("dma", SDHCIState,
+ dma_mr, TYPE_MEMORY_REGION, MemoryRegion *),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1340,6 +1369,11 @@ static void sdhci_sysbus_init(Object *obj)
static void sdhci_sysbus_finalize(Object *obj)
{
SDHCIState *s = SYSBUS_SDHCI(obj);
+
+ if (s->dma_mr) {
+ object_unparent(OBJECT(s->dma_mr));
+ }
+
sdhci_uninitfn(s);
}
@@ -1348,22 +1382,42 @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
SDHCIState *s = SYSBUS_SDHCI(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
- s->buf_maxsz = sdhci_get_fifolen(s);
- s->fifo_buffer = g_malloc0(s->buf_maxsz);
+ sdhci_common_realize(s, errp);
+ if (errp && *errp) {
+ return;
+ }
+
+ if (s->dma_mr) {
+ address_space_init(s->dma_as, s->dma_mr, "sdhci-dma");
+ } else {
+ /* use system_memory() if property "dma" not set */
+ s->dma_as = &address_space_memory;
+ }
+
sysbus_init_irq(sbd, &s->irq);
- memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
- SDHC_REGISTERS_MAP_SIZE);
sysbus_init_mmio(sbd, &s->iomem);
}
+static void sdhci_sysbus_unrealize(DeviceState *dev, Error **errp)
+{
+ SDHCIState *s = SYSBUS_SDHCI(dev);
+
+ sdhci_common_unrealize(s, &error_abort);
+
+ if (s->dma_mr) {
+ address_space_destroy(s->dma_as);
+ }
+}
+
static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- dc->vmsd = &sdhci_vmstate;
dc->props = sdhci_sysbus_properties;
dc->realize = sdhci_sysbus_realize;
- dc->reset = sdhci_poweron_reset;
+ dc->unrealize = sdhci_sysbus_unrealize;
+
+ sdhci_common_class_init(klass, data);
}
static const TypeInfo sdhci_sysbus_info = {
@@ -1375,6 +1429,8 @@ static const TypeInfo sdhci_sysbus_info = {
.class_init = sdhci_sysbus_class_init,
};
+/* --- qdev bus master --- */
+
static void sdhci_bus_class_init(ObjectClass *klass, void *data)
{
SDBusClass *sbc = SD_BUS_CLASS(klass);
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 24001dc3e6..f88f509e0a 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -50,6 +50,9 @@ typedef struct {
SDState *sd;
} ssi_sd_state;
+#define TYPE_SSI_SD "ssi-sd"
+#define SSI_SD(obj) OBJECT_CHECK(ssi_sd_state, (obj), TYPE_SSI_SD)
+
/* State word bits. */
#define SSI_SDR_LOCKED 0x0001
#define SSI_SDR_WP_ERASE 0x0002
@@ -241,7 +244,6 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
DriveInfo *dinfo;
- s->mode = SSI_SD_CMD;
/* FIXME use a qdev drive property instead of drive_get_next() */
dinfo = drive_get_next(IF_SD);
s->sd = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, true);
@@ -251,6 +253,24 @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
}
}
+static void ssi_sd_reset(DeviceState *dev)
+{
+ ssi_sd_state *s = SSI_SD(dev);
+
+ s->mode = SSI_SD_CMD;
+ s->cmd = 0;
+ memset(s->cmdarg, 0, sizeof(s->cmdarg));
+ memset(s->response, 0, sizeof(s->response));
+ s->arglen = 0;
+ s->response_pos = 0;
+ s->stopping = 0;
+
+ /* Since we're still using the legacy SD API the card is not plugged
+ * into any bus, and we must reset it manually.
+ */
+ device_reset(DEVICE(s->sd));
+}
+
static void ssi_sd_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -260,10 +280,11 @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
k->transfer = ssi_sd_transfer;
k->cs_polarity = SSI_CS_LOW;
dc->vmsd = &vmstate_ssi_sd;
+ dc->reset = ssi_sd_reset;
}
static const TypeInfo ssi_sd_info = {
- .name = "ssi-sd",
+ .name = TYPE_SSI_SD,
.parent = TYPE_SSI_SLAVE,
.instance_size = sizeof(ssi_sd_state),
.class_init = ssi_sd_class_init,
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
index 6eca3470e2..0a121156a3 100644
--- a/hw/sd/trace-events
+++ b/hw/sd/trace-events
@@ -1,5 +1,19 @@
# See docs/devel/tracing.txt for syntax documentation.
+# hw/sd/sdhci.c
+sdhci_set_inserted(const char *level) "card state changed: %s"
+sdhci_send_command(uint8_t cmd, uint32_t arg) "CMD%02u ARG[0x%08x]"
+sdhci_error(const char *msg) "%s"
+sdhci_response4(uint32_t r0) "RSPREG[31..0]=0x%08x"
+sdhci_response16(uint32_t r3, uint32_t r2, uint32_t r1, uint32_t r0) "RSPREG[127..96]=0x%08x, RSPREG[95..64]=0x%08x, RSPREG[63..32]=0x%08x, RSPREG[31..0]=0x%08x"
+sdhci_end_transfer(uint8_t cmd, uint32_t arg) "Automatically issue CMD%02u 0x%08x"
+sdhci_adma(const char *desc, uint32_t sysad) "%s: admasysaddr=0x%" PRIx32
+sdhci_adma_loop(uint64_t addr, uint16_t length, uint8_t attr) "addr=0x%08" PRIx64 ", len=%d, attr=0x%x"
+sdhci_adma_transfer_completed(void) ""
+sdhci_access(const char *access, unsigned int size, uint64_t offset, const char *dir, uint64_t val, uint64_t val2) "%s%u: addr[0x%04" PRIx64 "] %s 0x%08" PRIx64 " (%" PRIu64 ")"
+sdhci_read_dataport(uint16_t data_count) "all %u bytes of data have been read from input buffer"
+sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of data"
+
# hw/sd/milkymist-memcard.c
milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
index cbb01af57f..4ec2e35500 100644
--- a/hw/sh4/sh_pci.c
+++ b/hw/sh4/sh_pci.c
@@ -131,12 +131,12 @@ static int sh_pci_device_init(SysBusDevice *dev)
for (i = 0; i < 4; i++) {
sysbus_init_irq(dev, &s->irq[i]);
}
- phb->bus = pci_register_bus(DEVICE(dev), "pci",
- sh_pci_set_irq, sh_pci_map_irq,
- s->irq,
- get_system_memory(),
- get_system_io(),
- PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS);
+ phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
+ sh_pci_set_irq, sh_pci_map_irq,
+ s->irq,
+ get_system_memory(),
+ get_system_io(),
+ PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS);
memory_region_init_io(&s->memconfig_p4, OBJECT(s), &sh_pci_reg_ops, s,
"sh_pci", 0x224);
memory_region_init_alias(&s->memconfig_a7, OBJECT(s), "sh_pci.2",
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 1a5437a07d..5d11f01874 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -96,6 +96,11 @@ static struct {
} type4;
static struct {
+ size_t nvalues;
+ const char **values;
+} type11;
+
+static struct {
const char *loc_pfx, *bank, *manufacturer, *serial, *asset, *part;
uint16_t speed;
} type17;
@@ -282,6 +287,14 @@ static const QemuOptDesc qemu_smbios_type4_opts[] = {
{ /* end of list */ }
};
+static const QemuOptDesc qemu_smbios_type11_opts[] = {
+ {
+ .name = "value",
+ .type = QEMU_OPT_STRING,
+ .help = "OEM string data",
+ },
+};
+
static const QemuOptDesc qemu_smbios_type17_opts[] = {
{
.name = "type",
@@ -590,6 +603,27 @@ static void smbios_build_type_4_table(unsigned instance)
smbios_type4_count++;
}
+static void smbios_build_type_11_table(void)
+{
+ char count_str[128];
+ size_t i;
+
+ if (type11.nvalues == 0) {
+ return;
+ }
+
+ SMBIOS_BUILD_TABLE_PRE(11, 0xe00, true); /* required */
+
+ snprintf(count_str, sizeof(count_str), "%zu", type11.nvalues);
+ t->count = type11.nvalues;
+
+ for (i = 0; i < type11.nvalues; i++) {
+ SMBIOS_TABLE_SET_STR_LIST(11, type11.values[i]);
+ }
+
+ SMBIOS_BUILD_TABLE_POST;
+}
+
#define ONE_KB ((ram_addr_t)1 << 10)
#define ONE_MB ((ram_addr_t)1 << 20)
#define ONE_GB ((ram_addr_t)1 << 30)
@@ -832,6 +866,8 @@ void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
smbios_build_type_4_table(i);
}
+ smbios_build_type_11_table();
+
#define MAX_DIMM_SZ (16ll * ONE_GB)
#define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
: ((ram_size - 1) % MAX_DIMM_SZ) + 1)
@@ -882,6 +918,38 @@ static void save_opt(const char **dest, QemuOpts *opts, const char *name)
}
}
+
+struct opt_list {
+ const char *name;
+ size_t *ndest;
+ const char ***dest;
+};
+
+static int save_opt_one(void *opaque,
+ const char *name, const char *value,
+ Error **errp)
+{
+ struct opt_list *opt = opaque;
+
+ if (!g_str_equal(name, opt->name)) {
+ return 0;
+ }
+
+ *opt->dest = g_renew(const char *, *opt->dest, (*opt->ndest) + 1);
+ (*opt->dest)[*opt->ndest] = value;
+ (*opt->ndest)++;
+ return 0;
+}
+
+static void save_opt_list(size_t *ndest, const char ***dest,
+ QemuOpts *opts, const char *name)
+{
+ struct opt_list opt = {
+ name, ndest, dest,
+ };
+ qemu_opt_foreach(opts, save_opt_one, &opt, NULL);
+}
+
void smbios_entry_add(QemuOpts *opts, Error **errp)
{
const char *val;
@@ -1035,6 +1103,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
save_opt(&type4.asset, opts, "asset");
save_opt(&type4.part, opts, "part");
return;
+ case 11:
+ qemu_opts_validate(opts, qemu_smbios_type11_opts, &error_fatal);
+ save_opt_list(&type11.nvalues, &type11.values, opts, "value");
+ return;
case 17:
qemu_opts_validate(opts, qemu_smbios_type17_opts, &error_fatal);
save_opt(&type17.loc_pfx, opts, "loc_pfx");
diff --git a/hw/smbios/smbios_build.h b/hw/smbios/smbios_build.h
index 68b8b72e09..93b360d520 100644
--- a/hw/smbios/smbios_build.h
+++ b/hw/smbios/smbios_build.h
@@ -63,6 +63,18 @@ extern unsigned smbios_table_cnt;
} \
} while (0)
+#define SMBIOS_TABLE_SET_STR_LIST(tbl_type, value) \
+ do { \
+ int len = (value != NULL) ? strlen(value) + 1 : 0; \
+ if (len > 1) { \
+ smbios_tables = g_realloc(smbios_tables, \
+ smbios_tables_len + len); \
+ memcpy(smbios_tables + smbios_tables_len, value, len); \
+ smbios_tables_len += len; \
+ ++str_index; \
+ } \
+ } while (0)
+
#define SMBIOS_BUILD_TABLE_POST \
do { \
size_t term_cnt, t_size; \
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
index d60daba882..185e1a3920 100644
--- a/hw/ssi/mss-spi.c
+++ b/hw/ssi/mss-spi.c
@@ -35,7 +35,7 @@
if (MSS_SPI_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt "\n", __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/ssi/omap_spi.c b/hw/ssi/omap_spi.c
index 22034656b8..34163e5646 100644
--- a/hw/ssi/omap_spi.c
+++ b/hw/ssi/omap_spi.c
@@ -295,10 +295,10 @@ static void omap_mcspi_write(void *opaque, hwaddr addr,
if ((value ^ s->ch[ch].config) & (3 << 14)) /* DMAR | DMAW */
omap_mcspi_dmarequest_update(s->ch + ch);
if (((value >> 12) & 3) == 3) /* TRM */
- fprintf(stderr, "%s: invalid TRM value (3)\n", __FUNCTION__);
+ fprintf(stderr, "%s: invalid TRM value (3)\n", __func__);
if (((value >> 7) & 0x1f) < 3) /* WL */
fprintf(stderr, "%s: invalid WL value (%" PRIx64 ")\n",
- __FUNCTION__, (value >> 7) & 0x1f);
+ __func__, (value >> 7) & 0x1f);
s->ch[ch].config = value & 0x7fffff;
break;
@@ -367,7 +367,7 @@ void omap_mcspi_attach(struct omap_mcspi_s *s,
int chipselect)
{
if (chipselect < 0 || chipselect >= s->chnum)
- hw_error("%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
+ hw_error("%s: Bad chipselect %i\n", __func__, chipselect);
s->ch[chipselect].txrx = txrx;
s->ch[chipselect].opaque = opaque;
diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c
index 26a1b4ddf5..69514da9fb 100644
--- a/hw/ssi/stm32f2xx_spi.c
+++ b/hw/ssi/stm32f2xx_spi.c
@@ -35,7 +35,7 @@
if (STM_SPI_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c
index 33482f04de..83585bc8b2 100644
--- a/hw/ssi/xilinx_spi.c
+++ b/hw/ssi/xilinx_spi.c
@@ -36,7 +36,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
- } while (0);
+ } while (0)
#else
#define DB_PRINT(...)
#endif
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index d8187fadd1..85c5d0cb92 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -43,7 +43,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/* config register */
#define R_CONFIG (0x00 / 4)
diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c
index ce1dc63911..96d534d8a8 100644
--- a/hw/timer/a9gtimer.c
+++ b/hw/timer/a9gtimer.c
@@ -37,7 +37,7 @@
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(...) DB_PRINT_L(0, ## __VA_ARGS__)
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
index 5e65fdb5a0..10056407ab 100644
--- a/hw/timer/cadence_ttc.c
+++ b/hw/timer/cadence_ttc.c
@@ -24,7 +24,7 @@
#define DB_PRINT(...) do { \
fprintf(stderr, ": %s: ", __func__); \
fprintf(stderr, ## __VA_ARGS__); \
- } while (0);
+ } while (0)
#else
#define DB_PRINT(...)
#endif
diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index 577371bc6d..d97436bc7b 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -70,6 +70,7 @@ typedef struct HPETState {
MemoryRegion iomem;
uint64_t hpet_offset;
+ bool hpet_offset_saved;
qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
uint32_t flags;
uint8_t rtc_irq_level;
@@ -221,7 +222,9 @@ static int hpet_pre_save(void *opaque)
HPETState *s = opaque;
/* save current counter value */
- s->hpet_counter = hpet_get_ticks(s);
+ if (hpet_enabled(s)) {
+ s->hpet_counter = hpet_get_ticks(s);
+ }
return 0;
}
@@ -252,7 +255,10 @@ static int hpet_post_load(void *opaque, int version_id)
HPETState *s = opaque;
/* Recalculate the offset between the main counter and guest time */
- s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ if (!s->hpet_offset_saved) {
+ s->hpet_offset = ticks_to_ns(s->hpet_counter)
+ - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ }
/* Push number of timers into capability returned via HPET_ID */
s->capability &= ~HPET_ID_NUM_TIM_MASK;
@@ -267,6 +273,13 @@ static int hpet_post_load(void *opaque, int version_id)
return 0;
}
+static bool hpet_offset_needed(void *opaque)
+{
+ HPETState *s = opaque;
+
+ return hpet_enabled(s) && s->hpet_offset_saved;
+}
+
static bool hpet_rtc_irq_level_needed(void *opaque)
{
HPETState *s = opaque;
@@ -285,6 +298,17 @@ static const VMStateDescription vmstate_hpet_rtc_irq_level = {
}
};
+static const VMStateDescription vmstate_hpet_offset = {
+ .name = "hpet/offset",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = hpet_offset_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(hpet_offset, HPETState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_hpet_timer = {
.name = "hpet_timer",
.version_id = 1,
@@ -320,6 +344,7 @@ static const VMStateDescription vmstate_hpet = {
},
.subsections = (const VMStateDescription*[]) {
&vmstate_hpet_rtc_irq_level,
+ &vmstate_hpet_offset,
NULL
}
};
@@ -762,6 +787,7 @@ static Property hpet_device_properties[] = {
DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
DEFINE_PROP_UINT32(HPET_INTCAP, HPETState, intcap, 0),
+ DEFINE_PROP_BOOL("hpet-offset-saved", HPETState, hpet_offset_saved, true),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
index 60f1213a3b..4f814572e2 100644
--- a/hw/timer/mss-timer.c
+++ b/hw/timer/mss-timer.c
@@ -36,7 +36,7 @@
if (MSS_TIMER_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt "\n", __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c
index 6d7c8a396f..ae2dc99832 100644
--- a/hw/timer/omap_gptimer.c
+++ b/hw/timer/omap_gptimer.c
@@ -357,7 +357,7 @@ static void omap_gp_timer_write(void *opaque, hwaddr addr,
s->config = value & 0x33d;
if (((value >> 3) & 3) == 3) /* IDLEMODE */
fprintf(stderr, "%s: illegal IDLEMODE value in TIOCP_CFG\n",
- __FUNCTION__);
+ __func__);
if (value & 2) /* SOFTRESET */
omap_gp_timer_reset(s);
break;
@@ -395,10 +395,10 @@ static void omap_gp_timer_write(void *opaque, hwaddr addr,
s->st = (value >> 0) & 1;
if (s->inout && s->trigger != gpt_trigger_none)
fprintf(stderr, "%s: GP timer pin must be an output "
- "for this trigger mode\n", __FUNCTION__);
+ "for this trigger mode\n", __func__);
if (!s->inout && s->capture != gpt_capture_none)
fprintf(stderr, "%s: GP timer pin must be an input "
- "for this capture mode\n", __FUNCTION__);
+ "for this capture mode\n", __func__);
if (s->trigger == gpt_trigger_none)
omap_gp_timer_out(s, s->scpwm);
/* TODO: make sure this doesn't overflow 32-bits */
diff --git a/hw/timer/stm32f2xx_timer.c b/hw/timer/stm32f2xx_timer.c
index e5f5e14a90..58fc7b1188 100644
--- a/hw/timer/stm32f2xx_timer.c
+++ b/hw/timer/stm32f2xx_timer.c
@@ -34,7 +34,7 @@
if (STM_TIMER_ERR_DEBUG >= lvl) { \
qemu_log("%s: " fmt, __func__, ## args); \
} \
-} while (0);
+} while (0)
#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
diff --git a/hw/timer/twl92230.c b/hw/timer/twl92230.c
index eb58c378e0..ef116c636c 100644
--- a/hw/timer/twl92230.c
+++ b/hw/timer/twl92230.c
@@ -403,7 +403,7 @@ static uint8_t menelaus_read(void *opaque, uint8_t addr)
default:
#ifdef VERBOSE
- printf("%s: unknown register %02x\n", __FUNCTION__, addr);
+ printf("%s: unknown register %02x\n", __func__, addr);
#endif
break;
}
@@ -615,7 +615,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
rtc_badness:
default:
fprintf(stderr, "%s: bad RTC_UPDATE value %02x\n",
- __FUNCTION__, value);
+ __func__, value);
s->status |= 1 << 10; /* RTCERR */
menelaus_update(s);
}
@@ -708,7 +708,7 @@ static void menelaus_write(void *opaque, uint8_t addr, uint8_t value)
default:
#ifdef VERBOSE
- printf("%s: unknown register %02x\n", __FUNCTION__, addr);
+ printf("%s: unknown register %02x\n", __func__, addr);
#endif
}
}
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 149fae63e6..29142f38bb 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -38,7 +38,7 @@
if (DEBUG_TPM) { \
fprintf(stderr, fmt, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
#define TYPE_TPM_PASSTHROUGH "tpm-passthrough"
#define TPM_PASSTHROUGH(obj) \
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 561384cd86..8b5eb01a2c 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -90,7 +90,7 @@ typedef struct TPMState {
if (DEBUG_TIS) { \
printf(fmt, ## __VA_ARGS__); \
} \
-} while (0);
+} while (0)
/* tis registers */
#define TPM_TIS_REG_ACCESS 0x00
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index c36bf30e4f..85c15addc5 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -688,7 +688,7 @@ int usb_desc_get_descriptor(USBDevice *dev, USBPacket *p,
break;
default:
- fprintf(stderr, "%s: %d unknown type %d (len %zd)\n", __FUNCTION__,
+ fprintf(stderr, "%s: %d unknown type %d (len %zd)\n", __func__,
dev->addr, type, len);
break;
}
diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
index 443e3c301d..0bbceaea0b 100644
--- a/hw/usb/dev-bluetooth.c
+++ b/hw/usb/dev-bluetooth.c
@@ -274,13 +274,13 @@ static void usb_bt_fifo_enqueue(struct usb_hci_in_fifo_s *fifo,
if (off <= DFIFO_LEN_MASK) {
if (off + len > DFIFO_LEN_MASK + 1 &&
(fifo->dsize = off + len) > (DFIFO_LEN_MASK + 1) * 2) {
- fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
+ fprintf(stderr, "%s: can't alloc %i bytes\n", __func__, len);
exit(-1);
}
buf = fifo->data + off;
} else {
if (fifo->dlen > fifo->dsize) {
- fprintf(stderr, "%s: can't alloc %i bytes\n", __FUNCTION__, len);
+ fprintf(stderr, "%s: can't alloc %i bytes\n", __func__, len);
exit(-1);
}
buf = fifo->data + off - fifo->dsize;
diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c
index 27d9d0bd82..d70a91a58c 100644
--- a/hw/usb/hcd-musb.c
+++ b/hw/usb/hcd-musb.c
@@ -253,8 +253,8 @@
/* #define MUSB_DEBUG */
#ifdef MUSB_DEBUG
-#define TRACE(fmt,...) fprintf(stderr, "%s@%d: " fmt "\n", __FUNCTION__, \
- __LINE__, ##__VA_ARGS__)
+#define TRACE(fmt, ...) fprintf(stderr, "%s@%d: " fmt "\n", __func__, \
+ __LINE__, ##__VA_ARGS__)
#else
#define TRACE(...)
#endif
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index af3a9d88de..228e82b3fb 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3416,7 +3416,7 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
&xhci->mem);
- if (pci_bus_is_express(dev->bus) ||
+ if (pci_bus_is_express(pci_get_bus(dev)) ||
xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) {
ret = pcie_endpoint_cap_init(dev, 0xa0);
assert(ret > 0);
diff --git a/hw/usb/tusb6010.c b/hw/usb/tusb6010.c
index 8f593a6fdb..2662c060ed 100644
--- a/hw/usb/tusb6010.c
+++ b/hw/usb/tusb6010.c
@@ -296,7 +296,7 @@ static uint32_t tusb_async_readb(void *opaque, hwaddr addr)
}
printf("%s: unknown register at %03x\n",
- __FUNCTION__, (int) (addr & 0xfff));
+ __func__, (int) (addr & 0xfff));
return 0;
}
@@ -313,7 +313,7 @@ static uint32_t tusb_async_readh(void *opaque, hwaddr addr)
}
printf("%s: unknown register at %03x\n",
- __FUNCTION__, (int) (addr & 0xfff));
+ __func__, (int) (addr & 0xfff));
return 0;
}
@@ -436,7 +436,7 @@ static uint32_t tusb_async_readw(void *opaque, hwaddr addr)
return 0x54059adf;
}
- printf("%s: unknown register at %03x\n", __FUNCTION__, offset);
+ printf("%s: unknown register at %03x\n", __func__, offset);
return 0;
}
@@ -456,7 +456,7 @@ static void tusb_async_writeb(void *opaque, hwaddr addr,
default:
printf("%s: unknown register at %03x\n",
- __FUNCTION__, (int) (addr & 0xfff));
+ __func__, (int) (addr & 0xfff));
return;
}
}
@@ -477,7 +477,7 @@ static void tusb_async_writeh(void *opaque, hwaddr addr,
default:
printf("%s: unknown register at %03x\n",
- __FUNCTION__, (int) (addr & 0xfff));
+ __func__, (int) (addr & 0xfff));
return;
}
}
@@ -505,7 +505,7 @@ static void tusb_async_writew(void *opaque, hwaddr addr,
s->dev_config = value;
s->host_mode = (value & TUSB_DEV_CONF_USB_HOST_MODE);
if (value & TUSB_DEV_CONF_PROD_TEST_MODE)
- hw_error("%s: Product Test mode not allowed\n", __FUNCTION__);
+ hw_error("%s: Product Test mode not allowed\n", __func__);
break;
case TUSB_PHY_OTG_CTRL_ENABLE:
@@ -636,7 +636,7 @@ static void tusb_async_writew(void *opaque, hwaddr addr,
break;
default:
- printf("%s: unknown register at %03x\n", __FUNCTION__, offset);
+ printf("%s: unknown register at %03x\n", __func__, offset);
return;
}
}
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index c977ee327f..2c71295125 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1654,8 +1654,8 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
return -EINVAL;
}
- if (!pci_bus_is_express(vdev->pdev.bus)) {
- PCIBus *bus = vdev->pdev.bus;
+ if (!pci_bus_is_express(pci_get_bus(&vdev->pdev))) {
+ PCIBus *bus = pci_get_bus(&vdev->pdev);
PCIDevice *bridge;
/*
@@ -1680,14 +1680,14 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
*/
while (!pci_bus_is_root(bus)) {
bridge = pci_bridge_get_device(bus);
- bus = bridge->bus;
+ bus = pci_get_bus(bridge);
}
if (pci_bus_is_express(bus)) {
return 0;
}
- } else if (pci_bus_is_root(vdev->pdev.bus)) {
+ } else if (pci_bus_is_root(pci_get_bus(&vdev->pdev))) {
/*
* On a Root Complex bus Endpoints become Root Complex Integrated
* Endpoints, which changes the type and clears the LNK & LNK2 fields.
@@ -1890,7 +1890,7 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
uint8_t *config;
/* Only add extended caps if we have them and the guest can see them */
- if (!pci_is_express(pdev) || !pci_bus_is_express(pdev->bus) ||
+ if (!pci_is_express(pdev) || !pci_bus_is_express(pci_get_bus(pdev)) ||
!pci_get_long(pdev->config + PCI_CONFIG_SPACE_SIZE)) {
return;
}
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 093675ed98..6eb97980ad 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -26,6 +26,11 @@
#define VHOST_MEMORY_MAX_NREGIONS 8
#define VHOST_USER_F_PROTOCOL_FEATURES 30
+/*
+ * Maximum size of virtio device config space
+ */
+#define VHOST_USER_MAX_CONFIG_SIZE 256
+
enum VhostUserProtocolFeature {
VHOST_USER_PROTOCOL_F_MQ = 0,
VHOST_USER_PROTOCOL_F_LOG_SHMFD = 1,
@@ -65,12 +70,15 @@ typedef enum VhostUserRequest {
VHOST_USER_SET_SLAVE_REQ_FD = 21,
VHOST_USER_IOTLB_MSG = 22,
VHOST_USER_SET_VRING_ENDIAN = 23,
+ VHOST_USER_GET_CONFIG = 24,
+ VHOST_USER_SET_CONFIG = 25,
VHOST_USER_MAX
} VhostUserRequest;
typedef enum VhostUserSlaveRequest {
VHOST_USER_SLAVE_NONE = 0,
VHOST_USER_SLAVE_IOTLB_MSG = 1,
+ VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2,
VHOST_USER_SLAVE_MAX
} VhostUserSlaveRequest;
@@ -92,7 +100,19 @@ typedef struct VhostUserLog {
uint64_t mmap_offset;
} VhostUserLog;
-typedef struct VhostUserMsg {
+typedef struct VhostUserConfig {
+ uint32_t offset;
+ uint32_t size;
+ uint32_t flags;
+ uint8_t region[VHOST_USER_MAX_CONFIG_SIZE];
+} VhostUserConfig;
+
+static VhostUserConfig c __attribute__ ((unused));
+#define VHOST_USER_CONFIG_HDR_SIZE (sizeof(c.offset) \
+ + sizeof(c.size) \
+ + sizeof(c.flags))
+
+typedef struct {
VhostUserRequest request;
#define VHOST_USER_VERSION_MASK (0x3)
@@ -100,7 +120,9 @@ typedef struct VhostUserMsg {
#define VHOST_USER_NEED_REPLY_MASK (0x1 << 3)
uint32_t flags;
uint32_t size; /* the following payload size */
- union {
+} QEMU_PACKED VhostUserHeader;
+
+typedef union {
#define VHOST_USER_VRING_IDX_MASK (0xff)
#define VHOST_USER_VRING_NOFD_MASK (0x1<<8)
uint64_t u64;
@@ -109,15 +131,18 @@ typedef struct VhostUserMsg {
VhostUserMemory memory;
VhostUserLog log;
struct vhost_iotlb_msg iotlb;
- } payload;
+ VhostUserConfig config;
+} VhostUserPayload;
+
+typedef struct VhostUserMsg {
+ VhostUserHeader hdr;
+ VhostUserPayload payload;
} QEMU_PACKED VhostUserMsg;
static VhostUserMsg m __attribute__ ((unused));
-#define VHOST_USER_HDR_SIZE (sizeof(m.request) \
- + sizeof(m.flags) \
- + sizeof(m.size))
+#define VHOST_USER_HDR_SIZE (sizeof(VhostUserHeader))
-#define VHOST_USER_PAYLOAD_SIZE (sizeof(m) - VHOST_USER_HDR_SIZE)
+#define VHOST_USER_PAYLOAD_SIZE (sizeof(VhostUserPayload))
/* The version of the protocol we support */
#define VHOST_USER_VERSION (0x1)
@@ -142,33 +167,33 @@ static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
r = qemu_chr_fe_read_all(chr, p, size);
if (r != size) {
error_report("Failed to read msg header. Read %d instead of %d."
- " Original request %d.", r, size, msg->request);
+ " Original request %d.", r, size, msg->hdr.request);
goto fail;
}
/* validate received flags */
- if (msg->flags != (VHOST_USER_REPLY_MASK | VHOST_USER_VERSION)) {
+ if (msg->hdr.flags != (VHOST_USER_REPLY_MASK | VHOST_USER_VERSION)) {
error_report("Failed to read msg header."
- " Flags 0x%x instead of 0x%x.", msg->flags,
+ " Flags 0x%x instead of 0x%x.", msg->hdr.flags,
VHOST_USER_REPLY_MASK | VHOST_USER_VERSION);
goto fail;
}
/* validate message size is sane */
- if (msg->size > VHOST_USER_PAYLOAD_SIZE) {
+ if (msg->hdr.size > VHOST_USER_PAYLOAD_SIZE) {
error_report("Failed to read msg header."
- " Size %d exceeds the maximum %zu.", msg->size,
+ " Size %d exceeds the maximum %zu.", msg->hdr.size,
VHOST_USER_PAYLOAD_SIZE);
goto fail;
}
- if (msg->size) {
+ if (msg->hdr.size) {
p += VHOST_USER_HDR_SIZE;
- size = msg->size;
+ size = msg->hdr.size;
r = qemu_chr_fe_read_all(chr, p, size);
if (r != size) {
error_report("Failed to read msg payload."
- " Read %d instead of %d.", r, msg->size);
+ " Read %d instead of %d.", r, msg->hdr.size);
goto fail;
}
}
@@ -184,7 +209,7 @@ static int process_message_reply(struct vhost_dev *dev,
{
VhostUserMsg msg_reply;
- if ((msg->flags & VHOST_USER_NEED_REPLY_MASK) == 0) {
+ if ((msg->hdr.flags & VHOST_USER_NEED_REPLY_MASK) == 0) {
return 0;
}
@@ -192,10 +217,10 @@ static int process_message_reply(struct vhost_dev *dev,
return -1;
}
- if (msg_reply.request != msg->request) {
+ if (msg_reply.hdr.request != msg->hdr.request) {
error_report("Received unexpected msg type."
"Expected %d received %d",
- msg->request, msg_reply.request);
+ msg->hdr.request, msg_reply.hdr.request);
return -1;
}
@@ -222,15 +247,15 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
{
struct vhost_user *u = dev->opaque;
CharBackend *chr = u->chr;
- int ret, size = VHOST_USER_HDR_SIZE + msg->size;
+ int ret, size = VHOST_USER_HDR_SIZE + msg->hdr.size;
/*
* For non-vring specific requests, like VHOST_USER_SET_MEM_TABLE,
* we just need send it once in the first time. For later such
* request, we just ignore it.
*/
- if (vhost_user_one_time_request(msg->request) && dev->vq_index != 0) {
- msg->flags &= ~VHOST_USER_NEED_REPLY_MASK;
+ if (vhost_user_one_time_request(msg->hdr.request) && dev->vq_index != 0) {
+ msg->hdr.flags &= ~VHOST_USER_NEED_REPLY_MASK;
return 0;
}
@@ -257,11 +282,11 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
bool shmfd = virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_LOG_SHMFD);
VhostUserMsg msg = {
- .request = VHOST_USER_SET_LOG_BASE,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = VHOST_USER_SET_LOG_BASE,
+ .hdr.flags = VHOST_USER_VERSION,
.payload.log.mmap_size = log->size * sizeof(*(log->log)),
.payload.log.mmap_offset = 0,
- .size = sizeof(msg.payload.log),
+ .hdr.size = sizeof(msg.payload.log),
};
if (shmfd && log->fd != -1) {
@@ -273,15 +298,15 @@ static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
}
if (shmfd) {
- msg.size = 0;
+ msg.hdr.size = 0;
if (vhost_user_read(dev, &msg) < 0) {
return -1;
}
- if (msg.request != VHOST_USER_SET_LOG_BASE) {
+ if (msg.hdr.request != VHOST_USER_SET_LOG_BASE) {
error_report("Received unexpected msg type. "
"Expected %d received %d",
- VHOST_USER_SET_LOG_BASE, msg.request);
+ VHOST_USER_SET_LOG_BASE, msg.hdr.request);
return -1;
}
}
@@ -299,12 +324,12 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
VHOST_USER_PROTOCOL_F_REPLY_ACK);
VhostUserMsg msg = {
- .request = VHOST_USER_SET_MEM_TABLE,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = VHOST_USER_SET_MEM_TABLE,
+ .hdr.flags = VHOST_USER_VERSION,
};
if (reply_supported) {
- msg.flags |= VHOST_USER_NEED_REPLY_MASK;
+ msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
}
for (i = 0; i < dev->mem->nregions; ++i) {
@@ -317,11 +342,14 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
&offset);
fd = memory_region_get_fd(mr);
if (fd > 0) {
+ if (fd_num == VHOST_MEMORY_MAX_NREGIONS) {
+ error_report("Failed preparing vhost-user memory table msg");
+ return -1;
+ }
msg.payload.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
msg.payload.memory.regions[fd_num].memory_size = reg->memory_size;
msg.payload.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
msg.payload.memory.regions[fd_num].mmap_offset = offset;
- assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
fds[fd_num++] = fd;
}
}
@@ -334,9 +362,9 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
return -1;
}
- msg.size = sizeof(msg.payload.memory.nregions);
- msg.size += sizeof(msg.payload.memory.padding);
- msg.size += fd_num * sizeof(VhostUserMemoryRegion);
+ msg.hdr.size = sizeof(msg.payload.memory.nregions);
+ msg.hdr.size += sizeof(msg.payload.memory.padding);
+ msg.hdr.size += fd_num * sizeof(VhostUserMemoryRegion);
if (vhost_user_write(dev, &msg, fds, fd_num) < 0) {
return -1;
@@ -353,10 +381,10 @@ static int vhost_user_set_vring_addr(struct vhost_dev *dev,
struct vhost_vring_addr *addr)
{
VhostUserMsg msg = {
- .request = VHOST_USER_SET_VRING_ADDR,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = VHOST_USER_SET_VRING_ADDR,
+ .hdr.flags = VHOST_USER_VERSION,
.payload.addr = *addr,
- .size = sizeof(msg.payload.addr),
+ .hdr.size = sizeof(msg.payload.addr),
};
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
@@ -372,10 +400,10 @@ static int vhost_user_set_vring_endian(struct vhost_dev *dev,
bool cross_endian = virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_CROSS_ENDIAN);
VhostUserMsg msg = {
- .request = VHOST_USER_SET_VRING_ENDIAN,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = VHOST_USER_SET_VRING_ENDIAN,
+ .hdr.flags = VHOST_USER_VERSION,
.payload.state = *ring,
- .size = sizeof(msg.payload.state),
+ .hdr.size = sizeof(msg.payload.state),
};
if (!cross_endian) {
@@ -395,10 +423,10 @@ static int vhost_set_vring(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
VhostUserMsg msg = {
- .request = request,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = request,
+ .hdr.flags = VHOST_USER_VERSION,
.payload.state = *ring,
- .size = sizeof(msg.payload.state),
+ .hdr.size = sizeof(msg.payload.state),
};
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
@@ -444,10 +472,10 @@ static int vhost_user_get_vring_base(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
VhostUserMsg msg = {
- .request = VHOST_USER_GET_VRING_BASE,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = VHOST_USER_GET_VRING_BASE,
+ .hdr.flags = VHOST_USER_VERSION,
.payload.state = *ring,
- .size = sizeof(msg.payload.state),
+ .hdr.size = sizeof(msg.payload.state),
};
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
@@ -458,13 +486,13 @@ static int vhost_user_get_vring_base(struct vhost_dev *dev,
return -1;
}
- if (msg.request != VHOST_USER_GET_VRING_BASE) {
+ if (msg.hdr.request != VHOST_USER_GET_VRING_BASE) {
error_report("Received unexpected msg type. Expected %d received %d",
- VHOST_USER_GET_VRING_BASE, msg.request);
+ VHOST_USER_GET_VRING_BASE, msg.hdr.request);
return -1;
}
- if (msg.size != sizeof(msg.payload.state)) {
+ if (msg.hdr.size != sizeof(msg.payload.state)) {
error_report("Received bad msg size.");
return -1;
}
@@ -481,10 +509,10 @@ static int vhost_set_vring_file(struct vhost_dev *dev,
int fds[VHOST_MEMORY_MAX_NREGIONS];
size_t fd_num = 0;
VhostUserMsg msg = {
- .request = request,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = request,
+ .hdr.flags = VHOST_USER_VERSION,
.payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK,
- .size = sizeof(msg.payload.u64),
+ .hdr.size = sizeof(msg.payload.u64),
};
if (ioeventfd_enabled() && file->fd > 0) {
@@ -515,10 +543,10 @@ static int vhost_user_set_vring_call(struct vhost_dev *dev,
static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64)
{
VhostUserMsg msg = {
- .request = request,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = request,
+ .hdr.flags = VHOST_USER_VERSION,
.payload.u64 = u64,
- .size = sizeof(msg.payload.u64),
+ .hdr.size = sizeof(msg.payload.u64),
};
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
@@ -543,8 +571,8 @@ static int vhost_user_set_protocol_features(struct vhost_dev *dev,
static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64)
{
VhostUserMsg msg = {
- .request = request,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = request,
+ .hdr.flags = VHOST_USER_VERSION,
};
if (vhost_user_one_time_request(request) && dev->vq_index != 0) {
@@ -559,13 +587,13 @@ static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64)
return -1;
}
- if (msg.request != request) {
+ if (msg.hdr.request != request) {
error_report("Received unexpected msg type. Expected %d received %d",
- request, msg.request);
+ request, msg.hdr.request);
return -1;
}
- if (msg.size != sizeof(msg.payload.u64)) {
+ if (msg.hdr.size != sizeof(msg.payload.u64)) {
error_report("Received bad msg size.");
return -1;
}
@@ -583,8 +611,8 @@ static int vhost_user_get_features(struct vhost_dev *dev, uint64_t *features)
static int vhost_user_set_owner(struct vhost_dev *dev)
{
VhostUserMsg msg = {
- .request = VHOST_USER_SET_OWNER,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = VHOST_USER_SET_OWNER,
+ .hdr.flags = VHOST_USER_VERSION,
};
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
@@ -597,8 +625,8 @@ static int vhost_user_set_owner(struct vhost_dev *dev)
static int vhost_user_reset_device(struct vhost_dev *dev)
{
VhostUserMsg msg = {
- .request = VHOST_USER_RESET_OWNER,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = VHOST_USER_RESET_OWNER,
+ .hdr.flags = VHOST_USER_VERSION,
};
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
@@ -608,37 +636,56 @@ static int vhost_user_reset_device(struct vhost_dev *dev)
return 0;
}
+static int vhost_user_slave_handle_config_change(struct vhost_dev *dev)
+{
+ int ret = -1;
+
+ if (!dev->config_ops) {
+ return -1;
+ }
+
+ if (dev->config_ops->vhost_dev_config_notifier) {
+ ret = dev->config_ops->vhost_dev_config_notifier(dev);
+ }
+
+ return ret;
+}
+
static void slave_read(void *opaque)
{
struct vhost_dev *dev = opaque;
struct vhost_user *u = dev->opaque;
- VhostUserMsg msg = { 0, };
+ VhostUserHeader hdr = { 0, };
+ VhostUserPayload payload = { 0, };
int size, ret = 0;
/* Read header */
- size = read(u->slave_fd, &msg, VHOST_USER_HDR_SIZE);
+ size = read(u->slave_fd, &hdr, VHOST_USER_HDR_SIZE);
if (size != VHOST_USER_HDR_SIZE) {
error_report("Failed to read from slave.");
goto err;
}
- if (msg.size > VHOST_USER_PAYLOAD_SIZE) {
+ if (hdr.size > VHOST_USER_PAYLOAD_SIZE) {
error_report("Failed to read msg header."
- " Size %d exceeds the maximum %zu.", msg.size,
+ " Size %d exceeds the maximum %zu.", hdr.size,
VHOST_USER_PAYLOAD_SIZE);
goto err;
}
/* Read payload */
- size = read(u->slave_fd, &msg.payload, msg.size);
- if (size != msg.size) {
+ size = read(u->slave_fd, &payload, hdr.size);
+ if (size != hdr.size) {
error_report("Failed to read payload from slave.");
goto err;
}
- switch (msg.request) {
+ switch (hdr.request) {
case VHOST_USER_SLAVE_IOTLB_MSG:
- ret = vhost_backend_handle_iotlb_msg(dev, &msg.payload.iotlb);
+ ret = vhost_backend_handle_iotlb_msg(dev, &payload.iotlb);
+ break;
+ case VHOST_USER_SLAVE_CONFIG_CHANGE_MSG :
+ ret = vhost_user_slave_handle_config_change(dev);
break;
default:
error_report("Received unexpected msg type.");
@@ -649,15 +696,23 @@ static void slave_read(void *opaque)
* REPLY_ACK feature handling. Other reply types has to be managed
* directly in their request handlers.
*/
- if (msg.flags & VHOST_USER_NEED_REPLY_MASK) {
- msg.flags &= ~VHOST_USER_NEED_REPLY_MASK;
- msg.flags |= VHOST_USER_REPLY_MASK;
+ if (hdr.flags & VHOST_USER_NEED_REPLY_MASK) {
+ struct iovec iovec[2];
+
+
+ hdr.flags &= ~VHOST_USER_NEED_REPLY_MASK;
+ hdr.flags |= VHOST_USER_REPLY_MASK;
+
+ payload.u64 = !!ret;
+ hdr.size = sizeof(payload.u64);
- msg.payload.u64 = !!ret;
- msg.size = sizeof(msg.payload.u64);
+ iovec[0].iov_base = &hdr;
+ iovec[0].iov_len = VHOST_USER_HDR_SIZE;
+ iovec[1].iov_base = &payload;
+ iovec[1].iov_len = hdr.size;
- size = write(u->slave_fd, &msg, VHOST_USER_HDR_SIZE + msg.size);
- if (size != VHOST_USER_HDR_SIZE + msg.size) {
+ size = writev(u->slave_fd, iovec, ARRAY_SIZE(iovec));
+ if (size != VHOST_USER_HDR_SIZE + hdr.size) {
error_report("Failed to send msg reply to slave.");
goto err;
}
@@ -675,8 +730,8 @@ err:
static int vhost_setup_slave_channel(struct vhost_dev *dev)
{
VhostUserMsg msg = {
- .request = VHOST_USER_SET_SLAVE_REQ_FD,
- .flags = VHOST_USER_VERSION,
+ .hdr.request = VHOST_USER_SET_SLAVE_REQ_FD,
+ .hdr.flags = VHOST_USER_VERSION,
};
struct vhost_user *u = dev->opaque;
int sv[2], ret = 0;
@@ -697,7 +752,7 @@ static int vhost_setup_slave_channel(struct vhost_dev *dev)
qemu_set_fd_handler(u->slave_fd, slave_read, NULL, dev);
if (reply_supported) {
- msg.flags |= VHOST_USER_NEED_REPLY_MASK;
+ msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
}
ret = vhost_user_write(dev, &msg, &sv[1], 1);
@@ -842,10 +897,10 @@ static int vhost_user_migration_done(struct vhost_dev *dev, char* mac_addr)
/* if backend supports VHOST_USER_PROTOCOL_F_RARP ask it to send the RARP */
if (virtio_has_feature(dev->protocol_features,
VHOST_USER_PROTOCOL_F_RARP)) {
- msg.request = VHOST_USER_SEND_RARP;
- msg.flags = VHOST_USER_VERSION;
+ msg.hdr.request = VHOST_USER_SEND_RARP;
+ msg.hdr.flags = VHOST_USER_VERSION;
memcpy((char *)&msg.payload.u64, mac_addr, 6);
- msg.size = sizeof(msg.payload.u64);
+ msg.hdr.size = sizeof(msg.payload.u64);
return vhost_user_write(dev, &msg, NULL, 0);
}
@@ -879,12 +934,12 @@ static int vhost_user_net_set_mtu(struct vhost_dev *dev, uint16_t mtu)
return 0;
}
- msg.request = VHOST_USER_NET_SET_MTU;
+ msg.hdr.request = VHOST_USER_NET_SET_MTU;
msg.payload.u64 = mtu;
- msg.size = sizeof(msg.payload.u64);
- msg.flags = VHOST_USER_VERSION;
+ msg.hdr.size = sizeof(msg.payload.u64);
+ msg.hdr.flags = VHOST_USER_VERSION;
if (reply_supported) {
- msg.flags |= VHOST_USER_NEED_REPLY_MASK;
+ msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
}
if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
@@ -903,9 +958,9 @@ static int vhost_user_send_device_iotlb_msg(struct vhost_dev *dev,
struct vhost_iotlb_msg *imsg)
{
VhostUserMsg msg = {
- .request = VHOST_USER_IOTLB_MSG,
- .size = sizeof(msg.payload.iotlb),
- .flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK,
+ .hdr.request = VHOST_USER_IOTLB_MSG,
+ .hdr.size = sizeof(msg.payload.iotlb),
+ .hdr.flags = VHOST_USER_VERSION | VHOST_USER_NEED_REPLY_MASK,
.payload.iotlb = *imsg,
};
@@ -922,6 +977,83 @@ static void vhost_user_set_iotlb_callback(struct vhost_dev *dev, int enabled)
/* No-op as the receive channel is not dedicated to IOTLB messages. */
}
+static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config,
+ uint32_t config_len)
+{
+ VhostUserMsg msg = {
+ .hdr.request = VHOST_USER_GET_CONFIG,
+ .hdr.flags = VHOST_USER_VERSION,
+ .hdr.size = VHOST_USER_CONFIG_HDR_SIZE + config_len,
+ };
+
+ if (config_len > VHOST_USER_MAX_CONFIG_SIZE) {
+ return -1;
+ }
+
+ msg.payload.config.offset = 0;
+ msg.payload.config.size = config_len;
+ if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
+ return -1;
+ }
+
+ if (vhost_user_read(dev, &msg) < 0) {
+ return -1;
+ }
+
+ if (msg.hdr.request != VHOST_USER_GET_CONFIG) {
+ error_report("Received unexpected msg type. Expected %d received %d",
+ VHOST_USER_GET_CONFIG, msg.hdr.request);
+ return -1;
+ }
+
+ if (msg.hdr.size != VHOST_USER_CONFIG_HDR_SIZE + config_len) {
+ error_report("Received bad msg size.");
+ return -1;
+ }
+
+ memcpy(config, msg.payload.config.region, config_len);
+
+ return 0;
+}
+
+static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data,
+ uint32_t offset, uint32_t size, uint32_t flags)
+{
+ uint8_t *p;
+ bool reply_supported = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_REPLY_ACK);
+
+ VhostUserMsg msg = {
+ .hdr.request = VHOST_USER_SET_CONFIG,
+ .hdr.flags = VHOST_USER_VERSION,
+ .hdr.size = VHOST_USER_CONFIG_HDR_SIZE + size,
+ };
+
+ if (reply_supported) {
+ msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
+ }
+
+ if (size > VHOST_USER_MAX_CONFIG_SIZE) {
+ return -1;
+ }
+
+ msg.payload.config.offset = offset,
+ msg.payload.config.size = size,
+ msg.payload.config.flags = flags,
+ p = msg.payload.config.region;
+ memcpy(p, data, size);
+
+ if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
+ return -1;
+ }
+
+ if (reply_supported) {
+ return process_message_reply(dev, &msg);
+ }
+
+ return 0;
+}
+
const VhostOps user_ops = {
.backend_type = VHOST_BACKEND_TYPE_USER,
.vhost_backend_init = vhost_user_init,
@@ -948,4 +1080,6 @@ const VhostOps user_ops = {
.vhost_net_set_mtu = vhost_user_net_set_mtu,
.vhost_set_iotlb_callback = vhost_user_set_iotlb_callback,
.vhost_send_device_iotlb_msg = vhost_user_send_device_iotlb_msg,
+ .vhost_get_config = vhost_user_get_config,
+ .vhost_set_config = vhost_user_set_config,
};
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index e4290ce93d..386aef85be 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1505,6 +1505,38 @@ void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
}
}
+int vhost_dev_get_config(struct vhost_dev *hdev, uint8_t *config,
+ uint32_t config_len)
+{
+ assert(hdev->vhost_ops);
+
+ if (hdev->vhost_ops->vhost_get_config) {
+ return hdev->vhost_ops->vhost_get_config(hdev, config, config_len);
+ }
+
+ return -1;
+}
+
+int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *data,
+ uint32_t offset, uint32_t size, uint32_t flags)
+{
+ assert(hdev->vhost_ops);
+
+ if (hdev->vhost_ops->vhost_set_config) {
+ return hdev->vhost_ops->vhost_set_config(hdev, data, offset,
+ size, flags);
+ }
+
+ return -1;
+}
+
+void vhost_dev_set_config_notifier(struct vhost_dev *hdev,
+ const VhostDevConfigOps *ops)
+{
+ assert(hdev->vhost_ops);
+ hdev->config_ops = ops;
+}
+
/* Host notifiers must be enabled at this point. */
int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
{
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index 3042232daf..8106346927 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -256,6 +256,15 @@ bool virtio_bus_ioeventfd_enabled(VirtioBusState *bus)
return k->ioeventfd_assign && k->ioeventfd_enabled(proxy);
}
+static void virtio_bus_cleanup_event_notifier(EventNotifier *notifier)
+{
+ /* Test and clear notifier after disabling event,
+ * in case poll callback didn't have time to run.
+ */
+ virtio_queue_host_notifier_read(notifier);
+ event_notifier_cleanup(notifier);
+}
+
/*
* This function switches ioeventfd on/off in the device.
* The caller must set or clear the handlers for the EventNotifier.
@@ -283,19 +292,13 @@ int virtio_bus_set_host_notifier(VirtioBusState *bus, int n, bool assign)
r = k->ioeventfd_assign(proxy, notifier, n, true);
if (r < 0) {
error_report("%s: unable to assign ioeventfd: %d", __func__, r);
- goto cleanup_event_notifier;
+ virtio_bus_cleanup_event_notifier(notifier);
}
- return 0;
} else {
+ notifier->cleanup = virtio_bus_cleanup_event_notifier;
k->ioeventfd_assign(proxy, notifier, n, false);
}
-cleanup_event_notifier:
- /* Test and clear notifier after disabling event,
- * in case poll callback didn't have time to run.
- */
- virtio_queue_host_notifier_read(notifier);
- event_notifier_cleanup(notifier);
return r;
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index e92837c42b..9ae10f0cdd 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1588,9 +1588,11 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
"neither legacy nor transitional device.");
return ;
}
- /* legacy and transitional */
- pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
- pci_get_word(config + PCI_VENDOR_ID));
+ /*
+ * Legacy and transitional devices use specific subsystem IDs.
+ * Note that the subsystem vendor ID (config + PCI_SUBSYSTEM_VENDOR_ID)
+ * is set to PCI_SUBVENDOR_ID_REDHAT_QUMRANET by default.
+ */
pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
} else {
/* pure virtio-1.0 */
@@ -1708,8 +1710,8 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
{
VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
- bool pcie_port = pci_bus_is_express(pci_dev->bus) &&
- !pci_bus_is_root(pci_dev->bus);
+ bool pcie_port = pci_bus_is_express(pci_get_bus(pci_dev)) &&
+ !pci_bus_is_root(pci_get_bus(pci_dev));
if (kvm_enabled() && !kvm_has_many_ioeventfds()) {
proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
@@ -1976,6 +1978,58 @@ static const TypeInfo virtio_blk_pci_info = {
.class_init = virtio_blk_pci_class_init,
};
+#if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX)
+/* vhost-user-blk */
+
+static Property vhost_user_blk_pci_properties[] = {
+ DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
+ DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vhost_user_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+ VHostUserBlkPCI *dev = VHOST_USER_BLK_PCI(vpci_dev);
+ DeviceState *vdev = DEVICE(&dev->vdev);
+
+ qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+ object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+}
+
+static void vhost_user_blk_pci_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+ PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ dc->props = vhost_user_blk_pci_properties;
+ k->realize = vhost_user_blk_pci_realize;
+ pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+ pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
+ pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+ pcidev_k->class_id = PCI_CLASS_STORAGE_SCSI;
+}
+
+static void vhost_user_blk_pci_instance_init(Object *obj)
+{
+ VHostUserBlkPCI *dev = VHOST_USER_BLK_PCI(obj);
+
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+ TYPE_VHOST_USER_BLK);
+ object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+ "bootindex", &error_abort);
+}
+
+static const TypeInfo vhost_user_blk_pci_info = {
+ .name = TYPE_VHOST_USER_BLK_PCI,
+ .parent = TYPE_VIRTIO_PCI,
+ .instance_size = sizeof(VHostUserBlkPCI),
+ .instance_init = vhost_user_blk_pci_instance_init,
+ .class_init = vhost_user_blk_pci_class_init,
+};
+#endif
+
/* virtio-scsi-pci */
static Property virtio_scsi_pci_properties[] = {
@@ -2622,6 +2676,9 @@ static void virtio_pci_register_types(void)
type_register_static(&virtio_9p_pci_info);
#endif
type_register_static(&virtio_blk_pci_info);
+#if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX)
+ type_register_static(&vhost_user_blk_pci_info);
+#endif
type_register_static(&virtio_scsi_pci_info);
type_register_static(&virtio_balloon_pci_info);
type_register_static(&virtio_serial_pci_info);
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 12d3a90686..813082b0d7 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -27,6 +27,9 @@
#include "hw/virtio/virtio-gpu.h"
#include "hw/virtio/virtio-crypto.h"
#include "hw/virtio/vhost-user-scsi.h"
+#if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX)
+#include "hw/virtio/vhost-user-blk.h"
+#endif
#ifdef CONFIG_VIRTFS
#include "hw/9pfs/virtio-9p.h"
@@ -46,6 +49,7 @@ typedef struct VirtIOSerialPCI VirtIOSerialPCI;
typedef struct VirtIONetPCI VirtIONetPCI;
typedef struct VHostSCSIPCI VHostSCSIPCI;
typedef struct VHostUserSCSIPCI VHostUserSCSIPCI;
+typedef struct VHostUserBlkPCI VHostUserBlkPCI;
typedef struct VirtIORngPCI VirtIORngPCI;
typedef struct VirtIOInputPCI VirtIOInputPCI;
typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI;
@@ -244,6 +248,20 @@ struct VHostUserSCSIPCI {
VHostUserSCSI vdev;
};
+#if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX)
+/*
+ * vhost-user-blk-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VHOST_USER_BLK_PCI "vhost-user-blk-pci"
+#define VHOST_USER_BLK_PCI(obj) \
+ OBJECT_CHECK(VHostUserBlkPCI, (obj), TYPE_VHOST_USER_BLK_PCI)
+
+struct VHostUserBlkPCI {
+ VirtIOPCIProxy parent_obj;
+ VHostUserBlk vdev;
+};
+#endif
+
/*
* virtio-blk-pci: This extends VirtioPCIProxy.
*/
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ad564b0132..3ac3491bee 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2469,7 +2469,7 @@ void GCC_FMT_ATTR(2, 3) virtio_error(VirtIODevice *vdev, const char *fmt, ...)
va_end(ap);
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
- virtio_set_status(vdev, vdev->status | VIRTIO_CONFIG_S_NEEDS_RESET);
+ vdev->status = vdev->status | VIRTIO_CONFIG_S_NEEDS_RESET;
virtio_notify_config(vdev);
}
@@ -2574,6 +2574,7 @@ static int virtio_device_start_ioeventfd_impl(VirtIODevice *vdev)
VirtioBusState *qbus = VIRTIO_BUS(qdev_get_parent_bus(DEVICE(vdev)));
int n, r, err;
+ memory_region_transaction_begin();
for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
VirtQueue *vq = &vdev->vq[n];
if (!virtio_queue_get_num(vdev, n)) {
@@ -2596,6 +2597,7 @@ static int virtio_device_start_ioeventfd_impl(VirtIODevice *vdev)
}
event_notifier_set(&vq->host_notifier);
}
+ memory_region_transaction_commit();
return 0;
assign_error:
@@ -2609,6 +2611,7 @@ assign_error:
r = virtio_bus_set_host_notifier(qbus, n, false);
assert(r >= 0);
}
+ memory_region_transaction_commit();
return err;
}
@@ -2625,6 +2628,7 @@ static void virtio_device_stop_ioeventfd_impl(VirtIODevice *vdev)
VirtioBusState *qbus = VIRTIO_BUS(qdev_get_parent_bus(DEVICE(vdev)));
int n, r;
+ memory_region_transaction_begin();
for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
VirtQueue *vq = &vdev->vq[n];
@@ -2635,6 +2639,7 @@ static void virtio_device_stop_ioeventfd_impl(VirtIODevice *vdev)
r = virtio_bus_set_host_notifier(qbus, n, false);
assert(r >= 0);
}
+ memory_region_transaction_commit();
}
void virtio_device_stop_ioeventfd(VirtIODevice *vdev)
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index 0f849a26d2..7445b506ac 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -564,7 +564,7 @@ static void xen_set_dynamic_sysbus(void)
ObjectClass *oc = object_get_class(machine);
MachineClass *mc = MACHINE_CLASS(oc);
- mc->has_dynamic_sysbus = true;
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_XENSYSDEV);
}
int xen_be_register(const char *type, struct XenDevOps *ops)
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index d57c6d3485..f662f30370 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -73,7 +73,7 @@ void xen_pt_log(const PCIDevice *d, const char *f, ...)
va_start(ap, f);
if (d) {
- fprintf(stderr, "[%02x:%02x.%d] ", pci_bus_num(d->bus),
+ fprintf(stderr, "[%02x:%02x.%d] ", pci_dev_bus_num(d),
PCI_SLOT(d->devfn), PCI_FUNC(d->devfn));
}
vfprintf(stderr, f, ap);
@@ -602,7 +602,7 @@ static void xen_pt_region_update(XenPCIPassthroughState *s,
}
args.type = d->io_regions[bar].type;
- pci_for_each_device(d->bus, pci_bus_num(d->bus),
+ pci_for_each_device(pci_get_bus(d), pci_dev_bus_num(d),
xen_pt_check_bar_overlap, &args);
if (args.rc) {
XEN_PT_WARN(d, "Region: %d (addr: %#"FMT_PCIBUS
@@ -695,7 +695,7 @@ xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s,
PCIDevice *d = &s->dev;
gpu_dev_id = dev->device_id;
- igd_passthrough_isa_bridge_create(d->bus, gpu_dev_id);
+ igd_passthrough_isa_bridge_create(pci_get_bus(d), gpu_dev_id);
}
/* destroy. */
@@ -711,7 +711,7 @@ static void xen_pt_destroy(PCIDevice *d) {
intx = xen_pt_pci_intx(s);
rc = xc_domain_unbind_pt_irq(xen_xc, xen_domid, machine_irq,
PT_IRQ_TYPE_PCI,
- pci_bus_num(d->bus),
+ pci_dev_bus_num(d),
PCI_SLOT(s->dev.devfn),
intx,
0 /* isa_irq */);
@@ -867,7 +867,7 @@ static void xen_pt_realize(PCIDevice *d, Error **errp)
uint8_t e_intx = xen_pt_pci_intx(s);
rc = xc_domain_bind_pt_pci_irq(xen_xc, xen_domid, machine_irq,
- pci_bus_num(d->bus),
+ pci_dev_bus_num(d),
PCI_SLOT(d->devfn),
e_intx);
if (rc < 0) {
diff --git a/hw/xenpv/xen_domainbuild.c b/hw/xenpv/xen_domainbuild.c
index c89ced2e88..027f76fad1 100644
--- a/hw/xenpv/xen_domainbuild.c
+++ b/hw/xenpv/xen_domainbuild.c
@@ -25,22 +25,22 @@ static int xenstore_domain_mkdir(char *path)
int i;
if (!xs_mkdir(xenstore, 0, path)) {
- fprintf(stderr, "%s: xs_mkdir %s: failed\n", __FUNCTION__, path);
+ fprintf(stderr, "%s: xs_mkdir %s: failed\n", __func__, path);
return -1;
}
if (!xs_set_permissions(xenstore, 0, path, perms_ro, 2)) {
- fprintf(stderr, "%s: xs_set_permissions failed\n", __FUNCTION__);
+ fprintf(stderr, "%s: xs_set_permissions failed\n", __func__);
return -1;
}
for (i = 0; writable[i]; i++) {
snprintf(subpath, sizeof(subpath), "%s/%s", path, writable[i]);
if (!xs_mkdir(xenstore, 0, subpath)) {
- fprintf(stderr, "%s: xs_mkdir %s: failed\n", __FUNCTION__, subpath);
+ fprintf(stderr, "%s: xs_mkdir %s: failed\n", __func__, subpath);
return -1;
}
if (!xs_set_permissions(xenstore, 0, subpath, perms_rw, 2)) {
- fprintf(stderr, "%s: xs_set_permissions failed\n", __FUNCTION__);
+ fprintf(stderr, "%s: xs_set_permissions failed\n", __func__);
return -1;
}
}
@@ -158,7 +158,7 @@ static int xen_domain_watcher(void)
char byte;
if (pipe(fd) != 0) {
- qemu_log("%s: Huh? pipe error: %s\n", __FUNCTION__, strerror(errno));
+ qemu_log("%s: Huh? pipe error: %s\n", __func__, strerror(errno));
return -1;
}
if (fork() != 0)
@@ -190,7 +190,7 @@ static int xen_domain_watcher(void)
case -1:
if (errno == EINTR)
continue;
- qemu_log("%s: Huh? read error: %s\n", __FUNCTION__, strerror(errno));
+ qemu_log("%s: Huh? read error: %s\n", __func__, strerror(errno));
qemu_running = 0;
break;
case 0:
@@ -198,13 +198,13 @@ static int xen_domain_watcher(void)
qemu_running = 0;
break;
default:
- qemu_log("%s: Huh? data on the watch pipe?\n", __FUNCTION__);
+ qemu_log("%s: Huh? data on the watch pipe?\n", __func__);
break;
}
}
/* cleanup */
- qemu_log("%s: destroy domain %d\n", __FUNCTION__, xen_domid);
+ qemu_log("%s: destroy domain %d\n", __func__, xen_domid);
xc_domain_destroy(xen_xc, xen_domid);
_exit(0);
}
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index 31d2f25627..69a52a9f93 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -36,7 +36,7 @@ static void xen_init_pv(MachineState *machine)
/* Initialize backend core & drivers */
if (xen_be_init() != 0) {
- fprintf(stderr, "%s: xen backend core setup failed\n", __FUNCTION__);
+ fprintf(stderr, "%s: xen backend core setup failed\n", __func__);
exit(1);
}