1
Second ARM pull request of this week; this one has my next
1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
2
set of v8M patches and a handful of more minor stuff from
3
other people.
4
2
5
thanks
3
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging (2024-02-14 15:45:52 +0000)
6
-- PMM
7
4
8
The following changes since commit 8ee5f9b3ecc94e3eb7a8235f4b2c3ec9024807f6:
5
are available in the Git repository at:
9
6
10
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2017-09-07 10:45:18 +0100)
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240215
11
8
12
are available in the git repository at:
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
13
10
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170907
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +0000)
15
16
for you to fetch changes up to c99a55d38dd5b5131f3fcbbaf41828a09ee62544:
17
18
target/arm: Add Jazelle feature (2017-09-07 13:54:55 +0100)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
target-arm:
14
target-arm queue:
22
* cleanups converting to DEFINE_PROP_LINK
15
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
23
* allwinner-a10: mark as not user-creatable
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
24
* initial patches working towards ARMv8M support
17
* Fix some errors in SVE/SME handling of MTE tags
25
* implement generating aborts on memory transaction failures
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
26
* make BXJ behave correctly (ie not UNDEF) on ARMv6-and-later
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
21
* hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
22
* tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
23
* Don't assert on vmload/vmsave of M-profile CPUs
24
* hw/arm/smmuv3: add support for stage 1 access fault
25
* hw/arm/stellaris: QOM cleanups
26
* Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
27
* Improve Cortex_R52 IMPDEF sysreg modelling
28
* Allow access to SPSR_hyp from hyp mode
29
* New board model mps3-an536 (Cortex-R52)
27
30
28
----------------------------------------------------------------
31
----------------------------------------------------------------
29
Fam Zheng (6):
32
Luc Michel (1):
30
armv7m: Convert bitband.source-memory to DEFINE_PROP_LINK
33
hw/arm/smmuv3: add support for stage 1 access fault
31
armv7m: Convert armv7m.memory to DEFINE_PROP_LINK
32
gicv3: Convert to DEFINE_PROP_LINK
33
xlnx_zynqmp: Convert to DEFINE_PROP_LINK
34
xilinx_axienet: Convert to DEFINE_PROP_LINK
35
xilinx_axidma: Convert to DEFINE_PROP_LINK
36
34
37
Peter Maydell (23):
35
Nabih Estefan (1):
38
target/arm: Implement ARMv8M's PMSAv8 registers
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
39
target/arm: Implement new PMSAv8 behaviour
40
target/arm: Add state field, feature bit and migration for v8M secure state
41
target/arm: Register second AddressSpace for secure v8M CPUs
42
target/arm: Add MMU indexes for secure v8M
43
target/arm: Make BASEPRI register banked for v8M
44
target/arm: Make PRIMASK register banked for v8M
45
target/arm: Make FAULTMASK register banked for v8M
46
target/arm: Make CONTROL register banked for v8M
47
nvic: Add NS alias SCS region
48
target/arm: Make VTOR register banked for v8M
49
target/arm: Make MPU_MAIR0, MPU_MAIR1 registers banked for v8M
50
target/arm: Make MPU_RBAR, MPU_RLAR banked for v8M
51
target/arm: Make MPU_RNR register banked for v8M
52
target/arm: Make MPU_CTRL register banked for v8M
53
target/arm: Make CCR register banked for v8M
54
target/arm: Make MMFAR banked for v8M
55
target/arm: Make CFSR register banked for v8M
56
target/arm: Move regime_is_secure() to target/arm/internals.h
57
target/arm: Implement BXNS, and banked stack pointers
58
boards.h: Define new flag ignore_memory_transaction_failures
59
hw/arm: Set ignore_memory_transaction_failures for most ARM boards
60
target/arm: Implement new do_transaction_failed hook
61
37
62
Portia Stephens (1):
38
Peter Maydell (22):
63
target/arm: Add Jazelle feature
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
40
hw/block/tc58128: Don't emit deprecation warning under qtest
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
42
tests/qtest/bios-tables-test: Allow changes to virt GTDT
43
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
44
tests/qtest/bios-tables-tests: Update virt golden reference
45
hw/arm/npcm7xx: Call qemu_configure_nic_device() for GMAC modules
46
tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
47
target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU
48
target/arm: Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
49
target/arm: The Cortex-R52 has a read-only CBAR
50
target/arm: Add Cortex-R52 IMPDEF sysregs
51
target/arm: Allow access to SPSR_hyp from hyp mode
52
hw/misc/mps2-scc: Fix condition for CFG3 register
53
hw/misc/mps2-scc: Factor out which-board conditionals
54
hw/misc/mps2-scc: Make changes needed for AN536 FPGA image
55
hw/arm/mps3r: Initial skeleton for mps3-an536 board
56
hw/arm/mps3r: Add CPUs, GIC, and per-CPU RAM
57
hw/arm/mps3r: Add UARTs
58
hw/arm/mps3r: Add GPIO, watchdog, dual-timer, I2C devices
59
hw/arm/mps3r: Add remaining devices
60
docs: Add documentation for the mps3-an536 board
64
61
65
Thomas Huth (1):
62
Philippe Mathieu-Daudé (5):
66
hw/arm/allwinner-a10: Mark the allwinner-a10 device with user_creatable = false
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
64
hw/arm/stellaris: Convert ADC controller to Resettable interface
65
hw/arm/stellaris: Convert I2C controller to Resettable interface
66
hw/arm/stellaris: Add missing QOM 'machine' parent
67
hw/arm/stellaris: Add missing QOM 'SoC' parent
67
68
68
include/hw/boards.h | 11 ++
69
Richard Henderson (6):
69
include/hw/intc/armv7m_nvic.h | 1 +
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
70
include/qom/cpu.h | 7 +-
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
71
target/arm/cpu.h | 101 ++++++++++++--
72
target/arm: Adjust and validate mtedesc sizem1
72
target/arm/helper.h | 2 +
73
target/arm: Split out make_svemte_desc
73
target/arm/internals.h | 36 +++++
74
target/arm: Handle mte in do_ldrq, do_ldro
74
target/arm/translate.h | 1 +
75
target/arm: Fix SVE/SME gross MTE suppression checks
75
hw/arm/allwinner-a10.c | 2 +
76
hw/arm/armv7m.c | 16 +--
77
hw/arm/aspeed.c | 3 +
78
hw/arm/collie.c | 1 +
79
hw/arm/cubieboard.c | 1 +
80
hw/arm/digic_boards.c | 1 +
81
hw/arm/exynos4_boards.c | 2 +
82
hw/arm/gumstix.c | 2 +
83
hw/arm/highbank.c | 2 +
84
hw/arm/imx25_pdk.c | 1 +
85
hw/arm/integratorcp.c | 1 +
86
hw/arm/kzm.c | 1 +
87
hw/arm/mainstone.c | 1 +
88
hw/arm/musicpal.c | 1 +
89
hw/arm/netduino2.c | 1 +
90
hw/arm/nseries.c | 2 +
91
hw/arm/omap_sx1.c | 2 +
92
hw/arm/palm.c | 1 +
93
hw/arm/raspi.c | 1 +
94
hw/arm/realview.c | 4 +
95
hw/arm/sabrelite.c | 1 +
96
hw/arm/spitz.c | 4 +
97
hw/arm/stellaris.c | 2 +
98
hw/arm/tosa.c | 1 +
99
hw/arm/versatilepb.c | 2 +
100
hw/arm/vexpress.c | 1 +
101
hw/arm/xilinx_zynq.c | 1 +
102
hw/arm/xlnx-ep108.c | 2 +
103
hw/arm/xlnx-zynqmp.c | 7 +-
104
hw/arm/z2.c | 1 +
105
hw/dma/xilinx_axidma.c | 16 +--
106
hw/intc/arm_gicv3_its_kvm.c | 19 +--
107
hw/intc/armv7m_nvic.c | 291 ++++++++++++++++++++++++++++++++------
108
hw/net/xilinx_axienet.c | 16 +--
109
qom/cpu.c | 16 +++
110
target/arm/cpu.c | 88 +++++++++---
111
target/arm/helper.c | 315 +++++++++++++++++++++++++++++++++---------
112
target/arm/machine.c | 105 ++++++++++++--
113
target/arm/op_helper.c | 43 ++++++
114
target/arm/translate.c | 54 +++++++-
115
scripts/device-crash-test | 1 -
116
48 files changed, 978 insertions(+), 213 deletions(-)
117
76
77
MAINTAINERS | 3 +-
78
docs/system/arm/mps2.rst | 37 +-
79
configs/devices/arm-softmmu/default.mak | 1 +
80
hw/arm/smmuv3-internal.h | 1 +
81
include/hw/arm/smmu-common.h | 1 +
82
include/hw/arm/virt.h | 2 +
83
include/hw/misc/mps2-scc.h | 1 +
84
linux-user/aarch64/target_prctl.h | 29 +-
85
target/arm/internals.h | 2 +-
86
target/arm/tcg/translate-a64.h | 2 +
87
hw/arm/mps3r.c | 640 ++++++++++++++++++++++++++++++++
88
hw/arm/npcm7xx.c | 1 +
89
hw/arm/smmu-common.c | 11 +
90
hw/arm/smmuv3.c | 1 +
91
hw/arm/stellaris.c | 47 ++-
92
hw/arm/virt-acpi-build.c | 20 +-
93
hw/arm/virt.c | 60 ++-
94
hw/arm/xilinx_zynq.c | 2 +
95
hw/block/tc58128.c | 4 +-
96
hw/misc/mps2-scc.c | 138 ++++++-
97
hw/pci-host/raven.c | 1 +
98
target/arm/helper.c | 14 +-
99
target/arm/tcg/cpu32.c | 109 ++++++
100
target/arm/tcg/op_helper.c | 43 ++-
101
target/arm/tcg/sme_helper.c | 8 +-
102
target/arm/tcg/sve_helper.c | 12 +-
103
target/arm/tcg/translate-sme.c | 15 +-
104
target/arm/tcg/translate-sve.c | 83 +++--
105
target/arm/tcg/translate.c | 19 +-
106
tests/qtest/npcm7xx_emc-test.c | 5 +-
107
tests/qtest/npcm_gmac-test.c | 84 +----
108
hw/arm/Kconfig | 5 +
109
hw/arm/meson.build | 1 +
110
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
111
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
112
tests/qtest/meson.build | 4 +-
113
36 files changed, 1184 insertions(+), 222 deletions(-)
114
create mode 100644 hw/arm/mps3r.c
115
diff view generated by jsdifflib
1
From: Portia Stephens <portia.stephens@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This adds a feature bit indicating support of the (trivial) Jazelle
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
4
implementation if ARM_FEATURE_V6 is set or if the processor is arm926
4
connect FIQ output of the GIC CPU interfaces to the CPU.
5
or arm1026. This fixes the issue that any BXJ instruction will
6
result in an illegal_op. BXJ instructions will now check if the
7
architecture supports ARM_FEATURE_JAZELLE.
8
5
9
Signed-off-by: Portia Stephens <portia.stephens@xilinx.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
11
Message-id: 20170905211232.11092-1-portia.stephens@xilinx.com
12
[PMM: edited commit message and comment text a bit]
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
target/arm/cpu.h | 1 +
11
hw/arm/xilinx_zynq.c | 2 ++
17
target/arm/cpu.c | 3 +++
12
1 file changed, 2 insertions(+)
18
target/arm/translate.c | 2 +-
19
3 files changed, 5 insertions(+), 1 deletion(-)
20
13
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
16
--- a/hw/arm/xilinx_zynq.c
24
+++ b/target/arm/cpu.h
17
+++ b/hw/arm/xilinx_zynq.c
25
@@ -XXX,XX +XXX,XX @@ enum arm_features {
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
26
ARM_FEATURE_PMU, /* has PMU support */
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
27
ARM_FEATURE_VBAR, /* has cp15 VBAR */
20
sysbus_connect_irq(busdev, 0,
28
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
29
+ ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
22
+ sysbus_connect_irq(busdev, 1,
30
};
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
31
24
32
static inline int arm_feature(CPUARMState *env, int feature)
25
for (n = 0; n < 64; n++) {
33
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
pic[n] = qdev_get_gpio_in(dev, n);
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/cpu.c
36
+++ b/target/arm/cpu.c
37
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
38
}
39
if (arm_feature(env, ARM_FEATURE_V6)) {
40
set_feature(env, ARM_FEATURE_V5);
41
+ set_feature(env, ARM_FEATURE_JAZELLE);
42
if (!arm_feature(env, ARM_FEATURE_M)) {
43
set_feature(env, ARM_FEATURE_AUXCR);
44
}
45
@@ -XXX,XX +XXX,XX @@ static void arm926_initfn(Object *obj)
46
set_feature(&cpu->env, ARM_FEATURE_VFP);
47
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
48
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
49
+ set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
50
cpu->midr = 0x41069265;
51
cpu->reset_fpsid = 0x41011090;
52
cpu->ctr = 0x1dd20d2;
53
@@ -XXX,XX +XXX,XX @@ static void arm1026_initfn(Object *obj)
54
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
55
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
56
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
57
+ set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
58
cpu->midr = 0x4106a262;
59
cpu->reset_fpsid = 0x410110a0;
60
cpu->ctr = 0x1dd20d2;
61
diff --git a/target/arm/translate.c b/target/arm/translate.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/translate.c
64
+++ b/target/arm/translate.c
65
@@ -XXX,XX +XXX,XX @@
66
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
67
/* currently all emulated v5 cores are also v5TE, so don't bother */
68
#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
69
-#define ENABLE_ARCH_5J 0
70
+#define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
71
#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
72
#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
73
#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
74
--
27
--
75
2.7.4
28
2.34.1
76
29
77
30
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The API does not generate an error for setting ASYNC | SYNC; that merely
4
constrains the selection vs the per-cpu default. For qemu linux-user,
5
choose SYNC as the default.
6
7
Cc: qemu-stable@nongnu.org
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
11
Message-id: 20240207025210.8837-2-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
15
1 file changed, 17 insertions(+), 12 deletions(-)
16
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/linux-user/aarch64/target_prctl.h
20
+++ b/linux-user/aarch64/target_prctl.h
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
23
24
if (cpu_isar_feature(aa64_mte, cpu)) {
25
- switch (arg2 & PR_MTE_TCF_MASK) {
26
- case PR_MTE_TCF_NONE:
27
- case PR_MTE_TCF_SYNC:
28
- case PR_MTE_TCF_ASYNC:
29
- break;
30
- default:
31
- return -EINVAL;
32
- }
33
-
34
/*
35
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
36
- * Note that the syscall values are consistent with hw.
37
+ *
38
+ * The kernel has a per-cpu configuration for the sysadmin,
39
+ * /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
40
+ * which qemu does not implement.
41
+ *
42
+ * Because there is no performance difference between the modes, and
43
+ * because SYNC is most useful for debugging MTE errors, choose SYNC
44
+ * as the preferred mode. With this preference, and the way the API
45
+ * uses only two bits, there is no way for the program to select
46
+ * ASYMM mode.
47
*/
48
- env->cp15.sctlr_el[1] =
49
- deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT);
50
+ unsigned tcf = 0;
51
+ if (arg2 & PR_MTE_TCF_SYNC) {
52
+ tcf = 1;
53
+ } else if (arg2 & PR_MTE_TCF_ASYNC) {
54
+ tcf = 2;
55
+ }
56
+ env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
57
58
/*
59
* Write PR_MTE_TAG to GCR_EL1[Exclude].
60
--
61
2.34.1
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
QEMU currently exits unexpectedly when the user accidentially
3
The field is encoded as [0-3], which is convenient for
4
tries to do something like this:
4
indexing our array of function pointers, but the true
5
value is [1-4]. Adjust before calling do_mem_zpa.
5
6
6
$ aarch64-softmmu/qemu-system-aarch64 -S -M integratorcp -nographic
7
Add an assert, and move the comment re passing ZT to
7
QEMU 2.9.93 monitor - type 'help' for more information
8
the helper back next to the relevant code.
8
(qemu) device_add allwinner-a10
9
Unsupported NIC model: smc91c111
10
9
11
Exiting just due to a "device_add" should not happen. Looking closer
10
Cc: qemu-stable@nongnu.org
12
at the the realize and instance_init function of this device also
11
Fixes: 206adacfb8d ("target/arm: Add mte helpers for sve scalar + int loads")
13
reveals that it is using serial_hds and nd_table directly there, so
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
this device is clearly not creatable by the user and should be marked
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
15
accordingly.
14
Message-id: 20240207025210.8837-3-richard.henderson@linaro.org
16
17
Signed-off-by: Thomas Huth <thuth@redhat.com>
18
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
19
Message-id: 1503416789-32080-1-git-send-email-thuth@redhat.com
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
17
---
23
hw/arm/allwinner-a10.c | 2 ++
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
24
scripts/device-crash-test | 1 -
19
1 file changed, 8 insertions(+), 8 deletions(-)
25
2 files changed, 2 insertions(+), 1 deletion(-)
26
20
27
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
28
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/allwinner-a10.c
23
--- a/target/arm/tcg/translate-sve.c
30
+++ b/hw/arm/allwinner-a10.c
24
+++ b/target/arm/tcg/translate-sve.c
31
@@ -XXX,XX +XXX,XX @@ static void aw_a10_class_init(ObjectClass *oc, void *data)
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
32
DeviceClass *dc = DEVICE_CLASS(oc);
26
TCGv_ptr t_pg;
33
27
int desc = 0;
34
dc->realize = aw_a10_realize;
28
35
+ /* Reason: Uses serial_hds in realize and nd_table in instance_init */
29
- /*
36
+ dc->user_creatable = false;
30
- * For e.g. LD4, there are not enough arguments to pass all 4
31
- * registers as pointers, so encode the regno into the data field.
32
- * For consistency, do this even for LD1.
33
- */
34
+ assert(mte_n >= 1 && mte_n <= 4);
35
if (s->mte_active[0]) {
36
int msz = dtype_msz(dtype);
37
38
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
39
addr = clean_data_tbi(s, addr);
40
}
41
42
+ /*
43
+ * For e.g. LD4, there are not enough arguments to pass all 4
44
+ * registers as pointers, so encode the regno into the data field.
45
+ * For consistency, do this even for LD1.
46
+ */
47
desc = simd_desc(vsz, vsz, zt | desc);
48
t_pg = tcg_temp_new_ptr();
49
50
@@ -XXX,XX +XXX,XX @@ static void do_ld_zpa(DisasContext *s, int zt, int pg,
51
* accessible via the instruction encoding.
52
*/
53
assert(fn != NULL);
54
- do_mem_zpa(s, zt, pg, addr, dtype, nreg, false, fn);
55
+ do_mem_zpa(s, zt, pg, addr, dtype, nreg + 1, false, fn);
37
}
56
}
38
57
39
static const TypeInfo aw_a10_type_info = {
58
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
40
diff --git a/scripts/device-crash-test b/scripts/device-crash-test
59
@@ -XXX,XX +XXX,XX @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
41
index XXXXXXX..XXXXXXX 100755
60
if (nreg == 0) {
42
--- a/scripts/device-crash-test
61
/* ST1 */
43
+++ b/scripts/device-crash-test
62
fn = fn_single[s->mte_active[0]][be][msz][esz];
44
@@ -XXX,XX +XXX,XX @@ ERROR_WHITELIST = [
63
- nreg = 1;
45
{'log':r"Device [\w.,-]+ can not be dynamically instantiated"},
64
} else {
46
{'log':r"Platform Bus: Can not fit MMIO region of size "},
65
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
47
# other more specific errors we will ignore:
66
assert(msz == esz);
48
- {'device':'allwinner-a10', 'log':"Unsupported NIC model:"},
67
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
49
{'device':'.*-spapr-cpu-core', 'log':r"CPU core type should be"},
68
}
50
{'log':r"MSI(-X)? is not supported by interrupt controller"},
69
assert(fn != NULL);
51
{'log':r"pxb-pcie? devices cannot reside on a PCIe? bus"},
70
- do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn);
71
+ do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg + 1, true, fn);
72
}
73
74
static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
52
--
75
--
53
2.7.4
76
2.34.1
54
55
diff view generated by jsdifflib
1
Implement the new do_transaction_failed hook for ARM, which should
1
From: Richard Henderson <richard.henderson@linaro.org>
2
cause the CPU to take a prefetch abort or data abort.
3
2
3
When we added SVE_MTEDESC_SHIFT, we effectively limited the
4
maximum size of MTEDESC. Adjust SIZEM1 to consume the remaining
5
bits (32 - 10 - 5 - 12 == 5). Assert that the data to be stored
6
fits within the field (expecting 8 * 4 - 1 == 31, exact fit).
7
8
Cc: qemu-stable@nongnu.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 1504626814-23124-4-git-send-email-peter.maydell@linaro.org
8
---
14
---
9
target/arm/internals.h | 10 ++++++++++
15
target/arm/internals.h | 2 +-
10
target/arm/cpu.c | 1 +
16
target/arm/tcg/translate-sve.c | 7 ++++---
11
target/arm/op_helper.c | 43 +++++++++++++++++++++++++++++++++++++++++++
17
2 files changed, 5 insertions(+), 4 deletions(-)
12
3 files changed, 54 insertions(+)
13
18
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
21
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
22
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
19
MMUAccessType access_type,
24
FIELD(MTEDESC, TCMA, 6, 2)
20
int mmu_idx, uintptr_t retaddr);
25
FIELD(MTEDESC, WRITE, 8, 1)
21
26
FIELD(MTEDESC, ALIGN, 9, 3)
22
+/* arm_cpu_do_transaction_failed: handle a memory system error response
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
23
+ * (eg "no device/memory present at address") by raising an external abort
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
24
+ * exception
29
25
+ */
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
26
+void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
27
+ vaddr addr, unsigned size,
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
28
+ MMUAccessType access_type,
33
index XXXXXXX..XXXXXXX 100644
29
+ int mmu_idx, MemTxAttrs attrs,
34
--- a/target/arm/tcg/translate-sve.c
30
+ MemTxResult response, uintptr_t retaddr);
35
+++ b/target/arm/tcg/translate-sve.c
31
+
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
32
/* Call the EL change hook if one has been registered */
33
static inline void arm_call_el_change_hook(ARMCPU *cpu)
34
{
37
{
35
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
38
unsigned vsz = vec_full_reg_size(s);
36
index XXXXXXX..XXXXXXX 100644
39
TCGv_ptr t_pg;
37
--- a/target/arm/cpu.c
40
+ uint32_t sizem1;
38
+++ b/target/arm/cpu.c
41
int desc = 0;
39
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
42
40
#else
43
assert(mte_n >= 1 && mte_n <= 4);
41
cc->do_interrupt = arm_cpu_do_interrupt;
44
+ sizem1 = (mte_n << dtype_msz(dtype)) - 1;
42
cc->do_unaligned_access = arm_cpu_do_unaligned_access;
45
+ assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
43
+ cc->do_transaction_failed = arm_cpu_do_transaction_failed;
46
if (s->mte_active[0]) {
44
cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
47
- int msz = dtype_msz(dtype);
45
cc->asidx_from_attrs = arm_asidx_from_attrs;
48
-
46
cc->vmsd = &vmstate_arm_cpu;
49
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
47
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
50
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
48
index XXXXXXX..XXXXXXX 100644
51
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
49
--- a/target/arm/op_helper.c
52
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
50
+++ b/target/arm/op_helper.c
53
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
51
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
54
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
52
deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi);
55
desc <<= SVE_MTEDESC_SHIFT;
53
}
56
} else {
54
57
addr = clean_data_tbi(s, addr);
55
+/* arm_cpu_do_transaction_failed: handle a memory system error response
56
+ * (eg "no device/memory present at address") by raising an external abort
57
+ * exception
58
+ */
59
+void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
60
+ vaddr addr, unsigned size,
61
+ MMUAccessType access_type,
62
+ int mmu_idx, MemTxAttrs attrs,
63
+ MemTxResult response, uintptr_t retaddr)
64
+{
65
+ ARMCPU *cpu = ARM_CPU(cs);
66
+ CPUARMState *env = &cpu->env;
67
+ uint32_t fsr, fsc;
68
+ ARMMMUFaultInfo fi = {};
69
+ ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
70
+
71
+ if (retaddr) {
72
+ /* now we have a real cpu fault */
73
+ cpu_restore_state(cs, retaddr);
74
+ }
75
+
76
+ /* The EA bit in syndromes and fault status registers is an
77
+ * IMPDEF classification of external aborts. ARM implementations
78
+ * usually use this to indicate AXI bus Decode error (0) or
79
+ * Slave error (1); in QEMU we follow that.
80
+ */
81
+ fi.ea = (response != MEMTX_DECODE_ERROR);
82
+
83
+ /* The fault status register format depends on whether we're using
84
+ * the LPAE long descriptor format, or the short descriptor format.
85
+ */
86
+ if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
87
+ /* long descriptor form, STATUS 0b010000: synchronous ext abort */
88
+ fsr = (fi.ea << 12) | (1 << 9) | 0x10;
89
+ } else {
90
+ /* short descriptor form, FSR 0b01000 : synchronous ext abort */
91
+ fsr = (fi.ea << 12) | 0x8;
92
+ }
93
+ fsc = 0x10;
94
+
95
+ deliver_fault(cpu, addr, access_type, fsr, fsc, &fi);
96
+}
97
+
98
#endif /* !defined(CONFIG_USER_ONLY) */
99
100
uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
101
--
58
--
102
2.7.4
59
2.34.1
103
104
diff view generated by jsdifflib
1
For v8M the range 0xe002e000..0xe002efff is an alias region which
1
From: Richard Henderson <richard.henderson@linaro.org>
2
for secure accesses behaves like a NonSecure access to the main
3
SCS region. (For nonsecure accesses including when the security
4
extension is not implemented, it is RAZ/WI.)
5
2
3
Share code that creates mtedesc and embeds within simd_desc.
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 1503414539-28762-11-git-send-email-peter.maydell@linaro.org
8
---
11
---
9
include/hw/intc/armv7m_nvic.h | 1 +
12
target/arm/tcg/translate-a64.h | 2 ++
10
hw/intc/armv7m_nvic.c | 66 ++++++++++++++++++++++++++++++++++++++++++-
13
target/arm/tcg/translate-sme.c | 15 +++--------
11
2 files changed, 66 insertions(+), 1 deletion(-)
14
target/arm/tcg/translate-sve.c | 47 ++++++++++++++++++----------------
15
3 files changed, 31 insertions(+), 33 deletions(-)
12
16
13
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
17
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/intc/armv7m_nvic.h
19
--- a/target/arm/tcg/translate-a64.h
16
+++ b/include/hw/intc/armv7m_nvic.h
20
+++ b/target/arm/tcg/translate-a64.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct NVICState {
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
18
int exception_prio; /* group prio of the highest prio active exception */
22
bool sve_access_check(DisasContext *s);
19
23
bool sme_enabled_check(DisasContext *s);
20
MemoryRegion sysregmem;
24
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
21
+ MemoryRegion sysreg_ns_mem;
25
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
22
MemoryRegion container;
26
+ uint32_t msz, bool is_write, uint32_t data);
23
27
24
uint32_t num_irq;
28
/* This function corresponds to CheckStreamingSVEEnabled. */
25
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
29
static inline bool sme_sm_enabled_check(DisasContext *s)
30
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
26
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/intc/armv7m_nvic.c
32
--- a/target/arm/tcg/translate-sme.c
28
+++ b/hw/intc/armv7m_nvic.c
33
+++ b/target/arm/tcg/translate-sme.c
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps nvic_sysreg_ops = {
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
30
.endianness = DEVICE_NATIVE_ENDIAN,
35
36
TCGv_ptr t_za, t_pg;
37
TCGv_i64 addr;
38
- int svl, desc = 0;
39
+ uint32_t desc;
40
bool be = s->be_data == MO_BE;
41
bool mte = s->mte_active[0];
42
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
44
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
45
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
46
47
- if (mte) {
48
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
49
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
50
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
51
- desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
52
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
53
- desc <<= SVE_MTEDESC_SHIFT;
54
- } else {
55
+ if (!mte) {
56
addr = clean_data_tbi(s, addr);
57
}
58
- svl = streaming_vec_reg_size(s);
59
- desc = simd_desc(svl, svl, desc);
60
+
61
+ desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
62
63
fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
64
tcg_constant_i32(desc));
65
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/tcg/translate-sve.c
68
+++ b/target/arm/tcg/translate-sve.c
69
@@ -XXX,XX +XXX,XX @@ static const uint8_t dtype_esz[16] = {
70
3, 2, 1, 3
31
};
71
};
32
72
33
+static MemTxResult nvic_sysreg_ns_write(void *opaque, hwaddr addr,
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
34
+ uint64_t value, unsigned size,
74
- int dtype, uint32_t mte_n, bool is_write,
35
+ MemTxAttrs attrs)
75
- gen_helper_gvec_mem *fn)
36
+{
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
37
+ if (attrs.secure) {
77
+ uint32_t msz, bool is_write, uint32_t data)
38
+ /* S accesses to the alias act like NS accesses to the real region */
78
{
39
+ attrs.secure = 0;
79
- unsigned vsz = vec_full_reg_size(s);
40
+ return nvic_sysreg_write(opaque, addr, value, size, attrs);
80
- TCGv_ptr t_pg;
41
+ } else {
81
uint32_t sizem1;
42
+ /* NS attrs are RAZ/WI for privileged, and BusFault for user */
82
- int desc = 0;
43
+ if (attrs.user) {
83
+ uint32_t desc = 0;
44
+ return MEMTX_ERROR;
84
45
+ }
85
- assert(mte_n >= 1 && mte_n <= 4);
46
+ return MEMTX_OK;
86
- sizem1 = (mte_n << dtype_msz(dtype)) - 1;
87
+ /* Assert all of the data fits, with or without MTE enabled. */
88
+ assert(nregs >= 1 && nregs <= 4);
89
+ sizem1 = (nregs << msz) - 1;
90
assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
91
+ assert(data < 1u << SVE_MTEDESC_SHIFT);
92
+
93
if (s->mte_active[0]) {
94
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
95
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
96
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
97
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
98
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
99
desc <<= SVE_MTEDESC_SHIFT;
100
- } else {
47
+ }
101
+ }
102
+ return simd_desc(vsz, vsz, desc | data);
48
+}
103
+}
49
+
104
+
50
+static MemTxResult nvic_sysreg_ns_read(void *opaque, hwaddr addr,
105
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
51
+ uint64_t *data, unsigned size,
106
+ int dtype, uint32_t nregs, bool is_write,
52
+ MemTxAttrs attrs)
107
+ gen_helper_gvec_mem *fn)
53
+{
108
+{
54
+ if (attrs.secure) {
109
+ TCGv_ptr t_pg;
55
+ /* S accesses to the alias act like NS accesses to the real region */
110
+ uint32_t desc;
56
+ attrs.secure = 0;
57
+ return nvic_sysreg_read(opaque, addr, data, size, attrs);
58
+ } else {
59
+ /* NS attrs are RAZ/WI for privileged, and BusFault for user */
60
+ if (attrs.user) {
61
+ return MEMTX_ERROR;
62
+ }
63
+ *data = 0;
64
+ return MEMTX_OK;
65
+ }
66
+}
67
+
111
+
68
+static const MemoryRegionOps nvic_sysreg_ns_ops = {
112
+ if (!s->mte_active[0]) {
69
+ .read_with_attrs = nvic_sysreg_ns_read,
113
addr = clean_data_tbi(s, addr);
70
+ .write_with_attrs = nvic_sysreg_ns_write,
114
}
71
+ .endianness = DEVICE_NATIVE_ENDIAN,
115
72
+};
116
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
117
* registers as pointers, so encode the regno into the data field.
118
* For consistency, do this even for LD1.
119
*/
120
- desc = simd_desc(vsz, vsz, zt | desc);
121
+ desc = make_svemte_desc(s, vec_full_reg_size(s), nregs,
122
+ dtype_msz(dtype), is_write, zt);
123
t_pg = tcg_temp_new_ptr();
124
125
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
126
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
127
int scale, TCGv_i64 scalar, int msz, bool is_write,
128
gen_helper_gvec_mem_scatter *fn)
129
{
130
- unsigned vsz = vec_full_reg_size(s);
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
134
- int desc = 0;
135
-
136
- if (s->mte_active[0]) {
137
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
138
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
139
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
140
- desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
141
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
142
- desc <<= SVE_MTEDESC_SHIFT;
143
- }
144
- desc = simd_desc(vsz, vsz, desc | scale);
145
+ uint32_t desc;
146
147
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
148
tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm));
149
tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt));
73
+
150
+
74
static int nvic_post_load(void *opaque, int version_id)
151
+ desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
75
{
152
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
76
NVICState *s = opaque;
77
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
78
NVICState *s = NVIC(dev);
79
SysBusDevice *systick_sbd;
80
Error *err = NULL;
81
+ int regionlen;
82
83
s->cpu = ARM_CPU(qemu_get_cpu(0));
84
assert(s->cpu);
85
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
86
* 0xd00..0xd3c - SCS registers
87
* 0xd40..0xeff - Reserved or Not implemented
88
* 0xf00 - STIR
89
+ *
90
+ * Some registers within this space are banked between security states.
91
+ * In v8M there is a second range 0xe002e000..0xe002efff which is the
92
+ * NonSecure alias SCS; secure accesses to this behave like NS accesses
93
+ * to the main SCS range, and non-secure accesses (including when
94
+ * the security extension is not implemented) are RAZ/WI.
95
+ * Note that both the main SCS range and the alias range are defined
96
+ * to be exempt from memory attribution (R_BLJT) and so the memory
97
+ * transaction attribute always matches the current CPU security
98
+ * state (attrs.secure == env->v7m.secure). In the nvic_sysreg_ns_ops
99
+ * wrappers we change attrs.secure to indicate the NS access; so
100
+ * generally code determining which banked register to use should
101
+ * use attrs.secure; code determining actual behaviour of the system
102
+ * should use env->v7m.secure.
103
*/
104
- memory_region_init(&s->container, OBJECT(s), "nvic", 0x1000);
105
+ regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000;
106
+ memory_region_init(&s->container, OBJECT(s), "nvic", regionlen);
107
/* The system register region goes at the bottom of the priority
108
* stack as it covers the whole page.
109
*/
110
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
111
sysbus_mmio_get_region(systick_sbd, 0),
112
1);
113
114
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
115
+ memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
116
+ &nvic_sysreg_ns_ops, s,
117
+ "nvic_sysregs_ns", 0x1000);
118
+ memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
119
+ }
120
+
121
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
122
}
153
}
123
154
124
--
155
--
125
2.7.4
156
2.34.1
126
127
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
These functions "use the standard load helpers", but
4
fail to clean_data_tbi or populate mtedesc.
5
6
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
10
Message-id: 20240207025210.8837-6-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
14
1 file changed, 13 insertions(+), 2 deletions(-)
15
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/tcg/translate-sve.c
19
+++ b/target/arm/tcg/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
21
unsigned vsz = vec_full_reg_size(s);
22
TCGv_ptr t_pg;
23
int poff;
24
+ uint32_t desc;
25
26
/* Load the first quadword using the normal predicated load helpers. */
27
+ if (!s->mte_active[0]) {
28
+ addr = clean_data_tbi(s, addr);
29
+ }
30
+
31
poff = pred_full_reg_offset(s, pg);
32
if (vsz > 16) {
33
/*
34
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
35
36
gen_helper_gvec_mem *fn
37
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
38
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt)));
39
+ desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
40
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
41
42
/* Replicate that first quadword. */
43
if (vsz > 16) {
44
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
45
unsigned vsz_r32;
46
TCGv_ptr t_pg;
47
int poff, doff;
48
+ uint32_t desc;
49
50
if (vsz < 32) {
51
/*
52
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
53
}
54
55
/* Load the first octaword using the normal predicated load helpers. */
56
+ if (!s->mte_active[0]) {
57
+ addr = clean_data_tbi(s, addr);
58
+ }
59
60
poff = pred_full_reg_offset(s, pg);
61
if (vsz > 32) {
62
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
63
64
gen_helper_gvec_mem *fn
65
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
66
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(32, 32, zt)));
67
+ desc = make_svemte_desc(s, 32, 1, dtype_msz(dtype), false, zt);
68
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
69
70
/*
71
* Replicate that first octaword.
72
--
73
2.34.1
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Fam Zheng <famz@redhat.com>
3
The TBI and TCMA bits are located within mtedesc, not desc.
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
5
Message-id: 20170905131149.10669-5-famz@redhat.com
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
hw/arm/xlnx-zynqmp.c | 7 ++-----
12
target/arm/tcg/sme_helper.c | 8 ++++----
10
1 file changed, 2 insertions(+), 5 deletions(-)
13
target/arm/tcg/sve_helper.c | 12 ++++++------
14
2 files changed, 10 insertions(+), 10 deletions(-)
11
15
12
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/xlnx-zynqmp.c
18
--- a/target/arm/tcg/sme_helper.c
15
+++ b/hw/arm/xlnx-zynqmp.c
19
+++ b/target/arm/tcg/sme_helper.c
16
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
17
&error_abort);
21
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
22
23
/* Perform gross MTE suppression early. */
24
- if (!tbi_check(desc, bit55) ||
25
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
26
+ if (!tbi_check(mtedesc, bit55) ||
27
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
28
mtedesc = 0;
18
}
29
}
19
30
20
- object_property_add_link(obj, "ddr-ram", TYPE_MEMORY_REGION,
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
21
- (Object **)&s->ddr_ram,
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
22
- qdev_prop_allow_set_link_before_realize,
33
23
- OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
34
/* Perform gross MTE suppression early. */
24
-
35
- if (!tbi_check(desc, bit55) ||
25
object_initialize(&s->gic, sizeof(s->gic), gic_class_name());
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
26
qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
37
+ if (!tbi_check(mtedesc, bit55) ||
27
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
28
@@ -XXX,XX +XXX,XX @@ static Property xlnx_zynqmp_props[] = {
39
mtedesc = 0;
29
DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
40
}
30
DEFINE_PROP_BOOL("secure", XlnxZynqMPState, secure, false),
41
31
DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
32
+ DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
43
index XXXXXXX..XXXXXXX 100644
33
+ MemoryRegion *),
44
--- a/target/arm/tcg/sve_helper.c
34
DEFINE_PROP_END_OF_LIST()
45
+++ b/target/arm/tcg/sve_helper.c
35
};
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
48
49
/* Perform gross MTE suppression early. */
50
- if (!tbi_check(desc, bit55) ||
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
52
+ if (!tbi_check(mtedesc, bit55) ||
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
54
mtedesc = 0;
55
}
56
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
59
60
/* Perform gross MTE suppression early. */
61
- if (!tbi_check(desc, bit55) ||
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
63
+ if (!tbi_check(mtedesc, bit55) ||
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
65
mtedesc = 0;
66
}
67
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
69
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
70
71
/* Perform gross MTE suppression early. */
72
- if (!tbi_check(desc, bit55) ||
73
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
74
+ if (!tbi_check(mtedesc, bit55) ||
75
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
76
mtedesc = 0;
77
}
36
78
37
--
79
--
38
2.7.4
80
2.34.1
39
40
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
The raven_io_ops MemoryRegionOps is the only one in the source tree
2
which sets .valid.unaligned to indicate that it should support
3
unaligned accesses and which does not also set .impl.unaligned to
4
indicate that its read and write functions can do the unaligned
5
handling themselves. This is a problem, because at the moment the
6
core memory system does not implement the support for handling
7
unaligned accesses by doing a series of aligned accesses and
8
combining them (system/memory.c:access_with_adjusted_size() has a
9
TODO comment noting this).
2
10
3
Signed-off-by: Fam Zheng <famz@redhat.com>
11
Fortunately raven_io_read() and raven_io_write() will correctly deal
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
with the case of being passed an unaligned address, so we can fix the
5
Message-id: 20170905131149.10669-7-famz@redhat.com
13
missing unaligned access support by setting .impl.unaligned in the
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
MemoryRegionOps struct.
15
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Tested-by: Cédric Le Goater <clg@redhat.com>
19
Reviewed-by: Cédric Le Goater <clg@redhat.com>
20
Message-id: 20240112134640.1775041-1-peter.maydell@linaro.org
8
---
21
---
9
hw/dma/xilinx_axidma.c | 16 ++++------------
22
hw/pci-host/raven.c | 1 +
10
1 file changed, 4 insertions(+), 12 deletions(-)
23
1 file changed, 1 insertion(+)
11
24
12
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
13
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/dma/xilinx_axidma.c
27
--- a/hw/pci-host/raven.c
15
+++ b/hw/dma/xilinx_axidma.c
28
+++ b/hw/pci-host/raven.c
16
@@ -XXX,XX +XXX,XX @@ static void xilinx_axidma_init(Object *obj)
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
17
XilinxAXIDMA *s = XILINX_AXI_DMA(obj);
30
.write = raven_io_write,
18
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
31
.endianness = DEVICE_LITTLE_ENDIAN,
19
32
.impl.max_access_size = 4,
20
- object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,
33
+ .impl.unaligned = true,
21
- (Object **)&s->tx_data_dev,
34
.valid.unaligned = true,
22
- qdev_prop_allow_set_link_before_realize,
23
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
24
- &error_abort);
25
- object_property_add_link(obj, "axistream-control-connected",
26
- TYPE_STREAM_SLAVE,
27
- (Object **)&s->tx_control_dev,
28
- qdev_prop_allow_set_link_before_realize,
29
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
30
- &error_abort);
31
-
32
object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
33
TYPE_XILINX_AXI_DMA_DATA_STREAM);
34
object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),
35
@@ -XXX,XX +XXX,XX @@ static void xilinx_axidma_init(Object *obj)
36
37
static Property axidma_properties[] = {
38
DEFINE_PROP_UINT32("freqhz", XilinxAXIDMA, freqhz, 50000000),
39
+ DEFINE_PROP_LINK("axistream-connected", XilinxAXIDMA,
40
+ tx_data_dev, TYPE_STREAM_SLAVE, StreamSlave *),
41
+ DEFINE_PROP_LINK("axistream-control-connected", XilinxAXIDMA,
42
+ tx_control_dev, TYPE_STREAM_SLAVE, StreamSlave *),
43
DEFINE_PROP_END_OF_LIST(),
44
};
35
};
45
36
46
--
37
--
47
2.7.4
38
2.34.1
48
39
49
40
diff view generated by jsdifflib
1
Define a new MachineClass field ignore_memory_transaction_failures.
1
Suppress the deprecation warning when we're running under qtest,
2
If this is flag is true then the CPU will ignore memory transaction
2
to avoid "make check" including warning messages in its output.
3
failures which should cause the CPU to take an exception due to an
4
access to an unassigned physical address; the transaction will
5
instead return zero (for a read) or be ignored (for a write). This
6
should be set only by legacy board models which rely on the old
7
RAZ/WI behaviour for handling devices that QEMU does not yet model.
8
New board models should instead use "unimplemented-device" for all
9
memory ranges where the guest will attempt to probe for a device that
10
QEMU doesn't implement and a stub device is required.
11
12
We need this for ARM boards, where we're about to implement support for
13
generating external aborts on memory transaction failures. Too many
14
of our legacy board models rely on the RAZ/WI behaviour and we
15
would break currently working guests when their "probe for device"
16
code provoked an external abort rather than a RAZ.
17
3
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
20
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
21
Message-id: 1504626814-23124-2-git-send-email-peter.maydell@linaro.org
22
---
7
---
23
include/hw/boards.h | 11 +++++++++++
8
hw/block/tc58128.c | 4 +++-
24
include/qom/cpu.h | 7 ++++++-
9
1 file changed, 3 insertions(+), 1 deletion(-)
25
qom/cpu.c | 16 ++++++++++++++++
26
3 files changed, 33 insertions(+), 1 deletion(-)
27
10
28
diff --git a/include/hw/boards.h b/include/hw/boards.h
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
29
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/boards.h
13
--- a/hw/block/tc58128.c
31
+++ b/include/hw/boards.h
14
+++ b/hw/block/tc58128.c
32
@@ -XXX,XX +XXX,XX @@ typedef struct {
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
33
* size than the target architecture's minimum. (Attempting to create
16
34
* such a CPU will fail.) Note that changing this is a migration
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
35
* compatibility break for the machine.
36
+ * @ignore_memory_transaction_failures:
37
+ * If this is flag is true then the CPU will ignore memory transaction
38
+ * failures which should cause the CPU to take an exception due to an
39
+ * access to an unassigned physical address; the transaction will instead
40
+ * return zero (for a read) or be ignored (for a write). This should be
41
+ * set only by legacy board models which rely on the old RAZ/WI behaviour
42
+ * for handling devices that QEMU does not yet model. New board models
43
+ * should instead use "unimplemented-device" for all memory ranges where
44
+ * the guest will attempt to probe for a device that QEMU doesn't
45
+ * implement and a stub device is required.
46
*/
47
struct MachineClass {
48
/*< private >*/
49
@@ -XXX,XX +XXX,XX @@ struct MachineClass {
50
bool rom_file_has_mr;
51
int minimum_page_bits;
52
bool has_hotpluggable_cpus;
53
+ bool ignore_memory_transaction_failures;
54
int numa_mem_align_shift;
55
void (*numa_auto_assign_ram)(MachineClass *mc, NodeInfo *nodes,
56
int nb_nodes, ram_addr_t size);
57
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/include/qom/cpu.h
60
+++ b/include/qom/cpu.h
61
@@ -XXX,XX +XXX,XX @@ struct qemu_work_item;
62
* @trace_dstate_delayed: Delayed changes to trace_dstate (includes all changes
63
* to @trace_dstate).
64
* @trace_dstate: Dynamic tracing state of events for this vCPU (bitmask).
65
+ * @ignore_memory_transaction_failures: Cached copy of the MachineState
66
+ * flag of the same name: allows the board to suppress calling of the
67
+ * CPU do_transaction_failed hook function.
68
*
69
* State of one CPU core or thread.
70
*/
71
@@ -XXX,XX +XXX,XX @@ struct CPUState {
72
*/
73
bool throttle_thread_scheduled;
74
75
+ bool ignore_memory_transaction_failures;
76
+
77
/* Note that this is accessed at the start of every TB via a negative
78
offset from AREG0. Leave this field at the end so as to make the
79
(absolute value) offset as small as possible. This reduces code
80
@@ -XXX,XX +XXX,XX @@ static inline void cpu_transaction_failed(CPUState *cpu, hwaddr physaddr,
81
{
18
{
82
CPUClass *cc = CPU_GET_CLASS(cpu);
19
- warn_report_once("The TC58128 flash device is deprecated");
83
20
+ if (!qtest_enabled()) {
84
- if (cc->do_transaction_failed) {
21
+ warn_report_once("The TC58128 flash device is deprecated");
85
+ if (!cpu->ignore_memory_transaction_failures && cc->do_transaction_failed) {
86
cc->do_transaction_failed(cpu, physaddr, addr, size, access_type,
87
mmu_idx, attrs, response, retaddr);
88
}
89
diff --git a/qom/cpu.c b/qom/cpu.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/qom/cpu.c
92
+++ b/qom/cpu.c
93
@@ -XXX,XX +XXX,XX @@
94
#include "exec/cpu-common.h"
95
#include "qemu/error-report.h"
96
#include "sysemu/sysemu.h"
97
+#include "hw/boards.h"
98
#include "hw/qdev-properties.h"
99
#include "trace-root.h"
100
101
@@ -XXX,XX +XXX,XX @@ static void cpu_common_parse_features(const char *typename, char *features,
102
static void cpu_common_realizefn(DeviceState *dev, Error **errp)
103
{
104
CPUState *cpu = CPU(dev);
105
+ Object *machine = qdev_get_machine();
106
+
107
+ /* qdev_get_machine() can return something that's not TYPE_MACHINE
108
+ * if this is one of the user-only emulators; in that case there's
109
+ * no need to check the ignore_memory_transaction_failures board flag.
110
+ */
111
+ if (object_dynamic_cast(machine, TYPE_MACHINE)) {
112
+ ObjectClass *oc = object_get_class(machine);
113
+ MachineClass *mc = MACHINE_CLASS(oc);
114
+
115
+ if (mc) {
116
+ cpu->ignore_memory_transaction_failures =
117
+ mc->ignore_memory_transaction_failures;
118
+ }
119
+ }
22
+ }
120
23
init_dev(&tc58128_devs[0], zone1);
121
if (dev->hotplugged) {
24
init_dev(&tc58128_devs[1], zone2);
122
cpu_synchronize_post_init(cpu);
25
return sh7750_register_io_device(s, &tc58128);
123
--
26
--
124
2.7.4
27
2.34.1
125
28
126
29
diff view generated by jsdifflib
1
Make the CFSR register banked if v8M security extensions are enabled.
1
We deliberately don't include qtests_npcm7xx in qtests_aarch64,
2
because we already get the coverage of those tests via qtests_arm,
3
and we don't want to use extra CI minutes testing them twice.
2
4
3
Not all the bits in this register are banked: the BFSR
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
4
bits [15:8] are shared between S and NS, and we store them
6
that change.
5
in the NS copy of the register.
6
7
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 1503414539-28762-19-git-send-email-peter.maydell@linaro.org
11
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
10
---
12
---
11
target/arm/cpu.h | 7 ++++++-
13
tests/qtest/meson.build | 1 -
12
hw/intc/armv7m_nvic.c | 15 +++++++++++++--
14
1 file changed, 1 deletion(-)
13
target/arm/helper.c | 18 +++++++++---------
14
target/arm/machine.c | 3 ++-
15
4 files changed, 30 insertions(+), 13 deletions(-)
16
15
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
18
--- a/tests/qtest/meson.build
20
+++ b/target/arm/cpu.h
19
+++ b/tests/qtest/meson.build
21
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
22
uint32_t basepri[2];
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
23
uint32_t control[2];
22
(config_all_accel.has_key('CONFIG_TCG') and \
24
uint32_t ccr[2]; /* Configuration and Control */
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
25
- uint32_t cfsr; /* Configurable Fault Status */
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
26
+ uint32_t cfsr[2]; /* Configurable Fault Status */
25
['arm-cpu-features',
27
uint32_t hfsr; /* HardFault Status */
26
'numa-test',
28
uint32_t dfsr; /* Debug Fault Status Register */
27
'boot-serial-test',
29
uint32_t mmfar[2]; /* MemManage Fault Address */
30
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CFSR, NOCP, 16 + 3, 1)
31
FIELD(V7M_CFSR, UNALIGNED, 16 + 8, 1)
32
FIELD(V7M_CFSR, DIVBYZERO, 16 + 9, 1)
33
34
+/* V7M CFSR bit masks covering all of the subregister bits */
35
+FIELD(V7M_CFSR, MMFSR, 0, 8)
36
+FIELD(V7M_CFSR, BFSR, 8, 8)
37
+FIELD(V7M_CFSR, UFSR, 16, 16)
38
+
39
/* V7M HFSR bits */
40
FIELD(V7M_HFSR, VECTTBL, 1, 1)
41
FIELD(V7M_HFSR, FORCED, 30, 1)
42
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/intc/armv7m_nvic.c
45
+++ b/hw/intc/armv7m_nvic.c
46
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
47
}
48
return val;
49
case 0xd28: /* Configurable Fault Status. */
50
- return cpu->env.v7m.cfsr;
51
+ /* The BFSR bits [15:8] are shared between security states
52
+ * and we store them in the NS copy
53
+ */
54
+ val = cpu->env.v7m.cfsr[attrs.secure];
55
+ val |= cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
56
+ return val;
57
case 0xd2c: /* Hard Fault Status. */
58
return cpu->env.v7m.hfsr;
59
case 0xd30: /* Debug Fault Status. */
60
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
61
nvic_irq_update(s);
62
break;
63
case 0xd28: /* Configurable Fault Status. */
64
- cpu->env.v7m.cfsr &= ~value; /* W1C */
65
+ cpu->env.v7m.cfsr[attrs.secure] &= ~value; /* W1C */
66
+ if (attrs.secure) {
67
+ /* The BFSR bits [15:8] are shared between security states
68
+ * and we store them in the NS copy.
69
+ */
70
+ cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
71
+ }
72
break;
73
case 0xd2c: /* Hard Fault Status. */
74
cpu->env.v7m.hfsr &= ~value; /* W1C */
75
diff --git a/target/arm/helper.c b/target/arm/helper.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/helper.c
78
+++ b/target/arm/helper.c
79
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
80
/* Bad exception return: instead of popping the exception
81
* stack, directly take a usage fault on the current stack.
82
*/
83
- env->v7m.cfsr |= R_V7M_CFSR_INVPC_MASK;
84
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
85
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
86
v7m_exception_taken(cpu, type | 0xf0000000);
87
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
88
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
89
if (return_to_handler != arm_v7m_is_handler_mode(env)) {
90
/* Take an INVPC UsageFault by pushing the stack again. */
91
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
92
- env->v7m.cfsr |= R_V7M_CFSR_INVPC_MASK;
93
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
94
v7m_push_stack(cpu);
95
v7m_exception_taken(cpu, type | 0xf0000000);
96
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on new stackframe: "
97
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
98
switch (cs->exception_index) {
99
case EXCP_UDEF:
100
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
101
- env->v7m.cfsr |= R_V7M_CFSR_UNDEFINSTR_MASK;
102
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
103
break;
104
case EXCP_NOCP:
105
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
106
- env->v7m.cfsr |= R_V7M_CFSR_NOCP_MASK;
107
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
108
break;
109
case EXCP_INVSTATE:
110
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
111
- env->v7m.cfsr |= R_V7M_CFSR_INVSTATE_MASK;
112
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
113
break;
114
case EXCP_SWI:
115
/* The PC already points to the next instruction. */
116
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
117
case 0x8: /* External Abort */
118
switch (cs->exception_index) {
119
case EXCP_PREFETCH_ABORT:
120
- env->v7m.cfsr |= R_V7M_CFSR_PRECISERR_MASK;
121
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_PRECISERR_MASK;
122
qemu_log_mask(CPU_LOG_INT, "...with CFSR.PRECISERR\n");
123
break;
124
case EXCP_DATA_ABORT:
125
- env->v7m.cfsr |=
126
+ env->v7m.cfsr[M_REG_NS] |=
127
(R_V7M_CFSR_IBUSERR_MASK | R_V7M_CFSR_BFARVALID_MASK);
128
env->v7m.bfar = env->exception.vaddress;
129
qemu_log_mask(CPU_LOG_INT,
130
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
131
*/
132
switch (cs->exception_index) {
133
case EXCP_PREFETCH_ABORT:
134
- env->v7m.cfsr |= R_V7M_CFSR_IACCVIOL_MASK;
135
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK;
136
qemu_log_mask(CPU_LOG_INT, "...with CFSR.IACCVIOL\n");
137
break;
138
case EXCP_DATA_ABORT:
139
- env->v7m.cfsr |=
140
+ env->v7m.cfsr[env->v7m.secure] |=
141
(R_V7M_CFSR_DACCVIOL_MASK | R_V7M_CFSR_MMARVALID_MASK);
142
env->v7m.mmfar[env->v7m.secure] = env->exception.vaddress;
143
qemu_log_mask(CPU_LOG_INT,
144
diff --git a/target/arm/machine.c b/target/arm/machine.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/machine.c
147
+++ b/target/arm/machine.c
148
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
149
VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
150
VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU),
151
VMSTATE_UINT32(env.v7m.ccr[M_REG_NS], ARMCPU),
152
- VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
153
+ VMSTATE_UINT32(env.v7m.cfsr[M_REG_NS], ARMCPU),
154
VMSTATE_UINT32(env.v7m.hfsr, ARMCPU),
155
VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
156
VMSTATE_UINT32(env.v7m.mmfar[M_REG_NS], ARMCPU),
157
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
158
VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU),
159
VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU),
160
VMSTATE_UINT32(env.v7m.mmfar[M_REG_S], ARMCPU),
161
+ VMSTATE_UINT32(env.v7m.cfsr[M_REG_S], ARMCPU),
162
VMSTATE_END_OF_LIST()
163
}
164
};
165
--
28
--
166
2.7.4
29
2.34.1
167
30
168
31
diff view generated by jsdifflib
New patch
1
Allow changes to the virt GTDT -- we are going to add the IRQ
2
entry for a new timer to it.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
6
Message-id: 20240122143537.233498-2-peter.maydell@linaro.org
7
---
8
tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
9
1 file changed, 2 insertions(+)
10
11
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/bios-tables-test-allowed-diff.h
14
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
15
@@ -1 +1,3 @@
16
/* List of comma-separated changed AML files to ignore */
17
+"tests/data/acpi/virt/FACP",
18
+"tests/data/acpi/virt/GTDT",
19
--
20
2.34.1
diff view generated by jsdifflib
1
Make the MMFAR register banked if v8M security extensions are
1
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds a
2
enabled.
2
non-secure EL2 virtual timer. We implemented the timer itself in the
3
CPU model, but never wired up its IRQ line to the GIC.
4
5
Wire up the IRQ line (this is always safe whether the CPU has the
6
interrupt or not, since it always creates the outbound IRQ line).
7
Report it to the guest via dtb and ACPI if the CPU has the feature.
8
9
The DTB binding is documented in the kernel's
10
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
11
and the ACPI table entries are documented in the ACPI specification
12
version 6.3 or later.
13
14
Because the IRQ line ACPI binding is new in 6.3, we need to bump the
15
FADT table rev to show that we might be using 6.3 features.
16
17
Note that exposing this IRQ in the DTB will trigger a bug in EDK2
18
versions prior to edk2-stable202311, for users who use the virt board
19
with 'virtualization=on' to enable EL2 emulation and are booting an
20
EDK2 guest BIOS, if that EDK2 has assertions enabled. The effect is
21
that EDK2 will assert on bootup:
22
23
ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
24
25
If you see that assertion you should do one of:
26
* update your EDK2 binaries to edk2-stable202311 or newer
27
* use the 'virt-8.2' versioned machine type
28
* not use 'virtualization=on'
29
30
(The versions shipped with QEMU itself have the fix.)
3
31
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
6
Message-id: 1503414539-28762-18-git-send-email-peter.maydell@linaro.org
34
Message-id: 20240122143537.233498-3-peter.maydell@linaro.org
7
---
35
---
8
target/arm/cpu.h | 2 +-
36
include/hw/arm/virt.h | 2 ++
9
hw/intc/armv7m_nvic.c | 4 ++--
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
10
target/arm/helper.c | 4 ++--
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
11
target/arm/machine.c | 3 ++-
39
3 files changed, 67 insertions(+), 15 deletions(-)
12
4 files changed, 7 insertions(+), 6 deletions(-)
40
13
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
43
--- a/include/hw/arm/virt.h
17
+++ b/target/arm/cpu.h
44
+++ b/include/hw/arm/virt.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
19
uint32_t cfsr; /* Configurable Fault Status */
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
20
uint32_t hfsr; /* HardFault Status */
47
bool no_cpu_topology;
21
uint32_t dfsr; /* Debug Fault Status Register */
48
bool no_tcg_lpa2;
22
- uint32_t mmfar; /* MemManage Fault Address */
49
+ bool no_ns_el2_virt_timer_irq;
23
+ uint32_t mmfar[2]; /* MemManage Fault Address */
50
};
24
uint32_t bfar; /* BusFault Address */
51
25
unsigned mpu_ctrl[2]; /* MPU_CTRL */
52
struct VirtMachineState {
26
int exception;
53
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
27
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
54
PCIBus *bus;
55
char *oem_id;
56
char *oem_table_id;
57
+ bool ns_el2_virt_timer_irq;
58
};
59
60
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
61
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
28
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/armv7m_nvic.c
63
--- a/hw/arm/virt-acpi-build.c
30
+++ b/hw/intc/armv7m_nvic.c
64
+++ b/hw/arm/virt-acpi-build.c
31
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
65
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
32
case 0xd30: /* Debug Fault Status. */
66
}
33
return cpu->env.v7m.dfsr;
67
34
case 0xd34: /* MMFAR MemManage Fault Address */
68
/*
35
- return cpu->env.v7m.mmfar;
69
- * ACPI spec, Revision 5.1
36
+ return cpu->env.v7m.mmfar[attrs.secure];
70
- * 5.2.24 Generic Timer Description Table (GTDT)
37
case 0xd38: /* Bus Fault Address. */
71
+ * ACPI spec, Revision 6.5
38
return cpu->env.v7m.bfar;
72
+ * 5.2.25 Generic Timer Description Table (GTDT)
39
case 0xd3c: /* Aux Fault Status. */
73
*/
40
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
74
static void
41
cpu->env.v7m.dfsr &= ~value; /* W1C */
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
42
break;
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
43
case 0xd34: /* Mem Manage Address. */
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
44
- cpu->env.v7m.mmfar = value;
78
1 : /* Interrupt is Edge triggered */
45
+ cpu->env.v7m.mmfar[attrs.secure] = value;
79
0; /* Interrupt is Level triggered */
46
return;
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
47
case 0xd38: /* Bus Fault Address. */
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
48
cpu->env.v7m.bfar = value;
82
.oem_table_id = vms->oem_table_id };
49
diff --git a/target/arm/helper.c b/target/arm/helper.c
83
84
acpi_table_begin(&table, table_data);
85
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
86
build_append_int_noprefix(table_data, 0, 4);
87
/* Platform Timer Offset */
88
build_append_int_noprefix(table_data, 0, 4);
89
-
90
+ if (vms->ns_el2_virt_timer_irq) {
91
+ /* Virtual EL2 Timer GSIV */
92
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ, 4);
93
+ /* Virtual EL2 Timer Flags */
94
+ build_append_int_noprefix(table_data, irqflags, 4);
95
+ } else {
96
+ build_append_int_noprefix(table_data, 0, 4);
97
+ build_append_int_noprefix(table_data, 0, 4);
98
+ }
99
acpi_table_end(linker, &table);
100
}
101
102
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
103
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
104
VirtMachineState *vms, unsigned dsdt_tbl_offset)
105
{
106
- /* ACPI v6.0 */
107
+ /* ACPI v6.3 */
108
AcpiFadtData fadt = {
109
.rev = 6,
110
- .minor_ver = 0,
111
+ .minor_ver = 3,
112
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
113
.xdsdt_tbl_offset = &dsdt_tbl_offset,
114
};
115
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
50
index XXXXXXX..XXXXXXX 100644
116
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/helper.c
117
--- a/hw/arm/virt.c
52
+++ b/target/arm/helper.c
118
+++ b/hw/arm/virt.c
53
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
119
@@ -XXX,XX +XXX,XX @@ static void create_randomness(MachineState *ms, const char *node)
54
case EXCP_DATA_ABORT:
120
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
55
env->v7m.cfsr |=
121
}
56
(R_V7M_CFSR_DACCVIOL_MASK | R_V7M_CFSR_MMARVALID_MASK);
122
57
- env->v7m.mmfar = env->exception.vaddress;
123
+/*
58
+ env->v7m.mmfar[env->v7m.secure] = env->exception.vaddress;
124
+ * The CPU object always exposes the NS EL2 virt timer IRQ line,
59
qemu_log_mask(CPU_LOG_INT,
125
+ * but we don't want to advertise it to the guest in the dtb or ACPI
60
"...with CFSR.DACCVIOL and MMFAR 0x%x\n",
126
+ * table unless it's really going to do something.
61
- env->v7m.mmfar);
127
+ */
62
+ env->v7m.mmfar[env->v7m.secure]);
128
+static bool ns_el2_virt_timer_present(void)
63
break;
129
+{
64
}
130
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
65
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
131
+ CPUARMState *env = &cpu->env;
66
diff --git a/target/arm/machine.c b/target/arm/machine.c
132
+
67
index XXXXXXX..XXXXXXX 100644
133
+ return arm_feature(env, ARM_FEATURE_AARCH64) &&
68
--- a/target/arm/machine.c
134
+ arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
69
+++ b/target/arm/machine.c
135
+}
70
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
136
+
71
VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
137
static void create_fdt(VirtMachineState *vms)
72
VMSTATE_UINT32(env.v7m.hfsr, ARMCPU),
138
{
73
VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
139
MachineState *ms = MACHINE(vms);
74
- VMSTATE_UINT32(env.v7m.mmfar, ARMCPU),
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
75
+ VMSTATE_UINT32(env.v7m.mmfar[M_REG_NS], ARMCPU),
141
"arm,armv7-timer");
76
VMSTATE_UINT32(env.v7m.bfar, ARMCPU),
77
VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_NS], ARMCPU),
78
VMSTATE_INT32(env.v7m.exception, ARMCPU),
79
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
80
VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate),
81
VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU),
82
VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU),
83
+ VMSTATE_UINT32(env.v7m.mmfar[M_REG_S], ARMCPU),
84
VMSTATE_END_OF_LIST()
85
}
142
}
86
};
143
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
144
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
145
- GIC_FDT_IRQ_TYPE_PPI,
146
- INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
147
- GIC_FDT_IRQ_TYPE_PPI,
148
- INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
149
- GIC_FDT_IRQ_TYPE_PPI,
150
- INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
151
- GIC_FDT_IRQ_TYPE_PPI,
152
- INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
153
+ if (vms->ns_el2_virt_timer_irq) {
154
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
155
+ GIC_FDT_IRQ_TYPE_PPI,
156
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
157
+ GIC_FDT_IRQ_TYPE_PPI,
158
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
159
+ GIC_FDT_IRQ_TYPE_PPI,
160
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
161
+ GIC_FDT_IRQ_TYPE_PPI,
162
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags,
163
+ GIC_FDT_IRQ_TYPE_PPI,
164
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_VIRT_IRQ), irqflags);
165
+ } else {
166
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
167
+ GIC_FDT_IRQ_TYPE_PPI,
168
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
169
+ GIC_FDT_IRQ_TYPE_PPI,
170
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
171
+ GIC_FDT_IRQ_TYPE_PPI,
172
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
173
+ GIC_FDT_IRQ_TYPE_PPI,
174
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
175
+ }
176
}
177
178
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
180
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
181
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
182
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
183
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
184
};
185
186
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
187
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
188
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
189
object_unref(cpuobj);
190
}
191
+
192
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
193
+ vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
194
+ !vmc->no_ns_el2_virt_timer_irq;
195
+
196
fdt_add_timer_nodes(vms);
197
fdt_add_cpu_nodes(vms);
198
199
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
200
201
static void virt_machine_8_2_options(MachineClass *mc)
202
{
203
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
204
+
205
virt_machine_9_0_options(mc);
206
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
207
+ /*
208
+ * Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
209
+ * earlier machines. (Exposing it tickles a bug in older EDK2
210
+ * guest BIOS binaries.)
211
+ */
212
+ vmc->no_ns_el2_virt_timer_irq = true;
213
}
214
DEFINE_VIRT_MACHINE(8, 2)
215
87
--
216
--
88
2.7.4
217
2.34.1
89
90
diff view generated by jsdifflib
1
Make the CCR register banked if v8M security extensions are enabled.
1
Update the virt golden reference files to say that the FACP is ACPI
2
2
v6.3, and the GTDT table is a revision 3 table with space for the
3
This is slightly more complicated than the other "add banking"
3
virtual EL2 timer.
4
patches because there is one bit in the register which is not
4
5
banked. We keep the live data in the NS copy of the register,
5
Diffs from iasl:
6
and adjust it on register reads and writes. (Since we don't
6
7
currently implement the behaviour that the bit controls, there
7
@@ -XXX,XX +XXX,XX @@
8
is nowhere else that needs to care.)
8
/*
9
9
* Intel ACPI Component Architecture
10
This patch includes the enforcement of the bits which are newly
10
* AML/ASL+ Disassembler version 20200925 (64-bit version)
11
RES1 in ARMv8M.
11
* Copyright (c) 2000 - 2020 Intel Corporation
12
*
13
- * Disassembly of tests/data/acpi/virt/FACP, Mon Jan 22 13:48:40 2024
14
+ * Disassembly of /tmp/aml-W8RZH2, Mon Jan 22 13:48:40 2024
15
*
16
* ACPI Data Table [FACP]
17
*
18
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
19
*/
20
21
[000h 0000 4] Signature : "FACP" [Fixed ACPI Description Table (FADT)]
22
[004h 0004 4] Table Length : 00000114
23
[008h 0008 1] Revision : 06
24
-[009h 0009 1] Checksum : 15
25
+[009h 0009 1] Checksum : 12
26
[00Ah 0010 6] Oem ID : "BOCHS "
27
[010h 0016 8] Oem Table ID : "BXPC "
28
[018h 0024 4] Oem Revision : 00000001
29
[01Ch 0028 4] Asl Compiler ID : "BXPC"
30
[020h 0032 4] Asl Compiler Revision : 00000001
31
32
[024h 0036 4] FACS Address : 00000000
33
[028h 0040 4] DSDT Address : 00000000
34
[02Ch 0044 1] Model : 00
35
[02Dh 0045 1] PM Profile : 00 [Unspecified]
36
[02Eh 0046 2] SCI Interrupt : 0000
37
[030h 0048 4] SMI Command Port : 00000000
38
[034h 0052 1] ACPI Enable Value : 00
39
[035h 0053 1] ACPI Disable Value : 00
40
[036h 0054 1] S4BIOS Command : 00
41
[037h 0055 1] P-State Control : 00
42
@@ -XXX,XX +XXX,XX @@
43
Use APIC Physical Destination Mode (V4) : 0
44
Hardware Reduced (V5) : 1
45
Low Power S0 Idle (V5) : 0
46
47
[074h 0116 12] Reset Register : [Generic Address Structure]
48
[074h 0116 1] Space ID : 00 [SystemMemory]
49
[075h 0117 1] Bit Width : 00
50
[076h 0118 1] Bit Offset : 00
51
[077h 0119 1] Encoded Access Width : 00 [Undefined/Legacy]
52
[078h 0120 8] Address : 0000000000000000
53
54
[080h 0128 1] Value to cause reset : 00
55
[081h 0129 2] ARM Flags (decoded below) : 0003
56
PSCI Compliant : 1
57
Must use HVC for PSCI : 1
58
59
-[083h 0131 1] FADT Minor Revision : 00
60
+[083h 0131 1] FADT Minor Revision : 03
61
[084h 0132 8] FACS Address : 0000000000000000
62
[08Ch 0140 8] DSDT Address : 0000000000000000
63
[094h 0148 12] PM1A Event Block : [Generic Address Structure]
64
[094h 0148 1] Space ID : 00 [SystemMemory]
65
[095h 0149 1] Bit Width : 00
66
[096h 0150 1] Bit Offset : 00
67
[097h 0151 1] Encoded Access Width : 00 [Undefined/Legacy]
68
[098h 0152 8] Address : 0000000000000000
69
70
[0A0h 0160 12] PM1B Event Block : [Generic Address Structure]
71
[0A0h 0160 1] Space ID : 00 [SystemMemory]
72
[0A1h 0161 1] Bit Width : 00
73
[0A2h 0162 1] Bit Offset : 00
74
[0A3h 0163 1] Encoded Access Width : 00 [Undefined/Legacy]
75
[0A4h 0164 8] Address : 0000000000000000
76
77
@@ -XXX,XX +XXX,XX @@
78
[0F5h 0245 1] Bit Width : 00
79
[0F6h 0246 1] Bit Offset : 00
80
[0F7h 0247 1] Encoded Access Width : 00 [Undefined/Legacy]
81
[0F8h 0248 8] Address : 0000000000000000
82
83
[100h 0256 12] Sleep Status Register : [Generic Address Structure]
84
[100h 0256 1] Space ID : 00 [SystemMemory]
85
[101h 0257 1] Bit Width : 00
86
[102h 0258 1] Bit Offset : 00
87
[103h 0259 1] Encoded Access Width : 00 [Undefined/Legacy]
88
[104h 0260 8] Address : 0000000000000000
89
90
[10Ch 0268 8] Hypervisor ID : 00000000554D4551
91
92
Raw Table Data: Length 276 (0x114)
93
94
- 0000: 46 41 43 50 14 01 00 00 06 15 42 4F 43 48 53 20 // FACP......BOCHS
95
+ 0000: 46 41 43 50 14 01 00 00 06 12 42 4F 43 48 53 20 // FACP......BOCHS
96
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
97
0020: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
98
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
99
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
100
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
101
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
102
0070: 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
103
- 0080: 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
104
+ 0080: 00 03 00 03 00 00 00 00 00 00 00 00 00 00 00 00 // ................
105
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
106
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
107
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
108
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
109
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
110
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
111
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
112
0100: 00 00 00 00 00 00 00 00 00 00 00 00 51 45 4D 55 // ............QEMU
113
0110: 00 00 00 00 // ....
114
115
@@ -XXX,XX +XXX,XX @@
116
/*
117
* Intel ACPI Component Architecture
118
* AML/ASL+ Disassembler version 20200925 (64-bit version)
119
* Copyright (c) 2000 - 2020 Intel Corporation
120
*
121
- * Disassembly of tests/data/acpi/virt/GTDT, Mon Jan 22 13:48:40 2024
122
+ * Disassembly of /tmp/aml-XDSZH2, Mon Jan 22 13:48:40 2024
123
*
124
* ACPI Data Table [GTDT]
125
*
126
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
127
*/
128
129
[000h 0000 4] Signature : "GTDT" [Generic Timer Description Table]
130
-[004h 0004 4] Table Length : 00000060
131
-[008h 0008 1] Revision : 02
132
-[009h 0009 1] Checksum : 9C
133
+[004h 0004 4] Table Length : 00000068
134
+[008h 0008 1] Revision : 03
135
+[009h 0009 1] Checksum : 93
136
[00Ah 0010 6] Oem ID : "BOCHS "
137
[010h 0016 8] Oem Table ID : "BXPC "
138
[018h 0024 4] Oem Revision : 00000001
139
[01Ch 0028 4] Asl Compiler ID : "BXPC"
140
[020h 0032 4] Asl Compiler Revision : 00000001
141
142
[024h 0036 8] Counter Block Address : FFFFFFFFFFFFFFFF
143
[02Ch 0044 4] Reserved : 00000000
144
145
[030h 0048 4] Secure EL1 Interrupt : 0000001D
146
[034h 0052 4] EL1 Flags (decoded below) : 00000000
147
Trigger Mode : 0
148
Polarity : 0
149
Always On : 0
150
151
[038h 0056 4] Non-Secure EL1 Interrupt : 0000001E
152
@@ -XXX,XX +XXX,XX @@
153
154
[040h 0064 4] Virtual Timer Interrupt : 0000001B
155
[044h 0068 4] VT Flags (decoded below) : 00000000
156
Trigger Mode : 0
157
Polarity : 0
158
Always On : 0
159
160
[048h 0072 4] Non-Secure EL2 Interrupt : 0000001A
161
[04Ch 0076 4] NEL2 Flags (decoded below) : 00000000
162
Trigger Mode : 0
163
Polarity : 0
164
Always On : 0
165
[050h 0080 8] Counter Read Block Address : FFFFFFFFFFFFFFFF
166
167
[058h 0088 4] Platform Timer Count : 00000000
168
[05Ch 0092 4] Platform Timer Offset : 00000000
169
+[060h 0096 4] Virtual EL2 Timer GSIV : 00000000
170
+[064h 0100 4] Virtual EL2 Timer Flags : 00000000
171
172
-Raw Table Data: Length 96 (0x60)
173
+Raw Table Data: Length 104 (0x68)
174
175
- 0000: 47 54 44 54 60 00 00 00 02 9C 42 4F 43 48 53 20 // GTDT`.....BOCHS
176
+ 0000: 47 54 44 54 68 00 00 00 03 93 42 4F 43 48 53 20 // GTDTh.....BOCHS
177
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
178
0020: 01 00 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 // ................
179
0030: 1D 00 00 00 00 00 00 00 1E 00 00 00 04 00 00 00 // ................
180
0040: 1B 00 00 00 00 00 00 00 1A 00 00 00 00 00 00 00 // ................
181
0050: FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 // ................
182
+ 0060: 00 00 00 00 00 00 00 00 // ........
12
183
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
184
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 1503414539-28762-17-git-send-email-peter.maydell@linaro.org
185
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
186
Message-id: 20240122143537.233498-4-peter.maydell@linaro.org
15
---
187
---
16
target/arm/cpu.h | 2 +-
188
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
17
hw/intc/armv7m_nvic.c | 33 +++++++++++++++++++++++++++------
189
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
18
target/arm/cpu.c | 12 +++++++++---
190
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
19
target/arm/helper.c | 5 +++--
191
3 files changed, 2 deletions(-)
20
target/arm/machine.c | 3 ++-
192
21
5 files changed, 42 insertions(+), 13 deletions(-)
193
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
22
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
194
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
195
--- a/tests/qtest/bios-tables-test-allowed-diff.h
26
+++ b/target/arm/cpu.h
196
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
197
@@ -1,3 +1 @@
28
uint32_t vecbase[2];
198
/* List of comma-separated changed AML files to ignore */
29
uint32_t basepri[2];
199
-"tests/data/acpi/virt/FACP",
30
uint32_t control[2];
200
-"tests/data/acpi/virt/GTDT",
31
- uint32_t ccr; /* Configuration and Control */
201
diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP
32
+ uint32_t ccr[2]; /* Configuration and Control */
33
uint32_t cfsr; /* Configurable Fault Status */
34
uint32_t hfsr; /* HardFault Status */
35
uint32_t dfsr; /* Debug Fault Status Register */
36
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
37
index XXXXXXX..XXXXXXX 100644
202
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/armv7m_nvic.c
203
GIT binary patch
39
+++ b/hw/intc/armv7m_nvic.c
204
delta 25
40
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
205
gcmbQjG=+)F&CxkPgpq-PO=u!l<;2F$$vli407<0<)c^nh
41
/* TODO: Implement SLEEPONEXIT. */
206
42
return 0;
207
delta 28
43
case 0xd14: /* Configuration Control. */
208
kcmbQjG=+)F&CxkPgpq-PO>`nx<-|!<6Akz$^DuG%0AAS!ssI20
44
- return cpu->env.v7m.ccr;
209
45
+ /* The BFHFNMIGN bit is the only non-banked bit; we
210
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
46
+ * keep it in the non-secure copy of the register.
47
+ */
48
+ val = cpu->env.v7m.ccr[attrs.secure];
49
+ val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
50
+ return val;
51
case 0xd24: /* System Handler Status. */
52
val = 0;
53
if (s->vectors[ARMV7M_EXCP_MEM].active) {
54
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
55
R_V7M_CCR_USERSETMPEND_MASK |
56
R_V7M_CCR_NONBASETHRDENA_MASK);
57
58
- cpu->env.v7m.ccr = value;
59
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
60
+ /* v8M makes NONBASETHRDENA and STKALIGN be RES1 */
61
+ value |= R_V7M_CCR_NONBASETHRDENA_MASK
62
+ | R_V7M_CCR_STKALIGN_MASK;
63
+ }
64
+ if (attrs.secure) {
65
+ /* the BFHFNMIGN bit is not banked; keep that in the NS copy */
66
+ cpu->env.v7m.ccr[M_REG_NS] =
67
+ (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
68
+ | (value & R_V7M_CCR_BFHFNMIGN_MASK);
69
+ value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
70
+ }
71
+
72
+ cpu->env.v7m.ccr[attrs.secure] = value;
73
break;
74
case 0xd24: /* System Handler Control. */
75
s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
76
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
77
}
78
}
79
80
-static bool nvic_user_access_ok(NVICState *s, hwaddr offset)
81
+static bool nvic_user_access_ok(NVICState *s, hwaddr offset, MemTxAttrs attrs)
82
{
83
/* Return true if unprivileged access to this register is permitted. */
84
switch (offset) {
85
case 0xf00: /* STIR: accessible only if CCR.USERSETMPEND permits */
86
- return s->cpu->env.v7m.ccr & R_V7M_CCR_USERSETMPEND_MASK;
87
+ /* For access via STIR_NS it is the NS CCR.USERSETMPEND that
88
+ * controls access even though the CPU is in Secure state (I_QDKX).
89
+ */
90
+ return s->cpu->env.v7m.ccr[attrs.secure] & R_V7M_CCR_USERSETMPEND_MASK;
91
default:
92
/* All other user accesses cause a BusFault unconditionally */
93
return false;
94
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
95
unsigned i, startvec, end;
96
uint32_t val;
97
98
- if (attrs.user && !nvic_user_access_ok(s, addr)) {
99
+ if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
100
/* Generate BusFault for unprivileged accesses */
101
return MEMTX_ERROR;
102
}
103
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
104
105
trace_nvic_sysreg_write(addr, value, size);
106
107
- if (attrs.user && !nvic_user_access_ok(s, addr)) {
108
+ if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) {
109
/* Generate BusFault for unprivileged accesses */
110
return MEMTX_ERROR;
111
}
112
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
113
index XXXXXXX..XXXXXXX 100644
211
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/cpu.c
212
GIT binary patch
115
+++ b/target/arm/cpu.c
213
delta 25
116
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
214
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
117
env->v7m.secure = true;
215
118
}
216
delta 16
119
217
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
120
- /* The reset value of this bit is IMPDEF, but ARM recommends
218
121
+ /* In v7M the reset value of this bit is IMPDEF, but ARM recommends
122
* that it resets to 1, so QEMU always does that rather than making
123
- * it dependent on CPU model.
124
+ * it dependent on CPU model. In v8M it is RES1.
125
*/
126
- env->v7m.ccr = R_V7M_CCR_STKALIGN_MASK;
127
+ env->v7m.ccr[M_REG_NS] = R_V7M_CCR_STKALIGN_MASK;
128
+ env->v7m.ccr[M_REG_S] = R_V7M_CCR_STKALIGN_MASK;
129
+ if (arm_feature(env, ARM_FEATURE_V8)) {
130
+ /* in v8M the NONBASETHRDENA bit [0] is RES1 */
131
+ env->v7m.ccr[M_REG_NS] |= R_V7M_CCR_NONBASETHRDENA_MASK;
132
+ env->v7m.ccr[M_REG_S] |= R_V7M_CCR_NONBASETHRDENA_MASK;
133
+ }
134
135
/* Unlike A/R profile, M profile defines the reset LR value */
136
env->regs[14] = 0xffffffff;
137
diff --git a/target/arm/helper.c b/target/arm/helper.c
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/arm/helper.c
140
+++ b/target/arm/helper.c
141
@@ -XXX,XX +XXX,XX @@ static void v7m_push_stack(ARMCPU *cpu)
142
uint32_t xpsr = xpsr_read(env);
143
144
/* Align stack pointer if the guest wants that */
145
- if ((env->regs[13] & 4) && (env->v7m.ccr & R_V7M_CCR_STKALIGN_MASK)) {
146
+ if ((env->regs[13] & 4) &&
147
+ (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKALIGN_MASK)) {
148
env->regs[13] -= 4;
149
xpsr |= XPSR_SPREALIGN;
150
}
151
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
152
/* fall through */
153
case 9: /* Return to Thread using Main stack */
154
if (!rettobase &&
155
- !(env->v7m.ccr & R_V7M_CCR_NONBASETHRDENA_MASK)) {
156
+ !(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_NONBASETHRDENA_MASK)) {
157
ufault = true;
158
}
159
break;
160
diff --git a/target/arm/machine.c b/target/arm/machine.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/target/arm/machine.c
163
+++ b/target/arm/machine.c
164
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
165
VMSTATE_UINT32(env.v7m.vecbase[M_REG_NS], ARMCPU),
166
VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
167
VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU),
168
- VMSTATE_UINT32(env.v7m.ccr, ARMCPU),
169
+ VMSTATE_UINT32(env.v7m.ccr[M_REG_NS], ARMCPU),
170
VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
171
VMSTATE_UINT32(env.v7m.hfsr, ARMCPU),
172
VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
173
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
174
VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU),
175
VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate),
176
VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU),
177
+ VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU),
178
VMSTATE_END_OF_LIST()
179
}
180
};
181
--
219
--
182
2.7.4
220
2.34.1
183
184
diff view generated by jsdifflib
New patch
1
The patchset adding the GMAC ethernet to this SoC crossed in the
2
mail with the patchset cleaning up the NIC handling. When we
3
create the GMAC modules we must call qemu_configure_nic_device()
4
so that the user has the opportunity to use the -nic commandline
5
option to create a network backend and connect it to the GMACs.
1
6
7
Add the missing call.
8
9
Fixes: 21e5326a7c ("hw/arm: Add GMAC devices to NPCM7XX SoC")
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
12
Message-id: 20240206171231.396392-2-peter.maydell@linaro.org
13
---
14
hw/arm/npcm7xx.c | 1 +
15
1 file changed, 1 insertion(+)
16
17
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/npcm7xx.c
20
+++ b/hw/arm/npcm7xx.c
21
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
22
for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
23
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]);
24
25
+ qemu_configure_nic_device(DEVICE(sbd), false, NULL);
26
/*
27
* The device exists regardless of whether it's connected to a QEMU
28
* netdev backend. So always instantiate it even if there is no
29
--
30
2.34.1
diff view generated by jsdifflib
1
Make the MPU_CTRL register banked if v8M security extensions are
1
Currently QEMU will warn if there is a NIC on the board that
2
enabled.
2
is not connected to a backend. By default the '-nic user' will
3
get used for all NICs, but if you manually connect a specific
4
NIC to a specific backend, then the other NICs on the board
5
have no backend and will be warned about:
6
7
qemu-system-arm: warning: nic npcm7xx-emc.1 has no peer
8
qemu-system-arm: warning: nic npcm-gmac.0 has no peer
9
qemu-system-arm: warning: nic npcm-gmac.1 has no peer
10
11
So suppress those warnings by manually connecting every NIC
12
on the board to some backend.
3
13
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
6
Message-id: 1503414539-28762-16-git-send-email-peter.maydell@linaro.org
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 20240206171231.396392-3-peter.maydell@linaro.org
7
---
18
---
8
target/arm/cpu.h | 2 +-
19
tests/qtest/npcm7xx_emc-test.c | 5 ++++-
9
hw/intc/armv7m_nvic.c | 9 +++++----
20
1 file changed, 4 insertions(+), 1 deletion(-)
10
target/arm/helper.c | 5 +++--
11
target/arm/machine.c | 3 ++-
12
4 files changed, 11 insertions(+), 8 deletions(-)
13
21
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
24
--- a/tests/qtest/npcm7xx_emc-test.c
17
+++ b/target/arm/cpu.h
25
+++ b/tests/qtest/npcm7xx_emc-test.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
26
@@ -XXX,XX +XXX,XX @@ static int *packet_test_init(int module_num, GString *cmd_line)
19
uint32_t dfsr; /* Debug Fault Status Register */
27
* KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
20
uint32_t mmfar; /* MemManage Fault Address */
28
* in the 'model' field to specify the device to match.
21
uint32_t bfar; /* BusFault Address */
29
*/
22
- unsigned mpu_ctrl; /* MPU_CTRL */
30
- g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d ",
23
+ unsigned mpu_ctrl[2]; /* MPU_CTRL */
31
+ g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
24
int exception;
32
+ "-nic user,model=npcm7xx-emc "
25
uint32_t primask[2];
33
+ "-nic user,model=npcm-gmac "
26
uint32_t faultmask[2];
34
+ "-nic user,model=npcm-gmac",
27
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
35
test_sockets[1], module_num);
28
index XXXXXXX..XXXXXXX 100644
36
29
--- a/hw/intc/armv7m_nvic.c
37
g_test_queue_destroy(packet_test_clear, test_sockets);
30
+++ b/hw/intc/armv7m_nvic.c
31
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
32
return cpu->pmsav7_dregion << 8;
33
break;
34
case 0xd94: /* MPU_CTRL */
35
- return cpu->env.v7m.mpu_ctrl;
36
+ return cpu->env.v7m.mpu_ctrl[attrs.secure];
37
case 0xd98: /* MPU_RNR */
38
return cpu->env.pmsav7.rnr[attrs.secure];
39
case 0xd9c: /* MPU_RBAR */
40
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
41
qemu_log_mask(LOG_GUEST_ERROR, "MPU_CTRL: HFNMIENA and !ENABLE is "
42
"UNPREDICTABLE\n");
43
}
44
- cpu->env.v7m.mpu_ctrl = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
45
- R_V7M_MPU_CTRL_HFNMIENA_MASK |
46
- R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
47
+ cpu->env.v7m.mpu_ctrl[attrs.secure]
48
+ = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
49
+ R_V7M_MPU_CTRL_HFNMIENA_MASK |
50
+ R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
51
tlb_flush(CPU(cpu));
52
break;
53
case 0xd98: /* MPU_RNR */
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/helper.c
57
+++ b/target/arm/helper.c
58
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
59
ARMMMUIdx mmu_idx)
60
{
61
if (arm_feature(env, ARM_FEATURE_M)) {
62
- switch (env->v7m.mpu_ctrl &
63
+ switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] &
64
(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
65
case R_V7M_MPU_CTRL_ENABLE_MASK:
66
/* Enabled, but not for HardFault and NMI */
67
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_use_background_region(ARMCPU *cpu,
68
}
69
70
if (arm_feature(env, ARM_FEATURE_M)) {
71
- return env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
72
+ return env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)]
73
+ & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
74
} else {
75
return regime_sctlr(env, mmu_idx) & SCTLR_BR;
76
}
77
diff --git a/target/arm/machine.c b/target/arm/machine.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/machine.c
80
+++ b/target/arm/machine.c
81
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
82
VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
83
VMSTATE_UINT32(env.v7m.mmfar, ARMCPU),
84
VMSTATE_UINT32(env.v7m.bfar, ARMCPU),
85
- VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU),
86
+ VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_NS], ARMCPU),
87
VMSTATE_INT32(env.v7m.exception, ARMCPU),
88
VMSTATE_END_OF_LIST()
89
},
90
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
91
0, vmstate_info_uint32, uint32_t),
92
VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU),
93
VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate),
94
+ VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU),
95
VMSTATE_END_OF_LIST()
96
}
97
};
98
--
38
--
99
2.7.4
39
2.34.1
100
101
diff view generated by jsdifflib
1
Make the MPU_RNR register banked if v8M security extensions are
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
2
enabled.
2
CPU, and in fact if you try to do it we will assert:
3
3
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
5
(assertion=0x5555565a8c70 "!arm_feature(env, ARM_FEATURE_M)", file=0x5555565a6e5c "../../target/arm/helper.c", line=12600, function=0x5555565a9560 <__PRETTY_FUNCTION__.0> "arm_security_space_below_el3") at ./assert/assert.c:101
6
#7 0x0000555555ebf412 in arm_security_space_below_el3 (env=0x555557bc8190) at ../../target/arm/helper.c:12600
7
#8 0x0000555555ea6f89 in arm_is_el2_enabled (env=0x555557bc8190) at ../../target/arm/cpu.h:2595
8
#9 0x0000555555ea942f in arm_mdcr_el2_eff (env=0x555557bc8190) at ../../target/arm/internals.h:1512
9
10
We might call pmu_counter_enabled() on an M-profile CPU (for example
11
from the migration pre/post hooks in machine.c); this should always
12
return false because these CPUs don't set ARM_FEATURE_PMU.
13
14
Avoid the assertion by not calling arm_mdcr_el2_eff() before we
15
have done the early return for "PMU not present".
16
17
This fixes an assertion failure if you try to do a loadvm or
18
savevm for an M-profile board.
19
20
Cc: qemu-stable@nongnu.org
21
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2155
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 1503414539-28762-15-git-send-email-peter.maydell@linaro.org
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
7
---
26
---
8
target/arm/cpu.h | 2 +-
27
target/arm/helper.c | 12 ++++++++++--
9
hw/intc/armv7m_nvic.c | 18 +++++++++---------
28
1 file changed, 10 insertions(+), 2 deletions(-)
10
target/arm/cpu.c | 3 ++-
11
target/arm/helper.c | 6 +++---
12
target/arm/machine.c | 13 +++++++++++--
13
5 files changed, 26 insertions(+), 16 deletions(-)
14
29
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
20
uint32_t *drbar;
21
uint32_t *drsr;
22
uint32_t *dracr;
23
- uint32_t rnr;
24
+ uint32_t rnr[2];
25
} pmsav7;
26
27
/* PMSAv8 MPU */
28
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/intc/armv7m_nvic.c
31
+++ b/hw/intc/armv7m_nvic.c
32
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
33
case 0xd94: /* MPU_CTRL */
34
return cpu->env.v7m.mpu_ctrl;
35
case 0xd98: /* MPU_RNR */
36
- return cpu->env.pmsav7.rnr;
37
+ return cpu->env.pmsav7.rnr[attrs.secure];
38
case 0xd9c: /* MPU_RBAR */
39
case 0xda4: /* MPU_RBAR_A1 */
40
case 0xdac: /* MPU_RBAR_A2 */
41
case 0xdb4: /* MPU_RBAR_A3 */
42
{
43
- int region = cpu->env.pmsav7.rnr;
44
+ int region = cpu->env.pmsav7.rnr[attrs.secure];
45
46
if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
47
/* PMSAv8M handling of the aliases is different from v7M:
48
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
49
case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
50
case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
51
{
52
- int region = cpu->env.pmsav7.rnr;
53
+ int region = cpu->env.pmsav7.rnr[attrs.secure];
54
55
if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
56
/* PMSAv8M handling of the aliases is different from v7M:
57
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
58
PRIu32 "/%" PRIu32 "\n",
59
value, cpu->pmsav7_dregion);
60
} else {
61
- cpu->env.pmsav7.rnr = value;
62
+ cpu->env.pmsav7.rnr[attrs.secure] = value;
63
}
64
break;
65
case 0xd9c: /* MPU_RBAR */
66
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
67
*/
68
int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
69
70
- region = cpu->env.pmsav7.rnr;
71
+ region = cpu->env.pmsav7.rnr[attrs.secure];
72
if (aliasno) {
73
region = deposit32(region, 0, 2, aliasno);
74
}
75
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
76
region, cpu->pmsav7_dregion);
77
return;
78
}
79
- cpu->env.pmsav7.rnr = region;
80
+ cpu->env.pmsav7.rnr[attrs.secure] = region;
81
} else {
82
- region = cpu->env.pmsav7.rnr;
83
+ region = cpu->env.pmsav7.rnr[attrs.secure];
84
}
85
86
if (region >= cpu->pmsav7_dregion) {
87
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
88
case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
89
case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
90
{
91
- int region = cpu->env.pmsav7.rnr;
92
+ int region = cpu->env.pmsav7.rnr[attrs.secure];
93
94
if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
95
/* PMSAv8M handling of the aliases is different from v7M:
96
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
97
*/
98
int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
99
100
- region = cpu->env.pmsav7.rnr;
101
+ region = cpu->env.pmsav7.rnr[attrs.secure];
102
if (aliasno) {
103
region = deposit32(region, 0, 2, aliasno);
104
}
105
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/cpu.c
108
+++ b/target/arm/cpu.c
109
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
110
sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
111
}
112
}
113
- env->pmsav7.rnr = 0;
114
+ env->pmsav7.rnr[M_REG_NS] = 0;
115
+ env->pmsav7.rnr[M_REG_S] = 0;
116
env->pmsav8.mair0[M_REG_NS] = 0;
117
env->pmsav8.mair0[M_REG_S] = 0;
118
env->pmsav8.mair1[M_REG_NS] = 0;
119
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
120
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/helper.c
32
--- a/target/arm/helper.c
122
+++ b/target/arm/helper.c
33
+++ b/target/arm/helper.c
123
@@ -XXX,XX +XXX,XX @@ static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri)
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
124
return 0;
35
bool enabled, prohibited = false, filtered;
36
bool secure = arm_is_secure(env);
37
int el = arm_current_el(env);
38
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
39
- uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
40
+ uint64_t mdcr_el2;
41
+ uint8_t hpmn;
42
43
+ /*
44
+ * We might be called for M-profile cores where MDCR_EL2 doesn't
45
+ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check
46
+ * must be before we read that value.
47
+ */
48
if (!arm_feature(env, ARM_FEATURE_PMU)) {
49
return false;
125
}
50
}
126
51
127
- u32p += env->pmsav7.rnr;
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
128
+ u32p += env->pmsav7.rnr[M_REG_NS];
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
129
return *u32p;
130
}
131
132
@@ -XXX,XX +XXX,XX @@ static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri,
133
return;
134
}
135
136
- u32p += env->pmsav7.rnr;
137
+ u32p += env->pmsav7.rnr[M_REG_NS];
138
tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
139
*u32p = value;
140
}
141
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
142
.resetfn = arm_cp_reset_ignore },
143
{ .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0,
144
.access = PL1_RW,
145
- .fieldoffset = offsetof(CPUARMState, pmsav7.rnr),
146
+ .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]),
147
.writefn = pmsav7_rgnr_write,
148
.resetfn = arm_cp_reset_ignore },
149
REGINFO_SENTINEL
150
diff --git a/target/arm/machine.c b/target/arm/machine.c
151
index XXXXXXX..XXXXXXX 100644
152
--- a/target/arm/machine.c
153
+++ b/target/arm/machine.c
154
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id)
155
{
156
ARMCPU *cpu = opaque;
157
158
- return cpu->env.pmsav7.rnr < cpu->pmsav7_dregion;
159
+ return cpu->env.pmsav7.rnr[M_REG_NS] < cpu->pmsav7_dregion;
160
}
161
162
static const VMStateDescription vmstate_pmsav7 = {
163
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav7_rnr = {
164
.minimum_version_id = 1,
165
.needed = pmsav7_rnr_needed,
166
.fields = (VMStateField[]) {
167
- VMSTATE_UINT32(env.pmsav7.rnr, ARMCPU),
168
+ VMSTATE_UINT32(env.pmsav7.rnr[M_REG_NS], ARMCPU),
169
VMSTATE_END_OF_LIST()
170
}
171
};
172
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav8 = {
173
}
174
};
175
176
+static bool s_rnr_vmstate_validate(void *opaque, int version_id)
177
+{
178
+ ARMCPU *cpu = opaque;
179
+
54
+
180
+ return cpu->env.pmsav7.rnr[M_REG_S] < cpu->pmsav7_dregion;
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
181
+}
56
(counter < hpmn || counter == 31)) {
182
+
57
e = env->cp15.c9_pmcr & PMCRE;
183
static bool m_security_needed(void *opaque)
184
{
185
ARMCPU *cpu = opaque;
186
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
187
0, vmstate_info_uint32, uint32_t),
188
VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion,
189
0, vmstate_info_uint32, uint32_t),
190
+ VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU),
191
+ VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate),
192
VMSTATE_END_OF_LIST()
193
}
194
};
195
--
58
--
196
2.7.4
59
2.34.1
197
60
198
61
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
From: Nabih Estefan <nabihestefan@google.com>
2
2
3
Signed-off-by: Fam Zheng <famz@redhat.com>
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
5
Message-id: 20170905131149.10669-3-famz@redhat.com
5
6
Change-Id: Iabd0fba14910c3f1e883c4a9521350f3db9ffab8
7
Signed-Off-By: Nabih Estefan <nabihestefan@google.com>
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
9
Message-id: 20240208194759.2858582-2-nabihestefan@google.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: commit message tweaks]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
13
---
9
hw/arm/armv7m.c | 8 ++------
14
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
10
1 file changed, 2 insertions(+), 6 deletions(-)
15
tests/qtest/meson.build | 3 +-
16
2 files changed, 4 insertions(+), 83 deletions(-)
11
17
12
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/armv7m.c
20
--- a/tests/qtest/npcm_gmac-test.c
15
+++ b/hw/arm/armv7m.c
21
+++ b/tests/qtest/npcm_gmac-test.c
16
@@ -XXX,XX +XXX,XX @@ static void armv7m_instance_init(Object *obj)
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
17
23
const GMACModule *module;
18
/* Can't init the cpu here, we don't yet know which model to use */
24
} TestData;
19
25
20
- object_property_add_link(obj, "memory",
26
-/* Values extracted from hw/arm/npcm8xx.c */
21
- TYPE_MEMORY_REGION,
27
+/* Values extracted from hw/arm/npcm7xx.c */
22
- (Object **)&s->board_memory,
28
static const GMACModule gmac_module_list[] = {
23
- qdev_prop_allow_set_link_before_realize,
29
{
24
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
30
.irq = 14,
25
- &error_abort);
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
26
memory_region_init(&s->container, obj, "armv7m-container", UINT64_MAX);
32
.irq = 15,
27
33
.base_addr = 0xf0804000
28
object_initialize(&s->nvic, sizeof(s->nvic), TYPE_NVIC);
34
},
29
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
35
- {
30
36
- .irq = 16,
31
static Property armv7m_properties[] = {
37
- .base_addr = 0xf0806000
32
DEFINE_PROP_STRING("cpu-model", ARMv7MState, cpu_model),
38
- },
33
+ DEFINE_PROP_LINK("memory", ARMv7MState, board_memory, TYPE_MEMORY_REGION,
39
- {
34
+ MemoryRegion *),
40
- .irq = 17,
35
DEFINE_PROP_END_OF_LIST(),
41
- .base_addr = 0xf0808000
42
- }
36
};
43
};
37
44
45
/* Returns the index of the GMAC module. */
46
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
47
return qtest_readl(qts, mod->base_addr + regno);
48
}
49
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
51
- NPCMRegister regno)
52
-{
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
55
- uint32_t read_offset = regno & 0x1ff;
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
57
-}
58
-
59
/* Check that GMAC registers are reset to default value */
60
static void test_init(gconstpointer test_data)
61
{
62
const TestData *td = test_data;
63
const GMACModule *mod = td->module;
64
- QTestState *qts = qtest_init("-machine npcm845-evb");
65
+ QTestState *qts = qtest_init("-machine npcm750-evb");
66
67
#define CHECK_REG32(regno, value) \
68
do { \
69
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
70
} while (0)
71
72
-#define CHECK_REG_PCS(regno, value) \
73
- do { \
74
- g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
75
- } while (0)
76
-
77
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
78
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
79
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
80
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
81
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
82
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
83
84
- /* TODO Add registers PCS */
85
- if (mod->base_addr == 0xf0802000) {
86
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
87
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
88
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
89
-
90
- CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
91
- CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
92
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e);
93
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0);
94
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020);
95
- CHECK_REG_PCS(NPCM_PCS_SR_MII_LP_BABL, 0);
96
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_EXPN, 0);
97
- CHECK_REG_PCS(NPCM_PCS_SR_MII_EXT_STS, 0xc000);
98
-
99
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
100
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
101
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
102
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
103
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
104
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
105
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0);
106
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x0048);
107
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0);
108
-
109
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
110
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
111
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
112
- CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
113
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
114
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
115
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_TXTIMER, 0);
116
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_RXTIMER, 0);
117
- CHECK_REG_PCS(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0);
118
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL1, 0);
119
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_STS, 0x0010);
120
- CHECK_REG_PCS(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0);
121
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MISC_STS, 0);
122
- CHECK_REG_PCS(NPCM_PCS_VR_MII_RX_LSTS, 0);
123
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_BSTCTRL0, 0x00a);
124
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_LVLCTRL0, 0x007f);
125
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL0, 0x0001);
126
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL1, 0);
127
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_STS, 0);
128
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL0, 0x0100);
129
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL1, 0x1100);
130
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0, 0x000e);
131
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL0, 0x0100);
132
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL1, 0x0032);
133
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_STS, 0x0001);
134
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL2, 0);
135
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_LVL_CTRL, 0x0019);
136
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL0, 0);
137
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL1, 0);
138
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_CTRL2, 0);
139
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_ERRCNT_SEL, 0);
140
- }
141
-
142
qtest_quit(qts);
143
}
144
145
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
146
index XXXXXXX..XXXXXXX 100644
147
--- a/tests/qtest/meson.build
148
+++ b/tests/qtest/meson.build
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
150
'npcm7xx_sdhci-test',
151
'npcm7xx_smbus-test',
152
'npcm7xx_timer-test',
153
- 'npcm7xx_watchdog_timer-test'] + \
154
+ 'npcm7xx_watchdog_timer-test',
155
+ 'npcm_gmac-test'] + \
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
157
qtests_aspeed = \
158
['aspeed_hace-test',
38
--
159
--
39
2.7.4
160
2.34.1
40
41
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
Signed-off-by: Fam Zheng <famz@redhat.com>
3
An access fault is raised when the Access Flag is not set in the
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
looked-up PTE and the AFFD field is not set in the corresponding context
5
Message-id: 20170905131149.10669-6-famz@redhat.com
5
descriptor. This was already implemented for stage 2. Implement it for
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
stage 1 as well.
7
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Tested-by: Mostafa Saleh <smostafa@google.com>
12
Message-id: 20240213082211.3330400-1-luc.michel@amd.com
13
[PMM: tweaked comment text]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
15
---
9
hw/net/xilinx_axienet.c | 16 ++++------------
16
hw/arm/smmuv3-internal.h | 1 +
10
1 file changed, 4 insertions(+), 12 deletions(-)
17
include/hw/arm/smmu-common.h | 1 +
18
hw/arm/smmu-common.c | 11 +++++++++++
19
hw/arm/smmuv3.c | 1 +
20
4 files changed, 14 insertions(+)
11
21
12
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
13
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/xilinx_axienet.c
24
--- a/hw/arm/smmuv3-internal.h
15
+++ b/hw/net/xilinx_axienet.c
25
+++ b/hw/arm/smmuv3-internal.h
16
@@ -XXX,XX +XXX,XX @@ static void xilinx_enet_init(Object *obj)
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
17
XilinxAXIEnet *s = XILINX_AXI_ENET(obj);
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
18
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
19
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
20
- object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE,
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
21
- (Object **) &s->tx_data_dev,
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
22
- qdev_prop_allow_set_link_before_realize,
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
23
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
24
- &error_abort);
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
25
- object_property_add_link(obj, "axistream-control-connected",
35
index XXXXXXX..XXXXXXX 100644
26
- TYPE_STREAM_SLAVE,
36
--- a/include/hw/arm/smmu-common.h
27
- (Object **) &s->tx_control_dev,
37
+++ b/include/hw/arm/smmu-common.h
28
- qdev_prop_allow_set_link_before_realize,
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
29
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
39
bool disabled; /* smmu is disabled */
30
- &error_abort);
40
bool bypassed; /* translation is bypassed */
31
-
41
bool aborted; /* translation is aborted */
32
object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
42
+ bool affd; /* AF fault disable */
33
TYPE_XILINX_AXI_ENET_DATA_STREAM);
43
uint32_t iotlb_hits; /* counts IOTLB hits */
34
object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
35
@@ -XXX,XX +XXX,XX @@ static Property xilinx_enet_properties[] = {
45
/* Used by stage-1 only. */
36
DEFINE_PROP_UINT32("rxmem", XilinxAXIEnet, c_rxmem, 0x1000),
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
37
DEFINE_PROP_UINT32("txmem", XilinxAXIEnet, c_txmem, 0x1000),
47
index XXXXXXX..XXXXXXX 100644
38
DEFINE_NIC_PROPERTIES(XilinxAXIEnet, conf),
48
--- a/hw/arm/smmu-common.c
39
+ DEFINE_PROP_LINK("axistream-connected", XilinxAXIEnet,
49
+++ b/hw/arm/smmu-common.c
40
+ tx_data_dev, TYPE_STREAM_SLAVE, StreamSlave *),
50
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
41
+ DEFINE_PROP_LINK("axistream-control-connected", XilinxAXIEnet,
51
pte_addr, pte, iova, gpa,
42
+ tx_control_dev, TYPE_STREAM_SLAVE, StreamSlave *),
52
block_size >> 20);
43
DEFINE_PROP_END_OF_LIST(),
53
}
44
};
54
+
55
+ /*
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
58
+ * An Access flag fault takes priority over a Permission fault.
59
+ */
60
+ if (!PTE_AF(pte) && !cfg->affd) {
61
+ info->type = SMMU_PTW_ERR_ACCESS;
62
+ goto error;
63
+ }
64
+
65
ap = PTE_AP(pte);
66
if (is_permission_fault(ap, perm)) {
67
info->type = SMMU_PTW_ERR_PERMISSION;
68
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/smmuv3.c
71
+++ b/hw/arm/smmuv3.c
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
74
cfg->tbi = CD_TBI(cd);
75
cfg->asid = CD_ASID(cd);
76
+ cfg->affd = CD_AFFD(cd);
77
78
trace_smmuv3_decode_cd(cfg->oas);
45
79
46
--
80
--
47
2.7.4
81
2.34.1
48
49
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Signed-off-by: Fam Zheng <famz@redhat.com>
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Message-id: 20170905131149.10669-4-famz@redhat.com
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
hw/intc/arm_gicv3_its_kvm.c | 19 +++++++------------
8
hw/arm/stellaris.c | 6 ++++--
9
1 file changed, 7 insertions(+), 12 deletions(-)
9
1 file changed, 4 insertions(+), 2 deletions(-)
10
10
11
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/arm_gicv3_its_kvm.c
13
--- a/hw/arm/stellaris.c
14
+++ b/hw/intc/arm_gicv3_its_kvm.c
14
+++ b/hw/arm/stellaris.c
15
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
16
qemu_add_vm_change_state_handler(vm_change_state_handler, s);
16
}
17
}
17
}
18
18
19
-static void kvm_arm_its_init(Object *obj)
19
-static void stellaris_adc_reset(StellarisADCState *s)
20
-{
20
+static void stellaris_adc_reset_hold(Object *obj)
21
- GICv3ITSState *s = KVM_ARM_ITS(obj);
21
{
22
-
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
23
- object_property_add_link(obj, "parent-gicv3",
23
int n;
24
- "kvm-arm-gicv3", (Object **)&s->gicv3,
24
25
- object_property_allow_set_link,
25
for (n = 0; n < 4; n++) {
26
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
27
- &error_abort);
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
28
-}
28
"adc", 0x1000);
29
-
29
sysbus_init_mmio(sbd, &s->iomem);
30
/**
30
- stellaris_adc_reset(s);
31
* kvm_arm_its_pre_save - handles the saving of ITS registers.
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
32
* ITS tables are flushed into guest RAM separately and earlier,
33
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
34
GITS_CTLR, &s->ctlr, true, &error_abort);
35
}
32
}
36
33
37
+static Property kvm_arm_its_props[] = {
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
38
+ DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "kvm-arm-gicv3",
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
39
+ GICv3State *),
40
+ DEFINE_PROP_END_OF_LIST(),
41
+};
42
+
43
static void kvm_arm_its_class_init(ObjectClass *klass, void *data)
44
{
36
{
45
DeviceClass *dc = DEVICE_CLASS(klass);
37
DeviceClass *dc = DEVICE_CLASS(klass);
46
GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
47
39
48
dc->realize = kvm_arm_its_realize;
40
+ rc->phases.hold = stellaris_adc_reset_hold;
49
+ dc->props = kvm_arm_its_props;
41
dc->vmsd = &vmstate_stellaris_adc;
50
icc->send_msi = kvm_its_send_msi;
42
}
51
icc->pre_save = kvm_arm_its_pre_save;
52
icc->post_load = kvm_arm_its_post_load;
53
@@ -XXX,XX +XXX,XX @@ static const TypeInfo kvm_arm_its_info = {
54
.name = TYPE_KVM_ARM_ITS,
55
.parent = TYPE_ARM_GICV3_ITS_COMMON,
56
.instance_size = sizeof(GICv3ITSState),
57
- .instance_init = kvm_arm_its_init,
58
.class_init = kvm_arm_its_class_init,
59
};
60
43
61
--
44
--
62
2.7.4
45
2.34.1
63
46
64
47
diff view generated by jsdifflib
1
Set the MachineClass flag ignore_memory_transaction_failures
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
for almost all ARM boards. This means they retain the legacy
3
behaviour that accesses to unimplemented addresses will RAZ/WI
4
rather than aborting, when a subsequent commit adds support
5
for external aborts.
6
2
7
The exceptions are:
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
* virt -- we know that guests won't try to prod devices
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
that we don't describe in the device tree or ACPI tables
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
10
* mps2 -- this board was written to use unimplemented-device
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
for all the ranges with devices we don't yet handle
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
10
1 file changed, 22 insertions(+), 4 deletions(-)
12
11
13
New boards should not set the flag, but instead be written
14
like the mps2.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
18
Message-id: 1504626814-23124-3-git-send-email-peter.maydell@linaro.org
19
For the Xilinx boards:
20
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
21
---
22
hw/arm/aspeed.c | 3 +++
23
hw/arm/collie.c | 1 +
24
hw/arm/cubieboard.c | 1 +
25
hw/arm/digic_boards.c | 1 +
26
hw/arm/exynos4_boards.c | 2 ++
27
hw/arm/gumstix.c | 2 ++
28
hw/arm/highbank.c | 2 ++
29
hw/arm/imx25_pdk.c | 1 +
30
hw/arm/integratorcp.c | 1 +
31
hw/arm/kzm.c | 1 +
32
hw/arm/mainstone.c | 1 +
33
hw/arm/musicpal.c | 1 +
34
hw/arm/netduino2.c | 1 +
35
hw/arm/nseries.c | 2 ++
36
hw/arm/omap_sx1.c | 2 ++
37
hw/arm/palm.c | 1 +
38
hw/arm/raspi.c | 1 +
39
hw/arm/realview.c | 4 ++++
40
hw/arm/sabrelite.c | 1 +
41
hw/arm/spitz.c | 4 ++++
42
hw/arm/stellaris.c | 2 ++
43
hw/arm/tosa.c | 1 +
44
hw/arm/versatilepb.c | 2 ++
45
hw/arm/vexpress.c | 1 +
46
hw/arm/xilinx_zynq.c | 1 +
47
hw/arm/xlnx-ep108.c | 2 ++
48
hw/arm/z2.c | 1 +
49
27 files changed, 43 insertions(+)
50
51
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/arm/aspeed.c
54
+++ b/hw/arm/aspeed.c
55
@@ -XXX,XX +XXX,XX @@ static void palmetto_bmc_class_init(ObjectClass *oc, void *data)
56
mc->no_floppy = 1;
57
mc->no_cdrom = 1;
58
mc->no_parallel = 1;
59
+ mc->ignore_memory_transaction_failures = true;
60
}
61
62
static const TypeInfo palmetto_bmc_type = {
63
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_class_init(ObjectClass *oc, void *data)
64
mc->no_floppy = 1;
65
mc->no_cdrom = 1;
66
mc->no_parallel = 1;
67
+ mc->ignore_memory_transaction_failures = true;
68
}
69
70
static const TypeInfo ast2500_evb_type = {
71
@@ -XXX,XX +XXX,XX @@ static void romulus_bmc_class_init(ObjectClass *oc, void *data)
72
mc->no_floppy = 1;
73
mc->no_cdrom = 1;
74
mc->no_parallel = 1;
75
+ mc->ignore_memory_transaction_failures = true;
76
}
77
78
static const TypeInfo romulus_bmc_type = {
79
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/arm/collie.c
82
+++ b/hw/arm/collie.c
83
@@ -XXX,XX +XXX,XX @@ static void collie_machine_init(MachineClass *mc)
84
{
85
mc->desc = "Sharp SL-5500 (Collie) PDA (SA-1110)";
86
mc->init = collie_init;
87
+ mc->ignore_memory_transaction_failures = true;
88
}
89
90
DEFINE_MACHINE("collie", collie_machine_init)
91
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/hw/arm/cubieboard.c
94
+++ b/hw/arm/cubieboard.c
95
@@ -XXX,XX +XXX,XX @@ static void cubieboard_machine_init(MachineClass *mc)
96
mc->init = cubieboard_init;
97
mc->block_default_type = IF_IDE;
98
mc->units_per_default_bus = 1;
99
+ mc->ignore_memory_transaction_failures = true;
100
}
101
102
DEFINE_MACHINE("cubieboard", cubieboard_machine_init)
103
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/hw/arm/digic_boards.c
106
+++ b/hw/arm/digic_boards.c
107
@@ -XXX,XX +XXX,XX @@ static void canon_a1100_machine_init(MachineClass *mc)
108
{
109
mc->desc = "Canon PowerShot A1100 IS";
110
mc->init = &canon_a1100_init;
111
+ mc->ignore_memory_transaction_failures = true;
112
}
113
114
DEFINE_MACHINE("canon-a1100", canon_a1100_machine_init)
115
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
116
index XXXXXXX..XXXXXXX 100644
117
--- a/hw/arm/exynos4_boards.c
118
+++ b/hw/arm/exynos4_boards.c
119
@@ -XXX,XX +XXX,XX @@ static void nuri_class_init(ObjectClass *oc, void *data)
120
mc->desc = "Samsung NURI board (Exynos4210)";
121
mc->init = nuri_init;
122
mc->max_cpus = EXYNOS4210_NCPUS;
123
+ mc->ignore_memory_transaction_failures = true;
124
}
125
126
static const TypeInfo nuri_type = {
127
@@ -XXX,XX +XXX,XX @@ static void smdkc210_class_init(ObjectClass *oc, void *data)
128
mc->desc = "Samsung SMDKC210 board (Exynos4210)";
129
mc->init = smdkc210_init;
130
mc->max_cpus = EXYNOS4210_NCPUS;
131
+ mc->ignore_memory_transaction_failures = true;
132
}
133
134
static const TypeInfo smdkc210_type = {
135
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
136
index XXXXXXX..XXXXXXX 100644
137
--- a/hw/arm/gumstix.c
138
+++ b/hw/arm/gumstix.c
139
@@ -XXX,XX +XXX,XX @@ static void connex_class_init(ObjectClass *oc, void *data)
140
141
mc->desc = "Gumstix Connex (PXA255)";
142
mc->init = connex_init;
143
+ mc->ignore_memory_transaction_failures = true;
144
}
145
146
static const TypeInfo connex_type = {
147
@@ -XXX,XX +XXX,XX @@ static void verdex_class_init(ObjectClass *oc, void *data)
148
149
mc->desc = "Gumstix Verdex (PXA270)";
150
mc->init = verdex_init;
151
+ mc->ignore_memory_transaction_failures = true;
152
}
153
154
static const TypeInfo verdex_type = {
155
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/hw/arm/highbank.c
158
+++ b/hw/arm/highbank.c
159
@@ -XXX,XX +XXX,XX @@ static void highbank_class_init(ObjectClass *oc, void *data)
160
mc->block_default_type = IF_IDE;
161
mc->units_per_default_bus = 1;
162
mc->max_cpus = 4;
163
+ mc->ignore_memory_transaction_failures = true;
164
}
165
166
static const TypeInfo highbank_type = {
167
@@ -XXX,XX +XXX,XX @@ static void midway_class_init(ObjectClass *oc, void *data)
168
mc->block_default_type = IF_IDE;
169
mc->units_per_default_bus = 1;
170
mc->max_cpus = 4;
171
+ mc->ignore_memory_transaction_failures = true;
172
}
173
174
static const TypeInfo midway_type = {
175
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
176
index XXXXXXX..XXXXXXX 100644
177
--- a/hw/arm/imx25_pdk.c
178
+++ b/hw/arm/imx25_pdk.c
179
@@ -XXX,XX +XXX,XX @@ static void imx25_pdk_machine_init(MachineClass *mc)
180
{
181
mc->desc = "ARM i.MX25 PDK board (ARM926)";
182
mc->init = imx25_pdk_init;
183
+ mc->ignore_memory_transaction_failures = true;
184
}
185
186
DEFINE_MACHINE("imx25-pdk", imx25_pdk_machine_init)
187
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
188
index XXXXXXX..XXXXXXX 100644
189
--- a/hw/arm/integratorcp.c
190
+++ b/hw/arm/integratorcp.c
191
@@ -XXX,XX +XXX,XX @@ static void integratorcp_machine_init(MachineClass *mc)
192
{
193
mc->desc = "ARM Integrator/CP (ARM926EJ-S)";
194
mc->init = integratorcp_init;
195
+ mc->ignore_memory_transaction_failures = true;
196
}
197
198
DEFINE_MACHINE("integratorcp", integratorcp_machine_init)
199
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/hw/arm/kzm.c
202
+++ b/hw/arm/kzm.c
203
@@ -XXX,XX +XXX,XX @@ static void kzm_machine_init(MachineClass *mc)
204
{
205
mc->desc = "ARM KZM Emulation Baseboard (ARM1136)";
206
mc->init = kzm_init;
207
+ mc->ignore_memory_transaction_failures = true;
208
}
209
210
DEFINE_MACHINE("kzm", kzm_machine_init)
211
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/hw/arm/mainstone.c
214
+++ b/hw/arm/mainstone.c
215
@@ -XXX,XX +XXX,XX @@ static void mainstone2_machine_init(MachineClass *mc)
216
{
217
mc->desc = "Mainstone II (PXA27x)";
218
mc->init = mainstone_init;
219
+ mc->ignore_memory_transaction_failures = true;
220
}
221
222
DEFINE_MACHINE("mainstone", mainstone2_machine_init)
223
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
224
index XXXXXXX..XXXXXXX 100644
225
--- a/hw/arm/musicpal.c
226
+++ b/hw/arm/musicpal.c
227
@@ -XXX,XX +XXX,XX @@ static void musicpal_machine_init(MachineClass *mc)
228
{
229
mc->desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)";
230
mc->init = musicpal_init;
231
+ mc->ignore_memory_transaction_failures = true;
232
}
233
234
DEFINE_MACHINE("musicpal", musicpal_machine_init)
235
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
236
index XXXXXXX..XXXXXXX 100644
237
--- a/hw/arm/netduino2.c
238
+++ b/hw/arm/netduino2.c
239
@@ -XXX,XX +XXX,XX @@ static void netduino2_machine_init(MachineClass *mc)
240
{
241
mc->desc = "Netduino 2 Machine";
242
mc->init = netduino2_init;
243
+ mc->ignore_memory_transaction_failures = true;
244
}
245
246
DEFINE_MACHINE("netduino2", netduino2_machine_init)
247
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/hw/arm/nseries.c
250
+++ b/hw/arm/nseries.c
251
@@ -XXX,XX +XXX,XX @@ static void n800_class_init(ObjectClass *oc, void *data)
252
mc->desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)";
253
mc->init = n800_init;
254
mc->default_boot_order = "";
255
+ mc->ignore_memory_transaction_failures = true;
256
}
257
258
static const TypeInfo n800_type = {
259
@@ -XXX,XX +XXX,XX @@ static void n810_class_init(ObjectClass *oc, void *data)
260
mc->desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)";
261
mc->init = n810_init;
262
mc->default_boot_order = "";
263
+ mc->ignore_memory_transaction_failures = true;
264
}
265
266
static const TypeInfo n810_type = {
267
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
268
index XXXXXXX..XXXXXXX 100644
269
--- a/hw/arm/omap_sx1.c
270
+++ b/hw/arm/omap_sx1.c
271
@@ -XXX,XX +XXX,XX @@ static void sx1_machine_v2_class_init(ObjectClass *oc, void *data)
272
273
mc->desc = "Siemens SX1 (OMAP310) V2";
274
mc->init = sx1_init_v2;
275
+ mc->ignore_memory_transaction_failures = true;
276
}
277
278
static const TypeInfo sx1_machine_v2_type = {
279
@@ -XXX,XX +XXX,XX @@ static void sx1_machine_v1_class_init(ObjectClass *oc, void *data)
280
281
mc->desc = "Siemens SX1 (OMAP310) V1";
282
mc->init = sx1_init_v1;
283
+ mc->ignore_memory_transaction_failures = true;
284
}
285
286
static const TypeInfo sx1_machine_v1_type = {
287
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
288
index XXXXXXX..XXXXXXX 100644
289
--- a/hw/arm/palm.c
290
+++ b/hw/arm/palm.c
291
@@ -XXX,XX +XXX,XX @@ static void palmte_machine_init(MachineClass *mc)
292
{
293
mc->desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)";
294
mc->init = palmte_init;
295
+ mc->ignore_memory_transaction_failures = true;
296
}
297
298
DEFINE_MACHINE("cheetah", palmte_machine_init)
299
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
300
index XXXXXXX..XXXXXXX 100644
301
--- a/hw/arm/raspi.c
302
+++ b/hw/arm/raspi.c
303
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
304
mc->no_cdrom = 1;
305
mc->max_cpus = BCM2836_NCPUS;
306
mc->default_ram_size = 1024 * 1024 * 1024;
307
+ mc->ignore_memory_transaction_failures = true;
308
};
309
DEFINE_MACHINE("raspi2", raspi2_machine_init)
310
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
311
index XXXXXXX..XXXXXXX 100644
312
--- a/hw/arm/realview.c
313
+++ b/hw/arm/realview.c
314
@@ -XXX,XX +XXX,XX @@ static void realview_eb_class_init(ObjectClass *oc, void *data)
315
mc->desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)";
316
mc->init = realview_eb_init;
317
mc->block_default_type = IF_SCSI;
318
+ mc->ignore_memory_transaction_failures = true;
319
}
320
321
static const TypeInfo realview_eb_type = {
322
@@ -XXX,XX +XXX,XX @@ static void realview_eb_mpcore_class_init(ObjectClass *oc, void *data)
323
mc->init = realview_eb_mpcore_init;
324
mc->block_default_type = IF_SCSI;
325
mc->max_cpus = 4;
326
+ mc->ignore_memory_transaction_failures = true;
327
}
328
329
static const TypeInfo realview_eb_mpcore_type = {
330
@@ -XXX,XX +XXX,XX @@ static void realview_pb_a8_class_init(ObjectClass *oc, void *data)
331
332
mc->desc = "ARM RealView Platform Baseboard for Cortex-A8";
333
mc->init = realview_pb_a8_init;
334
+ mc->ignore_memory_transaction_failures = true;
335
}
336
337
static const TypeInfo realview_pb_a8_type = {
338
@@ -XXX,XX +XXX,XX @@ static void realview_pbx_a9_class_init(ObjectClass *oc, void *data)
339
mc->desc = "ARM RealView Platform Baseboard Explore for Cortex-A9";
340
mc->init = realview_pbx_a9_init;
341
mc->max_cpus = 4;
342
+ mc->ignore_memory_transaction_failures = true;
343
}
344
345
static const TypeInfo realview_pbx_a9_type = {
346
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
347
index XXXXXXX..XXXXXXX 100644
348
--- a/hw/arm/sabrelite.c
349
+++ b/hw/arm/sabrelite.c
350
@@ -XXX,XX +XXX,XX @@ static void sabrelite_machine_init(MachineClass *mc)
351
mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)";
352
mc->init = sabrelite_init;
353
mc->max_cpus = FSL_IMX6_NUM_CPUS;
354
+ mc->ignore_memory_transaction_failures = true;
355
}
356
357
DEFINE_MACHINE("sabrelite", sabrelite_machine_init)
358
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
359
index XXXXXXX..XXXXXXX 100644
360
--- a/hw/arm/spitz.c
361
+++ b/hw/arm/spitz.c
362
@@ -XXX,XX +XXX,XX @@ static void akitapda_class_init(ObjectClass *oc, void *data)
363
364
mc->desc = "Sharp SL-C1000 (Akita) PDA (PXA270)";
365
mc->init = akita_init;
366
+ mc->ignore_memory_transaction_failures = true;
367
}
368
369
static const TypeInfo akitapda_type = {
370
@@ -XXX,XX +XXX,XX @@ static void spitzpda_class_init(ObjectClass *oc, void *data)
371
mc->desc = "Sharp SL-C3000 (Spitz) PDA (PXA270)";
372
mc->init = spitz_init;
373
mc->block_default_type = IF_IDE;
374
+ mc->ignore_memory_transaction_failures = true;
375
}
376
377
static const TypeInfo spitzpda_type = {
378
@@ -XXX,XX +XXX,XX @@ static void borzoipda_class_init(ObjectClass *oc, void *data)
379
mc->desc = "Sharp SL-C3100 (Borzoi) PDA (PXA270)";
380
mc->init = borzoi_init;
381
mc->block_default_type = IF_IDE;
382
+ mc->ignore_memory_transaction_failures = true;
383
}
384
385
static const TypeInfo borzoipda_type = {
386
@@ -XXX,XX +XXX,XX @@ static void terrierpda_class_init(ObjectClass *oc, void *data)
387
mc->desc = "Sharp SL-C3200 (Terrier) PDA (PXA270)";
388
mc->init = terrier_init;
389
mc->block_default_type = IF_IDE;
390
+ mc->ignore_memory_transaction_failures = true;
391
}
392
393
static const TypeInfo terrierpda_type = {
394
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
395
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
396
--- a/hw/arm/stellaris.c
14
--- a/hw/arm/stellaris.c
397
+++ b/hw/arm/stellaris.c
15
+++ b/hw/arm/stellaris.c
398
@@ -XXX,XX +XXX,XX @@ static void lm3s811evb_class_init(ObjectClass *oc, void *data)
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
399
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
400
mc->desc = "Stellaris LM3S811EVB";
401
mc->init = lm3s811evb_init;
402
+ mc->ignore_memory_transaction_failures = true;
403
}
18
}
404
19
405
static const TypeInfo lm3s811evb_type = {
20
-/* I2C controller. */
406
@@ -XXX,XX +XXX,XX @@ static void lm3s6965evb_class_init(ObjectClass *oc, void *data)
21
+/*
407
22
+ * I2C controller.
408
mc->desc = "Stellaris LM3S6965EVB";
23
+ * ??? For now we only implement the master interface.
409
mc->init = lm3s6965evb_init;
24
+ */
410
+ mc->ignore_memory_transaction_failures = true;
25
26
#define TYPE_STELLARIS_I2C "stellaris-i2c"
27
OBJECT_DECLARE_SIMPLE_TYPE(stellaris_i2c_state, STELLARIS_I2C)
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
29
stellaris_i2c_update(s);
411
}
30
}
412
31
413
static const TypeInfo lm3s6965evb_type = {
32
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
414
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
33
+static void stellaris_i2c_reset_enter(Object *obj, ResetType type)
415
index XXXXXXX..XXXXXXX 100644
34
{
416
--- a/hw/arm/tosa.c
35
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
417
+++ b/hw/arm/tosa.c
36
+
418
@@ -XXX,XX +XXX,XX @@ static void tosapda_machine_init(MachineClass *mc)
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
419
mc->desc = "Sharp SL-6000 (Tosa) PDA (PXA255)";
38
i2c_end_transfer(s->bus);
420
mc->init = tosa_init;
39
+}
421
mc->block_default_type = IF_IDE;
40
+
422
+ mc->ignore_memory_transaction_failures = true;
41
+static void stellaris_i2c_reset_hold(Object *obj)
42
+{
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
44
45
s->msa = 0;
46
s->mcs = 0;
47
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
48
s->mimr = 0;
49
s->mris = 0;
50
s->mcr = 0;
51
+}
52
+
53
+static void stellaris_i2c_reset_exit(Object *obj)
54
+{
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
56
+
57
stellaris_i2c_update(s);
423
}
58
}
424
59
425
DEFINE_MACHINE("tosa", tosapda_machine_init)
60
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
426
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
61
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
427
index XXXXXXX..XXXXXXX 100644
62
"i2c", 0x1000);
428
--- a/hw/arm/versatilepb.c
63
sysbus_init_mmio(sbd, &s->iomem);
429
+++ b/hw/arm/versatilepb.c
64
- /* ??? For now we only implement the master interface. */
430
@@ -XXX,XX +XXX,XX @@ static void versatilepb_class_init(ObjectClass *oc, void *data)
65
- stellaris_i2c_reset(s);
431
mc->desc = "ARM Versatile/PB (ARM926EJ-S)";
432
mc->init = vpb_init;
433
mc->block_default_type = IF_SCSI;
434
+ mc->ignore_memory_transaction_failures = true;
435
}
66
}
436
67
437
static const TypeInfo versatilepb_type = {
68
/* Analogue to Digital Converter. This is only partially implemented,
438
@@ -XXX,XX +XXX,XX @@ static void versatileab_class_init(ObjectClass *oc, void *data)
69
@@ -XXX,XX +XXX,XX @@ type_init(stellaris_machine_init)
439
mc->desc = "ARM Versatile/AB (ARM926EJ-S)";
70
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
440
mc->init = vab_init;
71
{
441
mc->block_default_type = IF_SCSI;
72
DeviceClass *dc = DEVICE_CLASS(klass);
442
+ mc->ignore_memory_transaction_failures = true;
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
74
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
78
dc->vmsd = &vmstate_stellaris_i2c;
443
}
79
}
444
80
445
static const TypeInfo versatileab_type = {
446
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
447
index XXXXXXX..XXXXXXX 100644
448
--- a/hw/arm/vexpress.c
449
+++ b/hw/arm/vexpress.c
450
@@ -XXX,XX +XXX,XX @@ static void vexpress_class_init(ObjectClass *oc, void *data)
451
mc->desc = "ARM Versatile Express";
452
mc->init = vexpress_common_init;
453
mc->max_cpus = 4;
454
+ mc->ignore_memory_transaction_failures = true;
455
}
456
457
static void vexpress_a9_class_init(ObjectClass *oc, void *data)
458
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
459
index XXXXXXX..XXXXXXX 100644
460
--- a/hw/arm/xilinx_zynq.c
461
+++ b/hw/arm/xilinx_zynq.c
462
@@ -XXX,XX +XXX,XX @@ static void zynq_machine_init(MachineClass *mc)
463
mc->init = zynq_init;
464
mc->max_cpus = 1;
465
mc->no_sdcard = 1;
466
+ mc->ignore_memory_transaction_failures = true;
467
}
468
469
DEFINE_MACHINE("xilinx-zynq-a9", zynq_machine_init)
470
diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
471
index XXXXXXX..XXXXXXX 100644
472
--- a/hw/arm/xlnx-ep108.c
473
+++ b/hw/arm/xlnx-ep108.c
474
@@ -XXX,XX +XXX,XX @@ static void xlnx_ep108_machine_init(MachineClass *mc)
475
mc->init = xlnx_ep108_init;
476
mc->block_default_type = IF_IDE;
477
mc->units_per_default_bus = 1;
478
+ mc->ignore_memory_transaction_failures = true;
479
}
480
481
DEFINE_MACHINE("xlnx-ep108", xlnx_ep108_machine_init)
482
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_init(MachineClass *mc)
483
mc->init = xlnx_ep108_init;
484
mc->block_default_type = IF_IDE;
485
mc->units_per_default_bus = 1;
486
+ mc->ignore_memory_transaction_failures = true;
487
}
488
489
DEFINE_MACHINE("xlnx-zcu102", xlnx_zcu102_machine_init)
490
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
491
index XXXXXXX..XXXXXXX 100644
492
--- a/hw/arm/z2.c
493
+++ b/hw/arm/z2.c
494
@@ -XXX,XX +XXX,XX @@ static void z2_machine_init(MachineClass *mc)
495
{
496
mc->desc = "Zipit Z2 (PXA27x)";
497
mc->init = z2_init;
498
+ mc->ignore_memory_transaction_failures = true;
499
}
500
501
DEFINE_MACHINE("z2", z2_machine_init)
502
--
81
--
503
2.7.4
82
2.34.1
504
83
505
84
diff view generated by jsdifflib
1
Make the PRIMASK register banked if v8M security extensions are enabled.
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Note that we do not yet implement the functionality of the new
3
QDev objects created with qdev_new() need to manually add
4
AIRCR.PRIS bit (which allows the effect of the NS copy of PRIMASK to
4
their parent relationship with object_property_add_child().
5
be restricted).
6
5
6
This commit plug the devices which aren't part of the SoC;
7
they will be plugged into a SoC container in the next one.
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1503414539-28762-8-git-send-email-peter.maydell@linaro.org
10
---
13
---
11
target/arm/cpu.h | 2 +-
14
hw/arm/stellaris.c | 4 ++++
12
hw/intc/armv7m_nvic.c | 2 +-
15
1 file changed, 4 insertions(+)
13
target/arm/helper.c | 4 ++--
14
target/arm/machine.c | 9 +++++++--
15
4 files changed, 11 insertions(+), 6 deletions(-)
16
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
19
--- a/hw/arm/stellaris.c
20
+++ b/target/arm/cpu.h
20
+++ b/hw/arm/stellaris.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
22
uint32_t bfar; /* BusFault Address */
22
&error_fatal);
23
unsigned mpu_ctrl; /* MPU_CTRL */
23
24
int exception;
24
ssddev = qdev_new("ssd0323");
25
- uint32_t primask;
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
26
+ uint32_t primask[2];
26
qdev_prop_set_uint8(ssddev, "cs", 1);
27
uint32_t faultmask;
27
qdev_realize_and_unref(ssddev, bus, &error_fatal);
28
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
28
29
} v7m;
29
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
30
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
30
+ object_property_add_child(OBJECT(ms), "splitter",
31
index XXXXXXX..XXXXXXX 100644
31
+ OBJECT(gpio_d_splitter));
32
--- a/hw/intc/armv7m_nvic.c
32
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
33
+++ b/hw/intc/armv7m_nvic.c
33
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
34
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
34
qdev_connect_gpio_out(
35
35
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
36
if (env->v7m.faultmask) {
36
DeviceState *gpad;
37
running = -1;
37
38
- } else if (env->v7m.primask) {
38
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
39
+ } else if (env->v7m.primask[env->v7m.secure]) {
39
+ object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
40
running = 0;
40
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
41
} else if (env->v7m.basepri[env->v7m.secure] > 0) {
41
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
42
running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s);
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/helper.c
46
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
48
return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ?
49
env->regs[13] : env->v7m.other_sp;
50
case 16: /* PRIMASK */
51
- return env->v7m.primask;
52
+ return env->v7m.primask[env->v7m.secure];
53
case 17: /* BASEPRI */
54
case 18: /* BASEPRI_MAX */
55
return env->v7m.basepri[env->v7m.secure];
56
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
57
}
58
break;
59
case 16: /* PRIMASK */
60
- env->v7m.primask = val & 1;
61
+ env->v7m.primask[env->v7m.secure] = val & 1;
62
break;
63
case 17: /* BASEPRI */
64
env->v7m.basepri[env->v7m.secure] = val & 0xff;
65
diff --git a/target/arm/machine.c b/target/arm/machine.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/machine.c
68
+++ b/target/arm/machine.c
69
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_faultmask_primask = {
70
.minimum_version_id = 1,
71
.fields = (VMStateField[]) {
72
VMSTATE_UINT32(env.v7m.faultmask, ARMCPU),
73
- VMSTATE_UINT32(env.v7m.primask, ARMCPU),
74
+ VMSTATE_UINT32(env.v7m.primask[M_REG_NS], ARMCPU),
75
VMSTATE_END_OF_LIST()
76
}
77
};
78
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
79
.fields = (VMStateField[]) {
80
VMSTATE_UINT32(env.v7m.secure, ARMCPU),
81
VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
82
+ VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
83
VMSTATE_END_OF_LIST()
84
}
85
};
86
@@ -XXX,XX +XXX,XX @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
87
* differences are that the T bit is not in the same place, the
88
* primask/faultmask info may be in the CPSR I and F bits, and
89
* we do not want the mode bits.
90
+ * We know that this cleanup happened before v8M, so there
91
+ * is no complication with banked primask/faultmask.
92
*/
93
uint32_t newval = val;
94
95
+ assert(!arm_feature(env, ARM_FEATURE_M_SECURITY));
96
+
97
newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE);
98
if (val & CPSR_T) {
99
newval |= XPSR_T;
100
@@ -XXX,XX +XXX,XX @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
101
env->v7m.faultmask = 1;
102
}
103
if (val & CPSR_I) {
104
- env->v7m.primask = 1;
105
+ env->v7m.primask[M_REG_NS] = 1;
106
}
107
val = newval;
108
}
42
}
109
--
43
--
110
2.7.4
44
2.34.1
111
45
112
46
diff view generated by jsdifflib
1
From: Fam Zheng <famz@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Signed-off-by: Fam Zheng <famz@redhat.com>
3
QDev objects created with qdev_new() need to manually add
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
their parent relationship with object_property_add_child().
5
Message-id: 20170905131149.10669-2-famz@redhat.com
5
6
Since we don't model the SoC, just use a QOM container.
7
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20240213155214.13619-5-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
hw/arm/armv7m.c | 8 ++------
13
hw/arm/stellaris.c | 11 ++++++++++-
10
1 file changed, 2 insertions(+), 6 deletions(-)
14
1 file changed, 10 insertions(+), 1 deletion(-)
11
15
12
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
16
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/armv7m.c
18
--- a/hw/arm/stellaris.c
15
+++ b/hw/arm/armv7m.c
19
+++ b/hw/arm/stellaris.c
16
@@ -XXX,XX +XXX,XX @@ static void bitband_init(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
17
BitBandState *s = BITBAND(obj);
21
* 400fe000 system control
18
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
22
*/
19
23
20
- object_property_add_link(obj, "source-memory",
24
+ Object *soc_container;
21
- TYPE_MEMORY_REGION,
25
DeviceState *gpio_dev[7], *nvic;
22
- (Object **)&s->source_memory,
26
qemu_irq gpio_in[7][8];
23
- qdev_prop_allow_set_link_before_realize,
27
qemu_irq gpio_out[7][8];
24
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
25
- &error_abort);
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
26
memory_region_init_io(&s->iomem, obj, &bitband_ops, s,
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
27
"bitband", 0x02000000);
31
28
sysbus_init_mmio(dev, &s->iomem);
32
+ soc_container = object_new("container");
29
@@ -XXX,XX +XXX,XX @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
30
34
+
31
static Property bitband_properties[] = {
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
32
DEFINE_PROP_UINT32("base", BitBandState, base, 0),
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
33
+ DEFINE_PROP_LINK("source-memory", BitBandState, source_memory,
37
&error_fatal);
34
+ TYPE_MEMORY_REGION, MemoryRegion *),
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
35
DEFINE_PROP_END_OF_LIST(),
39
* need its sysclk output.
36
};
40
*/
37
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
43
44
/*
45
* Most devices come preprogrammed with a MAC address in the user data.
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
48
49
nvic = qdev_new(TYPE_ARMV7M);
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
55
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
57
sbd = SYS_BUS_DEVICE(dev);
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
59
qdev_connect_clock_in(dev, "clk",
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
61
sysbus_realize_and_unref(sbd, &error_fatal);
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
63
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
66
-
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
68
qdev_connect_clock_in(dev, "WDOGCLK",
69
qdev_get_clock_out(ssys_dev, "SYSCLK"));
70
71
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
72
SysBusDevice *sbd;
73
74
dev = qdev_new("pl011_luminary");
75
+ object_property_add_child(soc_container, "uart[*]", OBJECT(dev));
76
sbd = SYS_BUS_DEVICE(dev);
77
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
78
sysbus_realize_and_unref(sbd, &error_fatal);
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
80
DeviceState *enet;
81
82
enet = qdev_new("stellaris_enet");
83
+ object_property_add_child(soc_container, "enet", OBJECT(enet));
84
if (nd) {
85
qdev_set_nic_properties(enet, nd);
86
} else {
38
--
87
--
39
2.7.4
88
2.34.1
40
89
41
90
diff view generated by jsdifflib
1
Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security
1
We support two different encodings for the AArch32 IMPDEF
2
extensions are enabled.
2
CBAR register -- older cores like the Cortex A9, A7, A15
3
have this at 4, c15, c0, 0; newer cores like the
4
Cortex A35, A53, A57 and A72 have it at 1 c15 c0 0.
3
5
4
We can freely add more items to vmstate_m_security without
6
When we implemented this we picked which encoding to
5
breaking migration compatibility, because no CPU currently
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
6
has the ARM_FEATURE_M_SECURITY bit enabled and so this
8
However this isn't right for three cases:
7
subsection is not yet used by anything.
9
* the qemu-system-arm 'max' CPU, which is supposed to be
10
a variant on a Cortex-A57; it ought to use the same
11
encoding the A57 does and which the AArch64 'max'
12
exposes to AArch32 guest code
13
* the Cortex-R52, which is AArch32-only but has the CBAR
14
at the newer encoding (and where we incorrectly are
15
not yet setting ARM_FEATURE_CBAR_RO anyway)
16
* any possible future support for other v8 AArch32
17
only CPUs, or for supporting "boot the CPU into
18
AArch32 mode" on our existing cores like the A57 etc
19
20
Make the decision of the encoding be based on whether
21
the CPU implements the ARM_FEATURE_V8 flag instead.
22
23
This changes the behaviour only for the qemu-system-arm
24
'-cpu max'. We don't expect anybody to be relying on the
25
old behaviour because:
26
* it's not what the real hardware Cortex-A57 does
27
(and that's what our ID register claims we are)
28
* we don't implement the memory-mapped GICv3 support
29
which is the only thing that exists at the peripheral
30
base address pointed to by the register
8
31
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 1503414539-28762-14-git-send-email-peter.maydell@linaro.org
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
12
---
35
---
13
target/arm/cpu.h | 4 ++--
36
target/arm/helper.c | 2 +-
14
hw/intc/armv7m_nvic.c | 8 ++++----
37
1 file changed, 1 insertion(+), 1 deletion(-)
15
target/arm/cpu.c | 26 ++++++++++++++++++++------
16
target/arm/helper.c | 11 ++++++-----
17
target/arm/machine.c | 12 ++++++++----
18
5 files changed, 40 insertions(+), 21 deletions(-)
19
38
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
25
* pmsav7.rnr (region number register)
26
* pmsav7_dregion (number of configured regions)
27
*/
28
- uint32_t *rbar;
29
- uint32_t *rlar;
30
+ uint32_t *rbar[2];
31
+ uint32_t *rlar[2];
32
uint32_t mair0[2];
33
uint32_t mair1[2];
34
} pmsav8;
35
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/intc/armv7m_nvic.c
38
+++ b/hw/intc/armv7m_nvic.c
39
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
40
if (region >= cpu->pmsav7_dregion) {
41
return 0;
42
}
43
- return cpu->env.pmsav8.rbar[region];
44
+ return cpu->env.pmsav8.rbar[attrs.secure][region];
45
}
46
47
if (region >= cpu->pmsav7_dregion) {
48
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
49
if (region >= cpu->pmsav7_dregion) {
50
return 0;
51
}
52
- return cpu->env.pmsav8.rlar[region];
53
+ return cpu->env.pmsav8.rlar[attrs.secure][region];
54
}
55
56
if (region >= cpu->pmsav7_dregion) {
57
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
58
if (region >= cpu->pmsav7_dregion) {
59
return;
60
}
61
- cpu->env.pmsav8.rbar[region] = value;
62
+ cpu->env.pmsav8.rbar[attrs.secure][region] = value;
63
tlb_flush(CPU(cpu));
64
return;
65
}
66
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
67
if (region >= cpu->pmsav7_dregion) {
68
return;
69
}
70
- cpu->env.pmsav8.rlar[region] = value;
71
+ cpu->env.pmsav8.rlar[attrs.secure][region] = value;
72
tlb_flush(CPU(cpu));
73
return;
74
}
75
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/cpu.c
78
+++ b/target/arm/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
80
if (arm_feature(env, ARM_FEATURE_PMSA)) {
81
if (cpu->pmsav7_dregion > 0) {
82
if (arm_feature(env, ARM_FEATURE_V8)) {
83
- memset(env->pmsav8.rbar, 0,
84
- sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion);
85
- memset(env->pmsav8.rlar, 0,
86
- sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion);
87
+ memset(env->pmsav8.rbar[M_REG_NS], 0,
88
+ sizeof(*env->pmsav8.rbar[M_REG_NS])
89
+ * cpu->pmsav7_dregion);
90
+ memset(env->pmsav8.rlar[M_REG_NS], 0,
91
+ sizeof(*env->pmsav8.rlar[M_REG_NS])
92
+ * cpu->pmsav7_dregion);
93
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
94
+ memset(env->pmsav8.rbar[M_REG_S], 0,
95
+ sizeof(*env->pmsav8.rbar[M_REG_S])
96
+ * cpu->pmsav7_dregion);
97
+ memset(env->pmsav8.rlar[M_REG_S], 0,
98
+ sizeof(*env->pmsav8.rlar[M_REG_S])
99
+ * cpu->pmsav7_dregion);
100
+ }
101
} else if (arm_feature(env, ARM_FEATURE_V7)) {
102
memset(env->pmsav7.drbar, 0,
103
sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
104
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
105
if (nr) {
106
if (arm_feature(env, ARM_FEATURE_V8)) {
107
/* PMSAv8 */
108
- env->pmsav8.rbar = g_new0(uint32_t, nr);
109
- env->pmsav8.rlar = g_new0(uint32_t, nr);
110
+ env->pmsav8.rbar[M_REG_NS] = g_new0(uint32_t, nr);
111
+ env->pmsav8.rlar[M_REG_NS] = g_new0(uint32_t, nr);
112
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
113
+ env->pmsav8.rbar[M_REG_S] = g_new0(uint32_t, nr);
114
+ env->pmsav8.rlar[M_REG_S] = g_new0(uint32_t, nr);
115
+ }
116
} else {
117
env->pmsav7.drbar = g_new0(uint32_t, nr);
118
env->pmsav7.drsr = g_new0(uint32_t, nr);
119
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
120
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/helper.c
41
--- a/target/arm/helper.c
122
+++ b/target/arm/helper.c
42
+++ b/target/arm/helper.c
123
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
124
{
44
* AArch64 cores we might need to add a specific feature flag
125
ARMCPU *cpu = arm_env_get_cpu(env);
45
* to indicate cores with "flavour 2" CBAR.
126
bool is_user = regime_is_user(env, mmu_idx);
46
*/
127
+ uint32_t secure = regime_is_secure(env, mmu_idx);
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
128
int n;
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
129
int matchregion = -1;
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
130
bool hit = false;
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
131
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
51
| extract64(cpu->reset_cbar, 32, 12);
132
* with bits [4:0] all zeroes, but the limit address is bits
133
* [31:5] from the register with bits [4:0] all ones.
134
*/
135
- uint32_t base = env->pmsav8.rbar[n] & ~0x1f;
136
- uint32_t limit = env->pmsav8.rlar[n] | 0x1f;
137
+ uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
138
+ uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
139
140
- if (!(env->pmsav8.rlar[n] & 0x1)) {
141
+ if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
142
/* Region disabled */
143
continue;
144
}
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
146
/* hit using the background region */
147
get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
148
} else {
149
- uint32_t ap = extract32(env->pmsav8.rbar[matchregion], 1, 2);
150
- uint32_t xn = extract32(env->pmsav8.rbar[matchregion], 0, 1);
151
+ uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
152
+ uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
153
154
if (m_is_system_region(env, address)) {
155
/* System space is always execute never */
156
diff --git a/target/arm/machine.c b/target/arm/machine.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/target/arm/machine.c
159
+++ b/target/arm/machine.c
160
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav8 = {
161
.minimum_version_id = 1,
162
.needed = pmsav8_needed,
163
.fields = (VMStateField[]) {
164
- VMSTATE_VARRAY_UINT32(env.pmsav8.rbar, ARMCPU, pmsav7_dregion, 0,
165
- vmstate_info_uint32, uint32_t),
166
- VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0,
167
- vmstate_info_uint32, uint32_t),
168
+ VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_NS], ARMCPU, pmsav7_dregion,
169
+ 0, vmstate_info_uint32, uint32_t),
170
+ VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_NS], ARMCPU, pmsav7_dregion,
171
+ 0, vmstate_info_uint32, uint32_t),
172
VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
173
VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),
174
VMSTATE_END_OF_LIST()
175
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
176
VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU),
177
VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU),
178
VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU),
179
+ VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_S], ARMCPU, pmsav7_dregion,
180
+ 0, vmstate_info_uint32, uint32_t),
181
+ VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion,
182
+ 0, vmstate_info_uint32, uint32_t),
183
VMSTATE_END_OF_LIST()
184
}
185
};
186
--
52
--
187
2.7.4
53
2.34.1
188
189
diff view generated by jsdifflib
1
Make the CONTROL register banked if v8M security extensions are enabled.
1
The Cortex-R52 implements the Configuration Base Address Register
2
(CBAR), as a read-only register. Add ARM_FEATURE_CBAR_RO to this CPU
3
type, so that our implementation provides the register and the
4
associated qdev property.
2
5
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 1503414539-28762-10-git-send-email-peter.maydell@linaro.org
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
6
---
9
---
7
target/arm/cpu.h | 5 +++--
10
target/arm/tcg/cpu32.c | 1 +
8
target/arm/helper.c | 21 +++++++++++----------
11
1 file changed, 1 insertion(+)
9
target/arm/machine.c | 3 ++-
10
target/arm/translate.c | 2 +-
11
4 files changed, 17 insertions(+), 14 deletions(-)
12
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
15
--- a/target/arm/tcg/cpu32.c
16
+++ b/target/arm/cpu.h
16
+++ b/target/arm/tcg/cpu32.c
17
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
18
uint32_t other_sp;
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
19
uint32_t vecbase;
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
20
uint32_t basepri[2];
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
21
- uint32_t control;
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
22
+ uint32_t control[2];
22
cpu->midr = 0x411fd133; /* r1p3 */
23
uint32_t ccr; /* Configuration and Control */
23
cpu->revidr = 0x00000000;
24
uint32_t cfsr; /* Configurable Fault Status */
24
cpu->reset_fpsid = 0x41034023;
25
uint32_t hfsr; /* HardFault Status */
26
@@ -XXX,XX +XXX,XX @@ static inline bool arm_v7m_is_handler_mode(CPUARMState *env)
27
static inline int arm_current_el(CPUARMState *env)
28
{
29
if (arm_feature(env, ARM_FEATURE_M)) {
30
- return arm_v7m_is_handler_mode(env) || !(env->v7m.control & 1);
31
+ return arm_v7m_is_handler_mode(env) ||
32
+ !(env->v7m.control[env->v7m.secure] & 1);
33
}
34
35
if (is_a64(env)) {
36
diff --git a/target/arm/helper.c b/target/arm/helper.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/helper.c
39
+++ b/target/arm/helper.c
40
@@ -XXX,XX +XXX,XX @@ static uint32_t v7m_pop(CPUARMState *env)
41
static void switch_v7m_sp(CPUARMState *env, bool new_spsel)
42
{
43
uint32_t tmp;
44
- bool old_spsel = env->v7m.control & R_V7M_CONTROL_SPSEL_MASK;
45
+ uint32_t old_control = env->v7m.control[env->v7m.secure];
46
+ bool old_spsel = old_control & R_V7M_CONTROL_SPSEL_MASK;
47
48
if (old_spsel != new_spsel) {
49
tmp = env->v7m.other_sp;
50
env->v7m.other_sp = env->regs[13];
51
env->regs[13] = tmp;
52
53
- env->v7m.control = deposit32(env->v7m.control,
54
+ env->v7m.control[env->v7m.secure] = deposit32(old_control,
55
R_V7M_CONTROL_SPSEL_SHIFT,
56
R_V7M_CONTROL_SPSEL_LENGTH, new_spsel);
57
}
58
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
59
}
60
61
lr = 0xfffffff1;
62
- if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
63
+ if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
64
lr |= 4;
65
}
66
if (!arm_v7m_is_handler_mode(env)) {
67
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
68
return xpsr_read(env) & mask;
69
break;
70
case 20: /* CONTROL */
71
- return env->v7m.control;
72
+ return env->v7m.control[env->v7m.secure];
73
}
74
75
if (el == 0) {
76
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
77
78
switch (reg) {
79
case 8: /* MSP */
80
- return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ?
81
+ return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
82
env->v7m.other_sp : env->regs[13];
83
case 9: /* PSP */
84
- return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ?
85
+ return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
86
env->regs[13] : env->v7m.other_sp;
87
case 16: /* PRIMASK */
88
return env->v7m.primask[env->v7m.secure];
89
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
90
}
91
break;
92
case 8: /* MSP */
93
- if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
94
+ if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
95
env->v7m.other_sp = val;
96
} else {
97
env->regs[13] = val;
98
}
99
break;
100
case 9: /* PSP */
101
- if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) {
102
+ if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
103
env->regs[13] = val;
104
} else {
105
env->v7m.other_sp = val;
106
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
107
if (!arm_v7m_is_handler_mode(env)) {
108
switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
109
}
110
- env->v7m.control &= ~R_V7M_CONTROL_NPRIV_MASK;
111
- env->v7m.control |= val & R_V7M_CONTROL_NPRIV_MASK;
112
+ env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
113
+ env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
114
break;
115
default:
116
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special"
117
diff --git a/target/arm/machine.c b/target/arm/machine.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/machine.c
120
+++ b/target/arm/machine.c
121
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
122
.fields = (VMStateField[]) {
123
VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
124
VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
125
- VMSTATE_UINT32(env.v7m.control, ARMCPU),
126
+ VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU),
127
VMSTATE_UINT32(env.v7m.ccr, ARMCPU),
128
VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
129
VMSTATE_UINT32(env.v7m.hfsr, ARMCPU),
130
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
131
VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
132
VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
133
VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
134
+ VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU),
135
VMSTATE_END_OF_LIST()
136
}
137
};
138
diff --git a/target/arm/translate.c b/target/arm/translate.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/target/arm/translate.c
141
+++ b/target/arm/translate.c
142
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
143
if (xpsr & XPSR_EXCP) {
144
mode = "handler";
145
} else {
146
- if (env->v7m.control & R_V7M_CONTROL_NPRIV_MASK) {
147
+ if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
148
mode = "unpriv-thread";
149
} else {
150
mode = "priv-thread";
151
--
25
--
152
2.7.4
26
2.34.1
153
154
diff view generated by jsdifflib
1
Make the VTOR register banked if v8M security extensions are enabled.
1
Add the Cortex-R52 IMPDEF sysregs, by defining them here and
2
also by enabling the AUXCR feature which defines the ACTLR
3
and HACTLR registers. As is our usual practice, we make these
4
simple reads-as-zero stubs for now.
2
5
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 1503414539-28762-12-git-send-email-peter.maydell@linaro.org
8
Message-id: 20240206132931.38376-4-peter.maydell@linaro.org
6
---
9
---
7
target/arm/cpu.h | 2 +-
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
8
hw/intc/armv7m_nvic.c | 13 +++++++------
11
1 file changed, 108 insertions(+)
9
target/arm/helper.c | 2 +-
10
target/arm/machine.c | 3 ++-
11
4 files changed, 11 insertions(+), 9 deletions(-)
12
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
15
--- a/target/arm/tcg/cpu32.c
16
+++ b/target/arm/cpu.h
16
+++ b/target/arm/tcg/cpu32.c
17
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
18
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
19
struct {
20
uint32_t other_sp;
21
- uint32_t vecbase;
22
+ uint32_t vecbase[2];
23
uint32_t basepri[2];
24
uint32_t control[2];
25
uint32_t ccr; /* Configuration and Control */
26
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/armv7m_nvic.c
29
+++ b/hw/intc/armv7m_nvic.c
30
@@ -XXX,XX +XXX,XX @@ static void set_irq_level(void *opaque, int n, int level)
31
}
32
}
19
}
33
20
34
-static uint32_t nvic_readl(NVICState *s, uint32_t offset)
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
35
+static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
24
+ { .name = "IMP_ATCMREGIONR",
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
27
+ { .name = "IMP_BTCMREGIONR",
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
30
+ { .name = "IMP_CTCMREGIONR",
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
33
+ { .name = "IMP_CSCTLR",
34
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
35
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
36
+ { .name = "IMP_BPCTLR",
37
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1,
38
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
39
+ { .name = "IMP_MEMPROTCLR",
40
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 2,
41
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
42
+ { .name = "IMP_SLAVEPCTLR",
43
+ .cp = 15, .opc1 = 0, .crn = 11, .crm = 0, .opc2 = 0,
44
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
45
+ { .name = "IMP_PERIPHREGIONR",
46
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
47
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
48
+ { .name = "IMP_FLASHIFREGIONR",
49
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 1,
50
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
51
+ { .name = "IMP_BUILDOPTR",
52
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
53
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
54
+ { .name = "IMP_PINOPTR",
55
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
56
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
57
+ { .name = "IMP_QOSR",
58
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 1,
59
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
60
+ { .name = "IMP_BUSTIMEOUTR",
61
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 2,
62
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
63
+ { .name = "IMP_INTMONR",
64
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 4,
65
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
66
+ { .name = "IMP_ICERR0",
67
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 0,
68
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
69
+ { .name = "IMP_ICERR1",
70
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 1,
71
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
72
+ { .name = "IMP_DCERR0",
73
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 0,
74
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
75
+ { .name = "IMP_DCERR1",
76
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 1,
77
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
78
+ { .name = "IMP_TCMERR0",
79
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 0,
80
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
81
+ { .name = "IMP_TCMERR1",
82
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 1,
83
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
84
+ { .name = "IMP_TCMSYNDR0",
85
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 2,
86
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
87
+ { .name = "IMP_TCMSYNDR1",
88
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 3,
89
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
90
+ { .name = "IMP_FLASHERR0",
91
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 0,
92
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
93
+ { .name = "IMP_FLASHERR1",
94
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 1,
95
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
96
+ { .name = "IMP_CDBGDR0",
97
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 0,
98
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
99
+ { .name = "IMP_CBDGBR1",
100
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 1,
101
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
102
+ { .name = "IMP_TESTR0",
103
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 0,
104
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
105
+ { .name = "IMP_TESTR1",
106
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 1,
107
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
108
+ { .name = "IMP_CDBGDCI",
109
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 15, .opc2 = 0,
110
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
111
+ { .name = "IMP_CDBGDCT",
112
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 0,
113
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
114
+ { .name = "IMP_CDBGICT",
115
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 1,
116
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
117
+ { .name = "IMP_CDBGDCD",
118
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 0,
119
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
120
+ { .name = "IMP_CDBGICD",
121
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 1,
122
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
123
+};
124
+
125
+
126
static void cortex_r52_initfn(Object *obj)
36
{
127
{
37
ARMCPU *cpu = s->cpu;
128
ARMCPU *cpu = ARM_CPU(obj);
38
uint32_t val;
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
39
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
40
/* ISRPREEMPT not implemented */
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
41
return val;
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
42
case 0xd08: /* Vector Table Offset. */
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
43
- return cpu->env.v7m.vecbase;
134
cpu->midr = 0x411fd133; /* r1p3 */
44
+ return cpu->env.v7m.vecbase[attrs.secure];
135
cpu->revidr = 0x00000000;
45
case 0xd0c: /* Application Interrupt/Reset Control. */
136
cpu->reset_fpsid = 0x41034023;
46
return 0xfa050000 | (s->prigroup << 8);
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
47
case 0xd10: /* System Control. */
138
48
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
139
cpu->pmsav7_dregion = 16;
49
}
140
cpu->pmsav8r_hdregion = 16;
141
+
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
50
}
143
}
51
144
52
-static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
145
static void cortex_r5f_initfn(Object *obj)
53
+static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
54
+ MemTxAttrs attrs)
55
{
56
ARMCPU *cpu = s->cpu;
57
58
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
59
}
60
break;
61
case 0xd08: /* Vector Table Offset. */
62
- cpu->env.v7m.vecbase = value & 0xffffff80;
63
+ cpu->env.v7m.vecbase[attrs.secure] = value & 0xffffff80;
64
break;
65
case 0xd0c: /* Application Interrupt/Reset Control. */
66
if ((value >> 16) == 0x05fa) {
67
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
68
break;
69
default:
70
if (size == 4) {
71
- val = nvic_readl(s, offset);
72
+ val = nvic_readl(s, offset, attrs);
73
} else {
74
qemu_log_mask(LOG_GUEST_ERROR,
75
"NVIC: Bad read of size %d at offset 0x%x\n",
76
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
77
return MEMTX_OK;
78
}
79
if (size == 4) {
80
- nvic_writel(s, offset, value);
81
+ nvic_writel(s, offset, value, attrs);
82
return MEMTX_OK;
83
}
84
qemu_log_mask(LOG_GUEST_ERROR,
85
diff --git a/target/arm/helper.c b/target/arm/helper.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/helper.c
88
+++ b/target/arm/helper.c
89
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu)
90
CPUState *cs = CPU(cpu);
91
CPUARMState *env = &cpu->env;
92
MemTxResult result;
93
- hwaddr vec = env->v7m.vecbase + env->v7m.exception * 4;
94
+ hwaddr vec = env->v7m.vecbase[env->v7m.secure] + env->v7m.exception * 4;
95
uint32_t addr;
96
97
addr = address_space_ldl(cs->as, vec,
98
diff --git a/target/arm/machine.c b/target/arm/machine.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/machine.c
101
+++ b/target/arm/machine.c
102
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
103
.minimum_version_id = 4,
104
.needed = m_needed,
105
.fields = (VMStateField[]) {
106
- VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
107
+ VMSTATE_UINT32(env.v7m.vecbase[M_REG_NS], ARMCPU),
108
VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
109
VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU),
110
VMSTATE_UINT32(env.v7m.ccr, ARMCPU),
111
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
112
VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
113
VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
114
VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU),
115
+ VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU),
116
VMSTATE_END_OF_LIST()
117
}
118
};
119
--
146
--
120
2.7.4
147
2.34.1
121
122
diff view generated by jsdifflib
1
Make the BASEPRI register banked if v8M security extensions are enabled.
1
Architecturally, the AArch32 MSR/MRS to/from banked register
2
instructions are UNPREDICTABLE for attempts to access a banked
3
register that the guest could access in a more direct way (e.g.
4
using this insn to access r8_fiq when already in FIQ mode). QEMU has
5
chosen to UNDEF on all of these.
2
6
3
Note that we do not yet implement the functionality of the new
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
4
AIRCR.PRIS bit (which allows the effect of the NS copy of BASEPRI to
8
out that real hardware permits this, with the same effect as if the
5
be restricted).
9
guest had directly written to SPSR. Further, there is some
10
guest code out there that assumes it can do this, because it
11
happens to work on hardware: an example Cortex-R52 startup code
12
fragment uses this, and it got copied into various other places,
13
including Zephyr. Zephyr was fixed to not use this:
14
https://github.com/zephyrproject-rtos/zephyr/issues/47330
15
but other examples are still out there, like the selftest
16
binary for the MPS3-AN536.
17
18
For convenience of being able to run guest code, permit
19
this UNPREDICTABLE access instead of UNDEFing it.
6
20
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1503414539-28762-7-git-send-email-peter.maydell@linaro.org
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
10
---
24
---
11
target/arm/cpu.h | 14 +++++++++++++-
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
12
hw/intc/armv7m_nvic.c | 4 ++--
26
target/arm/tcg/translate.c | 19 +++++++++++------
13
target/arm/helper.c | 10 ++++++----
27
2 files changed, 43 insertions(+), 19 deletions(-)
14
target/arm/machine.c | 3 ++-
15
4 files changed, 23 insertions(+), 8 deletions(-)
16
28
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
18
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
31
--- a/target/arm/tcg/op_helper.c
20
+++ b/target/arm/cpu.h
32
+++ b/target/arm/tcg/op_helper.c
21
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
22
#define ARMV7M_EXCP_PENDSV 14
34
*/
23
#define ARMV7M_EXCP_SYSTICK 15
35
int curmode = env->uncached_cpsr & CPSR_M;
24
36
25
+/* For M profile, some registers are banked secure vs non-secure;
37
- if (regno == 17) {
26
+ * these are represented as a 2-element array where the first element
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
27
+ * is the non-secure copy and the second is the secure copy.
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
28
+ * When the CPU does not have implement the security extension then
40
- goto undef;
29
+ * only the first element is used.
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
30
+ * This means that the copy for the current security state can be
42
+ /*
31
+ * accessed via env->registerfield[env->v7m.secure] (whether the security
43
+ * Handle Hyp target regs first because some are special cases
32
+ * extension is implemented or not).
44
+ * which don't want the usual "not accessible from tgtmode" check.
33
+ */
45
+ */
34
+#define M_REG_NS 0
46
+ switch (regno) {
35
+#define M_REG_S 1
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
36
+
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
37
/* ARM-specific interrupt pending bits. */
49
+ goto undef;
38
#define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1
50
+ }
39
#define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_EXT_2
51
+ break;
40
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
52
+ case 13:
41
struct {
53
+ if (curmode != ARM_CPU_MODE_MON) {
42
uint32_t other_sp;
54
+ goto undef;
43
uint32_t vecbase;
55
+ }
44
- uint32_t basepri;
56
+ break;
45
+ uint32_t basepri[2];
57
+ default:
46
uint32_t control;
58
+ g_assert_not_reached();
47
uint32_t ccr; /* Configuration and Control */
59
}
48
uint32_t cfsr; /* Configurable Fault Status */
60
return;
49
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/intc/armv7m_nvic.c
52
+++ b/hw/intc/armv7m_nvic.c
53
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
54
running = -1;
55
} else if (env->v7m.primask) {
56
running = 0;
57
- } else if (env->v7m.basepri > 0) {
58
- running = env->v7m.basepri & nvic_gprio_mask(s);
59
+ } else if (env->v7m.basepri[env->v7m.secure] > 0) {
60
+ running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s);
61
} else {
62
running = NVIC_NOEXC_PRIO; /* lower than any possible priority */
63
}
61
}
64
diff --git a/target/arm/helper.c b/target/arm/helper.c
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
65
index XXXXXXX..XXXXXXX 100644
63
}
66
--- a/target/arm/helper.c
64
}
67
+++ b/target/arm/helper.c
65
68
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
69
return env->v7m.primask;
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
70
case 17: /* BASEPRI */
68
- if (curmode != ARM_CPU_MODE_MON) {
71
case 18: /* BASEPRI_MAX */
69
- goto undef;
72
- return env->v7m.basepri;
70
- }
73
+ return env->v7m.basepri[env->v7m.secure];
71
- }
74
case 19: /* FAULTMASK */
72
-
75
return env->v7m.faultmask;
73
return;
76
default:
74
77
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
75
undef:
78
env->v7m.primask = val & 1;
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
79
break;
77
80
case 17: /* BASEPRI */
78
switch (regno) {
81
- env->v7m.basepri = val & 0xff;
79
case 16: /* SPSRs */
82
+ env->v7m.basepri[env->v7m.secure] = val & 0xff;
80
- env->banked_spsr[bank_number(tgtmode)] = value;
83
break;
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
84
case 18: /* BASEPRI_MAX */
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
85
val &= 0xff;
83
+ env->spsr = value;
86
- if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0))
84
+ } else {
87
- env->v7m.basepri = val;
85
+ env->banked_spsr[bank_number(tgtmode)] = value;
88
+ if (val != 0 && (val < env->v7m.basepri[env->v7m.secure]
89
+ || env->v7m.basepri[env->v7m.secure] == 0)) {
90
+ env->v7m.basepri[env->v7m.secure] = val;
91
+ }
86
+ }
92
break;
87
break;
93
case 19: /* FAULTMASK */
88
case 17: /* ELR_Hyp */
94
env->v7m.faultmask = val & 1;
89
env->elr_el[2] = value;
95
diff --git a/target/arm/machine.c b/target/arm/machine.c
90
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
91
92
switch (regno) {
93
case 16: /* SPSRs */
94
- return env->banked_spsr[bank_number(tgtmode)];
95
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
96
+ /* Only happens for SPSR_Hyp access in Hyp mode */
97
+ return env->spsr;
98
+ } else {
99
+ return env->banked_spsr[bank_number(tgtmode)];
100
+ }
101
case 17: /* ELR_Hyp */
102
return env->elr_el[2];
103
case 13:
104
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
96
index XXXXXXX..XXXXXXX 100644
105
index XXXXXXX..XXXXXXX 100644
97
--- a/target/arm/machine.c
106
--- a/target/arm/tcg/translate.c
98
+++ b/target/arm/machine.c
107
+++ b/target/arm/tcg/translate.c
99
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
108
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
100
.needed = m_needed,
109
break;
101
.fields = (VMStateField[]) {
110
case ARM_CPU_MODE_HYP:
102
VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
111
/*
103
- VMSTATE_UINT32(env.v7m.basepri, ARMCPU),
112
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
104
+ VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU),
113
- * (and so we can forbid accesses from EL2 or below). elr_hyp
105
VMSTATE_UINT32(env.v7m.control, ARMCPU),
114
- * can be accessed also from Hyp mode, so forbid accesses from
106
VMSTATE_UINT32(env.v7m.ccr, ARMCPU),
115
- * EL0 or EL1.
107
VMSTATE_UINT32(env.v7m.cfsr, ARMCPU),
116
+ * r13_hyp can only be accessed from Monitor mode, and so we
108
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
117
+ * can forbid accesses from EL2 or below.
109
.needed = m_security_needed,
118
+ * elr_hyp can be accessed also from Hyp mode, so forbid
110
.fields = (VMStateField[]) {
119
+ * accesses from EL0 or EL1.
111
VMSTATE_UINT32(env.v7m.secure, ARMCPU),
120
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
112
+ VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
121
+ * and UNPREDICTABLE if accessed from anything except Monitor
113
VMSTATE_END_OF_LIST()
122
+ * mode. However there is some real-world code that will do
114
}
123
+ * it because at least some hardware happens to permit the
115
};
124
+ * access. (Notably a standard Cortex-R52 startup code fragment
125
+ * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
126
+ * this (incorrect) guest code to run.
127
*/
128
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
129
- (s->current_el < 3 && *regno != 17)) {
130
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
131
+ || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
132
goto undef;
133
}
134
break;
116
--
135
--
117
2.7.4
136
2.34.1
118
119
diff view generated by jsdifflib
1
Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security
1
We currently guard the CFG3 register read with
2
extensions are enabled.
2
(scc_partno(s) == 0x524 && scc_partno(s) == 0x547)
3
which is clearly wrong as it is never true.
3
4
5
This register is present on all board types except AN524
6
and AN527; correct the condition.
7
8
Fixes: 6ac80818941829c0 ("hw/misc/mps2-scc: Implement changes for AN547")
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 1503414539-28762-13-git-send-email-peter.maydell@linaro.org
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
7
---
13
---
8
target/arm/cpu.h | 4 ++--
14
hw/misc/mps2-scc.c | 2 +-
9
hw/intc/armv7m_nvic.c | 8 ++++----
15
1 file changed, 1 insertion(+), 1 deletion(-)
10
target/arm/cpu.c | 6 ++++--
11
target/arm/machine.c | 6 ++++--
12
4 files changed, 14 insertions(+), 10 deletions(-)
13
16
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
19
--- a/hw/misc/mps2-scc.c
17
+++ b/target/arm/cpu.h
20
+++ b/hw/misc/mps2-scc.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
19
*/
22
r = s->cfg2;
20
uint32_t *rbar;
23
break;
21
uint32_t *rlar;
24
case A_CFG3:
22
- uint32_t mair0;
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
23
- uint32_t mair1;
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
24
+ uint32_t mair0[2];
27
/* CFG3 reserved on AN524 */
25
+ uint32_t mair1[2];
26
} pmsav8;
27
28
void *nvic;
29
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/intc/armv7m_nvic.c
32
+++ b/hw/intc/armv7m_nvic.c
33
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
34
if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
35
goto bad_offset;
28
goto bad_offset;
36
}
29
}
37
- return cpu->env.pmsav8.mair0;
38
+ return cpu->env.pmsav8.mair0[attrs.secure];
39
case 0xdc4: /* MPU_MAIR1 */
40
if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
41
goto bad_offset;
42
}
43
- return cpu->env.pmsav8.mair1;
44
+ return cpu->env.pmsav8.mair1[attrs.secure];
45
default:
46
bad_offset:
47
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
48
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
49
}
50
if (cpu->pmsav7_dregion) {
51
/* Register is RES0 if no MPU regions are implemented */
52
- cpu->env.pmsav8.mair0 = value;
53
+ cpu->env.pmsav8.mair0[attrs.secure] = value;
54
}
55
/* We don't need to do anything else because memory attributes
56
* only affect cacheability, and we don't implement caching.
57
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
58
}
59
if (cpu->pmsav7_dregion) {
60
/* Register is RES0 if no MPU regions are implemented */
61
- cpu->env.pmsav8.mair1 = value;
62
+ cpu->env.pmsav8.mair1[attrs.secure] = value;
63
}
64
/* We don't need to do anything else because memory attributes
65
* only affect cacheability, and we don't implement caching.
66
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/cpu.c
69
+++ b/target/arm/cpu.c
70
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
71
}
72
}
73
env->pmsav7.rnr = 0;
74
- env->pmsav8.mair0 = 0;
75
- env->pmsav8.mair1 = 0;
76
+ env->pmsav8.mair0[M_REG_NS] = 0;
77
+ env->pmsav8.mair0[M_REG_S] = 0;
78
+ env->pmsav8.mair1[M_REG_NS] = 0;
79
+ env->pmsav8.mair1[M_REG_S] = 0;
80
}
81
82
set_flush_to_zero(1, &env->vfp.standard_fp_status);
83
diff --git a/target/arm/machine.c b/target/arm/machine.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/machine.c
86
+++ b/target/arm/machine.c
87
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav8 = {
88
vmstate_info_uint32, uint32_t),
89
VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0,
90
vmstate_info_uint32, uint32_t),
91
- VMSTATE_UINT32(env.pmsav8.mair0, ARMCPU),
92
- VMSTATE_UINT32(env.pmsav8.mair1, ARMCPU),
93
+ VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
94
+ VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),
95
VMSTATE_END_OF_LIST()
96
}
97
};
98
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
99
VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
100
VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU),
101
VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU),
102
+ VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU),
103
+ VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU),
104
VMSTATE_END_OF_LIST()
105
}
106
};
107
--
30
--
108
2.7.4
31
2.34.1
109
32
110
33
diff view generated by jsdifflib
1
Implement the BXNS v8M instruction, which is like BX but will do a
1
The MPS SCC device has a lot of different flavours for the various
2
jump-and-switch-to-NonSecure if the branch target address has bit 0
2
different MPS FPGA images, which look mostly similar but have
3
clear.
3
differences in how particular registers are handled. Currently we
4
deal with this with a lot of open-coded checks on scc_partno(), but
5
as we add more board types this is getting a bit hard to read.
4
6
5
This is the first piece of code which implements "switch to the
7
Factor out the conditions into some functions which we can
6
other security state", so the commit also includes the code to
8
give more descriptive names to.
7
switch the stack pointers around, which is the only complicated
8
part of switching security state.
9
10
BLXNS is more complicated than just "BXNS but set the link register",
11
so we leave it for a separate commit.
12
9
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 1503414539-28762-21-git-send-email-peter.maydell@linaro.org
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
16
---
14
---
17
target/arm/cpu.h | 13 +++++++++
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
18
target/arm/helper.h | 2 ++
16
1 file changed, 31 insertions(+), 14 deletions(-)
19
target/arm/translate.h | 1 +
20
target/arm/helper.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++
21
target/arm/machine.c | 2 ++
22
target/arm/translate.c | 42 ++++++++++++++++++++++++++-
23
6 files changed, 138 insertions(+), 1 deletion(-)
24
17
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
26
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
20
--- a/hw/misc/mps2-scc.c
28
+++ b/target/arm/cpu.h
21
+++ b/hw/misc/mps2-scc.c
29
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
30
} cp15;
23
return extract32(s->id, 4, 8);
31
32
struct {
33
+ /* M profile has up to 4 stack pointers:
34
+ * a Main Stack Pointer and a Process Stack Pointer for each
35
+ * of the Secure and Non-Secure states. (If the CPU doesn't support
36
+ * the security extension then it has only two SPs.)
37
+ * In QEMU we always store the currently active SP in regs[13],
38
+ * and the non-active SP for the current security state in
39
+ * v7m.other_sp. The stack pointers for the inactive security state
40
+ * are stored in other_ss_msp and other_ss_psp.
41
+ * switch_v7m_security_state() is responsible for rearranging them
42
+ * when we change security state.
43
+ */
44
uint32_t other_sp;
45
+ uint32_t other_ss_msp;
46
+ uint32_t other_ss_psp;
47
uint32_t vecbase[2];
48
uint32_t basepri[2];
49
uint32_t control[2];
50
diff --git a/target/arm/helper.h b/target/arm/helper.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.h
53
+++ b/target/arm/helper.h
54
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(cpsr_read, i32, env)
55
DEF_HELPER_3(v7m_msr, void, env, i32, i32)
56
DEF_HELPER_2(v7m_mrs, i32, env, i32)
57
58
+DEF_HELPER_2(v7m_bxns, void, env, i32)
59
+
60
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
61
DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
62
DEF_HELPER_2(get_cp_reg, i32, env, ptr)
63
diff --git a/target/arm/translate.h b/target/arm/translate.h
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.h
66
+++ b/target/arm/translate.h
67
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
68
int vec_len;
69
int vec_stride;
70
bool v7m_handler_mode;
71
+ bool v8m_secure; /* true if v8M and we're in Secure mode */
72
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
73
* so that top level loop can generate correct syndrome information.
74
*/
75
diff --git a/target/arm/helper.c b/target/arm/helper.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/helper.c
78
+++ b/target/arm/helper.c
79
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
80
return 0;
81
}
24
}
82
25
83
+void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
26
+/* Is CFG_REG2 present? */
27
+static bool have_cfg2(MPS2SCC *s)
84
+{
28
+{
85
+ /* translate.c should never generate calls here in user-only mode */
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
86
+ g_assert_not_reached();
87
+}
30
+}
88
+
31
+
89
void switch_mode(CPUARMState *env, int mode)
32
+/* Is CFG_REG3 present? */
90
{
33
+static bool have_cfg3(MPS2SCC *s)
91
ARMCPU *cpu = arm_env_get_cpu(env);
92
@@ -XXX,XX +XXX,XX @@ static uint32_t v7m_pop(CPUARMState *env)
93
return val;
94
}
95
96
+/* Return true if we're using the process stack pointer (not the MSP) */
97
+static bool v7m_using_psp(CPUARMState *env)
98
+{
34
+{
99
+ /* Handler mode always uses the main stack; for thread mode
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
100
+ * the CONTROL.SPSEL bit determines the answer.
101
+ * Note that in v7M it is not possible to be in Handler mode with
102
+ * CONTROL.SPSEL non-zero, but in v8M it is, so we must check both.
103
+ */
104
+ return !arm_v7m_is_handler_mode(env) &&
105
+ env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK;
106
+}
36
+}
107
+
37
+
108
/* Switch to V7M main or process stack pointer. */
38
+/* Is CFG_REG5 present? */
109
static void switch_v7m_sp(CPUARMState *env, bool new_spsel)
39
+static bool have_cfg5(MPS2SCC *s)
110
{
111
@@ -XXX,XX +XXX,XX @@ static void switch_v7m_sp(CPUARMState *env, bool new_spsel)
112
}
113
}
114
115
+/* Switch M profile security state between NS and S */
116
+static void switch_v7m_security_state(CPUARMState *env, bool new_secstate)
117
+{
40
+{
118
+ uint32_t new_ss_msp, new_ss_psp;
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
119
+
120
+ if (env->v7m.secure == new_secstate) {
121
+ return;
122
+ }
123
+
124
+ /* All the banked state is accessed by looking at env->v7m.secure
125
+ * except for the stack pointer; rearrange the SP appropriately.
126
+ */
127
+ new_ss_msp = env->v7m.other_ss_msp;
128
+ new_ss_psp = env->v7m.other_ss_psp;
129
+
130
+ if (v7m_using_psp(env)) {
131
+ env->v7m.other_ss_psp = env->regs[13];
132
+ env->v7m.other_ss_msp = env->v7m.other_sp;
133
+ } else {
134
+ env->v7m.other_ss_msp = env->regs[13];
135
+ env->v7m.other_ss_psp = env->v7m.other_sp;
136
+ }
137
+
138
+ env->v7m.secure = new_secstate;
139
+
140
+ if (v7m_using_psp(env)) {
141
+ env->regs[13] = new_ss_psp;
142
+ env->v7m.other_sp = new_ss_msp;
143
+ } else {
144
+ env->regs[13] = new_ss_msp;
145
+ env->v7m.other_sp = new_ss_psp;
146
+ }
147
+}
42
+}
148
+
43
+
149
+void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
44
+/* Is CFG_REG6 present? */
45
+static bool have_cfg6(MPS2SCC *s)
150
+{
46
+{
151
+ /* Handle v7M BXNS:
47
+ return scc_partno(s) == 0x524;
152
+ * - if the return value is a magic value, do exception return (like BX)
153
+ * - otherwise bit 0 of the return value is the target security state
154
+ */
155
+ if (dest >= 0xff000000) {
156
+ /* This is an exception return magic value; put it where
157
+ * do_v7m_exception_exit() expects and raise EXCEPTION_EXIT.
158
+ * Note that if we ever add gen_ss_advance() singlestep support to
159
+ * M profile this should count as an "instruction execution complete"
160
+ * event (compare gen_bx_excret_final_code()).
161
+ */
162
+ env->regs[15] = dest & ~1;
163
+ env->thumb = dest & 1;
164
+ HELPER(exception_internal)(env, EXCP_EXCEPTION_EXIT);
165
+ /* notreached */
166
+ }
167
+
168
+ /* translate.c should have made BXNS UNDEF unless we're secure */
169
+ assert(env->v7m.secure);
170
+
171
+ switch_v7m_security_state(env, dest & 1);
172
+ env->thumb = 1;
173
+ env->regs[15] = dest & ~1;
174
+}
48
+}
175
+
49
+
176
static uint32_t arm_v7m_load_vector(ARMCPU *cpu)
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
177
{
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
178
CPUState *cs = CPU(cpu);
52
*/
179
diff --git a/target/arm/machine.c b/target/arm/machine.c
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
180
index XXXXXXX..XXXXXXX 100644
54
r = s->cfg1;
181
--- a/target/arm/machine.c
55
break;
182
+++ b/target/arm/machine.c
56
case A_CFG2:
183
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
184
.needed = m_security_needed,
58
- /* CFG2 reserved on other boards */
185
.fields = (VMStateField[]) {
59
+ if (!have_cfg2(s)) {
186
VMSTATE_UINT32(env.v7m.secure, ARMCPU),
60
goto bad_offset;
187
+ VMSTATE_UINT32(env.v7m.other_ss_msp, ARMCPU),
61
}
188
+ VMSTATE_UINT32(env.v7m.other_ss_psp, ARMCPU),
62
r = s->cfg2;
189
VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
63
break;
190
VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
64
case A_CFG3:
191
VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
192
diff --git a/target/arm/translate.c b/target/arm/translate.c
66
- /* CFG3 reserved on AN524 */
193
index XXXXXXX..XXXXXXX 100644
67
+ if (!have_cfg3(s)) {
194
--- a/target/arm/translate.c
68
goto bad_offset;
195
+++ b/target/arm/translate.c
69
}
196
@@ -XXX,XX +XXX,XX @@ static inline void gen_bx_excret_final_code(DisasContext *s)
70
/* These are user-settable DIP switches on the board. We don't
197
gen_exception_internal(EXCP_EXCEPTION_EXIT);
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
198
}
72
r = s->cfg4;
199
73
break;
200
+static inline void gen_bxns(DisasContext *s, int rm)
74
case A_CFG5:
201
+{
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
202
+ TCGv_i32 var = load_reg(s, rm);
76
- /* CFG5 reserved on other boards */
203
+
77
+ if (!have_cfg5(s)) {
204
+ /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
78
goto bad_offset;
205
+ * we need to sync state before calling it, but:
79
}
206
+ * - we don't need to do gen_set_pc_im() because the bxns helper will
80
r = s->cfg5;
207
+ * always set the PC itself
81
break;
208
+ * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
82
case A_CFG6:
209
+ * unless it's outside an IT block or the last insn in an IT block,
83
- if (scc_partno(s) != 0x524) {
210
+ * so we know that condexec == 0 (already set at the top of the TB)
84
- /* CFG6 reserved on other boards */
211
+ * is correct in the non-UNPREDICTABLE cases, and we can choose
85
+ if (!have_cfg6(s)) {
212
+ * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
86
goto bad_offset;
213
+ */
87
}
214
+ gen_helper_v7m_bxns(cpu_env, var);
88
r = s->cfg6;
215
+ tcg_temp_free_i32(var);
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
216
+ s->is_jmp = DISAS_EXIT;
90
}
217
+}
91
break;
218
+
92
case A_CFG2:
219
/* Variant of store_reg which uses branch&exchange logic when storing
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
220
to r15 in ARM architecture v7 and above. The source must be a temporary
94
- /* CFG2 reserved on other boards */
221
and will be marked as dead. */
95
+ if (!have_cfg2(s)) {
222
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
96
goto bad_offset;
223
*/
97
}
224
bool link = insn & (1 << 7);
98
/* AN524: QSPI Select signal */
225
99
s->cfg2 = value;
226
- if (insn & 7) {
100
break;
227
+ if (insn & 3) {
101
case A_CFG5:
228
goto undef;
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
229
}
103
- /* CFG5 reserved on other boards */
230
if (link) {
104
+ if (!have_cfg5(s)) {
231
ARCH(5);
105
goto bad_offset;
232
}
106
}
233
+ if ((insn & 4)) {
107
/* AN524: ACLK frequency in Hz */
234
+ /* BXNS/BLXNS: only exists for v8M with the
108
s->cfg5 = value;
235
+ * security extensions, and always UNDEF if NonSecure.
109
break;
236
+ * We don't implement these in the user-only mode
110
case A_CFG6:
237
+ * either (in theory you can use them from Secure User
111
- if (scc_partno(s) != 0x524) {
238
+ * mode but they are too tied in to system emulation.)
112
- /* CFG6 reserved on other boards */
239
+ */
113
+ if (!have_cfg6(s)) {
240
+ if (!s->v8m_secure || IS_USER_ONLY) {
114
goto bad_offset;
241
+ goto undef;
115
}
242
+ }
116
/* AN524: Clock divider for BRAM */
243
+ if (link) {
244
+ /* BLXNS: not yet implemented */
245
+ goto undef;
246
+ } else {
247
+ gen_bxns(s, rm);
248
+ }
249
+ break;
250
+ }
251
+ /* BLX/BX */
252
tmp = load_reg(s, rm);
253
if (link) {
254
val = (uint32_t)s->pc | 1;
255
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
256
dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
257
dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
258
dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(tb->flags);
259
+ dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
260
+ regime_is_secure(env, dc->mmu_idx);
261
dc->cp_regs = cpu->cp_regs;
262
dc->features = env->features;
263
264
--
117
--
265
2.7.4
118
2.34.1
266
119
267
120
diff view generated by jsdifflib
1
As part of ARMv8M, we need to add support for the PMSAv8 MPU
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
2
architecture.
2
minor differences in the behaviour of the CFG registers depending on
3
3
the image. In many cases we don't really care about the functionality
4
PMSAv8 differs from PMSAv7 both in register/data layout (for instance
4
controlled by these registers and a reads-as-written or similar
5
using base and limit registers rather than base and size) and also in
5
behaviour is sufficient for the moment.
6
behaviour (for example it does not have subregions); rather than
6
7
trying to wedge it into the existing PMSAv7 code and data structures,
7
For the AN536 the required behaviour is:
8
we define separate ones.
8
9
9
* A_CFG0 has CPU reset and halt bits
10
This commit adds the data structures which hold the state for a
10
- implement as reads-as-written for the moment
11
PMSAv8 MPU and the register interface to it. The implementation of
11
* A_CFG1 has flash or ATCM address 0 remap handling
12
the MPU behaviour will be added in a subsequent commit.
12
- QEMU doesn't model this; implement as reads-as-written
13
* A_CFG2 has QSPI select (like AN524)
14
- implemented (no behaviour, as with AN524)
15
* A_CFG3 is MCC_MSB_ADDR "additional MCC addressing bits"
16
- QEMU doesn't care about these, so use the existing
17
RAZ behaviour for convenience
18
* A_CFG4 is board rev (like all other images)
19
- no change needed
20
* A_CFG5 is ACLK frq in hz (like AN524)
21
- implemented as reads-as-written, as for other boards
22
* A_CFG6 is core 0 vector table base address
23
- implemented as reads-as-written for the moment
24
* A_CFG7 is core 1 vector table base address
25
- implemented as reads-as-written for the moment
26
27
Make the changes necessary for this; leave TODO comments where
28
appropriate to indicate where we might want to come back and
29
implement things like CPU reset.
30
31
The other aspects of the device specific to this FPGA image (like the
32
values of the board ID and similar registers) will be set via the
33
device's qdev properties.
13
34
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 1503414539-28762-2-git-send-email-peter.maydell@linaro.org
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
17
---
39
---
18
target/arm/cpu.h | 13 ++++++
40
include/hw/misc/mps2-scc.h | 1 +
19
hw/intc/armv7m_nvic.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++----
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
20
target/arm/cpu.c | 36 ++++++++++-----
42
2 files changed, 92 insertions(+), 10 deletions(-)
21
target/arm/machine.c | 29 +++++++++++-
43
22
4 files changed, 180 insertions(+), 20 deletions(-)
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
23
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu.h
46
--- a/include/hw/misc/mps2-scc.h
27
+++ b/target/arm/cpu.h
47
+++ b/include/hw/misc/mps2-scc.h
28
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
29
uint32_t rnr;
49
uint32_t cfg4;
30
} pmsav7;
50
uint32_t cfg5;
31
51
uint32_t cfg6;
32
+ /* PMSAv8 MPU */
52
+ uint32_t cfg7;
33
+ struct {
53
uint32_t cfgdata_rtn;
34
+ /* The PMSAv8 implementation also shares some PMSAv7 config
54
uint32_t cfgdata_out;
35
+ * and state:
55
uint32_t cfgctrl;
36
+ * pmsav7.rnr (region number register)
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
37
+ * pmsav7_dregion (number of configured regions)
38
+ */
39
+ uint32_t *rbar;
40
+ uint32_t *rlar;
41
+ uint32_t mair0;
42
+ uint32_t mair1;
43
+ } pmsav8;
44
+
45
void *nvic;
46
const struct arm_boot_info *boot_info;
47
/* Store GICv3CPUState to access from this struct */
48
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
49
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/intc/armv7m_nvic.c
58
--- a/hw/misc/mps2-scc.c
51
+++ b/hw/intc/armv7m_nvic.c
59
+++ b/hw/misc/mps2-scc.c
52
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
53
{
61
REG32(CFG4, 0x10)
54
int region = cpu->env.pmsav7.rnr;
62
REG32(CFG5, 0x14)
55
63
REG32(CFG6, 0x18)
56
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
64
+REG32(CFG7, 0x1c)
57
+ /* PMSAv8M handling of the aliases is different from v7M:
65
REG32(CFGDATA_RTN, 0xa0)
58
+ * aliases A1, A2, A3 override the low two bits of the region
66
REG32(CFGDATA_OUT, 0xa4)
59
+ * number in MPU_RNR, and there is no 'region' field in the
67
REG32(CFGCTRL, 0xa8)
60
+ * RBAR register.
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
61
+ */
69
/* Is CFG_REG2 present? */
62
+ int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
70
static bool have_cfg2(MPS2SCC *s)
63
+ if (aliasno) {
71
{
64
+ region = deposit32(region, 0, 2, aliasno);
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
65
+ }
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
66
+ if (region >= cpu->pmsav7_dregion) {
74
+ scc_partno(s) == 0x536;
67
+ return 0;
75
}
68
+ }
76
69
+ return cpu->env.pmsav8.rbar[region];
77
/* Is CFG_REG3 present? */
70
+ }
78
static bool have_cfg3(MPS2SCC *s)
71
+
79
{
72
if (region >= cpu->pmsav7_dregion) {
80
- return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
73
return 0;
81
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
74
}
82
+ scc_partno(s) != 0x536;
75
return (cpu->env.pmsav7.drbar[region] & 0x1f) | (region & 0xf);
83
}
76
}
84
77
- case 0xda0: /* MPU_RASR */
85
/* Is CFG_REG5 present? */
78
- case 0xda8: /* MPU_RASR_A1 */
86
static bool have_cfg5(MPS2SCC *s)
79
- case 0xdb0: /* MPU_RASR_A2 */
87
{
80
- case 0xdb8: /* MPU_RASR_A3 */
88
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
81
+ case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
89
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
82
+ case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
90
+ scc_partno(s) == 0x536;
83
+ case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
91
}
84
+ case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
92
85
{
93
/* Is CFG_REG6 present? */
86
int region = cpu->env.pmsav7.rnr;
94
static bool have_cfg6(MPS2SCC *s)
87
95
{
88
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
96
- return scc_partno(s) == 0x524;
89
+ /* PMSAv8M handling of the aliases is different from v7M:
97
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x536;
90
+ * aliases A1, A2, A3 override the low two bits of the region
98
+}
91
+ * number in MPU_RNR.
99
+
92
+ */
100
+/* Is CFG_REG7 present? */
93
+ int aliasno = (offset - 0xda0) / 8; /* 0..3 */
101
+static bool have_cfg7(MPS2SCC *s)
94
+ if (aliasno) {
102
+{
95
+ region = deposit32(region, 0, 2, aliasno);
103
+ return scc_partno(s) == 0x536;
96
+ }
104
+}
97
+ if (region >= cpu->pmsav7_dregion) {
105
+
98
+ return 0;
106
+/* Does CFG_REG0 drive the 'remap' GPIO output? */
99
+ }
107
+static bool cfg0_is_remap(MPS2SCC *s)
100
+ return cpu->env.pmsav8.rlar[region];
108
+{
101
+ }
109
+ return scc_partno(s) != 0x536;
102
+
110
+}
103
if (region >= cpu->pmsav7_dregion) {
111
+
104
return 0;
112
+/* Is CFG_REG1 driving a set of LEDs? */
105
}
113
+static bool cfg1_is_leds(MPS2SCC *s)
106
return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) |
114
+{
107
(cpu->env.pmsav7.drsr[region] & 0xffff);
115
+ return scc_partno(s) != 0x536;
108
}
116
}
109
+ case 0xdc0: /* MPU_MAIR0 */
117
110
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
118
/* Handle a write via the SYS_CFG channel to the specified function/device.
119
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
120
if (!have_cfg3(s)) {
121
goto bad_offset;
122
}
123
- /* These are user-settable DIP switches on the board. We don't
124
+ /*
125
+ * These are user-settable DIP switches on the board. We don't
126
* model that, so just return zeroes.
127
+ *
128
+ * TODO: for AN536 this is MCC_MSB_ADDR "additional MCC addressing
129
+ * bits". These change which part of the DDR4 the motherboard
130
+ * configuration controller can see in its memory map (see the
131
+ * appnote section 2.4). QEMU doesn't model the MCC at all, so these
132
+ * bits are not interesting to us; read-as-zero is as good as anything
133
+ * else.
134
*/
135
r = 0;
136
break;
137
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
138
}
139
r = s->cfg6;
140
break;
141
+ case A_CFG7:
142
+ if (!have_cfg7(s)) {
111
+ goto bad_offset;
143
+ goto bad_offset;
112
+ }
144
+ }
113
+ return cpu->env.pmsav8.mair0;
145
+ r = s->cfg7;
114
+ case 0xdc4: /* MPU_MAIR1 */
146
+ break;
115
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
147
case A_CFGDATA_RTN:
148
r = s->cfgdata_rtn;
149
break;
150
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
151
* we always reflect bit 0 in the 'remap' GPIO output line,
152
* and let the board wire it up or not as it chooses.
153
* TODO on some boards bit 1 is CPU_WAIT.
154
+ *
155
+ * TODO: on the AN536 this register controls reset and halt
156
+ * for both CPUs. For the moment we don't implement this, so the
157
+ * register just reads as written.
158
*/
159
s->cfg0 = value;
160
- qemu_set_irq(s->remap, s->cfg0 & 1);
161
+ if (cfg0_is_remap(s)) {
162
+ qemu_set_irq(s->remap, s->cfg0 & 1);
163
+ }
164
break;
165
case A_CFG1:
166
s->cfg1 = value;
167
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
168
- led_set_state(s->led[i], extract32(value, i, 1));
169
+ /*
170
+ * On most boards this register drives LEDs.
171
+ *
172
+ * TODO: for AN536 this controls whether flash and ATCM are
173
+ * enabled or disabled on reset. QEMU doesn't model this, and
174
+ * always wires up RAM in the ATCM area and ROM in the flash area.
175
+ */
176
+ if (cfg1_is_leds(s)) {
177
+ for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
178
+ led_set_state(s->led[i], extract32(value, i, 1));
179
+ }
180
}
181
break;
182
case A_CFG2:
183
if (!have_cfg2(s)) {
184
goto bad_offset;
185
}
186
- /* AN524: QSPI Select signal */
187
+ /* AN524, AN536: QSPI Select signal */
188
s->cfg2 = value;
189
break;
190
case A_CFG5:
191
if (!have_cfg5(s)) {
192
goto bad_offset;
193
}
194
- /* AN524: ACLK frequency in Hz */
195
+ /* AN524, AN536: ACLK frequency in Hz */
196
s->cfg5 = value;
197
break;
198
case A_CFG6:
199
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
200
goto bad_offset;
201
}
202
/* AN524: Clock divider for BRAM */
203
+ /* AN536: Core 0 vector table base address */
204
+ s->cfg6 = value;
205
+ break;
206
+ case A_CFG7:
207
+ if (!have_cfg7(s)) {
116
+ goto bad_offset;
208
+ goto bad_offset;
117
+ }
209
+ }
118
+ return cpu->env.pmsav8.mair1;
210
+ /* AN536: Core 1 vector table base address */
119
default:
211
s->cfg6 = value;
120
+ bad_offset:
212
break;
121
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
213
case A_CFGDATA_OUT:
122
return 0;
214
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_finalize(Object *obj)
123
}
215
g_free(s->oscclk_reset);
124
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
216
}
125
{
217
126
int region;
218
+static bool cfg7_needed(void *opaque)
127
219
+{
128
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
220
+ MPS2SCC *s = opaque;
129
+ /* PMSAv8M handling of the aliases is different from v7M:
221
+
130
+ * aliases A1, A2, A3 override the low two bits of the region
222
+ return have_cfg7(s);
131
+ * number in MPU_RNR, and there is no 'region' field in the
223
+}
132
+ * RBAR register.
224
+
133
+ */
225
+static const VMStateDescription vmstate_cfg7 = {
134
+ int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
226
+ .name = "mps2-scc/cfg7",
135
+
136
+ region = cpu->env.pmsav7.rnr;
137
+ if (aliasno) {
138
+ region = deposit32(region, 0, 2, aliasno);
139
+ }
140
+ if (region >= cpu->pmsav7_dregion) {
141
+ return;
142
+ }
143
+ cpu->env.pmsav8.rbar[region] = value;
144
+ tlb_flush(CPU(cpu));
145
+ return;
146
+ }
147
+
148
if (value & (1 << 4)) {
149
/* VALID bit means use the region number specified in this
150
* value and also update MPU_RNR.REGION with that value.
151
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
152
tlb_flush(CPU(cpu));
153
break;
154
}
155
- case 0xda0: /* MPU_RASR */
156
- case 0xda8: /* MPU_RASR_A1 */
157
- case 0xdb0: /* MPU_RASR_A2 */
158
- case 0xdb8: /* MPU_RASR_A3 */
159
+ case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */
160
+ case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */
161
+ case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */
162
+ case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */
163
{
164
int region = cpu->env.pmsav7.rnr;
165
166
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
167
+ /* PMSAv8M handling of the aliases is different from v7M:
168
+ * aliases A1, A2, A3 override the low two bits of the region
169
+ * number in MPU_RNR.
170
+ */
171
+ int aliasno = (offset - 0xd9c) / 8; /* 0..3 */
172
+
173
+ region = cpu->env.pmsav7.rnr;
174
+ if (aliasno) {
175
+ region = deposit32(region, 0, 2, aliasno);
176
+ }
177
+ if (region >= cpu->pmsav7_dregion) {
178
+ return;
179
+ }
180
+ cpu->env.pmsav8.rlar[region] = value;
181
+ tlb_flush(CPU(cpu));
182
+ return;
183
+ }
184
+
185
if (region >= cpu->pmsav7_dregion) {
186
return;
187
}
188
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
189
tlb_flush(CPU(cpu));
190
break;
191
}
192
+ case 0xdc0: /* MPU_MAIR0 */
193
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
194
+ goto bad_offset;
195
+ }
196
+ if (cpu->pmsav7_dregion) {
197
+ /* Register is RES0 if no MPU regions are implemented */
198
+ cpu->env.pmsav8.mair0 = value;
199
+ }
200
+ /* We don't need to do anything else because memory attributes
201
+ * only affect cacheability, and we don't implement caching.
202
+ */
203
+ break;
204
+ case 0xdc4: /* MPU_MAIR1 */
205
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
206
+ goto bad_offset;
207
+ }
208
+ if (cpu->pmsav7_dregion) {
209
+ /* Register is RES0 if no MPU regions are implemented */
210
+ cpu->env.pmsav8.mair1 = value;
211
+ }
212
+ /* We don't need to do anything else because memory attributes
213
+ * only affect cacheability, and we don't implement caching.
214
+ */
215
+ break;
216
case 0xf00: /* Software Triggered Interrupt Register */
217
{
218
int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;
219
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
220
break;
221
}
222
default:
223
+ bad_offset:
224
qemu_log_mask(LOG_GUEST_ERROR,
225
"NVIC: Bad write offset 0x%x\n", offset);
226
}
227
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/target/arm/cpu.c
230
+++ b/target/arm/cpu.c
231
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
232
env->vfp.xregs[ARM_VFP_FPEXC] = 0;
233
#endif
234
235
- if (arm_feature(env, ARM_FEATURE_PMSA) &&
236
- arm_feature(env, ARM_FEATURE_V7)) {
237
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
238
if (cpu->pmsav7_dregion > 0) {
239
- memset(env->pmsav7.drbar, 0,
240
- sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
241
- memset(env->pmsav7.drsr, 0,
242
- sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion);
243
- memset(env->pmsav7.dracr, 0,
244
- sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
245
+ if (arm_feature(env, ARM_FEATURE_V8)) {
246
+ memset(env->pmsav8.rbar, 0,
247
+ sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion);
248
+ memset(env->pmsav8.rlar, 0,
249
+ sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion);
250
+ } else if (arm_feature(env, ARM_FEATURE_V7)) {
251
+ memset(env->pmsav7.drbar, 0,
252
+ sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
253
+ memset(env->pmsav7.drsr, 0,
254
+ sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion);
255
+ memset(env->pmsav7.dracr, 0,
256
+ sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
257
+ }
258
}
259
env->pmsav7.rnr = 0;
260
+ env->pmsav8.mair0 = 0;
261
+ env->pmsav8.mair1 = 0;
262
}
263
264
set_flush_to_zero(1, &env->vfp.standard_fp_status);
265
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
266
}
267
268
if (nr) {
269
- env->pmsav7.drbar = g_new0(uint32_t, nr);
270
- env->pmsav7.drsr = g_new0(uint32_t, nr);
271
- env->pmsav7.dracr = g_new0(uint32_t, nr);
272
+ if (arm_feature(env, ARM_FEATURE_V8)) {
273
+ /* PMSAv8 */
274
+ env->pmsav8.rbar = g_new0(uint32_t, nr);
275
+ env->pmsav8.rlar = g_new0(uint32_t, nr);
276
+ } else {
277
+ env->pmsav7.drbar = g_new0(uint32_t, nr);
278
+ env->pmsav7.drsr = g_new0(uint32_t, nr);
279
+ env->pmsav7.dracr = g_new0(uint32_t, nr);
280
+ }
281
}
282
}
283
284
diff --git a/target/arm/machine.c b/target/arm/machine.c
285
index XXXXXXX..XXXXXXX 100644
286
--- a/target/arm/machine.c
287
+++ b/target/arm/machine.c
288
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_needed(void *opaque)
289
CPUARMState *env = &cpu->env;
290
291
return arm_feature(env, ARM_FEATURE_PMSA) &&
292
- arm_feature(env, ARM_FEATURE_V7);
293
+ arm_feature(env, ARM_FEATURE_V7) &&
294
+ !arm_feature(env, ARM_FEATURE_V8);
295
}
296
297
static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id)
298
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav7_rnr = {
299
}
300
};
301
302
+static bool pmsav8_needed(void *opaque)
303
+{
304
+ ARMCPU *cpu = opaque;
305
+ CPUARMState *env = &cpu->env;
306
+
307
+ return arm_feature(env, ARM_FEATURE_PMSA) &&
308
+ arm_feature(env, ARM_FEATURE_V8);
309
+}
310
+
311
+static const VMStateDescription vmstate_pmsav8 = {
312
+ .name = "cpu/pmsav8",
313
+ .version_id = 1,
227
+ .version_id = 1,
314
+ .minimum_version_id = 1,
228
+ .minimum_version_id = 1,
315
+ .needed = pmsav8_needed,
229
+ .needed = cfg7_needed,
316
+ .fields = (VMStateField[]) {
230
+ .fields = (const VMStateField[]) {
317
+ VMSTATE_VARRAY_UINT32(env.pmsav8.rbar, ARMCPU, pmsav7_dregion, 0,
231
+ VMSTATE_UINT32(cfg7, MPS2SCC),
318
+ vmstate_info_uint32, uint32_t),
319
+ VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0,
320
+ vmstate_info_uint32, uint32_t),
321
+ VMSTATE_UINT32(env.pmsav8.mair0, ARMCPU),
322
+ VMSTATE_UINT32(env.pmsav8.mair1, ARMCPU),
323
+ VMSTATE_END_OF_LIST()
232
+ VMSTATE_END_OF_LIST()
324
+ }
233
+ }
325
+};
234
+};
326
+
235
+
327
static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
236
static const VMStateDescription mps2_scc_vmstate = {
328
VMStateField *field)
237
.name = "mps2-scc",
329
{
238
.version_id = 3,
330
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
239
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
331
*/
240
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
332
&vmstate_pmsav7_rnr,
241
0, vmstate_info_uint32, uint32_t),
333
&vmstate_pmsav7,
242
VMSTATE_END_OF_LIST()
334
+ &vmstate_pmsav8,
243
+ },
335
NULL
244
+ .subsections = (const VMStateDescription * const []) {
245
+ &vmstate_cfg7,
246
+ NULL
336
}
247
}
337
};
248
};
249
338
--
250
--
339
2.7.4
251
2.34.1
340
252
341
253
diff view generated by jsdifflib
1
If a v8M CPU supports the security extension then we need to
1
The AN536 is another FPGA image for the MPS3 development board. Unlike
2
give it two AddressSpaces, the same way we do already for
2
the existing FPGA images we already model, this board uses a Cortex-R
3
an A profile core with EL3.
3
family CPU, and it does not use any equivalent to the M-profile
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
It's therefore more convenient for us to model it as a completely
6
separate C file.
7
8
This commit adds the basic skeleton of the board model, and the
9
code to create all the RAM and ROM. We assume that we're probably
10
going to want to add more images in future, so use the same
11
base class/subclass setup that mps2-tz.c uses, even though at
12
the moment there's only a single subclass.
13
14
Following commits will add the CPUs and the peripherals.
4
15
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 1503414539-28762-5-git-send-email-peter.maydell@linaro.org
18
Message-id: 20240206132931.38376-9-peter.maydell@linaro.org
8
---
19
---
9
target/arm/cpu.c | 13 ++++++-------
20
MAINTAINERS | 3 +-
10
1 file changed, 6 insertions(+), 7 deletions(-)
21
configs/devices/arm-softmmu/default.mak | 1 +
11
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
23
hw/arm/Kconfig | 5 +
24
hw/arm/meson.build | 1 +
25
5 files changed, 248 insertions(+), 1 deletion(-)
26
create mode 100644 hw/arm/mps3r.c
27
28
diff --git a/MAINTAINERS b/MAINTAINERS
13
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
30
--- a/MAINTAINERS
15
+++ b/target/arm/cpu.c
31
+++ b/MAINTAINERS
16
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
17
init_cpreg_list(cpu);
33
F: hw/pci-host/designware.c
18
34
F: include/hw/pci-host/designware.h
19
#ifndef CONFIG_USER_ONLY
35
20
- if (cpu->has_el3) {
36
-MPS2
21
- cs->num_ases = 2;
37
+MPS2 / MPS3
22
- } else {
38
M: Peter Maydell <peter.maydell@linaro.org>
23
- cs->num_ases = 1;
39
L: qemu-arm@nongnu.org
24
- }
40
S: Maintained
25
-
41
F: hw/arm/mps2.c
26
- if (cpu->has_el3) {
42
F: hw/arm/mps2-tz.c
27
+ if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) {
43
+F: hw/arm/mps3r.c
28
AddressSpace *as;
44
F: hw/misc/mps2-*.c
29
45
F: include/hw/misc/mps2-*.h
30
+ cs->num_ases = 2;
46
F: hw/arm/armsse.c
31
+
47
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
32
if (!cpu->secure_memory) {
48
index XXXXXXX..XXXXXXX 100644
33
cpu->secure_memory = cs->memory;
49
--- a/configs/devices/arm-softmmu/default.mak
34
}
50
+++ b/configs/devices/arm-softmmu/default.mak
35
as = address_space_init_shareable(cpu->secure_memory,
51
@@ -XXX,XX +XXX,XX @@ CONFIG_ARM_VIRT=y
36
"cpu-secure-memory");
52
# CONFIG_INTEGRATOR=n
37
cpu_address_space_init(cs, as, ARMASIdx_S);
53
# CONFIG_FSL_IMX31=n
38
+ } else {
54
# CONFIG_MUSICPAL=n
39
+ cs->num_ases = 1;
55
+# CONFIG_MPS3R=n
40
}
56
# CONFIG_MUSCA=n
41
+
57
# CONFIG_CHEETAH=n
42
cpu_address_space_init(cs,
58
# CONFIG_SX1=n
43
address_space_init_shareable(cs->memory,
59
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
44
"cpu-memory"),
60
new file mode 100644
61
index XXXXXXX..XXXXXXX
62
--- /dev/null
63
+++ b/hw/arm/mps3r.c
64
@@ -XXX,XX +XXX,XX @@
65
+/*
66
+ * Arm MPS3 board emulation for Cortex-R-based FPGA images.
67
+ * (For M-profile images see mps2.c and mps2tz.c.)
68
+ *
69
+ * Copyright (c) 2017 Linaro Limited
70
+ * Written by Peter Maydell
71
+ *
72
+ * This program is free software; you can redistribute it and/or modify
73
+ * it under the terms of the GNU General Public License version 2 or
74
+ * (at your option) any later version.
75
+ */
76
+
77
+/*
78
+ * The MPS3 is an FPGA based dev board. This file handles FPGA images
79
+ * which use the Cortex-R CPUs. We model these separately from the
80
+ * M-profile images, because on M-profile the FPGA image is based on
81
+ * a "Subsystem for Embedded" which is similar to an SoC, whereas
82
+ * the R-profile FPGA images don't have that abstraction layer.
83
+ *
84
+ * We model the following FPGA images here:
85
+ * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536
86
+ *
87
+ * Application Note AN536:
88
+ * https://developer.arm.com/documentation/dai0536/latest/
89
+ */
90
+
91
+#include "qemu/osdep.h"
92
+#include "qemu/units.h"
93
+#include "qapi/error.h"
94
+#include "exec/address-spaces.h"
95
+#include "cpu.h"
96
+#include "hw/boards.h"
97
+#include "hw/arm/boot.h"
98
+
99
+/* Define the layout of RAM and ROM in a board */
100
+typedef struct RAMInfo {
101
+ const char *name;
102
+ hwaddr base;
103
+ hwaddr size;
104
+ int mrindex; /* index into rams[]; -1 for the system RAM block */
105
+ int flags;
106
+} RAMInfo;
107
+
108
+/*
109
+ * The MPS3 DDR is 3GiB, but on a 32-bit host QEMU doesn't permit
110
+ * emulation of that much guest RAM, so artificially make it smaller.
111
+ */
112
+#if HOST_LONG_BITS == 32
113
+#define MPS3_DDR_SIZE (1 * GiB)
114
+#else
115
+#define MPS3_DDR_SIZE (3 * GiB)
116
+#endif
117
+
118
+/*
119
+ * Flag values:
120
+ * IS_MAIN: this is the main machine RAM
121
+ * IS_ROM: this area is read-only
122
+ */
123
+#define IS_MAIN 1
124
+#define IS_ROM 2
125
+
126
+#define MPS3R_RAM_MAX 9
127
+
128
+typedef enum MPS3RFPGAType {
129
+ FPGA_AN536,
130
+} MPS3RFPGAType;
131
+
132
+struct MPS3RMachineClass {
133
+ MachineClass parent;
134
+ MPS3RFPGAType fpga_type;
135
+ const RAMInfo *raminfo;
136
+};
137
+
138
+struct MPS3RMachineState {
139
+ MachineState parent;
140
+ MemoryRegion ram[MPS3R_RAM_MAX];
141
+};
142
+
143
+#define TYPE_MPS3R_MACHINE "mps3r"
144
+#define TYPE_MPS3R_AN536_MACHINE MACHINE_TYPE_NAME("mps3-an536")
145
+
146
+OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
147
+
148
+static const RAMInfo an536_raminfo[] = {
149
+ {
150
+ .name = "ATCM",
151
+ .base = 0x00000000,
152
+ .size = 0x00008000,
153
+ .mrindex = 0,
154
+ }, {
155
+ /* We model the QSPI flash as simple ROM for now */
156
+ .name = "QSPI",
157
+ .base = 0x08000000,
158
+ .size = 0x00800000,
159
+ .flags = IS_ROM,
160
+ .mrindex = 1,
161
+ }, {
162
+ .name = "BRAM",
163
+ .base = 0x10000000,
164
+ .size = 0x00080000,
165
+ .mrindex = 2,
166
+ }, {
167
+ .name = "DDR",
168
+ .base = 0x20000000,
169
+ .size = MPS3_DDR_SIZE,
170
+ .mrindex = -1,
171
+ }, {
172
+ .name = "ATCM0",
173
+ .base = 0xee000000,
174
+ .size = 0x00008000,
175
+ .mrindex = 3,
176
+ }, {
177
+ .name = "BTCM0",
178
+ .base = 0xee100000,
179
+ .size = 0x00008000,
180
+ .mrindex = 4,
181
+ }, {
182
+ .name = "CTCM0",
183
+ .base = 0xee200000,
184
+ .size = 0x00008000,
185
+ .mrindex = 5,
186
+ }, {
187
+ .name = "ATCM1",
188
+ .base = 0xee400000,
189
+ .size = 0x00008000,
190
+ .mrindex = 6,
191
+ }, {
192
+ .name = "BTCM1",
193
+ .base = 0xee500000,
194
+ .size = 0x00008000,
195
+ .mrindex = 7,
196
+ }, {
197
+ .name = "CTCM1",
198
+ .base = 0xee600000,
199
+ .size = 0x00008000,
200
+ .mrindex = 8,
201
+ }, {
202
+ .name = NULL,
203
+ }
204
+};
205
+
206
+static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
207
+ const RAMInfo *raminfo)
208
+{
209
+ /* Return an initialized MemoryRegion for the RAMInfo. */
210
+ MemoryRegion *ram;
211
+
212
+ if (raminfo->mrindex < 0) {
213
+ /* Means this RAMInfo is for QEMU's "system memory" */
214
+ MachineState *machine = MACHINE(mms);
215
+ assert(!(raminfo->flags & IS_ROM));
216
+ return machine->ram;
217
+ }
218
+
219
+ assert(raminfo->mrindex < MPS3R_RAM_MAX);
220
+ ram = &mms->ram[raminfo->mrindex];
221
+
222
+ memory_region_init_ram(ram, NULL, raminfo->name,
223
+ raminfo->size, &error_fatal);
224
+ if (raminfo->flags & IS_ROM) {
225
+ memory_region_set_readonly(ram, true);
226
+ }
227
+ return ram;
228
+}
229
+
230
+static void mps3r_common_init(MachineState *machine)
231
+{
232
+ MPS3RMachineState *mms = MPS3R_MACHINE(machine);
233
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
234
+ MemoryRegion *sysmem = get_system_memory();
235
+
236
+ for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
237
+ MemoryRegion *mr = mr_for_raminfo(mms, ri);
238
+ memory_region_add_subregion(sysmem, ri->base, mr);
239
+ }
240
+}
241
+
242
+static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
243
+{
244
+ /*
245
+ * Set mc->default_ram_size and default_ram_id from the
246
+ * information in mmc->raminfo.
247
+ */
248
+ MachineClass *mc = MACHINE_CLASS(mmc);
249
+ const RAMInfo *p;
250
+
251
+ for (p = mmc->raminfo; p->name; p++) {
252
+ if (p->mrindex < 0) {
253
+ /* Found the entry for "system memory" */
254
+ mc->default_ram_size = p->size;
255
+ mc->default_ram_id = p->name;
256
+ return;
257
+ }
258
+ }
259
+ g_assert_not_reached();
260
+}
261
+
262
+static void mps3r_class_init(ObjectClass *oc, void *data)
263
+{
264
+ MachineClass *mc = MACHINE_CLASS(oc);
265
+
266
+ mc->init = mps3r_common_init;
267
+}
268
+
269
+static void mps3r_an536_class_init(ObjectClass *oc, void *data)
270
+{
271
+ MachineClass *mc = MACHINE_CLASS(oc);
272
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_CLASS(oc);
273
+ static const char * const valid_cpu_types[] = {
274
+ ARM_CPU_TYPE_NAME("cortex-r52"),
275
+ NULL
276
+ };
277
+
278
+ mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
279
+ mc->default_cpus = 2;
280
+ mc->min_cpus = mc->default_cpus;
281
+ mc->max_cpus = mc->default_cpus;
282
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
283
+ mc->valid_cpu_types = valid_cpu_types;
284
+ mmc->raminfo = an536_raminfo;
285
+ mps3r_set_default_ram_info(mmc);
286
+}
287
+
288
+static const TypeInfo mps3r_machine_types[] = {
289
+ {
290
+ .name = TYPE_MPS3R_MACHINE,
291
+ .parent = TYPE_MACHINE,
292
+ .abstract = true,
293
+ .instance_size = sizeof(MPS3RMachineState),
294
+ .class_size = sizeof(MPS3RMachineClass),
295
+ .class_init = mps3r_class_init,
296
+ }, {
297
+ .name = TYPE_MPS3R_AN536_MACHINE,
298
+ .parent = TYPE_MPS3R_MACHINE,
299
+ .class_init = mps3r_an536_class_init,
300
+ },
301
+};
302
+
303
+DEFINE_TYPES(mps3r_machine_types);
304
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
305
index XXXXXXX..XXXXXXX 100644
306
--- a/hw/arm/Kconfig
307
+++ b/hw/arm/Kconfig
308
@@ -XXX,XX +XXX,XX @@ config MAINSTONE
309
select PFLASH_CFI01
310
select SMC91C111
311
312
+config MPS3R
313
+ bool
314
+ default y
315
+ depends on TCG && ARM
316
+
317
config MUSCA
318
bool
319
default y
320
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
321
index XXXXXXX..XXXXXXX 100644
322
--- a/hw/arm/meson.build
323
+++ b/hw/arm/meson.build
324
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
325
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
326
arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
327
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
328
+arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
329
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
330
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
331
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
45
--
332
--
46
2.7.4
333
2.34.1
47
334
48
335
diff view generated by jsdifflib
1
Move the regime_is_secure() utility function to internals.h;
1
Create the CPUs, the GIC, and the per-CPU RAM block for
2
we are going to want to call it from translate.c.
2
the mps3-an536 board.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240206132931.38376-10-peter.maydell@linaro.org
6
Message-id: 1503414539-28762-20-git-send-email-peter.maydell@linaro.org
7
---
6
---
8
target/arm/internals.h | 26 ++++++++++++++++++++++++++
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
9
target/arm/helper.c | 26 --------------------------
8
1 file changed, 177 insertions(+), 3 deletions(-)
10
2 files changed, 26 insertions(+), 26 deletions(-)
11
9
12
diff --git a/target/arm/internals.h b/target/arm/internals.h
10
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/internals.h
12
--- a/hw/arm/mps3r.c
15
+++ b/target/arm/internals.h
13
+++ b/hw/arm/mps3r.c
16
@@ -XXX,XX +XXX,XX @@ static inline void arm_call_el_change_hook(ARMCPU *cpu)
14
@@ -XXX,XX +XXX,XX @@
17
}
15
#include "qemu/osdep.h"
16
#include "qemu/units.h"
17
#include "qapi/error.h"
18
+#include "qapi/qmp/qlist.h"
19
#include "exec/address-spaces.h"
20
#include "cpu.h"
21
#include "hw/boards.h"
22
+#include "hw/qdev-properties.h"
23
#include "hw/arm/boot.h"
24
+#include "hw/arm/bsa.h"
25
+#include "hw/intc/arm_gicv3.h"
26
27
/* Define the layout of RAM and ROM in a board */
28
typedef struct RAMInfo {
29
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
30
#define IS_ROM 2
31
32
#define MPS3R_RAM_MAX 9
33
+#define MPS3R_CPU_MAX 2
34
+
35
+#define PERIPHBASE 0xf0000000
36
+#define NUM_SPIS 96
37
38
typedef enum MPS3RFPGAType {
39
FPGA_AN536,
40
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineClass {
41
MachineClass parent;
42
MPS3RFPGAType fpga_type;
43
const RAMInfo *raminfo;
44
+ hwaddr loader_start;
45
};
46
47
struct MPS3RMachineState {
48
MachineState parent;
49
+ struct arm_boot_info bootinfo;
50
MemoryRegion ram[MPS3R_RAM_MAX];
51
+ Object *cpu[MPS3R_CPU_MAX];
52
+ MemoryRegion cpu_sysmem[MPS3R_CPU_MAX];
53
+ MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
54
+ MemoryRegion cpu_ram[MPS3R_CPU_MAX];
55
+ GICv3State gic;
56
};
57
58
#define TYPE_MPS3R_MACHINE "mps3r"
59
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
60
return ram;
18
}
61
}
19
62
20
+/* Return true if this address translation regime is secure */
63
+/*
21
+static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
64
+ * There is no defined secondary boot protocol for Linux for the AN536,
65
+ * because real hardware has a restriction that atomic operations between
66
+ * the two CPUs do not function correctly, and so true SMP is not
67
+ * possible. Therefore for cases where the user is directly booting
68
+ * a kernel, we treat the system as essentially uniprocessor, and
69
+ * put the secondary CPU into power-off state (as if the user on the
70
+ * real hardware had configured the secondary to be halted via the
71
+ * SCC config registers).
72
+ *
73
+ * Note that the default secondary boot code would not work here anyway
74
+ * as it assumes a GICv2, and we have a GICv3.
75
+ */
76
+static void mps3r_write_secondary_boot(ARMCPU *cpu,
77
+ const struct arm_boot_info *info)
22
+{
78
+{
23
+ switch (mmu_idx) {
79
+ /*
24
+ case ARMMMUIdx_S12NSE0:
80
+ * Power the secondary CPU off. This means we don't need to write any
25
+ case ARMMMUIdx_S12NSE1:
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
26
+ case ARMMMUIdx_S1NSE0:
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
27
+ case ARMMMUIdx_S1NSE1:
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
28
+ case ARMMMUIdx_S1E2:
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
29
+ case ARMMMUIdx_S2NS:
85
+ */
30
+ case ARMMMUIdx_MPriv:
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
31
+ case ARMMMUIdx_MNegPri:
87
+ if (cs != first_cpu) {
32
+ case ARMMMUIdx_MUser:
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
33
+ return false;
89
+ &error_abort);
34
+ case ARMMMUIdx_S1E3:
90
+ }
35
+ case ARMMMUIdx_S1SE0:
36
+ case ARMMMUIdx_S1SE1:
37
+ case ARMMMUIdx_MSPriv:
38
+ case ARMMMUIdx_MSNegPri:
39
+ case ARMMMUIdx_MSUser:
40
+ return true;
41
+ default:
42
+ g_assert_not_reached();
43
+ }
91
+ }
44
+}
92
+}
45
+
93
+
46
#endif
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
95
+ const struct arm_boot_info *info)
48
index XXXXXXX..XXXXXXX 100644
96
+{
49
--- a/target/arm/helper.c
97
+ /* We don't need to do anything here because the CPU will be off */
50
+++ b/target/arm/helper.c
98
+}
51
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
99
+
100
+static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
101
+{
102
+ MachineState *machine = MACHINE(mms);
103
+ DeviceState *gicdev;
104
+ QList *redist_region_count;
105
+
106
+ object_initialize_child(OBJECT(mms), "gic", &mms->gic, TYPE_ARM_GICV3);
107
+ gicdev = DEVICE(&mms->gic);
108
+ qdev_prop_set_uint32(gicdev, "num-cpu", machine->smp.cpus);
109
+ qdev_prop_set_uint32(gicdev, "num-irq", NUM_SPIS + GIC_INTERNAL);
110
+ redist_region_count = qlist_new();
111
+ qlist_append_int(redist_region_count, machine->smp.cpus);
112
+ qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);
113
+ object_property_set_link(OBJECT(&mms->gic), "sysmem",
114
+ OBJECT(sysmem), &error_fatal);
115
+ sysbus_realize(SYS_BUS_DEVICE(&mms->gic), &error_fatal);
116
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 0, PERIPHBASE);
117
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 1, PERIPHBASE + 0x100000);
118
+ /*
119
+ * Wire the outputs from each CPU's generic timer and the GICv3
120
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
121
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
122
+ */
123
+ for (int i = 0; i < machine->smp.cpus; i++) {
124
+ DeviceState *cpudev = DEVICE(mms->cpu[i]);
125
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&mms->gic);
126
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
127
+ int irq;
128
+ /*
129
+ * Mapping from the output timer irq lines from the CPU to the
130
+ * GIC PPI inputs used for this board. This isn't a BSA board,
131
+ * but it uses the standard convention for the PPI numbers.
132
+ */
133
+ const int timer_irq[] = {
134
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
135
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
136
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
137
+ };
138
+
139
+ for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
140
+ qdev_connect_gpio_out(cpudev, irq,
141
+ qdev_get_gpio_in(gicdev,
142
+ intidbase + timer_irq[irq]));
143
+ }
144
+
145
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
146
+ qdev_get_gpio_in(gicdev,
147
+ intidbase + ARCH_GIC_MAINT_IRQ));
148
+
149
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
150
+ qdev_get_gpio_in(gicdev,
151
+ intidbase + VIRTUAL_PMU_IRQ));
152
+
153
+ sysbus_connect_irq(gicsbd, i,
154
+ qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
155
+ sysbus_connect_irq(gicsbd, i + machine->smp.cpus,
156
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
157
+ sysbus_connect_irq(gicsbd, i + 2 * machine->smp.cpus,
158
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
159
+ sysbus_connect_irq(gicsbd, i + 3 * machine->smp.cpus,
160
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
161
+ }
162
+}
163
+
164
static void mps3r_common_init(MachineState *machine)
165
{
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
169
memory_region_add_subregion(sysmem, ri->base, mr);
52
}
170
}
171
+
172
+ assert(machine->smp.cpus <= MPS3R_CPU_MAX);
173
+ for (int i = 0; i < machine->smp.cpus; i++) {
174
+ g_autofree char *sysmem_name = g_strdup_printf("cpu-%d-memory", i);
175
+ g_autofree char *ramname = g_strdup_printf("cpu-%d-memory", i);
176
+ g_autofree char *alias_name = g_strdup_printf("sysmem-alias-%d", i);
177
+
178
+ /*
179
+ * Each CPU has some private RAM/peripherals, so create the container
180
+ * which will house those, with the whole-machine system memory being
181
+ * used where there's no CPU-specific device. Note that we need the
182
+ * sysmem_alias aliases because we can't put one MR (the original
183
+ * 'sysmem') into more than one other MR.
184
+ */
185
+ memory_region_init(&mms->cpu_sysmem[i], OBJECT(machine),
186
+ sysmem_name, UINT64_MAX);
187
+ memory_region_init_alias(&mms->sysmem_alias[i], OBJECT(machine),
188
+ alias_name, sysmem, 0, UINT64_MAX);
189
+ memory_region_add_subregion_overlap(&mms->cpu_sysmem[i], 0,
190
+ &mms->sysmem_alias[i], -1);
191
+
192
+ mms->cpu[i] = object_new(machine->cpu_type);
193
+ object_property_set_link(mms->cpu[i], "memory",
194
+ OBJECT(&mms->cpu_sysmem[i]), &error_abort);
195
+ object_property_set_int(mms->cpu[i], "reset-cbar",
196
+ PERIPHBASE, &error_abort);
197
+ qdev_realize(DEVICE(mms->cpu[i]), NULL, &error_fatal);
198
+ object_unref(mms->cpu[i]);
199
+
200
+ /* Per-CPU RAM */
201
+ memory_region_init_ram(&mms->cpu_ram[i], NULL, ramname,
202
+ 0x1000, &error_fatal);
203
+ memory_region_add_subregion(&mms->cpu_sysmem[i], 0xe7c01000,
204
+ &mms->cpu_ram[i]);
205
+ }
206
+
207
+ create_gic(mms, sysmem);
208
+
209
+ mms->bootinfo.ram_size = machine->ram_size;
210
+ mms->bootinfo.board_id = -1;
211
+ mms->bootinfo.loader_start = mmc->loader_start;
212
+ mms->bootinfo.write_secondary_boot = mps3r_write_secondary_boot;
213
+ mms->bootinfo.secondary_cpu_reset_hook = mps3r_secondary_cpu_reset;
214
+ arm_load_kernel(ARM_CPU(mms->cpu[0]), machine, &mms->bootinfo);
53
}
215
}
54
216
55
-/* Return true if this address translation regime is secure */
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
56
-static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
57
-{
219
/* Found the entry for "system memory" */
58
- switch (mmu_idx) {
220
mc->default_ram_size = p->size;
59
- case ARMMMUIdx_S12NSE0:
221
mc->default_ram_id = p->name;
60
- case ARMMMUIdx_S12NSE1:
222
+ mmc->loader_start = p->base;
61
- case ARMMMUIdx_S1NSE0:
223
return;
62
- case ARMMMUIdx_S1NSE1:
224
}
63
- case ARMMMUIdx_S1E2:
225
}
64
- case ARMMMUIdx_S2NS:
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
65
- case ARMMMUIdx_MPriv:
227
};
66
- case ARMMMUIdx_MNegPri:
228
67
- case ARMMMUIdx_MUser:
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
68
- return false;
230
- mc->default_cpus = 2;
69
- case ARMMMUIdx_S1E3:
231
- mc->min_cpus = mc->default_cpus;
70
- case ARMMMUIdx_S1SE0:
232
- mc->max_cpus = mc->default_cpus;
71
- case ARMMMUIdx_S1SE1:
233
+ /*
72
- case ARMMMUIdx_MSPriv:
234
+ * In the real FPGA image there are always two cores, but the standard
73
- case ARMMMUIdx_MSNegPri:
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
74
- case ARMMMUIdx_MSUser:
236
+ * that the second core is held in reset and halted. Many images built for
75
- return true;
237
+ * the board do not expect the second core to run at startup (especially
76
- default:
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
77
- g_assert_not_reached();
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
78
- }
240
+ *
79
-}
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
80
-
242
+ * with the default being -smp 1. This seems a more intuitive UI for
81
/* Return the SCTLR value which controls this address translation regime */
243
+ * QEMU users than, for instance, having a machine property to allow
82
static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
244
+ * the user to set the initial value of the SYSCON 0x000 register.
83
{
245
+ */
246
+ mc->default_cpus = 1;
247
+ mc->min_cpus = 1;
248
+ mc->max_cpus = 2;
249
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
250
mc->valid_cpu_types = valid_cpu_types;
251
mmc->raminfo = an536_raminfo;
84
--
252
--
85
2.7.4
253
2.34.1
86
87
diff view generated by jsdifflib
1
Make the FAULTMASK register banked if v8M security extensions are enabled.
1
This board has a lot of UARTs: there is one UART per CPU in the
2
per-CPU peripheral part of the address map, whose interrupts are
3
connected as per-CPU interrupt lines. Then there are 4 UARTs in the
4
normal part of the peripheral space, whose interrupts are shared
5
peripheral interrupts.
2
6
3
Note that we do not yet implement the functionality of the new
7
Connect and wire them all up; this involves some OR gates where
4
AIRCR.PRIS bit (which allows the effect of the NS copy of FAULTMASK to
8
multiple overflow interrupts are wired into one GIC input.
5
be restricted).
6
7
This patch includes the code to determine for v8M which copy
8
of FAULTMASK should be updated on exception exit; further
9
changes will be required to the exception exit code in general
10
to support v8M, so this is just a small piece of that.
11
12
The v8M ARM ARM introduces a notation where individual paragraphs
13
are labelled with R (for rule) or I (for information) followed
14
by a random group of subscript letters. In comments where we want
15
to refer to a particular part of the manual we use this convention,
16
which should be more stable across document revisions than using
17
section or page numbers.
18
9
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
21
Message-id: 1503414539-28762-9-git-send-email-peter.maydell@linaro.org
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
22
---
13
---
23
target/arm/cpu.h | 14 ++++++++++++--
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
24
hw/intc/armv7m_nvic.c | 9 ++++++++-
15
1 file changed, 94 insertions(+)
25
target/arm/helper.c | 20 ++++++++++++++++----
26
target/arm/machine.c | 5 +++--
27
4 files changed, 39 insertions(+), 9 deletions(-)
28
16
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
19
--- a/hw/arm/mps3r.c
32
+++ b/target/arm/cpu.h
20
+++ b/hw/arm/mps3r.c
33
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
21
@@ -XXX,XX +XXX,XX @@
34
unsigned mpu_ctrl; /* MPU_CTRL */
22
#include "qapi/qmp/qlist.h"
35
int exception;
23
#include "exec/address-spaces.h"
36
uint32_t primask[2];
24
#include "cpu.h"
37
- uint32_t faultmask;
25
+#include "sysemu/sysemu.h"
38
+ uint32_t faultmask[2];
26
#include "hw/boards.h"
39
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
27
+#include "hw/or-irq.h"
40
} v7m;
28
#include "hw/qdev-properties.h"
41
29
#include "hw/arm/boot.h"
42
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
30
#include "hw/arm/bsa.h"
43
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
31
+#include "hw/char/cmsdk-apb-uart.h"
44
*/
32
#include "hw/intc/arm_gicv3.h"
45
int armv7m_nvic_complete_irq(void *opaque, int irq);
33
46
+/**
34
/* Define the layout of RAM and ROM in a board */
47
+ * armv7m_nvic_raw_execution_priority: return the raw execution priority
35
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
48
+ * @opaque: the NVIC
36
49
+ *
37
#define MPS3R_RAM_MAX 9
50
+ * Returns: the raw execution priority as defined by the v8M architecture.
38
#define MPS3R_CPU_MAX 2
51
+ * This is the execution priority minus the effects of AIRCR.PRIS,
39
+#define MPS3R_UART_MAX 4 /* shared UART count */
52
+ * and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
40
53
+ * (v8M ARM ARM I_PKLD.)
41
#define PERIPHBASE 0xf0000000
42
#define NUM_SPIS 96
43
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
44
MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
45
MemoryRegion cpu_ram[MPS3R_CPU_MAX];
46
GICv3State gic;
47
+ /* per-CPU UARTs followed by the shared UARTs */
48
+ CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
49
+ OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
50
+ OrIRQState uart_oflow;
51
};
52
53
#define TYPE_MPS3R_MACHINE "mps3r"
54
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
55
56
OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
57
58
+/*
59
+ * Main clock frequency CLK in Hz (50MHz). In the image there are also
60
+ * ACLK, MCLK, GPUCLK and PERIPHCLK at the same frequency; for our
61
+ * model we just roll them all into one.
54
+ */
62
+ */
55
+int armv7m_nvic_raw_execution_priority(void *opaque);
63
+#define CLK_FRQ 50000000
56
64
+
57
/* Interface for defining coprocessor registers.
65
static const RAMInfo an536_raminfo[] = {
58
* Registers are defined in tables of arm_cp_reginfo structs
66
{
59
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
67
.name = "ATCM",
60
* we're in a HardFault or NMI handler.
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
61
*/
69
}
62
if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
63
- || env->v7m.faultmask) {
64
+ || env->v7m.faultmask[env->v7m.secure]) {
65
mmu_idx = ARMMMUIdx_MNegPri;
66
}
67
68
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/intc/armv7m_nvic.c
71
+++ b/hw/intc/armv7m_nvic.c
72
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
73
CPUARMState *env = &s->cpu->env;
74
int running;
75
76
- if (env->v7m.faultmask) {
77
+ if (env->v7m.faultmask[env->v7m.secure]) {
78
running = -1;
79
} else if (env->v7m.primask[env->v7m.secure]) {
80
running = 0;
81
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_can_take_pending_exception(void *opaque)
82
return nvic_exec_prio(s) > nvic_pending_prio(s);
83
}
70
}
84
71
85
+int armv7m_nvic_raw_execution_priority(void *opaque)
72
+/*
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
75
+ */
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
79
+ qemu_irq combirq)
86
+{
80
+{
87
+ NVICState *s = opaque;
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
82
+ SysBusDevice *sbd;
88
+
83
+
89
+ return s->exception_prio;
84
+ assert(uartno < ARRAY_SIZE(mms->uart));
85
+ object_initialize_child(OBJECT(mms), s, &mms->uart[uartno],
86
+ TYPE_CMSDK_APB_UART);
87
+ qdev_prop_set_uint32(DEVICE(&mms->uart[uartno]), "pclk-frq", CLK_FRQ);
88
+ qdev_prop_set_chr(DEVICE(&mms->uart[uartno]), "chardev", serial_hd(uartno));
89
+ sbd = SYS_BUS_DEVICE(&mms->uart[uartno]);
90
+ sysbus_realize(sbd, &error_fatal);
91
+ memory_region_add_subregion(mem, baseaddr,
92
+ sysbus_mmio_get_region(sbd, 0));
93
+ sysbus_connect_irq(sbd, 0, txirq);
94
+ sysbus_connect_irq(sbd, 1, rxirq);
95
+ sysbus_connect_irq(sbd, 2, txoverirq);
96
+ sysbus_connect_irq(sbd, 3, rxoverirq);
97
+ sysbus_connect_irq(sbd, 4, combirq);
90
+}
98
+}
91
+
99
+
92
/* caller must call nvic_irq_update() after this */
100
static void mps3r_common_init(MachineState *machine)
93
static void set_prio(NVICState *s, unsigned irq, uint8_t prio)
94
{
101
{
95
diff --git a/target/arm/helper.c b/target/arm/helper.c
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
96
index XXXXXXX..XXXXXXX 100644
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
97
--- a/target/arm/helper.c
104
MemoryRegion *sysmem = get_system_memory();
98
+++ b/target/arm/helper.c
105
+ DeviceState *gicdev;
99
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
106
107
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
108
MemoryRegion *mr = mr_for_raminfo(mms, ri);
109
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
100
}
110
}
101
111
102
if (env->v7m.exception != ARMV7M_EXCP_NMI) {
112
create_gic(mms, sysmem);
103
- /* Auto-clear FAULTMASK on return from other than NMI */
113
+ gicdev = DEVICE(&mms->gic);
104
- env->v7m.faultmask = 0;
114
+
105
+ /* Auto-clear FAULTMASK on return from other than NMI.
115
+ /*
106
+ * If the security extension is implemented then this only
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
107
+ * happens if the raw execution priority is >= 0; the
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
108
+ * value of the ES bit in the exception return value indicates
118
+ */
109
+ * which security state's faultmask to clear. (v8M ARM ARM R_KBNF.)
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
110
+ */
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
111
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
112
+ int es = type & 1;
122
+ DeviceState *orgate;
113
+ if (armv7m_nvic_raw_execution_priority(env->nvic) >= 0) {
123
+
114
+ env->v7m.faultmask[es] = 0;
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
115
+ }
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
116
+ } else {
126
+ TYPE_OR_IRQ);
117
+ env->v7m.faultmask[M_REG_NS] = 0;
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
118
+ }
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
119
}
129
+ qdev_realize(orgate, NULL, &error_fatal);
120
130
+ qdev_connect_gpio_out(orgate, 0,
121
switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception)) {
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
122
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
132
+
123
case 18: /* BASEPRI_MAX */
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
124
return env->v7m.basepri[env->v7m.secure];
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
125
case 19: /* FAULTMASK */
135
+ qdev_get_gpio_in(gicdev, intidbase + 16), /* rx */
126
- return env->v7m.faultmask;
136
+ qdev_get_gpio_in(orgate, 0), /* txover */
127
+ return env->v7m.faultmask[env->v7m.secure];
137
+ qdev_get_gpio_in(orgate, 1), /* rxover */
128
default:
138
+ qdev_get_gpio_in(gicdev, intidbase + 18) /* combined */);
129
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special"
139
+ }
130
" register %d\n", reg);
140
+ /*
131
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
141
+ * UARTs 2 to 5 are whole-system; all overflow IRQs are ORed
132
}
142
+ * together into IRQ 17
133
break;
143
+ */
134
case 19: /* FAULTMASK */
144
+ object_initialize_child(OBJECT(mms), "uart-oflow-orgate",
135
- env->v7m.faultmask = val & 1;
145
+ &mms->uart_oflow, TYPE_OR_IRQ);
136
+ env->v7m.faultmask[env->v7m.secure] = val & 1;
146
+ qdev_prop_set_uint32(DEVICE(&mms->uart_oflow), "num-lines",
137
break;
147
+ MPS3R_UART_MAX * 2);
138
case 20: /* CONTROL */
148
+ qdev_realize(DEVICE(&mms->uart_oflow), NULL, &error_fatal);
139
/* Writing to the SPSEL bit only has an effect if we are in
149
+ qdev_connect_gpio_out(DEVICE(&mms->uart_oflow), 0,
140
diff --git a/target/arm/machine.c b/target/arm/machine.c
150
+ qdev_get_gpio_in(gicdev, 17));
141
index XXXXXXX..XXXXXXX 100644
151
+
142
--- a/target/arm/machine.c
152
+ for (int i = 0; i < MPS3R_UART_MAX; i++) {
143
+++ b/target/arm/machine.c
153
+ hwaddr baseaddr = 0xe0205000 + i * 0x1000;
144
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_faultmask_primask = {
154
+ int rxirq = 5 + i * 2, txirq = 6 + i * 2, combirq = 13 + i;
145
.version_id = 1,
155
+
146
.minimum_version_id = 1,
156
+ create_uart(mms, i + MPS3R_CPU_MAX, sysmem, baseaddr,
147
.fields = (VMStateField[]) {
157
+ qdev_get_gpio_in(gicdev, txirq),
148
- VMSTATE_UINT32(env.v7m.faultmask, ARMCPU),
158
+ qdev_get_gpio_in(gicdev, rxirq),
149
+ VMSTATE_UINT32(env.v7m.faultmask[M_REG_NS], ARMCPU),
159
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2),
150
VMSTATE_UINT32(env.v7m.primask[M_REG_NS], ARMCPU),
160
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2 + 1),
151
VMSTATE_END_OF_LIST()
161
+ qdev_get_gpio_in(gicdev, combirq));
152
}
162
+ }
153
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_security = {
163
154
VMSTATE_UINT32(env.v7m.secure, ARMCPU),
164
mms->bootinfo.ram_size = machine->ram_size;
155
VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
165
mms->bootinfo.board_id = -1;
156
VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
157
+ VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU),
158
VMSTATE_END_OF_LIST()
159
}
160
};
161
@@ -XXX,XX +XXX,XX @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
162
* transferred using the vmstate_m_faultmask_primask subsection.
163
*/
164
if (val & CPSR_F) {
165
- env->v7m.faultmask = 1;
166
+ env->v7m.faultmask[M_REG_NS] = 1;
167
}
168
if (val & CPSR_I) {
169
env->v7m.primask[M_REG_NS] = 1;
170
--
166
--
171
2.7.4
167
2.34.1
172
168
173
169
diff view generated by jsdifflib
1
Implement the behavioural side of the new PMSAv8 specification.
1
Add the GPIO, watchdog, dual-timer and I2C devices to the mps3-an536
2
board. These are all simple devices that just need to be created and
3
wired up.
2
4
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 1503414539-28762-3-git-send-email-peter.maydell@linaro.org
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
6
---
8
---
7
target/arm/helper.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++-
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
8
1 file changed, 110 insertions(+), 1 deletion(-)
10
1 file changed, 59 insertions(+)
9
11
10
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
11
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/helper.c
14
--- a/hw/arm/mps3r.c
13
+++ b/target/arm/helper.c
15
+++ b/hw/arm/mps3r.c
14
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
16
@@ -XXX,XX +XXX,XX @@
15
return !(*prot & (1 << access_type));
17
#include "sysemu/sysemu.h"
16
}
18
#include "hw/boards.h"
17
19
#include "hw/or-irq.h"
18
+static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
20
+#include "hw/qdev-clock.h"
19
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
21
#include "hw/qdev-properties.h"
20
+ hwaddr *phys_ptr, int *prot, uint32_t *fsr)
22
#include "hw/arm/boot.h"
21
+{
23
#include "hw/arm/bsa.h"
22
+ ARMCPU *cpu = arm_env_get_cpu(env);
24
#include "hw/char/cmsdk-apb-uart.h"
23
+ bool is_user = regime_is_user(env, mmu_idx);
25
+#include "hw/i2c/arm_sbcon_i2c.h"
24
+ int n;
26
#include "hw/intc/arm_gicv3.h"
25
+ int matchregion = -1;
27
+#include "hw/misc/unimp.h"
26
+ bool hit = false;
28
+#include "hw/timer/cmsdk-apb-dualtimer.h"
29
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
30
31
/* Define the layout of RAM and ROM in a board */
32
typedef struct RAMInfo {
33
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
34
CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
35
OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
36
OrIRQState uart_oflow;
37
+ CMSDKAPBWatchdog watchdog;
38
+ CMSDKAPBDualTimer dualtimer;
39
+ ArmSbconI2CState i2c[5];
40
+ Clock *clk;
41
};
42
43
#define TYPE_MPS3R_MACHINE "mps3r"
44
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
45
MemoryRegion *sysmem = get_system_memory();
46
DeviceState *gicdev;
47
48
+ mms->clk = clock_new(OBJECT(machine), "CLK");
49
+ clock_set_hz(mms->clk, CLK_FRQ);
27
+
50
+
28
+ *phys_ptr = address;
51
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
29
+ *prot = 0;
52
MemoryRegion *mr = mr_for_raminfo(mms, ri);
53
memory_region_add_subregion(sysmem, ri->base, mr);
54
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
55
qdev_get_gpio_in(gicdev, combirq));
56
}
57
58
+ for (int i = 0; i < 4; i++) {
59
+ /* CMSDK GPIO controllers */
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
62
+ }
30
+
63
+
31
+ /* Unlike the ARM ARM pseudocode, we don't need to check whether this
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
32
+ * was an exception vector read from the vector table (which is always
65
+ TYPE_CMSDK_APB_WATCHDOG);
33
+ * done using the default system address map), because those accesses
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
34
+ * are done in arm_v7m_load_vector(), which always does a direct
67
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
35
+ * read using address_space_ldl(), rather than going via this function.
68
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
36
+ */
69
+ qdev_get_gpio_in(gicdev, 0));
37
+ if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */
70
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0xe0100000);
38
+ hit = true;
71
+
39
+ } else if (m_is_ppb_region(env, address)) {
72
+ object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
40
+ hit = true;
73
+ TYPE_CMSDK_APB_DUALTIMER);
41
+ } else if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
74
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->clk);
42
+ hit = true;
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
43
+ } else {
76
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
44
+ for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
77
+ qdev_get_gpio_in(gicdev, 3));
45
+ /* region search */
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 1,
46
+ /* Note that the base address is bits [31:5] from the register
79
+ qdev_get_gpio_in(gicdev, 1));
47
+ * with bits [4:0] all zeroes, but the limit address is bits
80
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 2,
48
+ * [31:5] from the register with bits [4:0] all ones.
81
+ qdev_get_gpio_in(gicdev, 2));
82
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0xe0101000);
83
+
84
+ for (int i = 0; i < ARRAY_SIZE(mms->i2c); i++) {
85
+ static const hwaddr i2cbase[] = {0xe0102000, /* Touch */
86
+ 0xe0103000, /* Audio */
87
+ 0xe0107000, /* Shield0 */
88
+ 0xe0108000, /* Shield1 */
89
+ 0xe0109000}; /* DDR4 EEPROM */
90
+ g_autofree char *s = g_strdup_printf("i2c%d", i);
91
+
92
+ object_initialize_child(OBJECT(mms), s, &mms->i2c[i],
93
+ TYPE_ARM_SBCON_I2C);
94
+ sysbus_realize(SYS_BUS_DEVICE(&mms->i2c[i]), &error_fatal);
95
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->i2c[i]), 0, i2cbase[i]);
96
+ if (i != 2 && i != 3) {
97
+ /*
98
+ * internal-only bus: mark it full to avoid user-created
99
+ * i2c devices being plugged into it.
49
+ */
100
+ */
50
+ uint32_t base = env->pmsav8.rbar[n] & ~0x1f;
101
+ qbus_mark_full(qdev_get_child_bus(DEVICE(&mms->i2c[i]), "i2c"));
51
+ uint32_t limit = env->pmsav8.rlar[n] | 0x1f;
52
+
53
+ if (!(env->pmsav8.rlar[n] & 0x1)) {
54
+ /* Region disabled */
55
+ continue;
56
+ }
57
+
58
+ if (address < base || address > limit) {
59
+ continue;
60
+ }
61
+
62
+ if (hit) {
63
+ /* Multiple regions match -- always a failure (unlike
64
+ * PMSAv7 where highest-numbered-region wins)
65
+ */
66
+ *fsr = 0x00d; /* permission fault */
67
+ return true;
68
+ }
69
+
70
+ matchregion = n;
71
+ hit = true;
72
+
73
+ if (base & ~TARGET_PAGE_MASK) {
74
+ qemu_log_mask(LOG_UNIMP,
75
+ "MPU_RBAR[%d]: No support for MPU region base"
76
+ "address of 0x%" PRIx32 ". Minimum alignment is "
77
+ "%d\n",
78
+ n, base, TARGET_PAGE_BITS);
79
+ continue;
80
+ }
81
+ if ((limit + 1) & ~TARGET_PAGE_MASK) {
82
+ qemu_log_mask(LOG_UNIMP,
83
+ "MPU_RBAR[%d]: No support for MPU region limit"
84
+ "address of 0x%" PRIx32 ". Minimum alignment is "
85
+ "%d\n",
86
+ n, limit, TARGET_PAGE_BITS);
87
+ continue;
88
+ }
89
+ }
102
+ }
90
+ }
103
+ }
91
+
104
+
92
+ if (!hit) {
105
mms->bootinfo.ram_size = machine->ram_size;
93
+ /* background fault */
106
mms->bootinfo.board_id = -1;
94
+ *fsr = 0;
107
mms->bootinfo.loader_start = mmc->loader_start;
95
+ return true;
96
+ }
97
+
98
+ if (matchregion == -1) {
99
+ /* hit using the background region */
100
+ get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
101
+ } else {
102
+ uint32_t ap = extract32(env->pmsav8.rbar[matchregion], 1, 2);
103
+ uint32_t xn = extract32(env->pmsav8.rbar[matchregion], 0, 1);
104
+
105
+ if (m_is_system_region(env, address)) {
106
+ /* System space is always execute never */
107
+ xn = 1;
108
+ }
109
+
110
+ *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
111
+ if (*prot && !xn) {
112
+ *prot |= PAGE_EXEC;
113
+ }
114
+ /* We don't need to look the attribute up in the MAIR0/MAIR1
115
+ * registers because that only tells us about cacheability.
116
+ */
117
+ }
118
+
119
+ *fsr = 0x00d; /* Permission fault */
120
+ return !(*prot & (1 << access_type));
121
+}
122
+
123
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
124
MMUAccessType access_type, ARMMMUIdx mmu_idx,
125
hwaddr *phys_ptr, int *prot, uint32_t *fsr)
126
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
127
bool ret;
128
*page_size = TARGET_PAGE_SIZE;
129
130
- if (arm_feature(env, ARM_FEATURE_V7)) {
131
+ if (arm_feature(env, ARM_FEATURE_V8)) {
132
+ /* PMSAv8 */
133
+ ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
134
+ phys_ptr, prot, fsr);
135
+ } else if (arm_feature(env, ARM_FEATURE_V7)) {
136
/* PMSAv7 */
137
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
138
phys_ptr, prot, fsr);
139
--
108
--
140
2.7.4
109
2.34.1
141
110
142
111
diff view generated by jsdifflib
1
As the first step in implementing ARM v8M's security extension:
1
Add the remaining devices (or unimplemented-device stubs) for
2
* add a new feature bit ARM_FEATURE_M_SECURITY
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
3
* add the CPU state field that indicates whether the CPU is
3
QSPI write-config block, and ethernet.
4
currently in the secure state
5
* add a migration subsection for this new state
6
(we will add the Secure copies of banked register state
7
to this subsection in later patches)
8
* add a #define for the one new-in-v8M exception type
9
* make the CPU debug log print S/NS status
10
4
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-id: 1503414539-28762-4-git-send-email-peter.maydell@linaro.org
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
14
---
8
---
15
target/arm/cpu.h | 3 +++
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
16
target/arm/cpu.c | 4 ++++
10
1 file changed, 74 insertions(+)
17
target/arm/machine.c | 20 ++++++++++++++++++++
18
target/arm/translate.c | 8 +++++++-
19
4 files changed, 34 insertions(+), 1 deletion(-)
20
11
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
14
--- a/hw/arm/mps3r.c
24
+++ b/target/arm/cpu.h
15
+++ b/hw/arm/mps3r.c
25
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
26
#define ARMV7M_EXCP_MEM 4
17
#include "hw/char/cmsdk-apb-uart.h"
27
#define ARMV7M_EXCP_BUS 5
18
#include "hw/i2c/arm_sbcon_i2c.h"
28
#define ARMV7M_EXCP_USAGE 6
19
#include "hw/intc/arm_gicv3.h"
29
+#define ARMV7M_EXCP_SECURE 7
20
+#include "hw/misc/mps2-scc.h"
30
#define ARMV7M_EXCP_SVC 11
21
+#include "hw/misc/mps2-fpgaio.h"
31
#define ARMV7M_EXCP_DEBUG 12
22
#include "hw/misc/unimp.h"
32
#define ARMV7M_EXCP_PENDSV 14
23
+#include "hw/net/lan9118.h"
33
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
24
+#include "hw/rtc/pl031.h"
34
int exception;
25
+#include "hw/ssi/pl022.h"
35
uint32_t primask;
26
#include "hw/timer/cmsdk-apb-dualtimer.h"
36
uint32_t faultmask;
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
37
+ uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
28
38
} v7m;
29
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
39
30
CMSDKAPBWatchdog watchdog;
40
/* Information associated with an exception about to be taken:
31
CMSDKAPBDualTimer dualtimer;
41
@@ -XXX,XX +XXX,XX @@ enum arm_features {
32
ArmSbconI2CState i2c[5];
42
ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */
33
+ PL022State spi[3];
43
ARM_FEATURE_PMU, /* has PMU support */
34
+ MPS2SCC scc;
44
ARM_FEATURE_VBAR, /* has cp15 VBAR */
35
+ MPS2FPGAIO fpgaio;
45
+ ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
36
+ UnimplementedDeviceState i2s_audio;
37
+ PL031State rtc;
38
Clock *clk;
46
};
39
};
47
40
48
static inline int arm_feature(CPUARMState *env, int feature)
41
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an536_raminfo[] = {
49
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/cpu.c
52
+++ b/target/arm/cpu.c
53
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
54
uint32_t initial_pc; /* Loaded from 0x4 */
55
uint8_t *rom;
56
57
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
58
+ env->v7m.secure = true;
59
+ }
60
+
61
/* The reset value of this bit is IMPDEF, but ARM recommends
62
* that it resets to 1, so QEMU always does that rather than making
63
* it dependent on CPU model.
64
diff --git a/target/arm/machine.c b/target/arm/machine.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/machine.c
67
+++ b/target/arm/machine.c
68
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav8 = {
69
}
42
}
70
};
43
};
71
44
72
+static bool m_security_needed(void *opaque)
45
+static const int an536_oscclk[] = {
73
+{
46
+ 24000000, /* 24MHz reference for RTC and timers */
74
+ ARMCPU *cpu = opaque;
47
+ 50000000, /* 50MHz ACLK */
75
+ CPUARMState *env = &cpu->env;
48
+ 50000000, /* 50MHz MCLK */
76
+
49
+ 50000000, /* 50MHz GPUCLK */
77
+ return arm_feature(env, ARM_FEATURE_M_SECURITY);
50
+ 24576000, /* 24.576MHz AUDCLK */
78
+}
51
+ 23750000, /* 23.75MHz HDLCDCLK */
79
+
52
+ 100000000, /* 100MHz DDR4_REF_CLK */
80
+static const VMStateDescription vmstate_m_security = {
81
+ .name = "cpu/m-security",
82
+ .version_id = 1,
83
+ .minimum_version_id = 1,
84
+ .needed = m_security_needed,
85
+ .fields = (VMStateField[]) {
86
+ VMSTATE_UINT32(env.v7m.secure, ARMCPU),
87
+ VMSTATE_END_OF_LIST()
88
+ }
89
+};
53
+};
90
+
54
+
91
static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
92
VMStateField *field)
56
const RAMInfo *raminfo)
93
{
57
{
94
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
95
&vmstate_pmsav7_rnr,
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
96
&vmstate_pmsav7,
60
MemoryRegion *sysmem = get_system_memory();
97
&vmstate_pmsav8,
61
DeviceState *gicdev;
98
+ &vmstate_m_security,
62
+ QList *oscclk;
99
NULL
63
64
mms->clk = clock_new(OBJECT(machine), "CLK");
65
clock_set_hz(mms->clk, CLK_FRQ);
66
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
67
}
100
}
68
}
101
};
69
102
diff --git a/target/arm/translate.c b/target/arm/translate.c
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
103
index XXXXXXX..XXXXXXX 100644
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
104
--- a/target/arm/translate.c
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
105
+++ b/target/arm/translate.c
106
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
107
if (arm_feature(env, ARM_FEATURE_M)) {
108
uint32_t xpsr = xpsr_read(env);
109
const char *mode;
110
+ const char *ns_status = "";
111
+
73
+
112
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
113
+ ns_status = env->v7m.secure ? "S " : "NS ";
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
114
+ }
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
115
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
116
if (xpsr & XPSR_EXCP) {
78
+ qdev_get_gpio_in(gicdev, 22 + i));
117
mode = "handler";
79
+ }
118
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
80
+
119
}
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
120
}
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
121
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
122
- cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s\n",
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
123
+ cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
124
xpsr,
86
+ oscclk = qlist_new();
125
xpsr & XPSR_N ? 'N' : '-',
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
126
xpsr & XPSR_Z ? 'Z' : '-',
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
127
xpsr & XPSR_C ? 'C' : '-',
89
+ }
128
xpsr & XPSR_V ? 'V' : '-',
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
129
xpsr & XPSR_T ? 'T' : 'A',
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
130
+ ns_status,
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
131
mode);
93
+
132
} else {
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
133
uint32_t psr = cpsr_read(env);
95
+
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
97
+ TYPE_MPS2_FPGAIO);
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
99
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "num-leds", 10);
100
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-switches", true);
101
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-dbgctrl", false);
102
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0xe0202000);
104
+
105
+ create_unimplemented_device("clcd", 0xe0209000, 0x1000);
106
+
107
+ object_initialize_child(OBJECT(mms), "rtc", &mms->rtc, TYPE_PL031);
108
+ sysbus_realize(SYS_BUS_DEVICE(&mms->rtc), &error_fatal);
109
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->rtc), 0, 0xe020a000);
110
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->rtc), 0,
111
+ qdev_get_gpio_in(gicdev, 4));
112
+
113
+ /*
114
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
115
+ * except that it doesn't support the checksum-offload feature.
116
+ */
117
+ lan9118_init(0xe0300000,
118
+ qdev_get_gpio_in(gicdev, 18));
119
+
120
+ create_unimplemented_device("usb", 0xe0301000, 0x1000);
121
+ create_unimplemented_device("qspi-write-config", 0xe0600000, 0x1000);
122
+
123
mms->bootinfo.ram_size = machine->ram_size;
124
mms->bootinfo.board_id = -1;
125
mms->bootinfo.loader_start = mmc->loader_start;
134
--
126
--
135
2.7.4
127
2.34.1
136
128
137
129
diff view generated by jsdifflib
1
Now that MPU lookups can return different results for v8M
1
Add documentation for the mps3-an536 board type.
2
when the CPU is in secure vs non-secure state, we need to
3
have separate MMU indexes; add the secure counterparts
4
to the existing three M profile MMU indexes.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 1503414539-28762-6-git-send-email-peter.maydell@linaro.org
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
9
---
6
---
10
target/arm/cpu.h | 19 +++++++++++++++++--
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
11
target/arm/helper.c | 9 ++++++++-
8
1 file changed, 34 insertions(+), 3 deletions(-)
12
2 files changed, 25 insertions(+), 3 deletions(-)
13
9
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
12
--- a/docs/system/arm/mps2.rst
17
+++ b/target/arm/cpu.h
13
+++ b/docs/system/arm/mps2.rst
18
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
14
@@ -XXX,XX +XXX,XX @@
19
* Execution priority negative (this is like privileged, but the
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
20
* MPU HFNMIENA bit means that it may have different access permission
16
-=========================================================================================================================================================
21
* check results to normal privileged code, so can't share a TLB).
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
22
+ * If the CPU supports the v8M Security Extension then there are also:
18
+=========================================================================================================================================================================
23
+ * Secure User
19
24
+ * Secure Privileged
20
-These board models all use Arm M-profile CPUs.
25
+ * Secure, execution priority negative
21
+These board models use Arm M-profile or R-profile CPUs.
26
*
22
27
* The ARMMMUIdx and the mmu index value used by the core QEMU TLB code
23
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
28
* are not quite the same -- different CPU types (most notably M profile
24
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
29
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
25
@@ -XXX,XX +XXX,XX @@ FPGA image.
30
ARMMMUIdx_MUser = 0 | ARM_MMU_IDX_M,
26
31
ARMMMUIdx_MPriv = 1 | ARM_MMU_IDX_M,
27
QEMU models the following FPGA images:
32
ARMMMUIdx_MNegPri = 2 | ARM_MMU_IDX_M,
28
33
+ ARMMMUIdx_MSUser = 3 | ARM_MMU_IDX_M,
29
+FPGA images using M-profile CPUs:
34
+ ARMMMUIdx_MSPriv = 4 | ARM_MMU_IDX_M,
35
+ ARMMMUIdx_MSNegPri = 5 | ARM_MMU_IDX_M,
36
/* Indexes below here don't have TLBs and are used only for AT system
37
* instructions or for the first stage of an S12 page table walk.
38
*/
39
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
40
ARMMMUIdxBit_MUser = 1 << 0,
41
ARMMMUIdxBit_MPriv = 1 << 1,
42
ARMMMUIdxBit_MNegPri = 1 << 2,
43
+ ARMMMUIdxBit_MSUser = 1 << 3,
44
+ ARMMMUIdxBit_MSPriv = 1 << 4,
45
+ ARMMMUIdxBit_MSNegPri = 1 << 5,
46
} ARMMMUIdxBit;
47
48
#define MMU_USER_IDX 0
49
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
50
case ARM_MMU_IDX_A:
51
return mmu_idx & 3;
52
case ARM_MMU_IDX_M:
53
- return mmu_idx == ARMMMUIdx_MUser ? 0 : 1;
54
+ return (mmu_idx == ARMMMUIdx_MUser || mmu_idx == ARMMMUIdx_MSUser)
55
+ ? 0 : 1;
56
default:
57
g_assert_not_reached();
58
}
59
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
60
*/
61
if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
62
|| env->v7m.faultmask) {
63
- return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri);
64
+ mmu_idx = ARMMMUIdx_MNegPri;
65
+ }
66
+
30
+
67
+ if (env->v7m.secure) {
31
``mps2-an385``
68
+ mmu_idx += ARMMMUIdx_MSUser;
32
Cortex-M3 as documented in Arm Application Note AN385
69
}
33
``mps2-an386``
70
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
71
return arm_to_core_mmu_idx(mmu_idx);
35
``mps3-an547``
72
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
73
index XXXXXXX..XXXXXXX 100644
37
74
--- a/target/arm/helper.c
38
+FPGA images using R-profile CPUs:
75
+++ b/target/arm/helper.c
39
+
76
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
40
+``mps3-an536``
77
case ARMMMUIdx_MPriv:
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
78
case ARMMMUIdx_MNegPri:
42
+
79
case ARMMMUIdx_MUser:
43
Differences between QEMU and real hardware:
80
+ case ARMMMUIdx_MSPriv:
44
81
+ case ARMMMUIdx_MSNegPri:
45
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
82
+ case ARMMMUIdx_MSUser:
46
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
83
return 1;
47
flash, but only as simple ROM, so attempting to rewrite the flash
84
default:
48
from the guest will fail
85
g_assert_not_reached();
49
- QEMU does not model the USB controller in MPS3 boards
86
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
50
+- AN536 does not support runtime control of CPU reset and halt via
87
case ARMMMUIdx_S1E3:
51
+ the SCC CFG_REG0 register.
88
case ARMMMUIdx_S1SE0:
52
+- AN536 does not support enabling or disabling the flash and ATCM
89
case ARMMMUIdx_S1SE1:
53
+ interfaces via the SCC CFG_REG1 register.
90
+ case ARMMMUIdx_MSPriv:
54
+- AN536 does not support setting of the initial vector table
91
+ case ARMMMUIdx_MSNegPri:
55
+ base address via the SCC CFG_REG6 and CFG_REG7 register config,
92
+ case ARMMMUIdx_MSUser:
56
+ and does not provide a mechanism for specifying these values at
93
return true;
57
+ startup, so all guest images must be built to start from TCM
94
default:
58
+ (i.e. to expect the interrupt vector base at 0 from reset).
95
g_assert_not_reached();
59
+- AN536 defaults to only creating a single CPU; this is the equivalent
96
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
60
+ of the way the real FPGA image usually runs with the second Cortex-R52
97
(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
61
+ held in halt via the initial SCC CFG_REG0 register setting. You can
98
case R_V7M_MPU_CTRL_ENABLE_MASK:
62
+ create the second CPU with ``-smp 2``; both CPUs will then start
99
/* Enabled, but not for HardFault and NMI */
63
+ execution immediately on startup.
100
- return mmu_idx == ARMMMUIdx_MNegPri;
64
+
101
+ return mmu_idx == ARMMMUIdx_MNegPri ||
65
+Note that for the AN536 the first UART is accessible only by
102
+ mmu_idx == ARMMMUIdx_MSNegPri;
66
+CPU0, and the second UART is accessible only by CPU1. The
103
case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK:
67
+first UART accessible shared between both CPUs is the third
104
/* Enabled for all cases */
68
+UART. Guest software might therefore be built to use either
105
return false;
69
+the first UART or the third UART; if you don't see any output
70
+from the UART you are looking at, try one of the others.
71
+(Even if the AN536 machine is started with a single CPU and so
72
+no "CPU1-only UART", the UART numbering remains the same,
73
+with the third UART being the first of the shared ones.)
74
75
Machine-specific options
76
""""""""""""""""""""""""
106
--
77
--
107
2.7.4
78
2.34.1
108
79
109
80
diff view generated by jsdifflib