aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-09-07 16:42:55 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-09-07 16:46:15 +0100
commitef475b5dd12684591e6264e517eaa5b3e90f7ffa (patch)
tree82bc4b153638fbfcdc2f7c3fff67bf94253db8ca /hw
parent7794b34e63fd42803e959c4989e5358f2412d325 (diff)
parentc99a55d38dd5b5131f3fcbbaf41828a09ee62544 (diff)
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20170907' into staging
target-arm: * cleanups converting to DEFINE_PROP_LINK * allwinner-a10: mark as not user-creatable * initial patches working towards ARMv8M support * implement generating aborts on memory transaction failures * make BXJ behave correctly (ie not UNDEF) on ARMv6-and-later # gpg: Signature made Thu 07 Sep 2017 14:26:07 BST # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20170907: (31 commits) target/arm: Add Jazelle feature target/arm: Implement new do_transaction_failed hook hw/arm: Set ignore_memory_transaction_failures for most ARM boards boards.h: Define new flag ignore_memory_transaction_failures target/arm: Implement BXNS, and banked stack pointers target/arm: Move regime_is_secure() to target/arm/internals.h target/arm: Make CFSR register banked for v8M target/arm: Make MMFAR banked for v8M target/arm: Make CCR register banked for v8M target/arm: Make MPU_CTRL register banked for v8M target/arm: Make MPU_RNR register banked for v8M target/arm: Make MPU_RBAR, MPU_RLAR banked for v8M target/arm: Make MPU_MAIR0, MPU_MAIR1 registers banked for v8M target/arm: Make VTOR register banked for v8M nvic: Add NS alias SCS region target/arm: Make CONTROL register banked for v8M target/arm: Make FAULTMASK register banked for v8M target/arm: Make PRIMASK register banked for v8M target/arm: Make BASEPRI register banked for v8M target/arm: Add MMU indexes for secure v8M ... # Conflicts: # target/arm/translate.c
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/allwinner-a10.c2
-rw-r--r--hw/arm/armv7m.c16
-rw-r--r--hw/arm/aspeed.c3
-rw-r--r--hw/arm/collie.c1
-rw-r--r--hw/arm/cubieboard.c1
-rw-r--r--hw/arm/digic_boards.c1
-rw-r--r--hw/arm/exynos4_boards.c2
-rw-r--r--hw/arm/gumstix.c2
-rw-r--r--hw/arm/highbank.c2
-rw-r--r--hw/arm/imx25_pdk.c1
-rw-r--r--hw/arm/integratorcp.c1
-rw-r--r--hw/arm/kzm.c1
-rw-r--r--hw/arm/mainstone.c1
-rw-r--r--hw/arm/musicpal.c1
-rw-r--r--hw/arm/netduino2.c1
-rw-r--r--hw/arm/nseries.c2
-rw-r--r--hw/arm/omap_sx1.c2
-rw-r--r--hw/arm/palm.c1
-rw-r--r--hw/arm/raspi.c1
-rw-r--r--hw/arm/realview.c4
-rw-r--r--hw/arm/sabrelite.c1
-rw-r--r--hw/arm/spitz.c4
-rw-r--r--hw/arm/stellaris.c2
-rw-r--r--hw/arm/tosa.c1
-rw-r--r--hw/arm/versatilepb.c2
-rw-r--r--hw/arm/vexpress.c1
-rw-r--r--hw/arm/xilinx_zynq.c1
-rw-r--r--hw/arm/xlnx-ep108.c2
-rw-r--r--hw/arm/xlnx-zynqmp.c7
-rw-r--r--hw/arm/z2.c1
-rw-r--r--hw/dma/xilinx_axidma.c16
-rw-r--r--hw/intc/arm_gicv3_its_kvm.c19
-rw-r--r--hw/intc/armv7m_nvic.c291
-rw-r--r--hw/net/xilinx_axienet.c16
34 files changed, 317 insertions, 93 deletions
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index f62a9a3541..43a3f01f45 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -118,6 +118,8 @@ static void aw_a10_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc);
dc->realize = aw_a10_realize;
+ /* Reason: Uses serial_hds in realize and nd_table in instance_init */
+ dc->user_creatable = false;
}
static const TypeInfo aw_a10_type_info = {
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index d2477e84e4..b64a409b40 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -97,12 +97,6 @@ static void bitband_init(Object *obj)
BitBandState *s = BITBAND(obj);
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
- object_property_add_link(obj, "source-memory",
- TYPE_MEMORY_REGION,
- (Object **)&s->source_memory,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
memory_region_init_io(&s->iomem, obj, &bitband_ops, s,
"bitband", 0x02000000);
sysbus_init_mmio(dev, &s->iomem);
@@ -138,12 +132,6 @@ static void armv7m_instance_init(Object *obj)
/* Can't init the cpu here, we don't yet know which model to use */
- object_property_add_link(obj, "memory",
- TYPE_MEMORY_REGION,
- (Object **)&s->board_memory,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
memory_region_init(&s->container, obj, "armv7m-container", UINT64_MAX);
object_initialize(&s->nvic, sizeof(s->nvic), TYPE_NVIC);
@@ -254,6 +242,8 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
static Property armv7m_properties[] = {
DEFINE_PROP_STRING("cpu-model", ARMv7MState, cpu_model),
+ DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION,
+ MemoryRegion *),
DEFINE_PROP_END_OF_LIST(),
};
@@ -349,6 +339,8 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
static Property bitband_properties[] = {
DEFINE_PROP_UINT32("base", BitBandState, base, 0),
+ DEFINE_PROP_LINK("source-memory", BitBandState, source_memory,
+ TYPE_MEMORY_REGION, MemoryRegion *),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 0c5635f300..ab895ad490 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -270,6 +270,7 @@ static void palmetto_bmc_class_init(ObjectClass *oc, void *data)
mc->no_floppy = 1;
mc->no_cdrom = 1;
mc->no_parallel = 1;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo palmetto_bmc_type = {
@@ -302,6 +303,7 @@ static void ast2500_evb_class_init(ObjectClass *oc, void *data)
mc->no_floppy = 1;
mc->no_cdrom = 1;
mc->no_parallel = 1;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo ast2500_evb_type = {
@@ -326,6 +328,7 @@ static void romulus_bmc_class_init(ObjectClass *oc, void *data)
mc->no_floppy = 1;
mc->no_cdrom = 1;
mc->no_parallel = 1;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo romulus_bmc_type = {
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index 2e69531287..8830192d86 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -64,6 +64,7 @@ static void collie_machine_init(MachineClass *mc)
{
mc->desc = "Sharp SL-5500 (Collie) PDA (SA-1110)";
mc->init = collie_init;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("collie", collie_machine_init)
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index b98e1c4a8c..32f1edd2fa 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -86,6 +86,7 @@ static void cubieboard_machine_init(MachineClass *mc)
mc->init = cubieboard_init;
mc->block_default_type = IF_IDE;
mc->units_per_default_bus = 1;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("cubieboard", cubieboard_machine_init)
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index 520c8e9ff1..9f11dcd11f 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -155,6 +155,7 @@ static void canon_a1100_machine_init(MachineClass *mc)
{
mc->desc = "Canon PowerShot A1100 IS";
mc->init = &canon_a1100_init;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("canon-a1100", canon_a1100_machine_init)
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index 7c03ed32b7..f1441ec6cf 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -189,6 +189,7 @@ static void nuri_class_init(ObjectClass *oc, void *data)
mc->desc = "Samsung NURI board (Exynos4210)";
mc->init = nuri_init;
mc->max_cpus = EXYNOS4210_NCPUS;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo nuri_type = {
@@ -204,6 +205,7 @@ static void smdkc210_class_init(ObjectClass *oc, void *data)
mc->desc = "Samsung SMDKC210 board (Exynos4210)";
mc->init = smdkc210_init;
mc->max_cpus = EXYNOS4210_NCPUS;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo smdkc210_type = {
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index d59d9ba4e4..092ce36ae0 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -128,6 +128,7 @@ static void connex_class_init(ObjectClass *oc, void *data)
mc->desc = "Gumstix Connex (PXA255)";
mc->init = connex_init;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo connex_type = {
@@ -142,6 +143,7 @@ static void verdex_class_init(ObjectClass *oc, void *data)
mc->desc = "Gumstix Verdex (PXA270)";
mc->init = verdex_init;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo verdex_type = {
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 942d5a82b9..ba2778948a 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -413,6 +413,7 @@ static void highbank_class_init(ObjectClass *oc, void *data)
mc->block_default_type = IF_IDE;
mc->units_per_default_bus = 1;
mc->max_cpus = 4;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo highbank_type = {
@@ -430,6 +431,7 @@ static void midway_class_init(ObjectClass *oc, void *data)
mc->block_default_type = IF_IDE;
mc->units_per_default_bus = 1;
mc->max_cpus = 4;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo midway_type = {
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
index 7d42c74001..9f3ee14739 100644
--- a/hw/arm/imx25_pdk.c
+++ b/hw/arm/imx25_pdk.c
@@ -148,6 +148,7 @@ static void imx25_pdk_machine_init(MachineClass *mc)
{
mc->desc = "ARM i.MX25 PDK board (ARM926)";
mc->init = imx25_pdk_init;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("imx25-pdk", imx25_pdk_machine_init)
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index d9530edffc..d603af982a 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -681,6 +681,7 @@ static void integratorcp_machine_init(MachineClass *mc)
{
mc->desc = "ARM Integrator/CP (ARM926EJ-S)";
mc->init = integratorcp_init;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("integratorcp", integratorcp_machine_init)
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index 3ed6577a55..f9c2228e31 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -142,6 +142,7 @@ static void kzm_machine_init(MachineClass *mc)
{
mc->desc = "ARM KZM Emulation Baseboard (ARM1136)";
mc->init = kzm_init;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("kzm", kzm_machine_init)
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index fb268e691e..637f52c052 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -196,6 +196,7 @@ static void mainstone2_machine_init(MachineClass *mc)
{
mc->desc = "Mainstone II (PXA27x)";
mc->init = mainstone_init;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("mainstone", mainstone2_machine_init)
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index a8b3d463fc..ab4ba31a24 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1718,6 +1718,7 @@ static void musicpal_machine_init(MachineClass *mc)
{
mc->desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)";
mc->init = musicpal_init;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("musicpal", musicpal_machine_init)
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
index 3cfe332dd1..9d34d4c214 100644
--- a/hw/arm/netduino2.c
+++ b/hw/arm/netduino2.c
@@ -45,6 +45,7 @@ static void netduino2_machine_init(MachineClass *mc)
{
mc->desc = "Netduino 2 Machine";
mc->init = netduino2_init;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("netduino2", netduino2_machine_init)
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 503a3b6d24..a32ac82702 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -1425,6 +1425,7 @@ static void n800_class_init(ObjectClass *oc, void *data)
mc->desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)";
mc->init = n800_init;
mc->default_boot_order = "";
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo n800_type = {
@@ -1440,6 +1441,7 @@ static void n810_class_init(ObjectClass *oc, void *data)
mc->desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)";
mc->init = n810_init;
mc->default_boot_order = "";
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo n810_type = {
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index 9809106617..45356172e8 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -223,6 +223,7 @@ static void sx1_machine_v2_class_init(ObjectClass *oc, void *data)
mc->desc = "Siemens SX1 (OMAP310) V2";
mc->init = sx1_init_v2;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo sx1_machine_v2_type = {
@@ -237,6 +238,7 @@ static void sx1_machine_v1_class_init(ObjectClass *oc, void *data)
mc->desc = "Siemens SX1 (OMAP310) V1";
mc->init = sx1_init_v1;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo sx1_machine_v1_type = {
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index 64cf8ca921..bf070a2d9c 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -274,6 +274,7 @@ static void palmte_machine_init(MachineClass *mc)
{
mc->desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)";
mc->init = palmte_init;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("cheetah", palmte_machine_init)
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 32cdc98c6d..5941c9f751 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -168,5 +168,6 @@ static void raspi2_machine_init(MachineClass *mc)
mc->no_cdrom = 1;
mc->max_cpus = BCM2836_NCPUS;
mc->default_ram_size = 1024 * 1024 * 1024;
+ mc->ignore_memory_transaction_failures = true;
};
DEFINE_MACHINE("raspi2", raspi2_machine_init)
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 273615652c..f3a49b6420 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -398,6 +398,7 @@ static void realview_eb_class_init(ObjectClass *oc, void *data)
mc->desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)";
mc->init = realview_eb_init;
mc->block_default_type = IF_SCSI;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo realview_eb_type = {
@@ -414,6 +415,7 @@ static void realview_eb_mpcore_class_init(ObjectClass *oc, void *data)
mc->init = realview_eb_mpcore_init;
mc->block_default_type = IF_SCSI;
mc->max_cpus = 4;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo realview_eb_mpcore_type = {
@@ -428,6 +430,7 @@ static void realview_pb_a8_class_init(ObjectClass *oc, void *data)
mc->desc = "ARM RealView Platform Baseboard for Cortex-A8";
mc->init = realview_pb_a8_init;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo realview_pb_a8_type = {
@@ -443,6 +446,7 @@ static void realview_pbx_a9_class_init(ObjectClass *oc, void *data)
mc->desc = "ARM RealView Platform Baseboard Explore for Cortex-A9";
mc->init = realview_pbx_a9_init;
mc->max_cpus = 4;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo realview_pbx_a9_type = {
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
index 4e7ac8cc4f..ee140e5d9e 100644
--- a/hw/arm/sabrelite.c
+++ b/hw/arm/sabrelite.c
@@ -122,6 +122,7 @@ static void sabrelite_machine_init(MachineClass *mc)
mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)";
mc->init = sabrelite_init;
mc->max_cpus = FSL_IMX6_NUM_CPUS;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("sabrelite", sabrelite_machine_init)
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 7f588cea21..6406421d0c 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -983,6 +983,7 @@ static void akitapda_class_init(ObjectClass *oc, void *data)
mc->desc = "Sharp SL-C1000 (Akita) PDA (PXA270)";
mc->init = akita_init;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo akitapda_type = {
@@ -998,6 +999,7 @@ static void spitzpda_class_init(ObjectClass *oc, void *data)
mc->desc = "Sharp SL-C3000 (Spitz) PDA (PXA270)";
mc->init = spitz_init;
mc->block_default_type = IF_IDE;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo spitzpda_type = {
@@ -1013,6 +1015,7 @@ static void borzoipda_class_init(ObjectClass *oc, void *data)
mc->desc = "Sharp SL-C3100 (Borzoi) PDA (PXA270)";
mc->init = borzoi_init;
mc->block_default_type = IF_IDE;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo borzoipda_type = {
@@ -1028,6 +1031,7 @@ static void terrierpda_class_init(ObjectClass *oc, void *data)
mc->desc = "Sharp SL-C3200 (Terrier) PDA (PXA270)";
mc->init = terrier_init;
mc->block_default_type = IF_IDE;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo terrierpda_type = {
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 408c1a14d3..b3aad23bdf 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1453,6 +1453,7 @@ static void lm3s811evb_class_init(ObjectClass *oc, void *data)
mc->desc = "Stellaris LM3S811EVB";
mc->init = lm3s811evb_init;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo lm3s811evb_type = {
@@ -1467,6 +1468,7 @@ static void lm3s6965evb_class_init(ObjectClass *oc, void *data)
mc->desc = "Stellaris LM3S6965EVB";
mc->init = lm3s6965evb_init;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo lm3s6965evb_type = {
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 8b757ff6a3..1134cf74db 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -263,6 +263,7 @@ static void tosapda_machine_init(MachineClass *mc)
mc->desc = "Sharp SL-6000 (Tosa) PDA (PXA255)";
mc->init = tosa_init;
mc->block_default_type = IF_IDE;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("tosa", tosapda_machine_init)
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index b0e9f5be65..76664e4722 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -403,6 +403,7 @@ static void versatilepb_class_init(ObjectClass *oc, void *data)
mc->desc = "ARM Versatile/PB (ARM926EJ-S)";
mc->init = vpb_init;
mc->block_default_type = IF_SCSI;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo versatilepb_type = {
@@ -418,6 +419,7 @@ static void versatileab_class_init(ObjectClass *oc, void *data)
mc->desc = "ARM Versatile/AB (ARM926EJ-S)";
mc->init = vab_init;
mc->block_default_type = IF_SCSI;
+ mc->ignore_memory_transaction_failures = true;
}
static const TypeInfo versatileab_type = {
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 571dd3609a..e3acab6adf 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -752,6 +752,7 @@ static void vexpress_class_init(ObjectClass *oc, void *data)
mc->desc = "ARM Versatile Express";
mc->init = vexpress_common_init;
mc->max_cpus = 4;
+ mc->ignore_memory_transaction_failures = true;
}
static void vexpress_a9_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index a750959d45..3759cf8dc3 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -326,6 +326,7 @@ static void zynq_machine_init(MachineClass *mc)
mc->init = zynq_init;
mc->max_cpus = 1;
mc->no_sdcard = 1;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("xilinx-zynq-a9", zynq_machine_init)
diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
index 860780ab8b..c339cd495c 100644
--- a/hw/arm/xlnx-ep108.c
+++ b/hw/arm/xlnx-ep108.c
@@ -122,6 +122,7 @@ static void xlnx_ep108_machine_init(MachineClass *mc)
mc->init = xlnx_ep108_init;
mc->block_default_type = IF_IDE;
mc->units_per_default_bus = 1;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("xlnx-ep108", xlnx_ep108_machine_init)
@@ -132,6 +133,7 @@ static void xlnx_zcu102_machine_init(MachineClass *mc)
mc->init = xlnx_ep108_init;
mc->block_default_type = IF_IDE;
mc->units_per_default_bus = 1;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("xlnx-zcu102", xlnx_zcu102_machine_init)
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 9eceadbdc8..22c2a33719 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -140,11 +140,6 @@ static void xlnx_zynqmp_init(Object *obj)
&error_abort);
}
- object_property_add_link(obj, "ddr-ram", TYPE_MEMORY_REGION,
- (Object **)&s->ddr_ram,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
-
object_initialize(&s->gic, sizeof(s->gic), gic_class_name());
qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
@@ -433,6 +428,8 @@ static Property xlnx_zynqmp_props[] = {
DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
DEFINE_PROP_BOOL("secure", XlnxZynqMPState, secure, false),
DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
+ DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
+ MemoryRegion *),
DEFINE_PROP_END_OF_LIST()
};
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 1607cbdb03..417bc1ac33 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -370,6 +370,7 @@ static void z2_machine_init(MachineClass *mc)
{
mc->desc = "Zipit Z2 (PXA27x)";
mc->init = z2_init;
+ mc->ignore_memory_transaction_failures = true;
}
DEFINE_MACHINE("z2", z2_machine_init)
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index 3987b5ff96..9b48103574 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -562,18 +562,6 @@ static void xilinx_axidma_init(Object *obj)
XilinxAXIDMA *s = XILINX_AXI_DMA(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
- object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,
- (Object **)&s->tx_data_dev,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
- object_property_add_link(obj, "axistream-control-connected",
- TYPE_STREAM_SLAVE,
- (Object **)&s->tx_control_dev,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
-
object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
TYPE_XILINX_AXI_DMA_DATA_STREAM);
object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),
@@ -593,6 +581,10 @@ static void xilinx_axidma_init(Object *obj)
static Property axidma_properties[] = {
DEFINE_PROP_UINT32("freqhz", XilinxAXIDMA, freqhz, 50000000),
+ DEFINE_PROP_LINK("axistream-connected", XilinxAXIDMA,
+ tx_data_dev, TYPE_STREAM_SLAVE, StreamSlave *),
+ DEFINE_PROP_LINK("axistream-control-connected", XilinxAXIDMA,
+ tx_control_dev, TYPE_STREAM_SLAVE, StreamSlave *),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
index 1f8991b8a6..39903d5eab 100644
--- a/hw/intc/arm_gicv3_its_kvm.c
+++ b/hw/intc/arm_gicv3_its_kvm.c
@@ -120,17 +120,6 @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
qemu_add_vm_change_state_handler(vm_change_state_handler, s);
}
-static void kvm_arm_its_init(Object *obj)
-{
- GICv3ITSState *s = KVM_ARM_ITS(obj);
-
- object_property_add_link(obj, "parent-gicv3",
- "kvm-arm-gicv3", (Object **)&s->gicv3,
- object_property_allow_set_link,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
-}
-
/**
* kvm_arm_its_pre_save - handles the saving of ITS registers.
* ITS tables are flushed into guest RAM separately and earlier,
@@ -205,12 +194,19 @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
GITS_CTLR, &s->ctlr, true, &error_abort);
}
+static Property kvm_arm_its_props[] = {
+ DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "kvm-arm-gicv3",
+ GICv3State *),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void kvm_arm_its_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
dc->realize = kvm_arm_its_realize;
+ dc->props = kvm_arm_its_props;
icc->send_msi = kvm_its_send_msi;
icc->pre_save = kvm_arm_its_pre_save;
icc->post_load = kvm_arm_its_post_load;
@@ -220,7 +216,6 @@ static const TypeInfo kvm_arm_its_info = {
.name = TYPE_KVM_ARM_ITS,
.parent = TYPE_ARM_GICV3_ITS_COMMON,
.instance_size = sizeof(GICv3ITSState),
- .instance_init = kvm_arm_its_init,
.class_init = kvm_arm_its_class_init,
};
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index bbfe2d55be..1fecfd6377 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -167,12 +167,12 @@ static inline int nvic_exec_prio(NVICState *s)
CPUARMState *env = &s->cpu->env;
int running;
- if (env->v7m.faultmask) {
+ if (env->v7m.faultmask[env->v7m.secure]) {
running = -1;
- } else if (env->v7m.primask) {
+ } else if (env->v7m.primask[env->v7m.secure]) {
running = 0;
- } else if (env->v7m.basepri > 0) {
- running = env->v7m.basepri & nvic_gprio_mask(s);
+ } else if (env->v7m.basepri[env->v7m.secure] > 0) {
+ running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s);
} else {
running = NVIC_NOEXC_PRIO; /* lower than any possible priority */
}
@@ -187,6 +187,13 @@ bool armv7m_nvic_can_take_pending_exception(void *opaque)
return nvic_exec_prio(s) > nvic_pending_prio(s);
}
+int armv7m_nvic_raw_execution_priority(void *opaque)
+{
+ NVICState *s = opaque;
+
+ return s->exception_prio;
+}
+
/* caller must call nvic_irq_update() after this */
static void set_prio(NVICState *s, unsigned irq, uint8_t prio)
{
@@ -396,7 +403,7 @@ static void set_irq_level(void *opaque, int n, int level)
}
}
-static uint32_t nvic_readl(NVICState *s, uint32_t offset)
+static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
{
ARMCPU *cpu = s->cpu;
uint32_t val;
@@ -434,14 +441,19 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
/* ISRPREEMPT not implemented */
return val;
case 0xd08: /* Vector Table Offset. */
- return cpu->env.v7m.vecbase;
+ return cpu->env.v7m.vecbase[attrs.secure];
case 0xd0c: /* Application Interrupt/Reset Control. */
return 0xfa050000 | (s->prigroup << 8);
case 0xd10: /* System Control. */
/* TODO: Implement SLEEPONEXIT. */
return 0;
case 0xd14: /* Configuration Control. */
- return cpu->env.v7m.ccr;
+ /* The BFHFNMIGN bit is the only non-banked bit; we
+ * keep it in the non-secure copy of the register.
+ */
+ val = cpu->env.v7m.ccr[attrs.secure];
+ val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
+ return val;
case 0xd24: /* System Handler Status. */
val = 0;
if (s->vectors[ARMV7M_EXCP_MEM].active) {
@@ -488,13 +500,18 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
}
return val;
case 0xd28: /* Configurable Fault Status. */
- return cpu->env.v7m.cfsr;
+ /* 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. */
return cpu->env.v7m.dfsr;
case 0xd34: /* MMFAR MemManage Fault Address */
- return cpu->env.v7m.mmfar;
+ return cpu->env.v7m.mmfar[attrs.secure];
case 0xd38: /* Bus Fault Address. */
return cpu->env.v7m.bfar;
case 0xd3c: /* Aux Fault Status. */
@@ -534,27 +551,58 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
return cpu->pmsav7_dregion << 8;
break;
case 0xd94: /* MPU_CTRL */
- return cpu->env.v7m.mpu_ctrl;
+ return cpu->env.v7m.mpu_ctrl[attrs.secure];
case 0xd98: /* MPU_RNR */
- return cpu->env.pmsav7.rnr;
+ return cpu->env.pmsav7.rnr[attrs.secure];
case 0xd9c: /* MPU_RBAR */
case 0xda4: /* MPU_RBAR_A1 */
case 0xdac: /* MPU_RBAR_A2 */
case 0xdb4: /* MPU_RBAR_A3 */
{
- int region = cpu->env.pmsav7.rnr;
+ int region = cpu->env.pmsav7.rnr[attrs.secure];
+
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ /* PMSAv8M handling of the aliases is different from v7M:
+ * aliases A1, A2, A3 override the low two bits of the region
+ * number in MPU_RNR, and there is no 'region' field in the
+ * RBAR register.
+ */
+ int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
+ if (aliasno) {
+ region = deposit32(region, 0, 2, aliasno);
+ }
+ if (region >= cpu->pmsav7_dregion) {
+ return 0;
+ }
+ return cpu->env.pmsav8.rbar[attrs.secure][region];
+ }
if (region >= cpu->pmsav7_dregion) {
return 0;
}
return (cpu->env.pmsav7.drbar[region] & 0x1f) | (region & 0xf);
}
- case 0xda0: /* MPU_RASR */
- case 0xda8: /* MPU_RASR_A1 */
- case 0xdb0: /* MPU_RASR_A2 */
- case 0xdb8: /* MPU_RASR_A3 */
+ case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
+ case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
+ case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
+ case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
{
- int region = cpu->env.pmsav7.rnr;
+ int region = cpu->env.pmsav7.rnr[attrs.secure];
+
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ /* PMSAv8M handling of the aliases is different from v7M:
+ * aliases A1, A2, A3 override the low two bits of the region
+ * number in MPU_RNR.
+ */
+ int aliasno = (offset - 0xda0) / 8; /* 0..3 */
+ if (aliasno) {
+ region = deposit32(region, 0, 2, aliasno);
+ }
+ if (region >= cpu->pmsav7_dregion) {
+ return 0;
+ }
+ return cpu->env.pmsav8.rlar[attrs.secure][region];
+ }
if (region >= cpu->pmsav7_dregion) {
return 0;
@@ -562,13 +610,25 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) |
(cpu->env.pmsav7.drsr[region] & 0xffff);
}
+ case 0xdc0: /* MPU_MAIR0 */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ return cpu->env.pmsav8.mair0[attrs.secure];
+ case 0xdc4: /* MPU_MAIR1 */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ return cpu->env.pmsav8.mair1[attrs.secure];
default:
+ bad_offset:
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
return 0;
}
}
-static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
+static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
+ MemTxAttrs attrs)
{
ARMCPU *cpu = s->cpu;
@@ -589,7 +649,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
}
break;
case 0xd08: /* Vector Table Offset. */
- cpu->env.v7m.vecbase = value & 0xffffff80;
+ cpu->env.v7m.vecbase[attrs.secure] = value & 0xffffff80;
break;
case 0xd0c: /* Application Interrupt/Reset Control. */
if ((value >> 16) == 0x05fa) {
@@ -623,7 +683,20 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
R_V7M_CCR_USERSETMPEND_MASK |
R_V7M_CCR_NONBASETHRDENA_MASK);
- cpu->env.v7m.ccr = value;
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ /* v8M makes NONBASETHRDENA and STKALIGN be RES1 */
+ value |= R_V7M_CCR_NONBASETHRDENA_MASK
+ | R_V7M_CCR_STKALIGN_MASK;
+ }
+ if (attrs.secure) {
+ /* the BFHFNMIGN bit is not banked; keep that in the NS copy */
+ cpu->env.v7m.ccr[M_REG_NS] =
+ (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
+ | (value & R_V7M_CCR_BFHFNMIGN_MASK);
+ value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
+ }
+
+ cpu->env.v7m.ccr[attrs.secure] = value;
break;
case 0xd24: /* System Handler Control. */
s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
@@ -643,7 +716,13 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
nvic_irq_update(s);
break;
case 0xd28: /* Configurable Fault Status. */
- cpu->env.v7m.cfsr &= ~value; /* W1C */
+ 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 */
@@ -652,7 +731,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
cpu->env.v7m.dfsr &= ~value; /* W1C */
break;
case 0xd34: /* Mem Manage Address. */
- cpu->env.v7m.mmfar = value;
+ cpu->env.v7m.mmfar[attrs.secure] = value;
return;
case 0xd38: /* Bus Fault Address. */
cpu->env.v7m.bfar = value;
@@ -670,9 +749,10 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
qemu_log_mask(LOG_GUEST_ERROR, "MPU_CTRL: HFNMIENA and !ENABLE is "
"UNPREDICTABLE\n");
}
- cpu->env.v7m.mpu_ctrl = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
- R_V7M_MPU_CTRL_HFNMIENA_MASK |
- R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
+ cpu->env.v7m.mpu_ctrl[attrs.secure]
+ = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
+ R_V7M_MPU_CTRL_HFNMIENA_MASK |
+ R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
tlb_flush(CPU(cpu));
break;
case 0xd98: /* MPU_RNR */
@@ -681,7 +761,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
PRIu32 "/%" PRIu32 "\n",
value, cpu->pmsav7_dregion);
} else {
- cpu->env.pmsav7.rnr = value;
+ cpu->env.pmsav7.rnr[attrs.secure] = value;
}
break;
case 0xd9c: /* MPU_RBAR */
@@ -691,6 +771,26 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
{
int region;
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ /* PMSAv8M handling of the aliases is different from v7M:
+ * aliases A1, A2, A3 override the low two bits of the region
+ * number in MPU_RNR, and there is no 'region' field in the
+ * RBAR register.
+ */
+ int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
+
+ region = cpu->env.pmsav7.rnr[attrs.secure];
+ if (aliasno) {
+ region = deposit32(region, 0, 2, aliasno);
+ }
+ if (region >= cpu->pmsav7_dregion) {
+ return;
+ }
+ cpu->env.pmsav8.rbar[attrs.secure][region] = value;
+ tlb_flush(CPU(cpu));
+ return;
+ }
+
if (value & (1 << 4)) {
/* VALID bit means use the region number specified in this
* value and also update MPU_RNR.REGION with that value.
@@ -702,9 +802,9 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
region, cpu->pmsav7_dregion);
return;
}
- cpu->env.pmsav7.rnr = region;
+ cpu->env.pmsav7.rnr[attrs.secure] = region;
} else {
- region = cpu->env.pmsav7.rnr;
+ region = cpu->env.pmsav7.rnr[attrs.secure];
}
if (region >= cpu->pmsav7_dregion) {
@@ -715,12 +815,31 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
tlb_flush(CPU(cpu));
break;
}
- case 0xda0: /* MPU_RASR */
- case 0xda8: /* MPU_RASR_A1 */
- case 0xdb0: /* MPU_RASR_A2 */
- case 0xdb8: /* MPU_RASR_A3 */
+ case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
+ case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
+ case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
+ case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
{
- int region = cpu->env.pmsav7.rnr;
+ int region = cpu->env.pmsav7.rnr[attrs.secure];
+
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ /* PMSAv8M handling of the aliases is different from v7M:
+ * aliases A1, A2, A3 override the low two bits of the region
+ * number in MPU_RNR.
+ */
+ int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
+
+ region = cpu->env.pmsav7.rnr[attrs.secure];
+ if (aliasno) {
+ region = deposit32(region, 0, 2, aliasno);
+ }
+ if (region >= cpu->pmsav7_dregion) {
+ return;
+ }
+ cpu->env.pmsav8.rlar[attrs.secure][region] = value;
+ tlb_flush(CPU(cpu));
+ return;
+ }
if (region >= cpu->pmsav7_dregion) {
return;
@@ -731,6 +850,30 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
tlb_flush(CPU(cpu));
break;
}
+ case 0xdc0: /* MPU_MAIR0 */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (cpu->pmsav7_dregion) {
+ /* Register is RES0 if no MPU regions are implemented */
+ cpu->env.pmsav8.mair0[attrs.secure] = value;
+ }
+ /* We don't need to do anything else because memory attributes
+ * only affect cacheability, and we don't implement caching.
+ */
+ break;
+ case 0xdc4: /* MPU_MAIR1 */
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
+ goto bad_offset;
+ }
+ if (cpu->pmsav7_dregion) {
+ /* Register is RES0 if no MPU regions are implemented */
+ cpu->env.pmsav8.mair1[attrs.secure] = value;
+ }
+ /* We don't need to do anything else because memory attributes
+ * only affect cacheability, and we don't implement caching.
+ */
+ break;
case 0xf00: /* Software Triggered Interrupt Register */
{
int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;
@@ -740,17 +883,21 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
break;
}
default:
+ bad_offset:
qemu_log_mask(LOG_GUEST_ERROR,
"NVIC: Bad write offset 0x%x\n", offset);
}
}
-static bool nvic_user_access_ok(NVICState *s, hwaddr offset)
+static bool nvic_user_access_ok(NVICState *s, hwaddr offset, MemTxAttrs attrs)
{
/* Return true if unprivileged access to this register is permitted. */
switch (offset) {
case 0xf00: /* STIR: accessible only if CCR.USERSETMPEND permits */
- return s->cpu->env.v7m.ccr & R_V7M_CCR_USERSETMPEND_MASK;
+ /* For access via STIR_NS it is the NS CCR.USERSETMPEND that
+ * controls access even though the CPU is in Secure state (I_QDKX).
+ */
+ return s->cpu->env.v7m.ccr[attrs.secure] & R_V7M_CCR_USERSETMPEND_MASK;
default:
/* All other user accesses cause a BusFault unconditionally */
return false;
@@ -766,7 +913,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
unsigned i, startvec, end;
uint32_t val;
- if (attrs.user && !nvic_user_access_ok(s, addr)) {
+ if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
/* Generate BusFault for unprivileged accesses */
return MEMTX_ERROR;
}
@@ -831,7 +978,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
break;
default:
if (size == 4) {
- val = nvic_readl(s, offset);
+ val = nvic_readl(s, offset, attrs);
} else {
qemu_log_mask(LOG_GUEST_ERROR,
"NVIC: Bad read of size %d at offset 0x%x\n",
@@ -856,7 +1003,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
trace_nvic_sysreg_write(addr, value, size);
- if (attrs.user && !nvic_user_access_ok(s, addr)) {
+ if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
/* Generate BusFault for unprivileged accesses */
return MEMTX_ERROR;
}
@@ -912,7 +1059,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
return MEMTX_OK;
}
if (size == 4) {
- nvic_writel(s, offset, value);
+ nvic_writel(s, offset, value, attrs);
return MEMTX_OK;
}
qemu_log_mask(LOG_GUEST_ERROR,
@@ -927,6 +1074,47 @@ static const MemoryRegionOps nvic_sysreg_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
+static MemTxResult nvic_sysreg_ns_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size,
+ MemTxAttrs attrs)
+{
+ if (attrs.secure) {
+ /* S accesses to the alias act like NS accesses to the real region */
+ attrs.secure = 0;
+ return nvic_sysreg_write(opaque, addr, value, size, attrs);
+ } else {
+ /* NS attrs are RAZ/WI for privileged, and BusFault for user */
+ if (attrs.user) {
+ return MEMTX_ERROR;
+ }
+ return MEMTX_OK;
+ }
+}
+
+static MemTxResult nvic_sysreg_ns_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
+{
+ if (attrs.secure) {
+ /* S accesses to the alias act like NS accesses to the real region */
+ attrs.secure = 0;
+ return nvic_sysreg_read(opaque, addr, data, size, attrs);
+ } else {
+ /* NS attrs are RAZ/WI for privileged, and BusFault for user */
+ if (attrs.user) {
+ return MEMTX_ERROR;
+ }
+ *data = 0;
+ return MEMTX_OK;
+ }
+}
+
+static const MemoryRegionOps nvic_sysreg_ns_ops = {
+ .read_with_attrs = nvic_sysreg_ns_read,
+ .write_with_attrs = nvic_sysreg_ns_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
static int nvic_post_load(void *opaque, int version_id)
{
NVICState *s = opaque;
@@ -1028,6 +1216,7 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
NVICState *s = NVIC(dev);
SysBusDevice *systick_sbd;
Error *err = NULL;
+ int regionlen;
s->cpu = ARM_CPU(qemu_get_cpu(0));
assert(s->cpu);
@@ -1060,8 +1249,23 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
* 0xd00..0xd3c - SCS registers
* 0xd40..0xeff - Reserved or Not implemented
* 0xf00 - STIR
+ *
+ * Some registers within this space are banked between security states.
+ * In v8M there is a second range 0xe002e000..0xe002efff which is the
+ * NonSecure alias SCS; secure accesses to this behave like NS accesses
+ * to the main SCS range, and non-secure accesses (including when
+ * the security extension is not implemented) are RAZ/WI.
+ * Note that both the main SCS range and the alias range are defined
+ * to be exempt from memory attribution (R_BLJT) and so the memory
+ * transaction attribute always matches the current CPU security
+ * state (attrs.secure == env->v7m.secure). In the nvic_sysreg_ns_ops
+ * wrappers we change attrs.secure to indicate the NS access; so
+ * generally code determining which banked register to use should
+ * use attrs.secure; code determining actual behaviour of the system
+ * should use env->v7m.secure.
*/
- memory_region_init(&s->container, OBJECT(s), "nvic", 0x1000);
+ regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000;
+ memory_region_init(&s->container, OBJECT(s), "nvic", regionlen);
/* The system register region goes at the bottom of the priority
* stack as it covers the whole page.
*/
@@ -1072,6 +1276,13 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
sysbus_mmio_get_region(systick_sbd, 0),
1);
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
+ memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
+ &nvic_sysreg_ns_ops, s,
+ "nvic_sysregs_ns", 0x1000);
+ memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
+ }
+
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
}
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 5ffa739f68..d4c2c89dc1 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -989,18 +989,6 @@ static void xilinx_enet_init(Object *obj)
XilinxAXIEnet *s = XILINX_AXI_ENET(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
- object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,
- (Object **) &s->tx_data_dev,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
- object_property_add_link(obj, "axistream-control-connected",
- TYPE_STREAM_SLAVE,
- (Object **) &s->tx_control_dev,
- qdev_prop_allow_set_link_before_realize,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
-
object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
TYPE_XILINX_AXI_ENET_DATA_STREAM);
object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),
@@ -1021,6 +1009,10 @@ static Property xilinx_enet_properties[] = {
DEFINE_PROP_UINT32("rxmem", XilinxAXIEnet, c_rxmem, 0x1000),
DEFINE_PROP_UINT32("txmem", XilinxAXIEnet, c_txmem, 0x1000),
DEFINE_NIC_PROPERTIES(XilinxAXIEnet, conf),
+ DEFINE_PROP_LINK("axistream-connected", XilinxAXIEnet,
+ tx_data_dev, TYPE_STREAM_SLAVE, StreamSlave *),
+ DEFINE_PROP_LINK("axistream-control-connected", XilinxAXIEnet,
+ tx_control_dev, TYPE_STREAM_SLAVE, StreamSlave *),
DEFINE_PROP_END_OF_LIST(),
};