aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/alpha/typhoon.c3
-rw-r--r--hw/arm/armv7m.c28
-rw-r--r--hw/arm/mps2-tz.c32
-rw-r--r--hw/arm/smmuv3.c2
-rw-r--r--hw/arm/stellaris.c12
-rw-r--r--hw/block/m25p80.c1
-rw-r--r--hw/block/pflash_cfi02.c97
-rw-r--r--hw/char/parallel.c50
-rw-r--r--hw/core/or-irq.c39
-rw-r--r--hw/dma/rc4030.c2
-rw-r--r--hw/i386/amd_iommu.c2
-rw-r--r--hw/i386/intel_iommu.c8
-rw-r--r--hw/input/pckbd.c14
-rw-r--r--hw/intc/arm_gicv3_kvm.c18
-rw-r--r--hw/intc/armv7m_nvic.c6
-rw-r--r--hw/m68k/mcf5206.c48
-rw-r--r--hw/misc/aspeed_scu.c20
-rw-r--r--hw/ppc/spapr_iommu.c5
-rw-r--r--hw/s390x/s390-pci-bus.c2
-rw-r--r--hw/s390x/s390-pci-inst.c4
-rw-r--r--hw/sh4/sh7750.c44
-rw-r--r--hw/sparc/sun4m_iommu.c3
-rw-r--r--hw/sparc64/sun4u_iommu.c2
-rw-r--r--hw/vfio/common.c6
-rw-r--r--hw/virtio/vhost.c7
-rw-r--r--hw/watchdog/wdt_i6300esb.c48
26 files changed, 292 insertions, 211 deletions
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 6a40869488..d3ed7cdbe8 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -666,7 +666,8 @@ static bool window_translate(TyphoonWindow *win, hwaddr addr,
Pchip and generate a machine check interrupt. */
static IOMMUTLBEntry typhoon_translate_iommu(IOMMUMemoryRegion *iommu,
hwaddr addr,
- IOMMUAccessFlags flag)
+ IOMMUAccessFlags flag,
+ int iommu_idx)
{
TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu);
IOMMUTLBEntry ret;
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index f123cc7d3d..9e00d4037c 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -178,6 +178,12 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
return;
}
}
+
+ /* Tell the CPU where the NVIC is; it will fail realize if it doesn't
+ * have one.
+ */
+ s->cpu->env.nvic = &s->nvic;
+
object_property_set_bool(OBJECT(s->cpu), true, "realized", &err);
if (err != NULL) {
error_propagate(errp, err);
@@ -202,7 +208,6 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
sbd = SYS_BUS_DEVICE(&s->nvic);
sysbus_connect_irq(sbd, 0,
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
- s->cpu->env.nvic = &s->nvic;
memory_region_add_subregion(&s->container, 0xe000e000,
sysbus_mmio_get_region(sbd, 0));
@@ -261,27 +266,6 @@ static void armv7m_reset(void *opaque)
cpu_reset(CPU(cpu));
}
-/* Init CPU and memory for a v7-M based board.
- mem_size is in bytes.
- Returns the ARMv7M device. */
-
-DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
- const char *kernel_filename, const char *cpu_type)
-{
- DeviceState *armv7m;
-
- armv7m = qdev_create(NULL, TYPE_ARMV7M);
- qdev_prop_set_uint32(armv7m, "num-irq", num_irq);
- qdev_prop_set_string(armv7m, "cpu-type", cpu_type);
- object_property_set_link(OBJECT(armv7m), OBJECT(get_system_memory()),
- "memory", &error_abort);
- /* This will exit with an error if the user passed us a bad cpu_type */
- qdev_init_nofail(armv7m);
-
- armv7m_load_kernel(ARM_CPU(first_cpu), kernel_filename, mem_size);
- return armv7m;
-}
-
void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
{
int image_size;
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index 8dc8bfd4ab..c5ef95e4cc 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -74,12 +74,13 @@ typedef struct {
UnimplementedDeviceState spi[5];
UnimplementedDeviceState i2c[4];
UnimplementedDeviceState i2s_audio;
- UnimplementedDeviceState gpio[5];
+ UnimplementedDeviceState gpio[4];
UnimplementedDeviceState dma[4];
UnimplementedDeviceState gfx;
CMSDKAPBUART uart[5];
SplitIRQ sec_resp_splitter;
qemu_or_irq uart_irq_orgate;
+ DeviceState *lan9118;
} MPS2TZMachineState;
#define TYPE_MPS2TZ_MACHINE "mps2tz"
@@ -224,6 +225,26 @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
}
+static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
+ const char *name, hwaddr size)
+{
+ SysBusDevice *s;
+ DeviceState *iotkitdev = DEVICE(&mms->iotkit);
+ NICInfo *nd = &nd_table[0];
+
+ /* In hardware this is a LAN9220; the LAN9118 is software compatible
+ * except that it doesn't support the checksum-offload feature.
+ */
+ qemu_check_nic_model(nd, "lan9118");
+ mms->lan9118 = qdev_create(NULL, "lan9118");
+ qdev_set_nic_properties(mms->lan9118, nd);
+ qdev_init_nofail(mms->lan9118);
+
+ s = SYS_BUS_DEVICE(mms->lan9118);
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 16));
+ return sysbus_mmio_get_region(s, 0);
+}
+
static void mps2tz_common_init(MachineState *machine)
{
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
@@ -363,7 +384,7 @@ static void mps2tz_common_init(MachineState *machine)
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x40101000, 0x1000 },
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x40102000, 0x1000 },
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x40103000, 0x1000 },
- { "gpio4", make_unimp_dev, &mms->gpio[4], 0x40104000, 0x1000 },
+ { "eth", make_eth_dev, NULL, 0x42000000, 0x100000 },
},
}, {
.name = "ahb_ppcexp1",
@@ -447,13 +468,6 @@ static void mps2tz_common_init(MachineState *machine)
"cfg_sec_resp", 0));
}
- /* In hardware this is a LAN9220; the LAN9118 is software compatible
- * except that it doesn't support the checksum-offload feature.
- * The ethernet controller is not behind a PPC.
- */
- lan9118_init(&nd_table[0], 0x42000000,
- qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 16));
-
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
index 42dc521c13..978330900d 100644
--- a/hw/arm/smmuv3.c
+++ b/hw/arm/smmuv3.c
@@ -538,7 +538,7 @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
}
static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
- IOMMUAccessFlags flag)
+ IOMMUAccessFlags flag, int iommu_idx)
{
SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
SMMUv3State *s = sdev->smmu;
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 502a20842c..a8f1f6a912 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -20,6 +20,7 @@
#include "qemu/log.h"
#include "exec/address-spaces.h"
#include "sysemu/sysemu.h"
+#include "hw/arm/armv7m.h"
#include "hw/char/pl011.h"
#include "hw/misc/unimp.h"
#include "cpu.h"
@@ -1298,8 +1299,13 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
&error_fatal);
memory_region_add_subregion(system_memory, 0x20000000, sram);
- nvic = armv7m_init(system_memory, flash_size, NUM_IRQ_LINES,
- ms->kernel_filename, ms->cpu_type);
+ nvic = qdev_create(NULL, TYPE_ARMV7M);
+ qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
+ qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
+ object_property_set_link(OBJECT(nvic), OBJECT(get_system_memory()),
+ "memory", &error_abort);
+ /* This will exit with an error if the user passed us a bad cpu_type */
+ qdev_init_nofail(nvic);
qdev_connect_gpio_out_named(nvic, "SYSRESETREQ", 0,
qemu_allocate_irq(&do_sys_reset, NULL, 0));
@@ -1431,6 +1437,8 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
create_unimplemented_device("analogue-comparator", 0x4003c000, 0x1000);
create_unimplemented_device("hibernation", 0x400fc000, 0x1000);
create_unimplemented_device("flash-control", 0x400fd000, 0x1000);
+
+ armv7m_load_kernel(ARM_CPU(first_cpu), ms->kernel_filename, flash_size);
}
/* FIXME: Figure out how to generate these from stellaris_boards. */
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index a5ccffb4aa..b0ed8fa418 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -698,6 +698,7 @@ static void complete_collecting_data(Flash *s)
case MAN_MACRONIX:
s->quad_enable = extract32(s->data[0], 6, 1);
if (s->len > 1) {
+ s->volatile_cfg = s->data[1];
s->four_bytes_address_mode = extract32(s->data[1], 5, 1);
}
break;
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index a8b3f7f978..6c18e5e578 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -493,102 +493,41 @@ static void pflash_write (pflash_t *pfl, hwaddr offset,
pfl->cmd = 0;
}
-
-static uint32_t pflash_readb_be(void *opaque, hwaddr addr)
-{
- return pflash_read(opaque, addr, 1, 1);
-}
-
-static uint32_t pflash_readb_le(void *opaque, hwaddr addr)
+static uint64_t pflash_be_readfn(void *opaque, hwaddr addr, unsigned size)
{
- return pflash_read(opaque, addr, 1, 0);
+ return pflash_read(opaque, addr, size, 1);
}
-static uint32_t pflash_readw_be(void *opaque, hwaddr addr)
+static void pflash_be_writefn(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
{
- pflash_t *pfl = opaque;
-
- return pflash_read(pfl, addr, 2, 1);
-}
-
-static uint32_t pflash_readw_le(void *opaque, hwaddr addr)
-{
- pflash_t *pfl = opaque;
-
- return pflash_read(pfl, addr, 2, 0);
-}
-
-static uint32_t pflash_readl_be(void *opaque, hwaddr addr)
-{
- pflash_t *pfl = opaque;
-
- return pflash_read(pfl, addr, 4, 1);
-}
-
-static uint32_t pflash_readl_le(void *opaque, hwaddr addr)
-{
- pflash_t *pfl = opaque;
-
- return pflash_read(pfl, addr, 4, 0);
+ pflash_write(opaque, addr, value, size, 1);
}
-static void pflash_writeb_be(void *opaque, hwaddr addr,
- uint32_t value)
+static uint64_t pflash_le_readfn(void *opaque, hwaddr addr, unsigned size)
{
- pflash_write(opaque, addr, value, 1, 1);
+ return pflash_read(opaque, addr, size, 0);
}
-static void pflash_writeb_le(void *opaque, hwaddr addr,
- uint32_t value)
+static void pflash_le_writefn(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
{
- pflash_write(opaque, addr, value, 1, 0);
-}
-
-static void pflash_writew_be(void *opaque, hwaddr addr,
- uint32_t value)
-{
- pflash_t *pfl = opaque;
-
- pflash_write(pfl, addr, value, 2, 1);
-}
-
-static void pflash_writew_le(void *opaque, hwaddr addr,
- uint32_t value)
-{
- pflash_t *pfl = opaque;
-
- pflash_write(pfl, addr, value, 2, 0);
-}
-
-static void pflash_writel_be(void *opaque, hwaddr addr,
- uint32_t value)
-{
- pflash_t *pfl = opaque;
-
- pflash_write(pfl, addr, value, 4, 1);
-}
-
-static void pflash_writel_le(void *opaque, hwaddr addr,
- uint32_t value)
-{
- pflash_t *pfl = opaque;
-
- pflash_write(pfl, addr, value, 4, 0);
+ pflash_write(opaque, addr, value, size, 0);
}
static const MemoryRegionOps pflash_cfi02_ops_be = {
- .old_mmio = {
- .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
- .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
- },
+ .read = pflash_be_readfn,
+ .write = pflash_be_writefn,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
.endianness = DEVICE_NATIVE_ENDIAN,
};
static const MemoryRegionOps pflash_cfi02_ops_le = {
- .old_mmio = {
- .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
- .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
- },
+ .read = pflash_le_readfn,
+ .write = pflash_le_writefn,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
.endianness = DEVICE_NATIVE_ENDIAN,
};
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 1542d62201..35748e6c1b 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -554,56 +554,28 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
}
/* Memory mapped interface */
-static uint32_t parallel_mm_readb (void *opaque, hwaddr addr)
+static uint64_t parallel_mm_readfn(void *opaque, hwaddr addr, unsigned size)
{
ParallelState *s = opaque;
- return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFF;
+ return parallel_ioport_read_sw(s, addr >> s->it_shift) &
+ MAKE_64BIT_MASK(0, size * 8);
}
-static void parallel_mm_writeb (void *opaque,
- hwaddr addr, uint32_t value)
+static void parallel_mm_writefn(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
{
ParallelState *s = opaque;
- parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFF);
-}
-
-static uint32_t parallel_mm_readw (void *opaque, hwaddr addr)
-{
- ParallelState *s = opaque;
-
- return parallel_ioport_read_sw(s, addr >> s->it_shift) & 0xFFFF;
-}
-
-static void parallel_mm_writew (void *opaque,
- hwaddr addr, uint32_t value)
-{
- ParallelState *s = opaque;
-
- parallel_ioport_write_sw(s, addr >> s->it_shift, value & 0xFFFF);
-}
-
-static uint32_t parallel_mm_readl (void *opaque, hwaddr addr)
-{
- ParallelState *s = opaque;
-
- return parallel_ioport_read_sw(s, addr >> s->it_shift);
-}
-
-static void parallel_mm_writel (void *opaque,
- hwaddr addr, uint32_t value)
-{
- ParallelState *s = opaque;
-
- parallel_ioport_write_sw(s, addr >> s->it_shift, value);
+ parallel_ioport_write_sw(s, addr >> s->it_shift,
+ value & MAKE_64BIT_MASK(0, size * 8));
}
static const MemoryRegionOps parallel_mm_ops = {
- .old_mmio = {
- .read = { parallel_mm_readb, parallel_mm_readw, parallel_mm_readl },
- .write = { parallel_mm_writeb, parallel_mm_writew, parallel_mm_writel },
- },
+ .read = parallel_mm_readfn,
+ .write = parallel_mm_writefn,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
.endianness = DEVICE_NATIVE_ENDIAN,
};
diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
index f9d76c4641..a86901b673 100644
--- a/hw/core/or-irq.c
+++ b/hw/core/or-irq.c
@@ -66,14 +66,49 @@ static void or_irq_init(Object *obj)
qdev_init_gpio_out(DEVICE(obj), &s->out_irq, 1);
}
+/* The original version of this device had a fixed 16 entries in its
+ * VMState array; devices with more inputs than this need to
+ * migrate the extra lines via a subsection.
+ * The subsection migrates as much of the levels[] array as is needed
+ * (including repeating the first 16 elements), to avoid the awkwardness
+ * of splitting it in two to meet the requirements of VMSTATE_VARRAY_UINT16.
+ */
+#define OLD_MAX_OR_LINES 16
+#if MAX_OR_LINES < OLD_MAX_OR_LINES
+#error MAX_OR_LINES must be at least 16 for migration compatibility
+#endif
+
+static bool vmstate_extras_needed(void *opaque)
+{
+ qemu_or_irq *s = OR_IRQ(opaque);
+
+ return s->num_lines >= OLD_MAX_OR_LINES;
+}
+
+static const VMStateDescription vmstate_or_irq_extras = {
+ .name = "or-irq-extras",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = vmstate_extras_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_VARRAY_UINT16_UNSAFE(levels, qemu_or_irq, num_lines, 0,
+ vmstate_info_bool, bool),
+ VMSTATE_END_OF_LIST(),
+ },
+};
+
static const VMStateDescription vmstate_or_irq = {
.name = TYPE_OR_IRQ,
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_BOOL_ARRAY(levels, qemu_or_irq, MAX_OR_LINES),
+ VMSTATE_BOOL_SUB_ARRAY(levels, qemu_or_irq, 0, OLD_MAX_OR_LINES),
VMSTATE_END_OF_LIST(),
- }
+ },
+ .subsections = (const VMStateDescription*[]) {
+ &vmstate_or_irq_extras,
+ NULL
+ },
};
static Property or_irq_properties[] = {
diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 5d4833eeca..ccd8612888 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -491,7 +491,7 @@ static const MemoryRegionOps jazzio_ops = {
};
static IOMMUTLBEntry rc4030_dma_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
- IOMMUAccessFlags flag)
+ IOMMUAccessFlags flag, int iommu_idx)
{
rc4030State *s = container_of(iommu, rc4030State, dma_mr);
IOMMUTLBEntry ret = {
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 63d46ff6ee..1fd669fef8 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -991,7 +991,7 @@ static inline bool amdvi_is_interrupt_addr(hwaddr addr)
}
static IOMMUTLBEntry amdvi_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
- IOMMUAccessFlags flag)
+ IOMMUAccessFlags flag, int iommu_idx)
{
AMDVIAddressSpace *as = container_of(iommu, AMDVIAddressSpace, iommu);
AMDVIState *s = as->iommu_state;
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index b5a09b7908..0a8cd4e9cc 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1023,7 +1023,7 @@ static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num,
static int vtd_sync_shadow_page_hook(IOMMUTLBEntry *entry,
void *private)
{
- memory_region_notify_iommu((IOMMUMemoryRegion *)private, *entry);
+ memory_region_notify_iommu((IOMMUMemoryRegion *)private, 0, *entry);
return 0;
}
@@ -1581,7 +1581,7 @@ static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
.addr_mask = size - 1,
.perm = IOMMU_NONE,
};
- memory_region_notify_iommu(&vtd_as->iommu, entry);
+ memory_region_notify_iommu(&vtd_as->iommu, 0, entry);
}
}
}
@@ -2015,7 +2015,7 @@ static bool vtd_process_device_iotlb_desc(IntelIOMMUState *s,
entry.iova = addr;
entry.perm = IOMMU_NONE;
entry.translated_addr = 0;
- memory_region_notify_iommu(&vtd_dev_as->iommu, entry);
+ memory_region_notify_iommu(&vtd_dev_as->iommu, 0, entry);
done:
return true;
@@ -2471,7 +2471,7 @@ static void vtd_mem_write(void *opaque, hwaddr addr,
}
static IOMMUTLBEntry vtd_iommu_translate(IOMMUMemoryRegion *iommu, hwaddr addr,
- IOMMUAccessFlags flag)
+ IOMMUAccessFlags flag, int iommu_idx)
{
VTDAddressSpace *vtd_as = container_of(iommu, VTDAddressSpace, iommu);
IntelIOMMUState *s = vtd_as->iommu_state;
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index f17f18e51b..f33e3fc63d 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -434,7 +434,7 @@ static const VMStateDescription vmstate_kbd = {
};
/* Memory mapped interface */
-static uint32_t kbd_mm_readb (void *opaque, hwaddr addr)
+static uint64_t kbd_mm_readfn(void *opaque, hwaddr addr, unsigned size)
{
KBDState *s = opaque;
@@ -444,7 +444,8 @@ static uint32_t kbd_mm_readb (void *opaque, hwaddr addr)
return kbd_read_data(s, 0, 1) & 0xff;
}
-static void kbd_mm_writeb (void *opaque, hwaddr addr, uint32_t value)
+static void kbd_mm_writefn(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
{
KBDState *s = opaque;
@@ -454,12 +455,13 @@ static void kbd_mm_writeb (void *opaque, hwaddr addr, uint32_t value)
kbd_write_data(s, 0, value & 0xff, 1);
}
+
static const MemoryRegionOps i8042_mmio_ops = {
+ .read = kbd_mm_readfn,
+ .write = kbd_mm_writefn,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
.endianness = DEVICE_NATIVE_ENDIAN,
- .old_mmio = {
- .read = { kbd_mm_readb, kbd_mm_readb, kbd_mm_readb },
- .write = { kbd_mm_writeb, kbd_mm_writeb, kbd_mm_writeb },
- },
};
void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
index 5649cac46e..d8d3b25403 100644
--- a/hw/intc/arm_gicv3_kvm.c
+++ b/hw/intc/arm_gicv3_kvm.c
@@ -135,7 +135,14 @@ static void kvm_dist_get_priority(GICv3State *s, uint32_t offset, uint8_t *bmp)
uint32_t reg, *field;
int irq;
- field = (uint32_t *)bmp;
+ /* For the KVM GICv3, affinity routing is always enabled, and the first 8
+ * GICD_IPRIORITYR<n> registers are always RAZ/WI. The corresponding
+ * functionality is replaced by GICR_IPRIORITYR<n>. It doesn't need to
+ * sync them. So it needs to skip the field of GIC_INTERNAL irqs in bmp and
+ * offset.
+ */
+ field = (uint32_t *)(bmp + GIC_INTERNAL);
+ offset += (GIC_INTERNAL * 8) / 8;
for_each_dist_irq_reg(irq, s->num_irq, 8) {
kvm_gicd_access(s, offset, &reg, false);
*field = reg;
@@ -149,7 +156,14 @@ static void kvm_dist_put_priority(GICv3State *s, uint32_t offset, uint8_t *bmp)
uint32_t reg, *field;
int irq;
- field = (uint32_t *)bmp;
+ /* For the KVM GICv3, affinity routing is always enabled, and the first 8
+ * GICD_IPRIORITYR<n> registers are always RAZ/WI. The corresponding
+ * functionality is replaced by GICR_IPRIORITYR<n>. It doesn't need to
+ * sync them. So it needs to skip the field of GIC_INTERNAL irqs in bmp and
+ * offset.
+ */
+ field = (uint32_t *)(bmp + GIC_INTERNAL);
+ offset += (GIC_INTERNAL * 8) / 8;
for_each_dist_irq_reg(irq, s->num_irq, 8) {
reg = *field;
kvm_gicd_access(s, offset, &reg, true);
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index c51151fa8a..661be8878a 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2183,7 +2183,11 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
int regionlen;
s->cpu = ARM_CPU(qemu_get_cpu(0));
- assert(s->cpu);
+
+ if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) {
+ error_setg(errp, "The NVIC can only be used with a Cortex-M CPU");
+ return;
+ }
if (s->num_irq > NVIC_MAX_IRQ) {
error_setg(errp, "num-irq %d exceeds NVIC maximum", s->num_irq);
diff --git a/hw/m68k/mcf5206.c b/hw/m68k/mcf5206.c
index 7abd84ac47..d7f26d6810 100644
--- a/hw/m68k/mcf5206.c
+++ b/hw/m68k/mcf5206.c
@@ -512,19 +512,43 @@ static void m5206_mbar_writel(void *opaque, hwaddr offset,
m5206_mbar_write(s, offset, value, 4);
}
+static uint64_t m5206_mbar_readfn(void *opaque, hwaddr addr, unsigned size)
+{
+ switch (size) {
+ case 1:
+ return m5206_mbar_readb(opaque, addr);
+ case 2:
+ return m5206_mbar_readw(opaque, addr);
+ case 4:
+ return m5206_mbar_readl(opaque, addr);
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void m5206_mbar_writefn(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ switch (size) {
+ case 1:
+ m5206_mbar_writeb(opaque, addr, value);
+ break;
+ case 2:
+ m5206_mbar_writew(opaque, addr, value);
+ break;
+ case 4:
+ m5206_mbar_writel(opaque, addr, value);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
static const MemoryRegionOps m5206_mbar_ops = {
- .old_mmio = {
- .read = {
- m5206_mbar_readb,
- m5206_mbar_readw,
- m5206_mbar_readl,
- },
- .write = {
- m5206_mbar_writeb,
- m5206_mbar_writew,
- m5206_mbar_writel,
- },
- },
+ .read = m5206_mbar_readfn,
+ .write = m5206_mbar_writefn,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
.endianness = DEVICE_NATIVE_ENDIAN,
};
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
index 5e6d5744ee..59315010db 100644
--- a/hw/misc/aspeed_scu.c
+++ b/hw/misc/aspeed_scu.c
@@ -16,6 +16,7 @@
#include "qapi/visitor.h"
#include "qemu/bitops.h"
#include "qemu/log.h"
+#include "crypto/random.h"
#include "trace.h"
#define TO_REG(offset) ((offset) >> 2)
@@ -154,6 +155,19 @@ static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
[BMC_DEV_ID] = 0x00002402U
};
+static uint32_t aspeed_scu_get_random(void)
+{
+ Error *err = NULL;
+ uint32_t num;
+
+ if (qcrypto_random_bytes((uint8_t *)&num, sizeof(num), &err)) {
+ error_report_err(err);
+ exit(1);
+ }
+
+ return num;
+}
+
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
{
AspeedSCUState *s = ASPEED_SCU(opaque);
@@ -167,6 +181,12 @@ static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
}
switch (reg) {
+ case RNG_DATA:
+ /* On hardware, RNG_DATA works regardless of
+ * the state of the enable bit in RNG_CTRL
+ */
+ s->regs[RNG_DATA] = aspeed_scu_get_random();
+ break;
case WAKEUP_EN:
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Read of write-only offset 0x%" HWADDR_PRIx "\n",
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index aaa6010d5c..1b0880ac9e 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -112,7 +112,8 @@ static void spapr_tce_free_table(uint64_t *table, int fd, uint32_t nb_table)
/* Called from RCU critical section */
static IOMMUTLBEntry spapr_tce_translate_iommu(IOMMUMemoryRegion *iommu,
hwaddr addr,
- IOMMUAccessFlags flag)
+ IOMMUAccessFlags flag,
+ int iommu_idx)
{
sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
uint64_t tce;
@@ -428,7 +429,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
entry.translated_addr = tce & page_mask;
entry.addr_mask = ~page_mask;
entry.perm = spapr_tce_iommu_access_flags(tce);
- memory_region_notify_iommu(&tcet->iommu, entry);
+ memory_region_notify_iommu(&tcet->iommu, 0, entry);
return H_SUCCESS;
}
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 10da87458e..e3e0ebb7f6 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -484,7 +484,7 @@ uint16_t s390_guest_io_table_walk(uint64_t g_iota, hwaddr addr,
}
static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRegion *mr, hwaddr addr,
- IOMMUAccessFlags flag)
+ IOMMUAccessFlags flag, int iommu_idx)
{
S390PCIIOMMU *iommu = container_of(mr, S390PCIIOMMU, iommu_mr);
S390IOTLBEntry *entry;
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index d1a5f79678..7b61367ee3 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -589,7 +589,7 @@ static void s390_pci_update_iotlb(S390PCIIOMMU *iommu, S390IOTLBEntry *entry)
}
notify.perm = IOMMU_NONE;
- memory_region_notify_iommu(&iommu->iommu_mr, notify);
+ memory_region_notify_iommu(&iommu->iommu_mr, 0, notify);
notify.perm = entry->perm;
}
@@ -601,7 +601,7 @@ static void s390_pci_update_iotlb(S390PCIIOMMU *iommu, S390IOTLBEntry *entry)
g_hash_table_replace(iommu->iotlb, &cache->iova, cache);
}
- memory_region_notify_iommu(&iommu->iommu_mr, notify);
+ memory_region_notify_iommu(&iommu->iommu_mr, 0, notify);
}
int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
diff --git a/hw/sh4/sh7750.c b/hw/sh4/sh7750.c
index 2dc07a904b..2fb6e618d9 100644
--- a/hw/sh4/sh7750.c
+++ b/hw/sh4/sh7750.c
@@ -450,15 +450,43 @@ static void sh7750_mem_writel(void *opaque, hwaddr addr,
}
}
+static uint64_t sh7750_mem_readfn(void *opaque, hwaddr addr, unsigned size)
+{
+ switch (size) {
+ case 1:
+ return sh7750_mem_readb(opaque, addr);
+ case 2:
+ return sh7750_mem_readw(opaque, addr);
+ case 4:
+ return sh7750_mem_readl(opaque, addr);
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void sh7750_mem_writefn(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ switch (size) {
+ case 1:
+ sh7750_mem_writeb(opaque, addr, value);
+ break;
+ case 2:
+ sh7750_mem_writew(opaque, addr, value);
+ break;
+ case 4:
+ sh7750_mem_writel(opaque, addr, value);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
static const MemoryRegionOps sh7750_mem_ops = {
- .old_mmio = {
- .read = {sh7750_mem_readb,
- sh7750_mem_readw,
- sh7750_mem_readl },
- .write = {sh7750_mem_writeb,
- sh7750_mem_writew,
- sh7750_mem_writel },
- },
+ .read = sh7750_mem_readfn,
+ .write = sh7750_mem_writefn,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
.endianness = DEVICE_NATIVE_ENDIAN,
};
diff --git a/hw/sparc/sun4m_iommu.c b/hw/sparc/sun4m_iommu.c
index b677601fc6..7ca1e3fce4 100644
--- a/hw/sparc/sun4m_iommu.c
+++ b/hw/sparc/sun4m_iommu.c
@@ -282,7 +282,8 @@ static void iommu_bad_addr(IOMMUState *s, hwaddr addr,
/* Called from RCU critical section */
static IOMMUTLBEntry sun4m_translate_iommu(IOMMUMemoryRegion *iommu,
hwaddr addr,
- IOMMUAccessFlags flags)
+ IOMMUAccessFlags flags,
+ int iommu_idx)
{
IOMMUState *is = container_of(iommu, IOMMUState, iommu);
hwaddr page, pa;
diff --git a/hw/sparc64/sun4u_iommu.c b/hw/sparc64/sun4u_iommu.c
index eb3aaa87e6..1ef7645ba5 100644
--- a/hw/sparc64/sun4u_iommu.c
+++ b/hw/sparc64/sun4u_iommu.c
@@ -73,7 +73,7 @@
/* Called from RCU critical section */
static IOMMUTLBEntry sun4u_translate_iommu(IOMMUMemoryRegion *iommu,
hwaddr addr,
- IOMMUAccessFlags flag)
+ IOMMUAccessFlags flag, int iommu_idx)
{
IOMMUState *is = container_of(iommu, IOMMUState, iommu);
hwaddr baseaddr, offset;
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 8e57265edf..fb396cf00a 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -507,6 +507,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
if (memory_region_is_iommu(section->mr)) {
VFIOGuestIOMMU *giommu;
IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
+ int iommu_idx;
trace_vfio_listener_region_add_iommu(iova, end);
/*
@@ -523,10 +524,13 @@ static void vfio_listener_region_add(MemoryListener *listener,
llend = int128_add(int128_make64(section->offset_within_region),
section->size);
llend = int128_sub(llend, int128_one());
+ iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
+ MEMTXATTRS_UNSPECIFIED);
iommu_notifier_init(&giommu->n, vfio_iommu_map_notify,
IOMMU_NOTIFIER_ALL,
section->offset_within_region,
- int128_get64(llend));
+ int128_get64(llend),
+ iommu_idx);
QLIST_INSERT_HEAD(&container->giommu_list, giommu, giommu_next);
memory_region_register_iommu_notifier(section->mr, &giommu->n);
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 96175b214d..b129cb9ddd 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -662,6 +662,8 @@ static void vhost_iommu_region_add(MemoryListener *listener,
iommu_listener);
struct vhost_iommu *iommu;
Int128 end;
+ int iommu_idx;
+ IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr);
if (!memory_region_is_iommu(section->mr)) {
return;
@@ -671,10 +673,13 @@ static void vhost_iommu_region_add(MemoryListener *listener,
end = int128_add(int128_make64(section->offset_within_region),
section->size);
end = int128_sub(end, int128_one());
+ iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
+ MEMTXATTRS_UNSPECIFIED);
iommu_notifier_init(&iommu->n, vhost_iommu_unmap_notify,
IOMMU_NOTIFIER_UNMAP,
section->offset_within_region,
- int128_get64(end));
+ int128_get64(end),
+ iommu_idx);
iommu->mr = section->mr;
iommu->iommu_offset = section->offset_within_address_space -
section->offset_within_region;
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
index e596b0804d..7b59469888 100644
--- a/hw/watchdog/wdt_i6300esb.c
+++ b/hw/watchdog/wdt_i6300esb.c
@@ -361,19 +361,43 @@ static void i6300esb_mem_writel(void *vp, hwaddr addr, uint32_t val)
}
}
+static uint64_t i6300esb_mem_readfn(void *opaque, hwaddr addr, unsigned size)
+{
+ switch (size) {
+ case 1:
+ return i6300esb_mem_readb(opaque, addr);
+ case 2:
+ return i6300esb_mem_readw(opaque, addr);
+ case 4:
+ return i6300esb_mem_readl(opaque, addr);
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void i6300esb_mem_writefn(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ switch (size) {
+ case 1:
+ i6300esb_mem_writeb(opaque, addr, value);
+ break;
+ case 2:
+ i6300esb_mem_writew(opaque, addr, value);
+ break;
+ case 4:
+ i6300esb_mem_writel(opaque, addr, value);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
static const MemoryRegionOps i6300esb_ops = {
- .old_mmio = {
- .read = {
- i6300esb_mem_readb,
- i6300esb_mem_readw,
- i6300esb_mem_readl,
- },
- .write = {
- i6300esb_mem_writeb,
- i6300esb_mem_writew,
- i6300esb_mem_writel,
- },
- },
+ .read = i6300esb_mem_readfn,
+ .write = i6300esb_mem_writefn,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
.endianness = DEVICE_LITTLE_ENDIAN,
};