1
Hi; this is the latest target-arm queue; most of this is a refactoring
1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
2
patchset from RTH for the arm page-table-walk emulation.
3
2
4
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)
5
-- PMM
6
7
The following changes since commit f1d33f55c47dfdaf8daacd618588ad3ae4c452d1:
8
9
Merge tag 'pull-testing-gdbstub-plugins-gitdm-061022-3' of https://github.com/stsquad/qemu into staging (2022-10-06 07:11:56 -0400)
10
4
11
are available in the Git repository at:
5
are available in the Git repository at:
12
6
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20221010
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240215
14
8
15
for you to fetch changes up to 915f62844cf62e428c7c178149b5ff1cbe129b07:
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
16
10
17
docs/system/arm/emulation.rst: Report FEAT_GTG support (2022-10-10 14:52:25 +0100)
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +0000)
18
12
19
----------------------------------------------------------------
13
----------------------------------------------------------------
20
target-arm queue:
14
target-arm queue:
21
* Retry KVM_CREATE_VM call if it fails EINTR
15
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
22
* allow setting SCR_EL3.EnTP2 when FEAT_SME is implemented
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
23
* docs/nuvoton: Update URL for images
17
* Fix some errors in SVE/SME handling of MTE tags
24
* refactoring of page table walk code
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
25
* hw/arm/boot: set CPTR_EL3.ESM and SCR_EL3.EnTP2 when booting Linux with EL3
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
26
* Don't allow guest to use unimplemented granule sizes
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
27
* Report FEAT_GTG support
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)
28
30
29
----------------------------------------------------------------
31
----------------------------------------------------------------
30
Jerome Forissier (2):
32
Luc Michel (1):
31
target/arm: allow setting SCR_EL3.EnTP2 when FEAT_SME is implemented
33
hw/arm/smmuv3: add support for stage 1 access fault
32
hw/arm/boot: set CPTR_EL3.ESM and SCR_EL3.EnTP2 when booting Linux with EL3
33
34
34
Joel Stanley (1):
35
Nabih Estefan (1):
35
docs/nuvoton: Update URL for images
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
36
37
37
Peter Maydell (4):
38
Peter Maydell (22):
38
target/arm/kvm: Retry KVM_CREATE_VM call if it fails EINTR
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
39
target/arm: Don't allow guest to use unimplemented granule sizes
40
hw/block/tc58128: Don't emit deprecation warning under qtest
40
target/arm: Use ARMGranuleSize in ARMVAParameters
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
41
docs/system/arm/emulation.rst: Report FEAT_GTG support
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
42
61
43
Richard Henderson (21):
62
Philippe Mathieu-Daudé (5):
44
target/arm: Split s2walk_secure from ipa_secure in get_phys_addr
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
45
target/arm: Make the final stage1+2 write to secure be unconditional
64
hw/arm/stellaris: Convert ADC controller to Resettable interface
46
target/arm: Add is_secure parameter to get_phys_addr_lpae
65
hw/arm/stellaris: Convert I2C controller to Resettable interface
47
target/arm: Fix S2 disabled check in S1_ptw_translate
66
hw/arm/stellaris: Add missing QOM 'machine' parent
48
target/arm: Add is_secure parameter to regime_translation_disabled
67
hw/arm/stellaris: Add missing QOM 'SoC' parent
49
target/arm: Split out get_phys_addr_with_secure
50
target/arm: Add is_secure parameter to v7m_read_half_insn
51
target/arm: Add TBFLAG_M32.SECURE
52
target/arm: Merge regime_is_secure into get_phys_addr
53
target/arm: Add is_secure parameter to do_ats_write
54
target/arm: Fold secure and non-secure a-profile mmu indexes
55
target/arm: Reorg regime_translation_disabled
56
target/arm: Drop secure check for HCR.TGE vs SCTLR_EL1.M
57
target/arm: Introduce arm_hcr_el2_eff_secstate
58
target/arm: Hoist read of *is_secure in S1_ptw_translate
59
target/arm: Remove env argument from combined_attrs_fwb
60
target/arm: Pass HCR to attribute subroutines.
61
target/arm: Fix ATS12NSO* from S PL1
62
target/arm: Split out get_phys_addr_disabled
63
target/arm: Fix cacheattr in get_phys_addr_disabled
64
target/arm: Use tlb_set_page_full
65
68
66
docs/system/arm/emulation.rst | 1 +
69
Richard Henderson (6):
67
docs/system/arm/nuvoton.rst | 4 +-
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
68
target/arm/cpu-param.h | 2 +-
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
69
target/arm/cpu.h | 181 ++++++++------
72
target/arm: Adjust and validate mtedesc sizem1
70
target/arm/internals.h | 150 ++++++-----
73
target/arm: Split out make_svemte_desc
71
hw/arm/boot.c | 4 +
74
target/arm: Handle mte in do_ldrq, do_ldro
72
target/arm/helper.c | 332 ++++++++++++++----------
75
target/arm: Fix SVE/SME gross MTE suppression checks
73
target/arm/kvm.c | 4 +-
76
74
target/arm/m_helper.c | 29 ++-
77
MAINTAINERS | 3 +-
75
target/arm/ptw.c | 570 ++++++++++++++++++++++--------------------
78
docs/system/arm/mps2.rst | 37 +-
76
target/arm/tlb_helper.c | 9 +-
79
configs/devices/arm-softmmu/default.mak | 1 +
77
target/arm/translate-a64.c | 8 -
80
hw/arm/smmuv3-internal.h | 1 +
78
target/arm/translate.c | 9 +-
81
include/hw/arm/smmu-common.h | 1 +
79
13 files changed, 717 insertions(+), 586 deletions(-)
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: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
While the stage2 call to get_phys_addr_lpae should never set
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
4
attrs.secure when given a non-secure input, it's just as easy
4
connect FIQ output of the GIC CPU interfaces to the CPU.
5
to make the final update to attrs.secure be unconditional and
6
false in the case of non-secure input.
7
5
8
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
10
Message-id: 20221007152159.1414065-1-richard.henderson@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
target/arm/ptw.c | 21 ++++++++++-----------
11
hw/arm/xilinx_zynq.c | 2 ++
15
1 file changed, 10 insertions(+), 11 deletions(-)
12
1 file changed, 2 insertions(+)
16
13
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/ptw.c
16
--- a/hw/arm/xilinx_zynq.c
20
+++ b/target/arm/ptw.c
17
+++ b/hw/arm/xilinx_zynq.c
21
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
22
result->cacheattrs = combine_cacheattrs(env, cacheattrs1,
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
23
result->cacheattrs);
20
sysbus_connect_irq(busdev, 0,
24
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
25
- /* Check if IPA translates to secure or non-secure PA space. */
22
+ sysbus_connect_irq(busdev, 1,
26
- if (is_secure) {
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
27
- if (ipa_secure) {
24
28
- result->attrs.secure =
25
for (n = 0; n < 64; n++) {
29
- !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW));
26
pic[n] = qdev_get_gpio_in(dev, n);
30
- } else {
31
- result->attrs.secure =
32
- !((env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))
33
- || (env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW)));
34
- }
35
- }
36
+ /*
37
+ * Check if IPA translates to secure or non-secure PA space.
38
+ * Note that VSTCR overrides VTCR and {N}SW overrides {N}SA.
39
+ */
40
+ result->attrs.secure =
41
+ (is_secure
42
+ && !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW))
43
+ && (ipa_secure
44
+ || !(env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))));
45
+
46
return 0;
47
} else {
48
/*
49
--
27
--
50
2.25.1
28
2.34.1
29
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This value is unused.
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.
4
6
7
Cc: qemu-stable@nongnu.org
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
7
Message-id: 20221001162318.153420-16-richard.henderson@linaro.org
11
Message-id: 20240207025210.8837-2-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
target/arm/ptw.c | 5 ++---
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
11
1 file changed, 2 insertions(+), 3 deletions(-)
15
1 file changed, 17 insertions(+), 12 deletions(-)
12
16
13
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/ptw.c
19
--- a/linux-user/aarch64/target_prctl.h
16
+++ b/target/arm/ptw.c
20
+++ b/linux-user/aarch64/target_prctl.h
17
@@ -XXX,XX +XXX,XX @@ static uint8_t force_cacheattr_nibble_wb(uint8_t attr)
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
18
* s1 and s2 for the HCR_EL2.FWB == 1 case, returning the
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
19
* combined attributes in MAIR_EL1 format.
23
20
*/
24
if (cpu_isar_feature(aa64_mte, cpu)) {
21
-static uint8_t combined_attrs_fwb(CPUARMState *env,
25
- switch (arg2 & PR_MTE_TCF_MASK) {
22
- ARMCacheAttrs s1, ARMCacheAttrs s2)
26
- case PR_MTE_TCF_NONE:
23
+static uint8_t combined_attrs_fwb(ARMCacheAttrs s1, ARMCacheAttrs s2)
27
- case PR_MTE_TCF_SYNC:
24
{
28
- case PR_MTE_TCF_ASYNC:
25
switch (s2.attrs) {
29
- break;
26
case 7:
30
- default:
27
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
31
- return -EINVAL;
28
32
- }
29
/* Combine memory type and cacheability attributes */
33
-
30
if (arm_hcr_el2_eff(env) & HCR_FWB) {
34
/*
31
- ret.attrs = combined_attrs_fwb(env, s1, s2);
35
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
32
+ ret.attrs = combined_attrs_fwb(s1, s2);
36
- * Note that the syscall values are consistent with hw.
33
} else {
37
+ *
34
ret.attrs = combined_attrs_nofwb(env, s1, s2);
38
+ * The kernel has a per-cpu configuration for the sysadmin,
35
}
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].
36
--
60
--
37
2.25.1
61
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Remove the use of regime_is_secure from arm_tr_init_disas_context.
3
The field is encoded as [0-3], which is convenient for
4
Instead, provide the value of v8m_secure directly from tb_flags.
4
indexing our array of function pointers, but the true
5
Rather than use regime_is_secure, use the env->v7m.secure directly,
5
value is [1-4]. Adjust before calling do_mem_zpa.
6
as per arm_mmu_idx_el.
7
6
7
Add an assert, and move the comment re passing ZT to
8
the helper back next to the relevant code.
9
10
Cc: qemu-stable@nongnu.org
11
Fixes: 206adacfb8d ("target/arm: Add mte helpers for sve scalar + int loads")
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
14
Message-id: 20240207025210.8837-3-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20221001162318.153420-8-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
17
---
13
target/arm/cpu.h | 2 ++
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
14
target/arm/helper.c | 4 ++++
19
1 file changed, 8 insertions(+), 8 deletions(-)
15
target/arm/translate.c | 3 +--
16
3 files changed, 7 insertions(+), 2 deletions(-)
17
20
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
23
--- a/target/arm/tcg/translate-sve.c
21
+++ b/target/arm/cpu.h
24
+++ b/target/arm/tcg/translate-sve.c
22
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 3, 1) /* Not cached. */
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
23
FIELD(TBFLAG_M32, FPCCR_S_WRONG, 4, 1) /* Not cached. */
26
TCGv_ptr t_pg;
24
/* Set if MVE insns are definitely not predicated by VPR or LTPSIZE */
27
int desc = 0;
25
FIELD(TBFLAG_M32, MVE_NO_PRED, 5, 1) /* Not cached. */
28
26
+/* Set if in secure mode */
29
- /*
27
+FIELD(TBFLAG_M32, SECURE, 6, 1)
30
- * For e.g. LD4, there are not enough arguments to pass all 4
28
31
- * registers as pointers, so encode the regno into the data field.
29
/*
32
- * For consistency, do this even for LD1.
30
* Bit usage when in AArch64 state
33
- */
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
+ assert(mte_n >= 1 && mte_n <= 4);
32
index XXXXXXX..XXXXXXX 100644
35
if (s->mte_active[0]) {
33
--- a/target/arm/helper.c
36
int msz = dtype_msz(dtype);
34
+++ b/target/arm/helper.c
37
35
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
38
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
36
DP_TBFLAG_M32(flags, STACKCHECK, 1);
39
addr = clean_data_tbi(s, addr);
37
}
40
}
38
41
39
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && env->v7m.secure) {
42
+ /*
40
+ DP_TBFLAG_M32(flags, SECURE, 1);
43
+ * For e.g. LD4, there are not enough arguments to pass all 4
41
+ }
44
+ * registers as pointers, so encode the regno into the data field.
42
+
45
+ * For consistency, do this even for LD1.
43
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
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);
44
}
56
}
45
57
46
diff --git a/target/arm/translate.c b/target/arm/translate.c
58
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
47
index XXXXXXX..XXXXXXX 100644
59
@@ -XXX,XX +XXX,XX @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
48
--- a/target/arm/translate.c
60
if (nreg == 0) {
49
+++ b/target/arm/translate.c
61
/* ST1 */
50
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
62
fn = fn_single[s->mte_active[0]][be][msz][esz];
51
dc->vfp_enabled = 1;
63
- nreg = 1;
52
dc->be_data = MO_TE;
64
} else {
53
dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
65
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
54
- dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
66
assert(msz == esz);
55
- regime_is_secure(env, dc->mmu_idx);
67
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
56
+ dc->v8m_secure = EX_TBFLAG_M32(tb_flags, SECURE);
68
}
57
dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
69
assert(fn != NULL);
58
dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
70
- do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn);
59
dc->v7m_new_fp_ctxt_needed =
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)
60
--
75
--
61
2.25.1
76
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Retain the existing get_phys_addr interface using the security
3
When we added SVE_MTEDESC_SHIFT, we effectively limited the
4
state derived from mmu_idx. Move the kerneldoc comments to the
4
maximum size of MTEDESC. Adjust SIZEM1 to consume the remaining
5
header file where they belong.
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).
6
7
8
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20221001162318.153420-6-richard.henderson@linaro.org
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
target/arm/internals.h | 40 ++++++++++++++++++++++++++++++++++++++
15
target/arm/internals.h | 2 +-
13
target/arm/ptw.c | 44 ++++++++++++++----------------------------
16
target/arm/tcg/translate-sve.c | 7 ++++---
14
2 files changed, 55 insertions(+), 29 deletions(-)
17
2 files changed, 5 insertions(+), 4 deletions(-)
15
18
16
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
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
21
--- a/target/arm/internals.h
19
+++ b/target/arm/internals.h
22
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct GetPhysAddrResult {
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
21
ARMCacheAttrs cacheattrs;
24
FIELD(MTEDESC, TCMA, 6, 2)
22
} GetPhysAddrResult;
25
FIELD(MTEDESC, WRITE, 8, 1)
23
26
FIELD(MTEDESC, ALIGN, 9, 3)
24
+/**
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
25
+ * get_phys_addr_with_secure: get the physical address for a virtual address
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
26
+ * @env: CPUARMState
29
27
+ * @address: virtual address to get physical address for
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
28
+ * @access_type: 0 for read, 1 for write, 2 for execute
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
29
+ * @mmu_idx: MMU index indicating required translation regime
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
30
+ * @is_secure: security state for the access
31
+ * @result: set on translation success.
32
+ * @fi: set to fault info if the translation fails
33
+ *
34
+ * Find the physical address corresponding to the given virtual address,
35
+ * by doing a translation table walk on MMU based systems or using the
36
+ * MPU state on MPU based systems.
37
+ *
38
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
39
+ * prot and page_size may not be filled in, and the populated fsr value provides
40
+ * information on why the translation aborted, in the format of a
41
+ * DFSR/IFSR fault register, with the following caveats:
42
+ * * we honour the short vs long DFSR format differences.
43
+ * * the WnR bit is never set (the caller must do this).
44
+ * * for PSMAv5 based systems we don't bother to return a full FSR format
45
+ * value.
46
+ */
47
+bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
48
+ MMUAccessType access_type,
49
+ ARMMMUIdx mmu_idx, bool is_secure,
50
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
51
+ __attribute__((nonnull));
52
+
53
+/**
54
+ * get_phys_addr: get the physical address for a virtual address
55
+ * @env: CPUARMState
56
+ * @address: virtual address to get physical address for
57
+ * @access_type: 0 for read, 1 for write, 2 for execute
58
+ * @mmu_idx: MMU index indicating required translation regime
59
+ * @result: set on translation success.
60
+ * @fi: set to fault info if the translation fails
61
+ *
62
+ * Similarly, but use the security regime of @mmu_idx.
63
+ */
64
bool get_phys_addr(CPUARMState *env, target_ulong address,
65
MMUAccessType access_type, ARMMMUIdx mmu_idx,
66
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
67
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
68
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/ptw.c
34
--- a/target/arm/tcg/translate-sve.c
70
+++ b/target/arm/ptw.c
35
+++ b/target/arm/tcg/translate-sve.c
71
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
72
return ret;
73
}
74
75
-/**
76
- * get_phys_addr - get the physical address for this virtual address
77
- *
78
- * Find the physical address corresponding to the given virtual address,
79
- * by doing a translation table walk on MMU based systems or using the
80
- * MPU state on MPU based systems.
81
- *
82
- * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
83
- * prot and page_size may not be filled in, and the populated fsr value provides
84
- * information on why the translation aborted, in the format of a
85
- * DFSR/IFSR fault register, with the following caveats:
86
- * * we honour the short vs long DFSR format differences.
87
- * * the WnR bit is never set (the caller must do this).
88
- * * for PSMAv5 based systems we don't bother to return a full FSR format
89
- * value.
90
- *
91
- * @env: CPUARMState
92
- * @address: virtual address to get physical address for
93
- * @access_type: 0 for read, 1 for write, 2 for execute
94
- * @mmu_idx: MMU index indicating required translation regime
95
- * @result: set on translation success.
96
- * @fi: set to fault info if the translation fails
97
- */
98
-bool get_phys_addr(CPUARMState *env, target_ulong address,
99
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
100
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
101
+bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
102
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
103
+ bool is_secure, GetPhysAddrResult *result,
104
+ ARMMMUFaultInfo *fi)
105
{
37
{
106
ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
38
unsigned vsz = vec_full_reg_size(s);
107
- bool is_secure = regime_is_secure(env, mmu_idx);
39
TCGv_ptr t_pg;
108
40
+ uint32_t sizem1;
109
if (mmu_idx != s1_mmu_idx) {
41
int desc = 0;
110
/*
42
111
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
43
assert(mte_n >= 1 && mte_n <= 4);
112
ARMMMUIdx s2_mmu_idx;
44
+ sizem1 = (mte_n << dtype_msz(dtype)) - 1;
113
bool is_el0;
45
+ assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
114
46
if (s->mte_active[0]) {
115
- ret = get_phys_addr(env, address, access_type, s1_mmu_idx,
47
- int msz = dtype_msz(dtype);
116
- result, fi);
48
-
117
+ ret = get_phys_addr_with_secure(env, address, access_type,
49
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
118
+ s1_mmu_idx, is_secure, result, fi);
50
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
119
51
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
120
/* If S1 fails or S2 is disabled, return early. */
52
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
121
if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2,
53
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
122
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
54
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
123
}
55
desc <<= SVE_MTEDESC_SHIFT;
124
}
56
} else {
125
57
addr = clean_data_tbi(s, addr);
126
+bool get_phys_addr(CPUARMState *env, target_ulong address,
127
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
128
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
129
+{
130
+ return get_phys_addr_with_secure(env, address, access_type, mmu_idx,
131
+ regime_is_secure(env, mmu_idx),
132
+ result, fi);
133
+}
134
+
135
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
136
MemTxAttrs *attrs)
137
{
138
--
58
--
139
2.25.1
59
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For page walking, we may require HCR for a security state
3
Share code that creates mtedesc and embeds within simd_desc.
4
that is not "current".
5
4
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>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-14-richard.henderson@linaro.org
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/cpu.h | 20 +++++++++++++-------
12
target/arm/tcg/translate-a64.h | 2 ++
12
target/arm/helper.c | 11 ++++++++---
13
target/arm/tcg/translate-sme.c | 15 +++--------
13
2 files changed, 21 insertions(+), 10 deletions(-)
14
target/arm/tcg/translate-sve.c | 47 ++++++++++++++++++----------------
15
3 files changed, 31 insertions(+), 33 deletions(-)
14
16
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
19
--- a/target/arm/tcg/translate-a64.h
18
+++ b/target/arm/cpu.h
20
+++ b/target/arm/tcg/translate-a64.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_secure(CPUARMState *env)
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
20
* Return true if the current security state has AArch64 EL2 or AArch32 Hyp.
22
bool sve_access_check(DisasContext *s);
21
* This corresponds to the pseudocode EL2Enabled()
23
bool sme_enabled_check(DisasContext *s);
22
*/
24
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
23
+static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
25
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
24
+{
26
+ uint32_t msz, bool is_write, uint32_t data);
25
+ return arm_feature(env, ARM_FEATURE_EL2)
27
26
+ && (!secure || (env->cp15.scr_el3 & SCR_EEL2));
28
/* This function corresponds to CheckStreamingSVEEnabled. */
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
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/tcg/translate-sme.c
33
+++ b/target/arm/tcg/translate-sme.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
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
71
};
72
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
74
- int dtype, uint32_t mte_n, bool is_write,
75
- gen_helper_gvec_mem *fn)
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
77
+ uint32_t msz, bool is_write, uint32_t data)
78
{
79
- unsigned vsz = vec_full_reg_size(s);
80
- TCGv_ptr t_pg;
81
uint32_t sizem1;
82
- int desc = 0;
83
+ uint32_t desc = 0;
84
85
- assert(mte_n >= 1 && mte_n <= 4);
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 {
101
+ }
102
+ return simd_desc(vsz, vsz, desc | data);
27
+}
103
+}
28
+
104
+
29
static inline bool arm_is_el2_enabled(CPUARMState *env)
105
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
106
+ int dtype, uint32_t nregs, bool is_write,
107
+ gen_helper_gvec_mem *fn)
108
+{
109
+ TCGv_ptr t_pg;
110
+ uint32_t desc;
111
+
112
+ if (!s->mte_active[0]) {
113
addr = clean_data_tbi(s, addr);
114
}
115
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)
30
{
129
{
31
- if (arm_feature(env, ARM_FEATURE_EL2)) {
130
- unsigned vsz = vec_full_reg_size(s);
32
- if (arm_is_secure_below_el3(env)) {
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
33
- return (env->cp15.scr_el3 & SCR_EEL2) != 0;
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
34
- }
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
35
- return true;
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;
36
- }
143
- }
37
- return false;
144
- desc = simd_desc(vsz, vsz, desc | scale);
38
+ return arm_is_el2_enabled_secstate(env, arm_is_secure_below_el3(env));
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));
150
+
151
+ desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
152
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
39
}
153
}
40
154
41
#else
42
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_secure(CPUARMState *env)
43
return false;
44
}
45
46
+static inline bool arm_is_el2_enabled_secstate(CPUARMState *env, bool secure)
47
+{
48
+ return false;
49
+}
50
+
51
static inline bool arm_is_el2_enabled(CPUARMState *env)
52
{
53
return false;
54
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
55
* "for all purposes other than a direct read or write access of HCR_EL2."
56
* Not included here is HCR_RW.
57
*/
58
+uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure);
59
uint64_t arm_hcr_el2_eff(CPUARMState *env);
60
uint64_t arm_hcrx_el2_eff(CPUARMState *env);
61
62
diff --git a/target/arm/helper.c b/target/arm/helper.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/arm/helper.c
65
+++ b/target/arm/helper.c
66
@@ -XXX,XX +XXX,XX @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
67
}
68
69
/*
70
- * Return the effective value of HCR_EL2.
71
+ * Return the effective value of HCR_EL2, at the given security state.
72
* Bits that are not included here:
73
* RW (read from SCR_EL3.RW as needed)
74
*/
75
-uint64_t arm_hcr_el2_eff(CPUARMState *env)
76
+uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, bool secure)
77
{
78
uint64_t ret = env->cp15.hcr_el2;
79
80
- if (!arm_is_el2_enabled(env)) {
81
+ if (!arm_is_el2_enabled_secstate(env, secure)) {
82
/*
83
* "This register has no effect if EL2 is not enabled in the
84
* current Security state". This is ARMv8.4-SecEL2 speak for
85
@@ -XXX,XX +XXX,XX @@ uint64_t arm_hcr_el2_eff(CPUARMState *env)
86
return ret;
87
}
88
89
+uint64_t arm_hcr_el2_eff(CPUARMState *env)
90
+{
91
+ return arm_hcr_el2_eff_secstate(env, arm_is_secure_below_el3(env));
92
+}
93
+
94
/*
95
* Corresponds to ARM pseudocode function ELIsInHost().
96
*/
97
--
155
--
98
2.25.1
156
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use a switch on mmu_idx for the a-profile indexes, instead of
3
These functions "use the standard load helpers", but
4
three different if's vs regime_el and arm_mmu_idx_is_stage1_of_2.
4
fail to clean_data_tbi or populate mtedesc.
5
5
6
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-12-richard.henderson@linaro.org
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
10
Message-id: 20240207025210.8837-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/ptw.c | 32 +++++++++++++++++++++++++-------
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
12
1 file changed, 25 insertions(+), 7 deletions(-)
14
1 file changed, 13 insertions(+), 2 deletions(-)
13
15
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
18
--- a/target/arm/tcg/translate-sve.c
17
+++ b/target/arm/ptw.c
19
+++ b/target/arm/tcg/translate-sve.c
18
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
19
21
unsigned vsz = vec_full_reg_size(s);
20
hcr_el2 = arm_hcr_el2_eff(env);
22
TCGv_ptr t_pg;
21
23
int poff;
22
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
24
+ uint32_t desc;
23
+ switch (mmu_idx) {
25
24
+ case ARMMMUIdx_Stage2:
26
/* Load the first quadword using the normal predicated load helpers. */
25
+ case ARMMMUIdx_Stage2_S:
27
+ if (!s->mte_active[0]) {
26
/* HCR.DC means HCR.VM behaves as 1 */
28
+ addr = clean_data_tbi(s, addr);
27
return (hcr_el2 & (HCR_DC | HCR_VM)) == 0;
29
+ }
28
- }
29
30
- if (hcr_el2 & HCR_TGE) {
31
+ case ARMMMUIdx_E10_0:
32
+ case ARMMMUIdx_E10_1:
33
+ case ARMMMUIdx_E10_1_PAN:
34
/* TGE means that NS EL0/1 act as if SCTLR_EL1.M is zero */
35
- if (!is_secure && regime_el(env, mmu_idx) == 1) {
36
+ if (!is_secure && (hcr_el2 & HCR_TGE)) {
37
return true;
38
}
39
- }
40
+ break;
41
42
- if ((hcr_el2 & HCR_DC) && arm_mmu_idx_is_stage1_of_2(mmu_idx)) {
43
+ case ARMMMUIdx_Stage1_E0:
44
+ case ARMMMUIdx_Stage1_E1:
45
+ case ARMMMUIdx_Stage1_E1_PAN:
46
/* HCR.DC means SCTLR_EL1.M behaves as 0 */
47
- return true;
48
+ if (hcr_el2 & HCR_DC) {
49
+ return true;
50
+ }
51
+ break;
52
+
30
+
53
+ case ARMMMUIdx_E20_0:
31
poff = pred_full_reg_offset(s, pg);
54
+ case ARMMMUIdx_E20_2:
32
if (vsz > 16) {
55
+ case ARMMMUIdx_E20_2_PAN:
33
/*
56
+ case ARMMMUIdx_E2:
34
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
57
+ case ARMMMUIdx_E3:
35
58
+ break;
36
gen_helper_gvec_mem *fn
59
+
37
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
60
+ default:
38
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt)));
61
+ g_assert_not_reached();
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)
62
}
53
}
63
54
64
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
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.
65
--
72
--
66
2.25.1
73
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These subroutines did not need ENV for anything except
3
The TBI and TCMA bits are located within mtedesc, not desc.
4
retrieving the effective value of HCR anyway.
5
4
6
We have computed the effective value of HCR in the callers,
5
Cc: qemu-stable@nongnu.org
7
and this will be especially important for interpreting HCR
8
in a non-current security state.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20221001162318.153420-17-richard.henderson@linaro.org
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
target/arm/ptw.c | 30 +++++++++++++++++-------------
12
target/arm/tcg/sme_helper.c | 8 ++++----
16
1 file changed, 17 insertions(+), 13 deletions(-)
13
target/arm/tcg/sve_helper.c | 12 ++++++------
14
2 files changed, 10 insertions(+), 10 deletions(-)
17
15
18
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/ptw.c
18
--- a/target/arm/tcg/sme_helper.c
21
+++ b/target/arm/ptw.c
19
+++ b/target/arm/tcg/sme_helper.c
22
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
23
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
21
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
24
}
22
25
23
/* Perform gross MTE suppression early. */
26
-static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
24
- if (!tbi_check(desc, bit55) ||
27
+static bool ptw_attrs_are_device(uint64_t hcr, ARMCacheAttrs cacheattrs)
25
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
28
{
26
+ if (!tbi_check(mtedesc, bit55) ||
29
/*
27
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
30
* For an S1 page table walk, the stage 1 attributes are always
28
mtedesc = 0;
31
@@ -XXX,XX +XXX,XX @@ static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
32
* when cacheattrs.attrs bit [2] is 0.
33
*/
34
assert(cacheattrs.is_s2_format);
35
- if (arm_hcr_el2_eff(env) & HCR_FWB) {
36
+ if (hcr & HCR_FWB) {
37
return (cacheattrs.attrs & 0x4) == 0;
38
} else {
39
return (cacheattrs.attrs & 0xc) == 0;
40
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
41
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
42
!regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
43
GetPhysAddrResult s2 = {};
44
+ uint64_t hcr;
45
int ret;
46
47
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
48
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
49
fi->s1ns = !is_secure;
50
return ~0;
51
}
52
- if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
53
- ptw_attrs_are_device(env, s2.cacheattrs)) {
54
+
55
+ hcr = arm_hcr_el2_eff(env);
56
+ if ((hcr & HCR_PTW) && ptw_attrs_are_device(hcr, s2.cacheattrs)) {
57
/*
58
* PTW set and S1 walk touched S2 Device memory:
59
* generate Permission fault.
60
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
61
* ref: shared/translation/attrs/S2AttrDecode()
62
* .../S2ConvertAttrsHints()
63
*/
64
-static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
65
+static uint8_t convert_stage2_attrs(uint64_t hcr, uint8_t s2attrs)
66
{
67
uint8_t hiattr = extract32(s2attrs, 2, 2);
68
uint8_t loattr = extract32(s2attrs, 0, 2);
69
uint8_t hihint = 0, lohint = 0;
70
71
if (hiattr != 0) { /* normal memory */
72
- if (arm_hcr_el2_eff(env) & HCR_CD) { /* cache disabled */
73
+ if (hcr & HCR_CD) { /* cache disabled */
74
hiattr = loattr = 1; /* non-cacheable */
75
} else {
76
if (hiattr != 1) { /* Write-through or write-back */
77
@@ -XXX,XX +XXX,XX @@ static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
78
* s1 and s2 for the HCR_EL2.FWB == 0 case, returning the
79
* combined attributes in MAIR_EL1 format.
80
*/
81
-static uint8_t combined_attrs_nofwb(CPUARMState *env,
82
+static uint8_t combined_attrs_nofwb(uint64_t hcr,
83
ARMCacheAttrs s1, ARMCacheAttrs s2)
84
{
85
uint8_t s1lo, s2lo, s1hi, s2hi, s2_mair_attrs, ret_attrs;
86
87
- s2_mair_attrs = convert_stage2_attrs(env, s2.attrs);
88
+ s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
89
90
s1lo = extract32(s1.attrs, 0, 4);
91
s2lo = extract32(s2_mair_attrs, 0, 4);
92
@@ -XXX,XX +XXX,XX @@ static uint8_t combined_attrs_fwb(ARMCacheAttrs s1, ARMCacheAttrs s2)
93
* @s1: Attributes from stage 1 walk
94
* @s2: Attributes from stage 2 walk
95
*/
96
-static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
97
+static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
98
ARMCacheAttrs s1, ARMCacheAttrs s2)
99
{
100
ARMCacheAttrs ret;
101
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
102
}
29
}
103
30
104
/* Combine memory type and cacheability attributes */
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
105
- if (arm_hcr_el2_eff(env) & HCR_FWB) {
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
106
+ if (hcr & HCR_FWB) {
33
107
ret.attrs = combined_attrs_fwb(s1, s2);
34
/* Perform gross MTE suppression early. */
108
} else {
35
- if (!tbi_check(desc, bit55) ||
109
- ret.attrs = combined_attrs_nofwb(env, s1, s2);
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
110
+ ret.attrs = combined_attrs_nofwb(hcr, s1, s2);
37
+ if (!tbi_check(mtedesc, bit55) ||
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
39
mtedesc = 0;
111
}
40
}
112
41
113
/*
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
114
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
43
index XXXXXXX..XXXXXXX 100644
115
ARMCacheAttrs cacheattrs1;
44
--- a/target/arm/tcg/sve_helper.c
116
ARMMMUIdx s2_mmu_idx;
45
+++ b/target/arm/tcg/sve_helper.c
117
bool is_el0;
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
118
+ uint64_t hcr;
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
119
48
120
ret = get_phys_addr_with_secure(env, address, access_type,
49
/* Perform gross MTE suppression early. */
121
s1_mmu_idx, is_secure, result, fi);
50
- if (!tbi_check(desc, bit55) ||
122
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
123
}
52
+ if (!tbi_check(mtedesc, bit55) ||
124
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
125
/* Combine the S1 and S2 cache attributes. */
54
mtedesc = 0;
126
- if (arm_hcr_el2_eff(env) & HCR_DC) {
55
}
127
+ hcr = arm_hcr_el2_eff(env);
56
128
+ if (hcr & HCR_DC) {
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
129
/*
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
130
* HCR.DC forces the first stage attributes to
59
131
* Normal Non-Shareable,
60
/* Perform gross MTE suppression early. */
132
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
61
- if (!tbi_check(desc, bit55) ||
133
}
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
134
cacheattrs1.shareability = 0;
63
+ if (!tbi_check(mtedesc, bit55) ||
135
}
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
136
- result->cacheattrs = combine_cacheattrs(env, cacheattrs1,
65
mtedesc = 0;
137
+ result->cacheattrs = combine_cacheattrs(hcr, cacheattrs1,
66
}
138
result->cacheattrs);
67
139
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
140
/*
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
}
78
141
--
79
--
142
2.25.1
80
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
Remove the use of regime_is_secure from v7m_read_half_insn, using
11
Fortunately raven_io_read() and raven_io_write() will correctly deal
4
the new parameter instead.
12
with the case of being passed an unaligned address, so we can fix the
13
missing unaligned access support by setting .impl.unaligned in the
14
MemoryRegionOps struct.
5
15
6
As it happens, both callers pass true, propagated from the argument
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
7
to arm_v7m_mmu_idx_for_secstate which created the mmu_idx argument,
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
but that is a detail of v7m_handle_execute_nsc we need not expose
18
Tested-by: Cédric Le Goater <clg@redhat.com>
9
to the callee.
19
Reviewed-by: Cédric Le Goater <clg@redhat.com>
20
Message-id: 20240112134640.1775041-1-peter.maydell@linaro.org
21
---
22
hw/pci-host/raven.c | 1 +
23
1 file changed, 1 insertion(+)
10
24
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20221001162318.153420-7-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/m_helper.c | 9 ++++-----
18
1 file changed, 4 insertions(+), 5 deletions(-)
19
20
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
21
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/m_helper.c
27
--- a/hw/pci-host/raven.c
23
+++ b/target/arm/m_helper.c
28
+++ b/hw/pci-host/raven.c
24
@@ -XXX,XX +XXX,XX @@ static bool do_v7m_function_return(ARMCPU *cpu)
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
25
return true;
30
.write = raven_io_write,
26
}
31
.endianness = DEVICE_LITTLE_ENDIAN,
27
32
.impl.max_access_size = 4,
28
-static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
33
+ .impl.unaligned = true,
29
+static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx, bool secure,
34
.valid.unaligned = true,
30
uint32_t addr, uint16_t *insn)
35
};
31
{
32
/*
33
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
34
ARMMMUFaultInfo fi = {};
35
MemTxResult txres;
36
37
- v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx,
38
- regime_is_secure(env, mmu_idx), &sattrs);
39
+ v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx, secure, &sattrs);
40
if (!sattrs.nsc || sattrs.ns) {
41
/*
42
* This must be the second half of the insn, and it straddles a
43
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
44
/* We want to do the MPU lookup as secure; work out what mmu_idx that is */
45
mmu_idx = arm_v7m_mmu_idx_for_secstate(env, true);
46
47
- if (!v7m_read_half_insn(cpu, mmu_idx, env->regs[15], &insn)) {
48
+ if (!v7m_read_half_insn(cpu, mmu_idx, true, env->regs[15], &insn)) {
49
return false;
50
}
51
52
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
53
goto gen_invep;
54
}
55
56
- if (!v7m_read_half_insn(cpu, mmu_idx, env->regs[15] + 2, &insn)) {
57
+ if (!v7m_read_half_insn(cpu, mmu_idx, true, env->regs[15] + 2, &insn)) {
58
return false;
59
}
60
36
61
--
37
--
62
2.25.1
38
2.34.1
63
39
64
40
diff view generated by jsdifflib
1
Occasionally the KVM_CREATE_VM ioctl can return EINTR, even though
1
Suppress the deprecation warning when we're running under qtest,
2
there is no pending signal to be taken. In commit 94ccff13382055
2
to avoid "make check" including warning messages in its output.
3
we added a retry-on-EINTR loop to the KVM_CREATE_VM call in the
4
generic KVM code. Adopt the same approach for the use of the
5
ioctl in the Arm-specific KVM code (where we use it to create a
6
scratch VM for probing for various things).
7
3
8
For more information, see the mailing list thread:
9
https://lore.kernel.org/qemu-devel/8735e0s1zw.wl-maz@kernel.org/
10
11
Reported-by: Vitaly Chikunov <vt@altlinux.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Vitaly Chikunov <vt@altlinux.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Reviewed-by: Eric Auger <eric.auger@redhat.com>
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
15
Acked-by: Marc Zyngier <maz@kernel.org>
16
Message-id: 20220930113824.1933293-1-peter.maydell@linaro.org
17
---
7
---
18
target/arm/kvm.c | 4 +++-
8
hw/block/tc58128.c | 4 +++-
19
1 file changed, 3 insertions(+), 1 deletion(-)
9
1 file changed, 3 insertions(+), 1 deletion(-)
20
10
21
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
22
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/kvm.c
13
--- a/hw/block/tc58128.c
24
+++ b/target/arm/kvm.c
14
+++ b/hw/block/tc58128.c
25
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
26
if (max_vm_pa_size < 0) {
16
27
max_vm_pa_size = 0;
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
28
}
18
{
29
- vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
19
- warn_report_once("The TC58128 flash device is deprecated");
30
+ do {
20
+ if (!qtest_enabled()) {
31
+ vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
21
+ warn_report_once("The TC58128 flash device is deprecated");
32
+ } while (vmfd == -1 && errno == EINTR);
22
+ }
33
if (vmfd < 0) {
23
init_dev(&tc58128_devs[0], zone1);
34
goto err;
24
init_dev(&tc58128_devs[1], zone2);
35
}
25
return sh7750_register_io_device(s, &tc58128);
36
--
26
--
37
2.25.1
27
2.34.1
28
29
diff view generated by jsdifflib
New patch
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.
1
4
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
6
that change.
7
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
12
---
13
tests/qtest/meson.build | 1 -
14
1 file changed, 1 deletion(-)
15
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qtest/meson.build
19
+++ b/tests/qtest/meson.build
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
22
(config_all_accel.has_key('CONFIG_TCG') and \
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
25
['arm-cpu-features',
26
'numa-test',
27
'boot-serial-test',
28
--
29
2.34.1
30
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
New patch
1
1
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds a
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.)
31
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
34
Message-id: 20240122143537.233498-3-peter.maydell@linaro.org
35
---
36
include/hw/arm/virt.h | 2 ++
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
39
3 files changed, 67 insertions(+), 15 deletions(-)
40
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/hw/arm/virt.h
44
+++ b/include/hw/arm/virt.h
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
47
bool no_cpu_topology;
48
bool no_tcg_lpa2;
49
+ bool no_ns_el2_virt_timer_irq;
50
};
51
52
struct VirtMachineState {
53
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
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
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/virt-acpi-build.c
64
+++ b/hw/arm/virt-acpi-build.c
65
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
}
67
68
/*
69
- * ACPI spec, Revision 5.1
70
- * 5.2.24 Generic Timer Description Table (GTDT)
71
+ * ACPI spec, Revision 6.5
72
+ * 5.2.25 Generic Timer Description Table (GTDT)
73
*/
74
static void
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
78
1 : /* Interrupt is Edge triggered */
79
0; /* Interrupt is Level triggered */
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
82
.oem_table_id = vms->oem_table_id };
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
116
index XXXXXXX..XXXXXXX 100644
117
--- a/hw/arm/virt.c
118
+++ b/hw/arm/virt.c
119
@@ -XXX,XX +XXX,XX @@ static void create_randomness(MachineState *ms, const char *node)
120
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
121
}
122
123
+/*
124
+ * The CPU object always exposes the NS EL2 virt timer IRQ line,
125
+ * but we don't want to advertise it to the guest in the dtb or ACPI
126
+ * table unless it's really going to do something.
127
+ */
128
+static bool ns_el2_virt_timer_present(void)
129
+{
130
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
131
+ CPUARMState *env = &cpu->env;
132
+
133
+ return arm_feature(env, ARM_FEATURE_AARCH64) &&
134
+ arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
135
+}
136
+
137
static void create_fdt(VirtMachineState *vms)
138
{
139
MachineState *ms = MACHINE(vms);
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
141
"arm,armv7-timer");
142
}
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
216
--
217
2.34.1
diff view generated by jsdifflib
New patch
1
1
Update the virt golden reference files to say that the FACP is ACPI
2
v6.3, and the GTDT table is a revision 3 table with space for the
3
virtual EL2 timer.
4
5
Diffs from iasl:
6
7
@@ -XXX,XX +XXX,XX @@
8
/*
9
* Intel ACPI Component Architecture
10
* AML/ASL+ Disassembler version 20200925 (64-bit version)
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 // ........
183
184
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
185
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
186
Message-id: 20240122143537.233498-4-peter.maydell@linaro.org
187
---
188
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
189
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
190
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
191
3 files changed, 2 deletions(-)
192
193
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
194
index XXXXXXX..XXXXXXX 100644
195
--- a/tests/qtest/bios-tables-test-allowed-diff.h
196
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
197
@@ -1,3 +1 @@
198
/* List of comma-separated changed AML files to ignore */
199
-"tests/data/acpi/virt/FACP",
200
-"tests/data/acpi/virt/GTDT",
201
diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP
202
index XXXXXXX..XXXXXXX 100644
203
GIT binary patch
204
delta 25
205
gcmbQjG=+)F&CxkPgpq-PO=u!l<;2F$$vli407<0<)c^nh
206
207
delta 28
208
kcmbQjG=+)F&CxkPgpq-PO>`nx<-|!<6Akz$^DuG%0AAS!ssI20
209
210
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
211
index XXXXXXX..XXXXXXX 100644
212
GIT binary patch
213
delta 25
214
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
215
216
delta 16
217
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
218
219
--
220
2.34.1
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
New patch
1
Currently QEMU will warn if there is a NIC on the board that
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:
1
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.
13
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 20240206171231.396392-3-peter.maydell@linaro.org
18
---
19
tests/qtest/npcm7xx_emc-test.c | 5 ++++-
20
1 file changed, 4 insertions(+), 1 deletion(-)
21
22
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/tests/qtest/npcm7xx_emc-test.c
25
+++ b/tests/qtest/npcm7xx_emc-test.c
26
@@ -XXX,XX +XXX,XX @@ static int *packet_test_init(int module_num, GString *cmd_line)
27
* KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
28
* in the 'model' field to specify the device to match.
29
*/
30
- g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d ",
31
+ g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
32
+ "-nic user,model=npcm7xx-emc "
33
+ "-nic user,model=npcm-gmac "
34
+ "-nic user,model=npcm-gmac",
35
test_sockets[1], module_num);
36
37
g_test_queue_destroy(packet_test_clear, test_sockets);
38
--
39
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
2
CPU, and in fact if you try to do it we will assert:
2
3
3
Use get_phys_addr_with_secure directly. For a-profile, this is the
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
4
one place where the value of is_secure may not equal arm_is_secure(env).
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
5
9
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
We might call pmu_counter_enabled() on an M-profile CPU (for example
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
from the migration pre/post hooks in machine.c); this should always
8
Message-id: 20221001162318.153420-10-richard.henderson@linaro.org
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
9
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>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
10
---
26
---
11
target/arm/helper.c | 19 ++++++++++++++-----
27
target/arm/helper.c | 12 ++++++++++--
12
1 file changed, 14 insertions(+), 5 deletions(-)
28
1 file changed, 10 insertions(+), 2 deletions(-)
13
29
14
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
15
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
32
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
33
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
19
35
bool enabled, prohibited = false, filtered;
20
#ifdef CONFIG_TCG
36
bool secure = arm_is_secure(env);
21
static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
37
int el = arm_current_el(env);
22
- MMUAccessType access_type, ARMMMUIdx mmu_idx)
38
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
23
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
39
- uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
24
+ bool is_secure)
40
+ uint64_t mdcr_el2;
25
{
41
+ uint8_t hpmn;
26
bool ret;
42
27
uint64_t par64;
43
+ /*
28
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
44
+ * We might be called for M-profile cores where MDCR_EL2 doesn't
29
ARMMMUFaultInfo fi = {};
45
+ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check
30
GetPhysAddrResult res = {};
46
+ * must be before we read that value.
31
47
+ */
32
- ret = get_phys_addr(env, value, access_type, mmu_idx, &res, &fi);
48
if (!arm_feature(env, ARM_FEATURE_PMU)) {
33
+ ret = get_phys_addr_with_secure(env, value, access_type, mmu_idx,
49
return false;
34
+ is_secure, &res, &fi);
35
36
/*
37
* ATS operations only do S1 or S1+S2 translations, so we never
38
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
39
switch (el) {
40
case 3:
41
mmu_idx = ARMMMUIdx_SE3;
42
+ secure = true;
43
break;
44
case 2:
45
g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
46
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
47
switch (el) {
48
case 3:
49
mmu_idx = ARMMMUIdx_SE10_0;
50
+ secure = true;
51
break;
52
case 2:
53
g_assert(!secure); /* ARMv8.4-SecEL2 is 64-bit only */
54
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
55
case 4:
56
/* stage 1+2 NonSecure PL1: ATS12NSOPR, ATS12NSOPW */
57
mmu_idx = ARMMMUIdx_E10_1;
58
+ secure = false;
59
break;
60
case 6:
61
/* stage 1+2 NonSecure PL0: ATS12NSOUR, ATS12NSOUW */
62
mmu_idx = ARMMMUIdx_E10_0;
63
+ secure = false;
64
break;
65
default:
66
g_assert_not_reached();
67
}
50
}
68
51
69
- par64 = do_ats_write(env, value, access_type, mmu_idx);
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
70
+ par64 = do_ats_write(env, value, access_type, mmu_idx, secure);
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
71
54
+
72
A32_BANKED_CURRENT_REG_SET(env, par, par64);
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
73
#else
56
(counter < hpmn || counter == 31)) {
74
@@ -XXX,XX +XXX,XX @@ static void ats1h_write(CPUARMState *env, const ARMCPRegInfo *ri,
57
e = env->cp15.c9_pmcr & PMCRE;
75
MMUAccessType access_type = ri->opc2 & 1 ? MMU_DATA_STORE : MMU_DATA_LOAD;
76
uint64_t par64;
77
78
- par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2);
79
+ /* There is no SecureEL2 for AArch32. */
80
+ par64 = do_ats_write(env, value, access_type, ARMMMUIdx_E2, false);
81
82
A32_BANKED_CURRENT_REG_SET(env, par, par64);
83
#else
84
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
85
break;
86
case 6: /* AT S1E3R, AT S1E3W */
87
mmu_idx = ARMMMUIdx_SE3;
88
+ secure = true;
89
break;
90
default:
91
g_assert_not_reached();
92
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
93
g_assert_not_reached();
94
}
95
96
- env->cp15.par_el[1] = do_ats_write(env, value, access_type, mmu_idx);
97
+ env->cp15.par_el[1] = do_ats_write(env, value, access_type,
98
+ mmu_idx, secure);
99
#else
100
/* Handled by hardware accelerator. */
101
g_assert_not_reached();
102
--
58
--
103
2.25.1
59
2.34.1
60
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Nabih Estefan <nabihestefan@google.com>
2
2
3
For a-profile aarch64, which does not bank system registers, it takes
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
quite a lot of code to switch between security states. In the process,
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
5
registers such as TCR_EL{1,2} must be swapped, which in itself requires
6
the flushing of softmmu tlbs. Therefore it doesn't buy us anything to
7
separate tlbs by security state.
8
5
9
Retain the distinction between Stage2 and Stage2_S.
6
Change-Id: Iabd0fba14910c3f1e883c4a9521350f3db9ffab8
10
7
Signed-Off-By: Nabih Estefan <nabihestefan@google.com>
11
This will be important as we implement FEAT_RME, and do not wish to
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
12
add a third set of mmu indexes for Realm state.
9
Message-id: 20240208194759.2858582-2-nabihestefan@google.com
13
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
[PMM: commit message tweaks]
16
Message-id: 20221001162318.153420-11-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
13
---
19
target/arm/cpu-param.h | 2 +-
14
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
20
target/arm/cpu.h | 72 +++++++------------
15
tests/qtest/meson.build | 3 +-
21
target/arm/internals.h | 31 +-------
16
2 files changed, 4 insertions(+), 83 deletions(-)
22
target/arm/helper.c | 144 +++++++++++++------------------------
23
target/arm/ptw.c | 25 ++-----
24
target/arm/translate-a64.c | 8 ---
25
target/arm/translate.c | 6 +-
26
7 files changed, 85 insertions(+), 203 deletions(-)
27
17
28
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
29
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu-param.h
20
--- a/tests/qtest/npcm_gmac-test.c
31
+++ b/target/arm/cpu-param.h
21
+++ b/tests/qtest/npcm_gmac-test.c
32
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
33
# define TARGET_PAGE_BITS_MIN 10
23
const GMACModule *module;
34
#endif
24
} TestData;
35
25
36
-#define NB_MMU_MODES 15
26
-/* Values extracted from hw/arm/npcm8xx.c */
37
+#define NB_MMU_MODES 8
27
+/* Values extracted from hw/arm/npcm7xx.c */
38
28
static const GMACModule gmac_module_list[] = {
39
#endif
29
{
40
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
.irq = 14,
41
index XXXXXXX..XXXXXXX 100644
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
42
--- a/target/arm/cpu.h
32
.irq = 15,
43
+++ b/target/arm/cpu.h
33
.base_addr = 0xf0804000
44
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
34
},
45
* table over and over.
35
- {
46
* 6. we need separate EL1/EL2 mmu_idx for handling the Privileged Access
36
- .irq = 16,
47
* Never (PAN) bit within PSTATE.
37
- .base_addr = 0xf0806000
48
+ * 7. we fold together the secure and non-secure regimes for A-profile,
38
- },
49
+ * because there are no banked system registers for aarch64, so the
39
- {
50
+ * process of switching between secure and non-secure is
40
- .irq = 17,
51
+ * already heavyweight.
41
- .base_addr = 0xf0808000
52
*
42
- }
53
* This gives us the following list of cases:
43
};
54
*
44
55
- * NS EL0 EL1&0 stage 1+2 (aka NS PL0)
45
/* Returns the index of the GMAC module. */
56
- * NS EL1 EL1&0 stage 1+2 (aka NS PL1)
46
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
57
- * NS EL1 EL1&0 stage 1+2 +PAN
47
return qtest_readl(qts, mod->base_addr + regno);
58
- * NS EL0 EL2&0
48
}
59
- * NS EL2 EL2&0
49
60
- * NS EL2 EL2&0 +PAN
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
61
- * NS EL2 (aka NS PL2)
51
- NPCMRegister regno)
62
- * S EL0 EL1&0 (aka S PL0)
52
-{
63
- * S EL1 EL1&0 (not used if EL3 is 32 bit)
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
64
- * S EL1 EL1&0 +PAN
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
65
- * S EL3 (aka S PL1)
55
- uint32_t read_offset = regno & 0x1ff;
66
+ * EL0 EL1&0 stage 1+2 (aka NS PL0)
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
67
+ * EL1 EL1&0 stage 1+2 (aka NS PL1)
57
-}
68
+ * EL1 EL1&0 stage 1+2 +PAN
69
+ * EL0 EL2&0
70
+ * EL2 EL2&0
71
+ * EL2 EL2&0 +PAN
72
+ * EL2 (aka NS PL2)
73
+ * EL3 (aka S PL1)
74
*
75
- * for a total of 11 different mmu_idx.
76
+ * for a total of 8 different mmu_idx.
77
*
78
* R profile CPUs have an MPU, but can use the same set of MMU indexes
79
- * as A profile. They only need to distinguish NS EL0 and NS EL1 (and
80
- * NS EL2 if we ever model a Cortex-R52).
81
+ * as A profile. They only need to distinguish EL0 and EL1 (and
82
+ * EL2 if we ever model a Cortex-R52).
83
*
84
* M profile CPUs are rather different as they do not have a true MMU.
85
* They have the following different MMU indexes:
86
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
87
#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
88
#define ARM_MMU_IDX_M 0x40 /* M profile */
89
90
-/* Meanings of the bits for A profile mmu idx values */
91
-#define ARM_MMU_IDX_A_NS 0x8
92
-
58
-
93
/* Meanings of the bits for M profile mmu idx values */
59
/* Check that GMAC registers are reset to default value */
94
#define ARM_MMU_IDX_M_PRIV 0x1
60
static void test_init(gconstpointer test_data)
95
#define ARM_MMU_IDX_M_NEGPRI 0x2
61
{
96
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
62
const TestData *td = test_data;
97
/*
63
const GMACModule *mod = td->module;
98
* A-profile.
64
- QTestState *qts = qtest_init("-machine npcm845-evb");
99
*/
65
+ QTestState *qts = qtest_init("-machine npcm750-evb");
100
- ARMMMUIdx_SE10_0 = 0 | ARM_MMU_IDX_A,
66
101
- ARMMMUIdx_SE20_0 = 1 | ARM_MMU_IDX_A,
67
#define CHECK_REG32(regno, value) \
102
- ARMMMUIdx_SE10_1 = 2 | ARM_MMU_IDX_A,
68
do { \
103
- ARMMMUIdx_SE20_2 = 3 | ARM_MMU_IDX_A,
69
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
104
- ARMMMUIdx_SE10_1_PAN = 4 | ARM_MMU_IDX_A,
70
} while (0)
105
- ARMMMUIdx_SE20_2_PAN = 5 | ARM_MMU_IDX_A,
71
106
- ARMMMUIdx_SE2 = 6 | ARM_MMU_IDX_A,
72
-#define CHECK_REG_PCS(regno, value) \
107
- ARMMMUIdx_SE3 = 7 | ARM_MMU_IDX_A,
73
- do { \
74
- g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
75
- } while (0)
108
-
76
-
109
- ARMMMUIdx_E10_0 = ARMMMUIdx_SE10_0 | ARM_MMU_IDX_A_NS,
77
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
110
- ARMMMUIdx_E20_0 = ARMMMUIdx_SE20_0 | ARM_MMU_IDX_A_NS,
78
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
111
- ARMMMUIdx_E10_1 = ARMMMUIdx_SE10_1 | ARM_MMU_IDX_A_NS,
79
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
112
- ARMMMUIdx_E20_2 = ARMMMUIdx_SE20_2 | ARM_MMU_IDX_A_NS,
80
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
113
- ARMMMUIdx_E10_1_PAN = ARMMMUIdx_SE10_1_PAN | ARM_MMU_IDX_A_NS,
81
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
114
- ARMMMUIdx_E20_2_PAN = ARMMMUIdx_SE20_2_PAN | ARM_MMU_IDX_A_NS,
82
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
115
- ARMMMUIdx_E2 = ARMMMUIdx_SE2 | ARM_MMU_IDX_A_NS,
83
116
+ ARMMMUIdx_E10_0 = 0 | ARM_MMU_IDX_A,
84
- /* TODO Add registers PCS */
117
+ ARMMMUIdx_E20_0 = 1 | ARM_MMU_IDX_A,
85
- if (mod->base_addr == 0xf0802000) {
118
+ ARMMMUIdx_E10_1 = 2 | ARM_MMU_IDX_A,
86
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
119
+ ARMMMUIdx_E20_2 = 3 | ARM_MMU_IDX_A,
87
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
120
+ ARMMMUIdx_E10_1_PAN = 4 | ARM_MMU_IDX_A,
88
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
121
+ ARMMMUIdx_E20_2_PAN = 5 | ARM_MMU_IDX_A,
122
+ ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A,
123
+ ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A,
124
125
/*
126
* These are not allocated TLBs and are used only for AT system
127
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
128
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
129
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
130
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
131
- ARMMMUIdx_Stage1_SE0 = 3 | ARM_MMU_IDX_NOTLB,
132
- ARMMMUIdx_Stage1_SE1 = 4 | ARM_MMU_IDX_NOTLB,
133
- ARMMMUIdx_Stage1_SE1_PAN = 5 | ARM_MMU_IDX_NOTLB,
134
/*
135
* Not allocated a TLB: used only for second stage of an S12 page
136
* table walk, or for descriptor loads during first stage of an S1
137
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
138
* then various TLB flush insns which currently are no-ops or flush
139
* only stage 1 MMU indexes will need to change to flush stage 2.
140
*/
141
- ARMMMUIdx_Stage2 = 6 | ARM_MMU_IDX_NOTLB,
142
- ARMMMUIdx_Stage2_S = 7 | ARM_MMU_IDX_NOTLB,
143
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
144
+ ARMMMUIdx_Stage2_S = 4 | ARM_MMU_IDX_NOTLB,
145
146
/*
147
* M-profile.
148
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
149
TO_CORE_BIT(E2),
150
TO_CORE_BIT(E20_2),
151
TO_CORE_BIT(E20_2_PAN),
152
- TO_CORE_BIT(SE10_0),
153
- TO_CORE_BIT(SE20_0),
154
- TO_CORE_BIT(SE10_1),
155
- TO_CORE_BIT(SE20_2),
156
- TO_CORE_BIT(SE10_1_PAN),
157
- TO_CORE_BIT(SE20_2_PAN),
158
- TO_CORE_BIT(SE2),
159
- TO_CORE_BIT(SE3),
160
+ TO_CORE_BIT(E3),
161
162
TO_CORE_BIT(MUser),
163
TO_CORE_BIT(MPriv),
164
diff --git a/target/arm/internals.h b/target/arm/internals.h
165
index XXXXXXX..XXXXXXX 100644
166
--- a/target/arm/internals.h
167
+++ b/target/arm/internals.h
168
@@ -XXX,XX +XXX,XX @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
169
case ARMMMUIdx_Stage1_E0:
170
case ARMMMUIdx_Stage1_E1:
171
case ARMMMUIdx_Stage1_E1_PAN:
172
- case ARMMMUIdx_Stage1_SE0:
173
- case ARMMMUIdx_Stage1_SE1:
174
- case ARMMMUIdx_Stage1_SE1_PAN:
175
case ARMMMUIdx_E10_0:
176
case ARMMMUIdx_E10_1:
177
case ARMMMUIdx_E10_1_PAN:
178
case ARMMMUIdx_E20_0:
179
case ARMMMUIdx_E20_2:
180
case ARMMMUIdx_E20_2_PAN:
181
- case ARMMMUIdx_SE10_0:
182
- case ARMMMUIdx_SE10_1:
183
- case ARMMMUIdx_SE10_1_PAN:
184
- case ARMMMUIdx_SE20_0:
185
- case ARMMMUIdx_SE20_2:
186
- case ARMMMUIdx_SE20_2_PAN:
187
return true;
188
default:
189
return false;
190
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
191
{
192
switch (mmu_idx) {
193
case ARMMMUIdx_Stage1_E1_PAN:
194
- case ARMMMUIdx_Stage1_SE1_PAN:
195
case ARMMMUIdx_E10_1_PAN:
196
case ARMMMUIdx_E20_2_PAN:
197
- case ARMMMUIdx_SE10_1_PAN:
198
- case ARMMMUIdx_SE20_2_PAN:
199
return true;
200
default:
201
return false;
202
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
203
static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
204
{
205
switch (mmu_idx) {
206
- case ARMMMUIdx_SE20_0:
207
- case ARMMMUIdx_SE20_2:
208
- case ARMMMUIdx_SE20_2_PAN:
209
case ARMMMUIdx_E20_0:
210
case ARMMMUIdx_E20_2:
211
case ARMMMUIdx_E20_2_PAN:
212
case ARMMMUIdx_Stage2:
213
case ARMMMUIdx_Stage2_S:
214
- case ARMMMUIdx_SE2:
215
case ARMMMUIdx_E2:
216
return 2;
217
- case ARMMMUIdx_SE3:
218
+ case ARMMMUIdx_E3:
219
return 3;
220
- case ARMMMUIdx_SE10_0:
221
- case ARMMMUIdx_Stage1_SE0:
222
- return arm_el_is_aa64(env, 3) ? 1 : 3;
223
- case ARMMMUIdx_SE10_1:
224
- case ARMMMUIdx_SE10_1_PAN:
225
+ case ARMMMUIdx_E10_0:
226
case ARMMMUIdx_Stage1_E0:
227
+ return arm_el_is_aa64(env, 3) || !arm_is_secure_below_el3(env) ? 1 : 3;
228
case ARMMMUIdx_Stage1_E1:
229
case ARMMMUIdx_Stage1_E1_PAN:
230
- case ARMMMUIdx_Stage1_SE1:
231
- case ARMMMUIdx_Stage1_SE1_PAN:
232
- case ARMMMUIdx_E10_0:
233
case ARMMMUIdx_E10_1:
234
case ARMMMUIdx_E10_1_PAN:
235
case ARMMMUIdx_MPrivNegPri:
236
@@ -XXX,XX +XXX,XX @@ static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx mmu_idx)
237
case ARMMMUIdx_Stage1_E0:
238
case ARMMMUIdx_Stage1_E1:
239
case ARMMMUIdx_Stage1_E1_PAN:
240
- case ARMMMUIdx_Stage1_SE0:
241
- case ARMMMUIdx_Stage1_SE1:
242
- case ARMMMUIdx_Stage1_SE1_PAN:
243
return true;
244
default:
245
return false;
246
diff --git a/target/arm/helper.c b/target/arm/helper.c
247
index XXXXXXX..XXXXXXX 100644
248
--- a/target/arm/helper.c
249
+++ b/target/arm/helper.c
250
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
251
/* Begin with base v8.0 state. */
252
uint64_t valid_mask = 0x3fff;
253
ARMCPU *cpu = env_archcpu(env);
254
+ uint64_t changed;
255
256
/*
257
* Because SCR_EL3 is the "real" cpreg and SCR is the alias, reset always
258
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
259
260
/* Clear all-context RES0 bits. */
261
value &= valid_mask;
262
- raw_write(env, ri, value);
263
+ changed = env->cp15.scr_el3 ^ value;
264
+ env->cp15.scr_el3 = value;
265
+
266
+ /*
267
+ * If SCR_EL3.NS changes, i.e. arm_is_secure_below_el3, then
268
+ * we must invalidate all TLBs below EL3.
269
+ */
270
+ if (changed & SCR_NS) {
271
+ tlb_flush_by_mmuidx(env_cpu(env), (ARMMMUIdxBit_E10_0 |
272
+ ARMMMUIdxBit_E20_0 |
273
+ ARMMMUIdxBit_E10_1 |
274
+ ARMMMUIdxBit_E20_2 |
275
+ ARMMMUIdxBit_E10_1_PAN |
276
+ ARMMMUIdxBit_E20_2_PAN |
277
+ ARMMMUIdxBit_E2));
278
+ }
279
}
280
281
static void scr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
282
@@ -XXX,XX +XXX,XX @@ static int gt_phys_redir_timeridx(CPUARMState *env)
283
case ARMMMUIdx_E20_0:
284
case ARMMMUIdx_E20_2:
285
case ARMMMUIdx_E20_2_PAN:
286
- case ARMMMUIdx_SE20_0:
287
- case ARMMMUIdx_SE20_2:
288
- case ARMMMUIdx_SE20_2_PAN:
289
return GTIMER_HYP;
290
default:
291
return GTIMER_PHYS;
292
@@ -XXX,XX +XXX,XX @@ static int gt_virt_redir_timeridx(CPUARMState *env)
293
case ARMMMUIdx_E20_0:
294
case ARMMMUIdx_E20_2:
295
case ARMMMUIdx_E20_2_PAN:
296
- case ARMMMUIdx_SE20_0:
297
- case ARMMMUIdx_SE20_2:
298
- case ARMMMUIdx_SE20_2_PAN:
299
return GTIMER_HYPVIRT;
300
default:
301
return GTIMER_VIRT;
302
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
303
/* stage 1 current state PL1: ATS1CPR, ATS1CPW, ATS1CPRP, ATS1CPWP */
304
switch (el) {
305
case 3:
306
- mmu_idx = ARMMMUIdx_SE3;
307
+ mmu_idx = ARMMMUIdx_E3;
308
secure = true;
309
break;
310
case 2:
311
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
312
/* fall through */
313
case 1:
314
if (ri->crm == 9 && (env->uncached_cpsr & CPSR_PAN)) {
315
- mmu_idx = (secure ? ARMMMUIdx_Stage1_SE1_PAN
316
- : ARMMMUIdx_Stage1_E1_PAN);
317
+ mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
318
} else {
319
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE1 : ARMMMUIdx_Stage1_E1;
320
+ mmu_idx = ARMMMUIdx_Stage1_E1;
321
}
322
break;
323
default:
324
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
325
/* stage 1 current state PL0: ATS1CUR, ATS1CUW */
326
switch (el) {
327
case 3:
328
- mmu_idx = ARMMMUIdx_SE10_0;
329
+ mmu_idx = ARMMMUIdx_E10_0;
330
secure = true;
331
break;
332
case 2:
333
@@ -XXX,XX +XXX,XX @@ static void ats_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
334
mmu_idx = ARMMMUIdx_Stage1_E0;
335
break;
336
case 1:
337
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE0 : ARMMMUIdx_Stage1_E0;
338
+ mmu_idx = ARMMMUIdx_Stage1_E0;
339
break;
340
default:
341
g_assert_not_reached();
342
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
343
switch (ri->opc1) {
344
case 0: /* AT S1E1R, AT S1E1W, AT S1E1RP, AT S1E1WP */
345
if (ri->crm == 9 && (env->pstate & PSTATE_PAN)) {
346
- mmu_idx = (secure ? ARMMMUIdx_Stage1_SE1_PAN
347
- : ARMMMUIdx_Stage1_E1_PAN);
348
+ mmu_idx = ARMMMUIdx_Stage1_E1_PAN;
349
} else {
350
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE1 : ARMMMUIdx_Stage1_E1;
351
+ mmu_idx = ARMMMUIdx_Stage1_E1;
352
}
353
break;
354
case 4: /* AT S1E2R, AT S1E2W */
355
- mmu_idx = secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2;
356
+ mmu_idx = ARMMMUIdx_E2;
357
break;
358
case 6: /* AT S1E3R, AT S1E3W */
359
- mmu_idx = ARMMMUIdx_SE3;
360
+ mmu_idx = ARMMMUIdx_E3;
361
secure = true;
362
break;
363
default:
364
@@ -XXX,XX +XXX,XX @@ static void ats_write64(CPUARMState *env, const ARMCPRegInfo *ri,
365
}
366
break;
367
case 2: /* AT S1E0R, AT S1E0W */
368
- mmu_idx = secure ? ARMMMUIdx_Stage1_SE0 : ARMMMUIdx_Stage1_E0;
369
+ mmu_idx = ARMMMUIdx_Stage1_E0;
370
break;
371
case 4: /* AT S12E1R, AT S12E1W */
372
- mmu_idx = secure ? ARMMMUIdx_SE10_1 : ARMMMUIdx_E10_1;
373
+ mmu_idx = ARMMMUIdx_E10_1;
374
break;
375
case 6: /* AT S12E0R, AT S12E0W */
376
- mmu_idx = secure ? ARMMMUIdx_SE10_0 : ARMMMUIdx_E10_0;
377
+ mmu_idx = ARMMMUIdx_E10_0;
378
break;
379
default:
380
g_assert_not_reached();
381
@@ -XXX,XX +XXX,XX @@ static void vmsa_tcr_ttbr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
382
uint16_t mask = ARMMMUIdxBit_E20_2 |
383
ARMMMUIdxBit_E20_2_PAN |
384
ARMMMUIdxBit_E20_0;
385
-
89
-
386
- if (arm_is_secure_below_el3(env)) {
90
- CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
387
- mask >>= ARM_MMU_IDX_A_NS;
91
- CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
388
- }
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);
389
-
98
-
390
tlb_flush_by_mmuidx(env_cpu(env), mask);
99
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
391
}
100
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
392
raw_write(env, ri, value);
101
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
393
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
102
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
394
uint16_t mask = ARMMMUIdxBit_E10_1 |
103
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
395
ARMMMUIdxBit_E10_1_PAN |
104
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
396
ARMMMUIdxBit_E10_0;
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);
397
-
108
-
398
- if (arm_is_secure_below_el3(env)) {
109
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
399
- mask >>= ARM_MMU_IDX_A_NS;
110
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
400
- }
111
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
401
-
112
- CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
402
tlb_flush_by_mmuidx(cs, mask);
113
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
403
raw_write(env, ri, value);
114
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
404
}
115
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_TXTIMER, 0);
405
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbmask(CPUARMState *env)
116
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_RXTIMER, 0);
406
ARMMMUIdxBit_E10_1_PAN |
117
- CHECK_REG_PCS(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0);
407
ARMMMUIdxBit_E10_0;
118
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL1, 0);
408
}
119
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_STS, 0x0010);
409
-
120
- CHECK_REG_PCS(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0);
410
- if (arm_is_secure_below_el3(env)) {
121
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MISC_STS, 0);
411
- mask >>= ARM_MMU_IDX_A_NS;
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);
412
- }
140
- }
413
-
141
-
414
return mask;
142
qtest_quit(qts);
415
}
143
}
416
144
417
@@ -XXX,XX +XXX,XX @@ static int vae1_tlbbits(CPUARMState *env, uint64_t addr)
145
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
418
mmu_idx = ARMMMUIdx_E10_0;
419
}
420
421
- if (arm_is_secure_below_el3(env)) {
422
- mmu_idx &= ~ARM_MMU_IDX_A_NS;
423
- }
424
-
425
return tlbbits_for_regime(env, mmu_idx, addr);
426
}
427
428
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
429
* stage 2 translations, whereas most other scopes only invalidate
430
* stage 1 translations.
431
*/
432
- if (arm_is_secure_below_el3(env)) {
433
- return ARMMMUIdxBit_SE10_1 |
434
- ARMMMUIdxBit_SE10_1_PAN |
435
- ARMMMUIdxBit_SE10_0;
436
- } else {
437
- return ARMMMUIdxBit_E10_1 |
438
- ARMMMUIdxBit_E10_1_PAN |
439
- ARMMMUIdxBit_E10_0;
440
- }
441
+ return (ARMMMUIdxBit_E10_1 |
442
+ ARMMMUIdxBit_E10_1_PAN |
443
+ ARMMMUIdxBit_E10_0);
444
}
445
446
static int e2_tlbmask(CPUARMState *env)
447
{
448
- if (arm_is_secure_below_el3(env)) {
449
- return ARMMMUIdxBit_SE20_0 |
450
- ARMMMUIdxBit_SE20_2 |
451
- ARMMMUIdxBit_SE20_2_PAN |
452
- ARMMMUIdxBit_SE2;
453
- } else {
454
- return ARMMMUIdxBit_E20_0 |
455
- ARMMMUIdxBit_E20_2 |
456
- ARMMMUIdxBit_E20_2_PAN |
457
- ARMMMUIdxBit_E2;
458
- }
459
+ return (ARMMMUIdxBit_E20_0 |
460
+ ARMMMUIdxBit_E20_2 |
461
+ ARMMMUIdxBit_E20_2_PAN |
462
+ ARMMMUIdxBit_E2);
463
}
464
465
static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
466
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri,
467
ARMCPU *cpu = env_archcpu(env);
468
CPUState *cs = CPU(cpu);
469
470
- tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_SE3);
471
+ tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_E3);
472
}
473
474
static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
475
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
476
{
477
CPUState *cs = env_cpu(env);
478
479
- tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_SE3);
480
+ tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_E3);
481
}
482
483
static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
484
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
485
CPUState *cs = CPU(cpu);
486
uint64_t pageaddr = sextract64(value << 12, 0, 56);
487
488
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_SE3);
489
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_E3);
490
}
491
492
static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
493
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
494
{
495
CPUState *cs = env_cpu(env);
496
uint64_t pageaddr = sextract64(value << 12, 0, 56);
497
- bool secure = arm_is_secure_below_el3(env);
498
- int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
499
- int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2,
500
- pageaddr);
501
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_E2, pageaddr);
502
503
- tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
504
+ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
505
+ ARMMMUIdxBit_E2, bits);
506
}
507
508
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
509
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
510
{
511
CPUState *cs = env_cpu(env);
512
uint64_t pageaddr = sextract64(value << 12, 0, 56);
513
- int bits = tlbbits_for_regime(env, ARMMMUIdx_SE3, pageaddr);
514
+ int bits = tlbbits_for_regime(env, ARMMMUIdx_E3, pageaddr);
515
516
tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr,
517
- ARMMMUIdxBit_SE3, bits);
518
+ ARMMMUIdxBit_E3, bits);
519
}
520
521
#ifdef TARGET_AARCH64
522
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae1is_write(CPUARMState *env,
523
524
static int vae2_tlbmask(CPUARMState *env)
525
{
526
- return (arm_is_secure_below_el3(env)
527
- ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2);
528
+ return ARMMMUIdxBit_E2;
529
}
530
531
static void tlbi_aa64_rvae2_write(CPUARMState *env,
532
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae3_write(CPUARMState *env,
533
* flush-last-level-only.
534
*/
535
536
- do_rvae_write(env, value, ARMMMUIdxBit_SE3,
537
- tlb_force_broadcast(env));
538
+ do_rvae_write(env, value, ARMMMUIdxBit_E3, tlb_force_broadcast(env));
539
}
540
541
static void tlbi_aa64_rvae3is_write(CPUARMState *env,
542
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae3is_write(CPUARMState *env,
543
* flush-last-level-only or inner/outer specific flushes.
544
*/
545
546
- do_rvae_write(env, value, ARMMMUIdxBit_SE3, true);
547
+ do_rvae_write(env, value, ARMMMUIdxBit_E3, true);
548
}
549
#endif
550
551
@@ -XXX,XX +XXX,XX @@ uint64_t arm_sctlr(CPUARMState *env, int el)
552
/* Only EL0 needs to be adjusted for EL1&0 or EL2&0. */
553
if (el == 0) {
554
ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, 0);
555
- el = (mmu_idx == ARMMMUIdx_E20_0 || mmu_idx == ARMMMUIdx_SE20_0)
556
- ? 2 : 1;
557
+ el = mmu_idx == ARMMMUIdx_E20_0 ? 2 : 1;
558
}
559
return env->cp15.sctlr_el[el];
560
}
561
@@ -XXX,XX +XXX,XX @@ int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
562
switch (mmu_idx) {
563
case ARMMMUIdx_E10_0:
564
case ARMMMUIdx_E20_0:
565
- case ARMMMUIdx_SE10_0:
566
- case ARMMMUIdx_SE20_0:
567
return 0;
568
case ARMMMUIdx_E10_1:
569
case ARMMMUIdx_E10_1_PAN:
570
- case ARMMMUIdx_SE10_1:
571
- case ARMMMUIdx_SE10_1_PAN:
572
return 1;
573
case ARMMMUIdx_E2:
574
case ARMMMUIdx_E20_2:
575
case ARMMMUIdx_E20_2_PAN:
576
- case ARMMMUIdx_SE2:
577
- case ARMMMUIdx_SE20_2:
578
- case ARMMMUIdx_SE20_2_PAN:
579
return 2;
580
- case ARMMMUIdx_SE3:
581
+ case ARMMMUIdx_E3:
582
return 3;
583
default:
584
g_assert_not_reached();
585
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_mmu_idx_el(CPUARMState *env, int el)
586
}
587
break;
588
case 3:
589
- return ARMMMUIdx_SE3;
590
+ return ARMMMUIdx_E3;
591
default:
592
g_assert_not_reached();
593
}
594
595
- if (arm_is_secure_below_el3(env)) {
596
- idx &= ~ARM_MMU_IDX_A_NS;
597
- }
598
-
599
return idx;
600
}
601
602
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
603
switch (mmu_idx) {
604
case ARMMMUIdx_E10_1:
605
case ARMMMUIdx_E10_1_PAN:
606
- case ARMMMUIdx_SE10_1:
607
- case ARMMMUIdx_SE10_1_PAN:
608
/* TODO: ARMv8.3-NV */
609
DP_TBFLAG_A64(flags, UNPRIV, 1);
610
break;
611
case ARMMMUIdx_E20_2:
612
case ARMMMUIdx_E20_2_PAN:
613
- case ARMMMUIdx_SE20_2:
614
- case ARMMMUIdx_SE20_2_PAN:
615
/*
616
* Note that EL20_2 is gated by HCR_EL2.E2H == 1, but EL20_0 is
617
* gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
618
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
619
index XXXXXXX..XXXXXXX 100644
146
index XXXXXXX..XXXXXXX 100644
620
--- a/target/arm/ptw.c
147
--- a/tests/qtest/meson.build
621
+++ b/target/arm/ptw.c
148
+++ b/tests/qtest/meson.build
622
@@ -XXX,XX +XXX,XX @@ unsigned int arm_pamax(ARMCPU *cpu)
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
623
ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
150
'npcm7xx_sdhci-test',
624
{
151
'npcm7xx_smbus-test',
625
switch (mmu_idx) {
152
'npcm7xx_timer-test',
626
- case ARMMMUIdx_SE10_0:
153
- 'npcm7xx_watchdog_timer-test'] + \
627
- return ARMMMUIdx_Stage1_SE0;
154
+ 'npcm7xx_watchdog_timer-test',
628
- case ARMMMUIdx_SE10_1:
155
+ 'npcm_gmac-test'] + \
629
- return ARMMMUIdx_Stage1_SE1;
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
630
- case ARMMMUIdx_SE10_1_PAN:
157
qtests_aspeed = \
631
- return ARMMMUIdx_Stage1_SE1_PAN;
158
['aspeed_hace-test',
632
case ARMMMUIdx_E10_0:
633
return ARMMMUIdx_Stage1_E0;
634
case ARMMMUIdx_E10_1:
635
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx)
636
static bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
637
{
638
switch (mmu_idx) {
639
- case ARMMMUIdx_SE10_0:
640
case ARMMMUIdx_E20_0:
641
- case ARMMMUIdx_SE20_0:
642
case ARMMMUIdx_Stage1_E0:
643
- case ARMMMUIdx_Stage1_SE0:
644
case ARMMMUIdx_MUser:
645
case ARMMMUIdx_MSUser:
646
case ARMMMUIdx_MUserNegPri:
647
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
648
649
s2_mmu_idx = (s2walk_secure
650
? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2);
651
- is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
652
+ is_el0 = mmu_idx == ARMMMUIdx_E10_0;
653
654
/*
655
* S1 is done, now do S2 translation.
656
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
657
case ARMMMUIdx_Stage1_E1:
658
case ARMMMUIdx_Stage1_E1_PAN:
659
case ARMMMUIdx_E2:
660
+ is_secure = arm_is_secure_below_el3(env);
661
+ break;
662
case ARMMMUIdx_Stage2:
663
case ARMMMUIdx_MPrivNegPri:
664
case ARMMMUIdx_MUserNegPri:
665
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
666
case ARMMMUIdx_MUser:
667
is_secure = false;
668
break;
669
- case ARMMMUIdx_SE3:
670
- case ARMMMUIdx_SE10_0:
671
- case ARMMMUIdx_SE10_1:
672
- case ARMMMUIdx_SE10_1_PAN:
673
- case ARMMMUIdx_SE20_0:
674
- case ARMMMUIdx_SE20_2:
675
- case ARMMMUIdx_SE20_2_PAN:
676
- case ARMMMUIdx_Stage1_SE0:
677
- case ARMMMUIdx_Stage1_SE1:
678
- case ARMMMUIdx_Stage1_SE1_PAN:
679
- case ARMMMUIdx_SE2:
680
+ case ARMMMUIdx_E3:
681
case ARMMMUIdx_Stage2_S:
682
case ARMMMUIdx_MSPrivNegPri:
683
case ARMMMUIdx_MSUserNegPri:
684
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
685
index XXXXXXX..XXXXXXX 100644
686
--- a/target/arm/translate-a64.c
687
+++ b/target/arm/translate-a64.c
688
@@ -XXX,XX +XXX,XX @@ static int get_a64_user_mem_index(DisasContext *s)
689
case ARMMMUIdx_E20_2_PAN:
690
useridx = ARMMMUIdx_E20_0;
691
break;
692
- case ARMMMUIdx_SE10_1:
693
- case ARMMMUIdx_SE10_1_PAN:
694
- useridx = ARMMMUIdx_SE10_0;
695
- break;
696
- case ARMMMUIdx_SE20_2:
697
- case ARMMMUIdx_SE20_2_PAN:
698
- useridx = ARMMMUIdx_SE20_0;
699
- break;
700
default:
701
g_assert_not_reached();
702
}
703
diff --git a/target/arm/translate.c b/target/arm/translate.c
704
index XXXXXXX..XXXXXXX 100644
705
--- a/target/arm/translate.c
706
+++ b/target/arm/translate.c
707
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
708
* otherwise, access as if at PL0.
709
*/
710
switch (s->mmu_idx) {
711
+ case ARMMMUIdx_E3:
712
case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
713
case ARMMMUIdx_E10_0:
714
case ARMMMUIdx_E10_1:
715
case ARMMMUIdx_E10_1_PAN:
716
return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
717
- case ARMMMUIdx_SE3:
718
- case ARMMMUIdx_SE10_0:
719
- case ARMMMUIdx_SE10_1:
720
- case ARMMMUIdx_SE10_1_PAN:
721
- return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
722
case ARMMMUIdx_MUser:
723
case ARMMMUIdx_MPriv:
724
return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
725
--
159
--
726
2.25.1
160
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
Do not apply memattr or shareability for Stage2 translations.
3
An access fault is raised when the Access Flag is not set in the
4
Make sure to apply HCR_{DC,DCT} only to Regime_EL10, per the
4
looked-up PTE and the AFFD field is not set in the corresponding context
5
pseudocode in AArch64.S1DisabledOutput.
5
descriptor. This was already implemented for stage 2. Implement it for
6
stage 1 as well.
6
7
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
9
Message-id: 20221001162318.153420-20-richard.henderson@linaro.org
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]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
target/arm/ptw.c | 48 +++++++++++++++++++++++++-----------------------
16
hw/arm/smmuv3-internal.h | 1 +
13
1 file changed, 25 insertions(+), 23 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(+)
14
21
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/ptw.c
24
--- a/hw/arm/smmuv3-internal.h
18
+++ b/target/arm/ptw.c
25
+++ b/hw/arm/smmuv3-internal.h
19
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
20
GetPhysAddrResult *result,
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
21
ARMMMUFaultInfo *fi)
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
22
{
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
23
- uint64_t hcr;
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
24
- uint8_t memattr;
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
25
+ uint8_t memattr = 0x00; /* Device nGnRnE */
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
26
+ uint8_t shareability = 0; /* non-sharable */
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
27
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
28
if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
35
index XXXXXXX..XXXXXXX 100644
29
int r_el = regime_el(env, mmu_idx);
36
--- a/include/hw/arm/smmu-common.h
30
+
37
+++ b/include/hw/arm/smmu-common.h
31
if (arm_el_is_aa64(env, r_el)) {
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
32
int pamax = arm_pamax(env_archcpu(env));
39
bool disabled; /* smmu is disabled */
33
uint64_t tcr = env->cp15.tcr_el[r_el];
40
bool bypassed; /* translation is bypassed */
34
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
41
bool aborted; /* translation is aborted */
35
*/
42
+ bool affd; /* AF fault disable */
36
address = extract64(address, 0, 52);
43
uint32_t iotlb_hits; /* counts IOTLB hits */
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
45
/* Used by stage-1 only. */
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/smmu-common.c
49
+++ b/hw/arm/smmu-common.c
50
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
51
pte_addr, pte, iova, gpa,
52
block_size >> 20);
37
}
53
}
38
+
54
+
39
+ /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
55
+ /*
40
+ if (r_el == 1) {
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
41
+ uint64_t hcr = arm_hcr_el2_eff_secstate(env, is_secure);
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
42
+ if (hcr & HCR_DC) {
58
+ * An Access flag fault takes priority over a Permission fault.
43
+ if (hcr & HCR_DCT) {
59
+ */
44
+ memattr = 0xf0; /* Tagged, Normal, WB, RWA */
60
+ if (!PTE_AF(pte) && !cfg->affd) {
45
+ } else {
61
+ info->type = SMMU_PTW_ERR_ACCESS;
46
+ memattr = 0xff; /* Normal, WB, RWA */
62
+ goto error;
47
+ }
48
+ }
49
+ }
63
+ }
50
+ if (memattr == 0 && access_type == MMU_INST_FETCH) {
64
+
51
+ if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
65
ap = PTE_AP(pte);
52
+ memattr = 0xee; /* Normal, WT, RA, NT */
66
if (is_permission_fault(ap, perm)) {
53
+ } else {
67
info->type = SMMU_PTW_ERR_PERMISSION;
54
+ memattr = 0x44; /* Normal, NC, No */
68
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
55
+ }
69
index XXXXXXX..XXXXXXX 100644
56
+ shareability = 2; /* outer sharable */
70
--- a/hw/arm/smmuv3.c
57
+ }
71
+++ b/hw/arm/smmuv3.c
58
+ result->cacheattrs.is_s2_format = false;
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
59
}
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
60
74
cfg->tbi = CD_TBI(cd);
61
result->phys = address;
75
cfg->asid = CD_ASID(cd);
62
result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
76
+ cfg->affd = CD_AFFD(cd);
63
result->page_size = TARGET_PAGE_SIZE;
77
64
-
78
trace_smmuv3_decode_cd(cfg->oas);
65
- /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
79
66
- hcr = arm_hcr_el2_eff_secstate(env, is_secure);
67
- result->cacheattrs.shareability = 0;
68
- result->cacheattrs.is_s2_format = false;
69
- if (hcr & HCR_DC) {
70
- if (hcr & HCR_DCT) {
71
- memattr = 0xf0; /* Tagged, Normal, WB, RWA */
72
- } else {
73
- memattr = 0xff; /* Normal, WB, RWA */
74
- }
75
- } else if (access_type == MMU_INST_FETCH) {
76
- if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
77
- memattr = 0xee; /* Normal, WT, RA, NT */
78
- } else {
79
- memattr = 0x44; /* Normal, NC, No */
80
- }
81
- result->cacheattrs.shareability = 2; /* outer sharable */
82
- } else {
83
- memattr = 0x00; /* Device, nGnRnE */
84
- }
85
+ result->cacheattrs.shareability = shareability;
86
result->cacheattrs.attrs = memattr;
87
return 0;
88
}
89
--
80
--
90
2.25.1
81
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Remove the use of regime_is_secure from regime_translation_disabled,
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
using the new parameter instead.
5
6
This fixes a bug in S1_ptw_translate and get_phys_addr where we had
7
passed ARMMMUIdx_Stage2 and not ARMMMUIdx_Stage2_S to determine if
8
Stage2 is disabled, affecting FEAT_SEL2.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20221001162318.153420-5-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
7
---
16
target/arm/ptw.c | 20 +++++++++++---------
8
hw/arm/stellaris.c | 6 ++++--
17
1 file changed, 11 insertions(+), 9 deletions(-)
9
1 file changed, 4 insertions(+), 2 deletions(-)
18
10
19
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/ptw.c
13
--- a/hw/arm/stellaris.c
22
+++ b/target/arm/ptw.c
14
+++ b/hw/arm/stellaris.c
23
@@ -XXX,XX +XXX,XX @@ static uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx, int ttbrn)
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
16
}
24
}
17
}
25
18
26
/* Return true if the specified stage of address translation is disabled */
19
-static void stellaris_adc_reset(StellarisADCState *s)
27
-static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx)
20
+static void stellaris_adc_reset_hold(Object *obj)
28
+static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
29
+ bool is_secure)
30
{
21
{
31
uint64_t hcr_el2;
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
32
23
int n;
33
if (arm_feature(env, ARM_FEATURE_M)) {
24
34
- switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] &
25
for (n = 0; n < 4; n++) {
35
+ switch (env->v7m.mpu_ctrl[is_secure] &
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
36
(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
37
case R_V7M_MPU_CTRL_ENABLE_MASK:
28
"adc", 0x1000);
38
/* Enabled, but not for HardFault and NMI */
29
sysbus_init_mmio(sbd, &s->iomem);
39
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx)
30
- stellaris_adc_reset(s);
40
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
41
if (hcr_el2 & HCR_TGE) {
32
}
42
/* TGE means that NS EL0/1 act as if SCTLR_EL1.M is zero */
33
43
- if (!regime_is_secure(env, mmu_idx) && regime_el(env, mmu_idx) == 1) {
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
44
+ if (!is_secure && regime_el(env, mmu_idx) == 1) {
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
45
return true;
36
{
46
}
37
DeviceClass *dc = DEVICE_CLASS(klass);
47
}
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
48
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
39
49
ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
40
+ rc->phases.hold = stellaris_adc_reset_hold;
50
41
dc->vmsd = &vmstate_stellaris_adc;
51
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
42
}
52
- !regime_translation_disabled(env, s2_mmu_idx)) {
53
+ !regime_translation_disabled(env, s2_mmu_idx, *is_secure)) {
54
GetPhysAddrResult s2 = {};
55
int ret;
56
57
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
58
uint32_t base;
59
bool is_user = regime_is_user(env, mmu_idx);
60
61
- if (regime_translation_disabled(env, mmu_idx)) {
62
+ if (regime_translation_disabled(env, mmu_idx, is_secure)) {
63
/* MPU disabled. */
64
result->phys = address;
65
result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
66
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
67
result->page_size = TARGET_PAGE_SIZE;
68
result->prot = 0;
69
70
- if (regime_translation_disabled(env, mmu_idx) ||
71
+ if (regime_translation_disabled(env, mmu_idx, secure) ||
72
m_is_ppb_region(env, address)) {
73
/*
74
* MPU disabled or M profile PPB access: use default memory map.
75
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
76
* are done in arm_v7m_load_vector(), which always does a direct
77
* read using address_space_ldl(), rather than going via this function.
78
*/
79
- if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */
80
+ if (regime_translation_disabled(env, mmu_idx, secure)) { /* MPU disabled */
81
hit = true;
82
} else if (m_is_ppb_region(env, address)) {
83
hit = true;
84
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
85
result, fi);
86
87
/* If S1 fails or S2 is disabled, return early. */
88
- if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
89
+ if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2,
90
+ is_secure)) {
91
return ret;
92
}
93
94
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
95
96
/* Definitely a real MMU, not an MPU */
97
98
- if (regime_translation_disabled(env, mmu_idx)) {
99
+ if (regime_translation_disabled(env, mmu_idx, is_secure)) {
100
uint64_t hcr;
101
uint8_t memattr;
102
43
103
--
44
--
104
2.25.1
45
2.34.1
105
46
106
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Adjust GetPhysAddrResult to fill in CPUTLBEntryFull,
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
4
so that it may be passed directly to tlb_set_page_full.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
6
The change is large, but mostly mechanical. The major
7
non-mechanical change is page_size -> lg_page_size.
8
Most of the time this is obvious, and is related to
9
TARGET_PAGE_BITS.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20221001162318.153420-21-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
8
---
16
target/arm/internals.h | 5 +-
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
17
target/arm/helper.c | 12 +--
10
1 file changed, 22 insertions(+), 4 deletions(-)
18
target/arm/m_helper.c | 20 ++---
19
target/arm/ptw.c | 179 ++++++++++++++++++++--------------------
20
target/arm/tlb_helper.c | 9 +-
21
5 files changed, 111 insertions(+), 114 deletions(-)
22
11
23
diff --git a/target/arm/internals.h b/target/arm/internals.h
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
24
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/internals.h
14
--- a/hw/arm/stellaris.c
26
+++ b/target/arm/internals.h
15
+++ b/hw/arm/stellaris.c
27
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCacheAttrs {
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
28
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
29
/* Fields that are valid upon success. */
30
typedef struct GetPhysAddrResult {
31
- hwaddr phys;
32
- target_ulong page_size;
33
- int prot;
34
- MemTxAttrs attrs;
35
+ CPUTLBEntryFull f;
36
ARMCacheAttrs cacheattrs;
37
} GetPhysAddrResult;
38
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
44
/* Create a 64-bit PAR */
45
par64 = (1 << 11); /* LPAE bit always set */
46
if (!ret) {
47
- par64 |= res.phys & ~0xfffULL;
48
- if (!res.attrs.secure) {
49
+ par64 |= res.f.phys_addr & ~0xfffULL;
50
+ if (!res.f.attrs.secure) {
51
par64 |= (1 << 9); /* NS */
52
}
53
par64 |= (uint64_t)res.cacheattrs.attrs << 56; /* ATTR */
54
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
55
*/
56
if (!ret) {
57
/* We do not set any attribute bits in the PAR */
58
- if (res.page_size == (1 << 24)
59
+ if (res.f.lg_page_size == 24
60
&& arm_feature(env, ARM_FEATURE_V7)) {
61
- par64 = (res.phys & 0xff000000) | (1 << 1);
62
+ par64 = (res.f.phys_addr & 0xff000000) | (1 << 1);
63
} else {
64
- par64 = res.phys & 0xfffff000;
65
+ par64 = res.f.phys_addr & 0xfffff000;
66
}
67
- if (!res.attrs.secure) {
68
+ if (!res.f.attrs.secure) {
69
par64 |= (1 << 9); /* NS */
70
}
71
} else {
72
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/m_helper.c
75
+++ b/target/arm/m_helper.c
76
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
77
}
78
goto pend_fault;
79
}
80
- address_space_stl_le(arm_addressspace(cs, res.attrs), res.phys, value,
81
- res.attrs, &txres);
82
+ address_space_stl_le(arm_addressspace(cs, res.f.attrs), res.f.phys_addr,
83
+ value, res.f.attrs, &txres);
84
if (txres != MEMTX_OK) {
85
/* BusFault trying to write the data */
86
if (mode == STACK_LAZYFP) {
87
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
88
goto pend_fault;
89
}
90
91
- value = address_space_ldl(arm_addressspace(cs, res.attrs), res.phys,
92
- res.attrs, &txres);
93
+ value = address_space_ldl(arm_addressspace(cs, res.f.attrs),
94
+ res.f.phys_addr, res.f.attrs, &txres);
95
if (txres != MEMTX_OK) {
96
/* BusFault trying to read the data */
97
qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
98
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx, bool secure,
99
qemu_log_mask(CPU_LOG_INT, "...really MemManage with CFSR.IACCVIOL\n");
100
return false;
101
}
102
- *insn = address_space_lduw_le(arm_addressspace(cs, res.attrs), res.phys,
103
- res.attrs, &txres);
104
+ *insn = address_space_lduw_le(arm_addressspace(cs, res.f.attrs),
105
+ res.f.phys_addr, res.f.attrs, &txres);
106
if (txres != MEMTX_OK) {
107
env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_IBUSERR_MASK;
108
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
109
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx,
110
}
111
return false;
112
}
113
- value = address_space_ldl(arm_addressspace(cs, res.attrs), res.phys,
114
- res.attrs, &txres);
115
+ value = address_space_ldl(arm_addressspace(cs, res.f.attrs),
116
+ res.f.phys_addr, res.f.attrs, &txres);
117
if (txres != MEMTX_OK) {
118
/* BusFault trying to read the data */
119
qemu_log_mask(CPU_LOG_INT,
120
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
121
} else {
122
mrvalid = true;
123
}
124
- r = res.prot & PAGE_READ;
125
- rw = res.prot & PAGE_WRITE;
126
+ r = res.f.prot & PAGE_READ;
127
+ rw = res.f.prot & PAGE_WRITE;
128
} else {
129
r = false;
130
rw = false;
131
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/ptw.c
134
+++ b/target/arm/ptw.c
135
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
136
assert(!is_secure);
137
}
138
139
- addr = s2.phys;
140
+ addr = s2.f.phys_addr;
141
}
142
return addr;
143
}
18
}
144
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
19
145
/* 1Mb section. */
20
-/* I2C controller. */
146
phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
21
+/*
147
ap = (desc >> 10) & 3;
22
+ * I2C controller.
148
- result->page_size = 1024 * 1024;
23
+ * ??? For now we only implement the master interface.
149
+ result->f.lg_page_size = 20; /* 1MB */
24
+ */
150
} else {
25
151
/* Lookup l2 entry. */
26
#define TYPE_STELLARIS_I2C "stellaris-i2c"
152
if (type == 1) {
27
OBJECT_DECLARE_SIMPLE_TYPE(stellaris_i2c_state, STELLARIS_I2C)
153
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
154
case 1: /* 64k page. */
29
stellaris_i2c_update(s);
155
phys_addr = (desc & 0xffff0000) | (address & 0xffff);
156
ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
157
- result->page_size = 0x10000;
158
+ result->f.lg_page_size = 16;
159
break;
160
case 2: /* 4k page. */
161
phys_addr = (desc & 0xfffff000) | (address & 0xfff);
162
ap = (desc >> (4 + ((address >> 9) & 6))) & 3;
163
- result->page_size = 0x1000;
164
+ result->f.lg_page_size = 12;
165
break;
166
case 3: /* 1k page, or ARMv6/XScale "extended small (4k) page" */
167
if (type == 1) {
168
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
169
if (arm_feature(env, ARM_FEATURE_XSCALE)
170
|| arm_feature(env, ARM_FEATURE_V6)) {
171
phys_addr = (desc & 0xfffff000) | (address & 0xfff);
172
- result->page_size = 0x1000;
173
+ result->f.lg_page_size = 12;
174
} else {
175
/*
176
* UNPREDICTABLE in ARMv5; we choose to take a
177
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
178
}
179
} else {
180
phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
181
- result->page_size = 0x400;
182
+ result->f.lg_page_size = 10;
183
}
184
ap = (desc >> 4) & 3;
185
break;
186
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
187
g_assert_not_reached();
188
}
189
}
190
- result->prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
191
- result->prot |= result->prot ? PAGE_EXEC : 0;
192
- if (!(result->prot & (1 << access_type))) {
193
+ result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
194
+ result->f.prot |= result->f.prot ? PAGE_EXEC : 0;
195
+ if (!(result->f.prot & (1 << access_type))) {
196
/* Access permission fault. */
197
fi->type = ARMFault_Permission;
198
goto do_fault;
199
}
200
- result->phys = phys_addr;
201
+ result->f.phys_addr = phys_addr;
202
return false;
203
do_fault:
204
fi->domain = domain;
205
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
206
phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
207
phys_addr |= (uint64_t)extract32(desc, 20, 4) << 32;
208
phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36;
209
- result->page_size = 0x1000000;
210
+ result->f.lg_page_size = 24; /* 16MB */
211
} else {
212
/* Section. */
213
phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
214
- result->page_size = 0x100000;
215
+ result->f.lg_page_size = 20; /* 1MB */
216
}
217
ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
218
xn = desc & (1 << 4);
219
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
220
case 1: /* 64k page. */
221
phys_addr = (desc & 0xffff0000) | (address & 0xffff);
222
xn = desc & (1 << 15);
223
- result->page_size = 0x10000;
224
+ result->f.lg_page_size = 16;
225
break;
226
case 2: case 3: /* 4k page. */
227
phys_addr = (desc & 0xfffff000) | (address & 0xfff);
228
xn = desc & 1;
229
- result->page_size = 0x1000;
230
+ result->f.lg_page_size = 12;
231
break;
232
default:
233
/* Never happens, but compiler isn't smart enough to tell. */
234
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
235
}
236
}
237
if (domain_prot == 3) {
238
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
239
+ result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
240
} else {
241
if (pxn && !regime_is_user(env, mmu_idx)) {
242
xn = 1;
243
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
244
fi->type = ARMFault_AccessFlag;
245
goto do_fault;
246
}
247
- result->prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
248
+ result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
249
} else {
250
- result->prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
251
+ result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
252
}
253
- if (result->prot && !xn) {
254
- result->prot |= PAGE_EXEC;
255
+ if (result->f.prot && !xn) {
256
+ result->f.prot |= PAGE_EXEC;
257
}
258
- if (!(result->prot & (1 << access_type))) {
259
+ if (!(result->f.prot & (1 << access_type))) {
260
/* Access permission fault. */
261
fi->type = ARMFault_Permission;
262
goto do_fault;
263
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
264
* the CPU doesn't support TZ or this is a non-secure translation
265
* regime, because the attribute will already be non-secure.
266
*/
267
- result->attrs.secure = false;
268
+ result->f.attrs.secure = false;
269
}
270
- result->phys = phys_addr;
271
+ result->f.phys_addr = phys_addr;
272
return false;
273
do_fault:
274
fi->domain = domain;
275
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
276
if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
277
ns = mmu_idx == ARMMMUIdx_Stage2;
278
xn = extract32(attrs, 11, 2);
279
- result->prot = get_S2prot(env, ap, xn, s1_is_el0);
280
+ result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
281
} else {
282
ns = extract32(attrs, 3, 1);
283
xn = extract32(attrs, 12, 1);
284
pxn = extract32(attrs, 11, 1);
285
- result->prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
286
+ result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
287
}
288
289
fault_type = ARMFault_Permission;
290
- if (!(result->prot & (1 << access_type))) {
291
+ if (!(result->f.prot & (1 << access_type))) {
292
goto do_fault;
293
}
294
295
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
296
* the CPU doesn't support TZ or this is a non-secure translation
297
* regime, because the attribute will already be non-secure.
298
*/
299
- result->attrs.secure = false;
300
+ result->f.attrs.secure = false;
301
}
302
/* When in aarch64 mode, and BTI is enabled, remember GP in the IOTLB. */
303
if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) {
304
- arm_tlb_bti_gp(&result->attrs) = true;
305
+ arm_tlb_bti_gp(&result->f.attrs) = true;
306
}
307
308
if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
309
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
310
result->cacheattrs.shareability = extract32(attrs, 6, 2);
311
}
312
313
- result->phys = descaddr;
314
- result->page_size = page_size;
315
+ result->f.phys_addr = descaddr;
316
+ result->f.lg_page_size = ctz64(page_size);
317
return false;
318
319
do_fault:
320
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
321
322
if (regime_translation_disabled(env, mmu_idx, is_secure)) {
323
/* MPU disabled. */
324
- result->phys = address;
325
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
326
+ result->f.phys_addr = address;
327
+ result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
328
return false;
329
}
330
331
- result->phys = address;
332
+ result->f.phys_addr = address;
333
for (n = 7; n >= 0; n--) {
334
base = env->cp15.c6_region[n];
335
if ((base & 1) == 0) {
336
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
337
fi->level = 1;
338
return true;
339
}
340
- result->prot = PAGE_READ | PAGE_WRITE;
341
+ result->f.prot = PAGE_READ | PAGE_WRITE;
342
break;
343
case 2:
344
- result->prot = PAGE_READ;
345
+ result->f.prot = PAGE_READ;
346
if (!is_user) {
347
- result->prot |= PAGE_WRITE;
348
+ result->f.prot |= PAGE_WRITE;
349
}
350
break;
351
case 3:
352
- result->prot = PAGE_READ | PAGE_WRITE;
353
+ result->f.prot = PAGE_READ | PAGE_WRITE;
354
break;
355
case 5:
356
if (is_user) {
357
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
358
fi->level = 1;
359
return true;
360
}
361
- result->prot = PAGE_READ;
362
+ result->f.prot = PAGE_READ;
363
break;
364
case 6:
365
- result->prot = PAGE_READ;
366
+ result->f.prot = PAGE_READ;
367
break;
368
default:
369
/* Bad permission. */
370
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
371
fi->level = 1;
372
return true;
373
}
374
- result->prot |= PAGE_EXEC;
375
+ result->f.prot |= PAGE_EXEC;
376
return false;
377
}
30
}
378
31
379
static void get_phys_addr_pmsav7_default(CPUARMState *env, ARMMMUIdx mmu_idx,
32
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
380
- int32_t address, int *prot)
33
+static void stellaris_i2c_reset_enter(Object *obj, ResetType type)
381
+ int32_t address, uint8_t *prot)
382
{
34
{
383
if (!arm_feature(env, ARM_FEATURE_M)) {
35
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
384
*prot = PAGE_READ | PAGE_WRITE;
36
+
385
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
386
int n;
38
i2c_end_transfer(s->bus);
387
bool is_user = regime_is_user(env, mmu_idx);
39
+}
388
40
+
389
- result->phys = address;
41
+static void stellaris_i2c_reset_hold(Object *obj)
390
- result->page_size = TARGET_PAGE_SIZE;
42
+{
391
- result->prot = 0;
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
392
+ result->f.phys_addr = address;
44
393
+ result->f.lg_page_size = TARGET_PAGE_BITS;
45
s->msa = 0;
394
+ result->f.prot = 0;
46
s->mcs = 0;
395
47
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
396
if (regime_translation_disabled(env, mmu_idx, secure) ||
48
s->mimr = 0;
397
m_is_ppb_region(env, address)) {
49
s->mris = 0;
398
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
50
s->mcr = 0;
399
* which always does a direct read using address_space_ldl(), rather
51
+}
400
* than going via this function, so we don't need to check that here.
52
+
401
*/
53
+static void stellaris_i2c_reset_exit(Object *obj)
402
- get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
54
+{
403
+ get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot);
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
404
} else { /* MPU enabled */
56
+
405
for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
57
stellaris_i2c_update(s);
406
/* region search */
407
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
408
if (ranges_overlap(base, rmask,
409
address & TARGET_PAGE_MASK,
410
TARGET_PAGE_SIZE)) {
411
- result->page_size = 1;
412
+ result->f.lg_page_size = 0;
413
}
414
continue;
415
}
416
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
417
continue;
418
}
419
if (rsize < TARGET_PAGE_BITS) {
420
- result->page_size = 1 << rsize;
421
+ result->f.lg_page_size = rsize;
422
}
423
break;
424
}
425
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
426
fi->type = ARMFault_Background;
427
return true;
428
}
429
- get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
430
+ get_phys_addr_pmsav7_default(env, mmu_idx, address,
431
+ &result->f.prot);
432
} else { /* a MPU hit! */
433
uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);
434
uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);
435
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
436
case 5:
437
break; /* no access */
438
case 3:
439
- result->prot |= PAGE_WRITE;
440
+ result->f.prot |= PAGE_WRITE;
441
/* fall through */
442
case 2:
443
case 6:
444
- result->prot |= PAGE_READ | PAGE_EXEC;
445
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
446
break;
447
case 7:
448
/* for v7M, same as 6; for R profile a reserved value */
449
if (arm_feature(env, ARM_FEATURE_M)) {
450
- result->prot |= PAGE_READ | PAGE_EXEC;
451
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
452
break;
453
}
454
/* fall through */
455
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
456
case 1:
457
case 2:
458
case 3:
459
- result->prot |= PAGE_WRITE;
460
+ result->f.prot |= PAGE_WRITE;
461
/* fall through */
462
case 5:
463
case 6:
464
- result->prot |= PAGE_READ | PAGE_EXEC;
465
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
466
break;
467
case 7:
468
/* for v7M, same as 6; for R profile a reserved value */
469
if (arm_feature(env, ARM_FEATURE_M)) {
470
- result->prot |= PAGE_READ | PAGE_EXEC;
471
+ result->f.prot |= PAGE_READ | PAGE_EXEC;
472
break;
473
}
474
/* fall through */
475
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
476
477
/* execute never */
478
if (xn) {
479
- result->prot &= ~PAGE_EXEC;
480
+ result->f.prot &= ~PAGE_EXEC;
481
}
482
}
483
}
484
485
fi->type = ARMFault_Permission;
486
fi->level = 1;
487
- return !(result->prot & (1 << access_type));
488
+ return !(result->f.prot & (1 << access_type));
489
}
58
}
490
59
491
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
60
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
492
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
61
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
493
uint32_t addr_page_base = address & TARGET_PAGE_MASK;
62
"i2c", 0x1000);
494
uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
63
sysbus_init_mmio(sbd, &s->iomem);
495
64
- /* ??? For now we only implement the master interface. */
496
- result->page_size = TARGET_PAGE_SIZE;
65
- stellaris_i2c_reset(s);
497
- result->phys = address;
498
- result->prot = 0;
499
+ result->f.lg_page_size = TARGET_PAGE_BITS;
500
+ result->f.phys_addr = address;
501
+ result->f.prot = 0;
502
if (mregion) {
503
*mregion = -1;
504
}
505
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
506
ranges_overlap(base, limit - base + 1,
507
addr_page_base,
508
TARGET_PAGE_SIZE)) {
509
- result->page_size = 1;
510
+ result->f.lg_page_size = 0;
511
}
512
continue;
513
}
514
515
if (base > addr_page_base || limit < addr_page_limit) {
516
- result->page_size = 1;
517
+ result->f.lg_page_size = 0;
518
}
519
520
if (matchregion != -1) {
521
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
522
523
if (matchregion == -1) {
524
/* hit using the background region */
525
- get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
526
+ get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot);
527
} else {
528
uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
529
uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
530
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
531
xn = 1;
532
}
533
534
- result->prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
535
- if (result->prot && !xn && !(pxn && !is_user)) {
536
- result->prot |= PAGE_EXEC;
537
+ result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
538
+ if (result->f.prot && !xn && !(pxn && !is_user)) {
539
+ result->f.prot |= PAGE_EXEC;
540
}
541
/*
542
* We don't need to look the attribute up in the MAIR0/MAIR1
543
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
544
545
fi->type = ARMFault_Permission;
546
fi->level = 1;
547
- return !(result->prot & (1 << access_type));
548
+ return !(result->f.prot & (1 << access_type));
549
}
66
}
550
67
551
static bool v8m_is_sau_exempt(CPUARMState *env,
68
/* Analogue to Digital Converter. This is only partially implemented,
552
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
69
@@ -XXX,XX +XXX,XX @@ type_init(stellaris_machine_init)
553
} else {
70
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
554
fi->type = ARMFault_QEMU_SFault;
71
{
555
}
72
DeviceClass *dc = DEVICE_CLASS(klass);
556
- result->page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
557
- result->phys = address;
74
558
- result->prot = 0;
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
559
+ result->f.lg_page_size = sattrs.subpage ? 0 : TARGET_PAGE_BITS;
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
560
+ result->f.phys_addr = address;
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
561
+ result->f.prot = 0;
78
dc->vmsd = &vmstate_stellaris_i2c;
562
return true;
563
}
564
} else {
565
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
566
* might downgrade a secure access to nonsecure.
567
*/
568
if (sattrs.ns) {
569
- result->attrs.secure = false;
570
+ result->f.attrs.secure = false;
571
} else if (!secure) {
572
/*
573
* NS access to S memory must fault.
574
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
575
* for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
576
*/
577
fi->type = ARMFault_QEMU_SFault;
578
- result->page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
579
- result->phys = address;
580
- result->prot = 0;
581
+ result->f.lg_page_size = sattrs.subpage ? 0 : TARGET_PAGE_BITS;
582
+ result->f.phys_addr = address;
583
+ result->f.prot = 0;
584
return true;
585
}
586
}
587
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
588
ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, secure,
589
result, fi, NULL);
590
if (sattrs.subpage) {
591
- result->page_size = 1;
592
+ result->f.lg_page_size = 0;
593
}
594
return ret;
595
}
79
}
596
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
80
597
result->cacheattrs.is_s2_format = false;
598
}
599
600
- result->phys = address;
601
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
602
- result->page_size = TARGET_PAGE_SIZE;
603
+ result->f.phys_addr = address;
604
+ result->f.prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
605
+ result->f.lg_page_size = TARGET_PAGE_BITS;
606
result->cacheattrs.shareability = shareability;
607
result->cacheattrs.attrs = memattr;
608
return 0;
609
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
610
return ret;
611
}
612
613
- ipa = result->phys;
614
- ipa_secure = result->attrs.secure;
615
+ ipa = result->f.phys_addr;
616
+ ipa_secure = result->f.attrs.secure;
617
if (is_secure) {
618
/* Select TCR based on the NS bit from the S1 walk. */
619
s2walk_secure = !(ipa_secure
620
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
621
* Save the stage1 results so that we may merge
622
* prot and cacheattrs later.
623
*/
624
- s1_prot = result->prot;
625
+ s1_prot = result->f.prot;
626
cacheattrs1 = result->cacheattrs;
627
memset(result, 0, sizeof(*result));
628
629
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
630
fi->s2addr = ipa;
631
632
/* Combine the S1 and S2 perms. */
633
- result->prot &= s1_prot;
634
+ result->f.prot &= s1_prot;
635
636
/* If S2 fails, return early. */
637
if (ret) {
638
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
639
* Check if IPA translates to secure or non-secure PA space.
640
* Note that VSTCR overrides VTCR and {N}SW overrides {N}SA.
641
*/
642
- result->attrs.secure =
643
+ result->f.attrs.secure =
644
(is_secure
645
&& !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW))
646
&& (ipa_secure
647
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
648
* cannot upgrade an non-secure translation regime's attributes
649
* to secure.
650
*/
651
- result->attrs.secure = is_secure;
652
- result->attrs.user = regime_is_user(env, mmu_idx);
653
+ result->f.attrs.secure = is_secure;
654
+ result->f.attrs.user = regime_is_user(env, mmu_idx);
655
656
/*
657
* Fast Context Switch Extension. This doesn't exist at all in v8.
658
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
659
660
if (arm_feature(env, ARM_FEATURE_PMSA)) {
661
bool ret;
662
- result->page_size = TARGET_PAGE_SIZE;
663
+ result->f.lg_page_size = TARGET_PAGE_BITS;
664
665
if (arm_feature(env, ARM_FEATURE_V8)) {
666
/* PMSAv8 */
667
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
668
(access_type == MMU_DATA_STORE ? "writing" : "execute"),
669
(uint32_t)address, mmu_idx,
670
ret ? "Miss" : "Hit",
671
- result->prot & PAGE_READ ? 'r' : '-',
672
- result->prot & PAGE_WRITE ? 'w' : '-',
673
- result->prot & PAGE_EXEC ? 'x' : '-');
674
+ result->f.prot & PAGE_READ ? 'r' : '-',
675
+ result->f.prot & PAGE_WRITE ? 'w' : '-',
676
+ result->f.prot & PAGE_EXEC ? 'x' : '-');
677
678
return ret;
679
}
680
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
681
bool ret;
682
683
ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &res, &fi);
684
- *attrs = res.attrs;
685
+ *attrs = res.f.attrs;
686
687
if (ret) {
688
return -1;
689
}
690
- return res.phys;
691
+ return res.f.phys_addr;
692
}
693
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
694
index XXXXXXX..XXXXXXX 100644
695
--- a/target/arm/tlb_helper.c
696
+++ b/target/arm/tlb_helper.c
697
@@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
698
* target page size are handled specially, so for those we
699
* pass in the exact addresses.
700
*/
701
- if (res.page_size >= TARGET_PAGE_SIZE) {
702
- res.phys &= TARGET_PAGE_MASK;
703
+ if (res.f.lg_page_size >= TARGET_PAGE_BITS) {
704
+ res.f.phys_addr &= TARGET_PAGE_MASK;
705
address &= TARGET_PAGE_MASK;
706
}
707
/* Notice and record tagged memory. */
708
if (cpu_isar_feature(aa64_mte, cpu) && res.cacheattrs.attrs == 0xf0) {
709
- arm_tlb_mte_tagged(&res.attrs) = true;
710
+ arm_tlb_mte_tagged(&res.f.attrs) = true;
711
}
712
713
- tlb_set_page_with_attrs(cs, address, res.phys, res.attrs,
714
- res.prot, mmu_idx, res.page_size);
715
+ tlb_set_page_full(cs, mmu_idx, address, &res.f);
716
return true;
717
} else if (probe) {
718
return false;
719
--
81
--
720
2.25.1
82
2.34.1
83
84
diff view generated by jsdifflib
1
From: Jerome Forissier <jerome.forissier@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
According to the Linux kernel booting.rst [1], CPTR_EL3.ESM and
3
QDev objects created with qdev_new() need to manually add
4
SCR_EL3.EnTP2 must be initialized to 1 when EL3 is present and FEAT_SME
4
their parent relationship with object_property_add_child().
5
is advertised. This has to be taken care of when QEMU boots directly
6
into the kernel (i.e., "-M virt,secure=on -cpu max -kernel Image").
7
5
8
Cc: qemu-stable@nongnu.org
6
This commit plug the devices which aren't part of the SoC;
9
Fixes: 78cb9776662a ("target/arm: Enable SME for -cpu max")
7
they will be plugged into a SoC container in the next one.
10
Link: [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/arm64/booting.rst?h=v6.0#n321
8
11
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20221003145641.1921467-1-jerome.forissier@linaro.org
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
hw/arm/boot.c | 4 ++++
14
hw/arm/stellaris.c | 4 ++++
17
1 file changed, 4 insertions(+)
15
1 file changed, 4 insertions(+)
18
16
19
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/boot.c
19
--- a/hw/arm/stellaris.c
22
+++ b/hw/arm/boot.c
20
+++ b/hw/arm/stellaris.c
23
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
24
if (cpu_isar_feature(aa64_sve, cpu)) {
22
&error_fatal);
25
env->cp15.cptr_el[3] |= R_CPTR_EL3_EZ_MASK;
23
26
}
24
ssddev = qdev_new("ssd0323");
27
+ if (cpu_isar_feature(aa64_sme, cpu)) {
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
28
+ env->cp15.cptr_el[3] |= R_CPTR_EL3_ESM_MASK;
26
qdev_prop_set_uint8(ssddev, "cs", 1);
29
+ env->cp15.scr_el3 |= SCR_ENTP2;
27
qdev_realize_and_unref(ssddev, bus, &error_fatal);
30
+ }
28
31
/* AArch64 kernels never boot in secure mode */
29
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
32
assert(!info->secure_boot);
30
+ object_property_add_child(OBJECT(ms), "splitter",
33
/* This hook is only supported for AArch32 currently:
31
+ OBJECT(gpio_d_splitter));
32
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
33
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
34
qdev_connect_gpio_out(
35
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
36
DeviceState *gpad;
37
38
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
39
+ object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
40
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
41
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
42
}
34
--
43
--
35
2.25.1
44
2.34.1
45
46
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Rename the argument to is_secure_ptr, and introduce a
3
QDev objects created with qdev_new() need to manually add
4
local variable is_secure with the value. We only write
4
their parent relationship with object_property_add_child().
5
back to the pointer toward the end of the function.
6
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>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20240213155214.13619-5-philmd@linaro.org
9
Message-id: 20221001162318.153420-15-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
target/arm/ptw.c | 22 ++++++++++++----------
13
hw/arm/stellaris.c | 11 ++++++++++-
13
1 file changed, 12 insertions(+), 10 deletions(-)
14
1 file changed, 10 insertions(+), 1 deletion(-)
14
15
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/ptw.c
18
--- a/hw/arm/stellaris.c
18
+++ b/target/arm/ptw.c
19
+++ b/hw/arm/stellaris.c
19
@@ -XXX,XX +XXX,XX @@ static bool ptw_attrs_are_device(CPUARMState *env, ARMCacheAttrs cacheattrs)
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
20
21
* 400fe000 system control
21
/* Translate a S1 pagetable walk through S2 if needed. */
22
*/
22
static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
23
23
- hwaddr addr, bool *is_secure,
24
+ Object *soc_container;
24
+ hwaddr addr, bool *is_secure_ptr,
25
DeviceState *gpio_dev[7], *nvic;
25
ARMMMUFaultInfo *fi)
26
qemu_irq gpio_in[7][8];
26
{
27
qemu_irq gpio_out[7][8];
27
- ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
28
+ bool is_secure = *is_secure_ptr;
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
29
+ ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
30
31
31
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
32
+ soc_container = object_new("container");
32
- !regime_translation_disabled(env, s2_mmu_idx, *is_secure)) {
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
33
+ !regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
34
+
34
GetPhysAddrResult s2 = {};
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
35
int ret;
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
36
37
&error_fatal);
37
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
38
- *is_secure, false, &s2, fi);
39
* need its sysclk output.
39
+ is_secure, false, &s2, fi);
40
*/
40
if (ret) {
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
41
assert(fi->type != ARMFault_None);
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
42
fi->s2addr = addr;
43
43
fi->stage2 = true;
44
/*
44
fi->s1ptw = true;
45
* Most devices come preprogrammed with a MAC address in the user data.
45
- fi->s1ns = !*is_secure;
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
46
+ fi->s1ns = !is_secure;
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
47
return ~0;
48
48
}
49
nvic = qdev_new(TYPE_ARMV7M);
49
if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
50
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
51
fi->s2addr = addr;
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
52
fi->stage2 = true;
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
53
fi->s1ptw = true;
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
54
- fi->s1ns = !*is_secure;
55
55
+ fi->s1ns = !is_secure;
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
56
return ~0;
57
sbd = SYS_BUS_DEVICE(dev);
57
}
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
58
59
qdev_connect_clock_in(dev, "clk",
59
if (arm_is_secure_below_el3(env)) {
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
60
/* Check if page table walk is to secure or non-secure PA space. */
61
sysbus_realize_and_unref(sbd, &error_fatal);
61
- if (*is_secure) {
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
62
- *is_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
63
63
+ if (is_secure) {
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
64
+ is_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
65
} else {
66
-
66
- *is_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
67
+ is_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
68
qdev_connect_clock_in(dev, "WDOGCLK",
68
}
69
qdev_get_clock_out(ssys_dev, "SYSCLK"));
69
+ *is_secure_ptr = is_secure;
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);
70
} else {
86
} else {
71
- assert(!*is_secure);
72
+ assert(!is_secure);
73
}
74
75
addr = s2.phys;
76
--
87
--
77
2.25.1
88
2.34.1
89
90
diff view generated by jsdifflib
1
From: Jerome Forissier <jerome.forissier@linaro.org>
1
We support two different encodings for the AArch32 IMPDEF
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.
2
5
3
Updates write_scr() to allow setting SCR_EL3.EnTP2 when FEAT_SME is
6
When we implemented this we picked which encoding to
4
implemented. SCR_EL3 being a 64-bit register, valid_mask is changed
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
5
to uint64_t and the SCR_* constants in target/arm/cpu.h are extended
8
However this isn't right for three cases:
6
to 64-bit so that masking and bitwise not (~) behave as expected.
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
7
19
8
This enables booting Linux with Trusted Firmware-A at EL3 with
20
Make the decision of the encoding be based on whether
9
"-M virt,secure=on -cpu max".
21
the CPU implements the ARM_FEATURE_V8 flag instead.
10
22
11
Cc: qemu-stable@nongnu.org
23
This changes the behaviour only for the qemu-system-arm
12
Fixes: 78cb9776662a ("target/arm: Enable SME for -cpu max")
24
'-cpu max'. We don't expect anybody to be relying on the
13
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
25
old behaviour because:
14
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
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
31
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20221004072354.27037-1-jerome.forissier@linaro.org
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
35
---
19
target/arm/cpu.h | 54 ++++++++++++++++++++++-----------------------
36
target/arm/helper.c | 2 +-
20
target/arm/helper.c | 5 ++++-
37
1 file changed, 1 insertion(+), 1 deletion(-)
21
2 files changed, 31 insertions(+), 28 deletions(-)
22
38
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
28
29
#define HPFAR_NS (1ULL << 63)
30
31
-#define SCR_NS (1U << 0)
32
-#define SCR_IRQ (1U << 1)
33
-#define SCR_FIQ (1U << 2)
34
-#define SCR_EA (1U << 3)
35
-#define SCR_FW (1U << 4)
36
-#define SCR_AW (1U << 5)
37
-#define SCR_NET (1U << 6)
38
-#define SCR_SMD (1U << 7)
39
-#define SCR_HCE (1U << 8)
40
-#define SCR_SIF (1U << 9)
41
-#define SCR_RW (1U << 10)
42
-#define SCR_ST (1U << 11)
43
-#define SCR_TWI (1U << 12)
44
-#define SCR_TWE (1U << 13)
45
-#define SCR_TLOR (1U << 14)
46
-#define SCR_TERR (1U << 15)
47
-#define SCR_APK (1U << 16)
48
-#define SCR_API (1U << 17)
49
-#define SCR_EEL2 (1U << 18)
50
-#define SCR_EASE (1U << 19)
51
-#define SCR_NMEA (1U << 20)
52
-#define SCR_FIEN (1U << 21)
53
-#define SCR_ENSCXT (1U << 25)
54
-#define SCR_ATA (1U << 26)
55
-#define SCR_FGTEN (1U << 27)
56
-#define SCR_ECVEN (1U << 28)
57
-#define SCR_TWEDEN (1U << 29)
58
+#define SCR_NS (1ULL << 0)
59
+#define SCR_IRQ (1ULL << 1)
60
+#define SCR_FIQ (1ULL << 2)
61
+#define SCR_EA (1ULL << 3)
62
+#define SCR_FW (1ULL << 4)
63
+#define SCR_AW (1ULL << 5)
64
+#define SCR_NET (1ULL << 6)
65
+#define SCR_SMD (1ULL << 7)
66
+#define SCR_HCE (1ULL << 8)
67
+#define SCR_SIF (1ULL << 9)
68
+#define SCR_RW (1ULL << 10)
69
+#define SCR_ST (1ULL << 11)
70
+#define SCR_TWI (1ULL << 12)
71
+#define SCR_TWE (1ULL << 13)
72
+#define SCR_TLOR (1ULL << 14)
73
+#define SCR_TERR (1ULL << 15)
74
+#define SCR_APK (1ULL << 16)
75
+#define SCR_API (1ULL << 17)
76
+#define SCR_EEL2 (1ULL << 18)
77
+#define SCR_EASE (1ULL << 19)
78
+#define SCR_NMEA (1ULL << 20)
79
+#define SCR_FIEN (1ULL << 21)
80
+#define SCR_ENSCXT (1ULL << 25)
81
+#define SCR_ATA (1ULL << 26)
82
+#define SCR_FGTEN (1ULL << 27)
83
+#define SCR_ECVEN (1ULL << 28)
84
+#define SCR_TWEDEN (1ULL << 29)
85
#define SCR_TWEDEL MAKE_64BIT_MASK(30, 4)
86
#define SCR_TME (1ULL << 34)
87
#define SCR_AMVOFFEN (1ULL << 35)
88
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
89
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/helper.c
41
--- a/target/arm/helper.c
91
+++ b/target/arm/helper.c
42
+++ b/target/arm/helper.c
92
@@ -XXX,XX +XXX,XX @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
93
static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
44
* AArch64 cores we might need to add a specific feature flag
94
{
45
* to indicate cores with "flavour 2" CBAR.
95
/* Begin with base v8.0 state. */
46
*/
96
- uint32_t valid_mask = 0x3fff;
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
97
+ uint64_t valid_mask = 0x3fff;
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
98
ARMCPU *cpu = env_archcpu(env);
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
99
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
100
/*
51
| extract64(cpu->reset_cbar, 32, 12);
101
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
102
if (cpu_isar_feature(aa64_doublefault, cpu)) {
103
valid_mask |= SCR_EASE | SCR_NMEA;
104
}
105
+ if (cpu_isar_feature(aa64_sme, cpu)) {
106
+ valid_mask |= SCR_ENTP2;
107
+ }
108
} else {
109
valid_mask &= ~(SCR_RW | SCR_ST);
110
if (cpu_isar_feature(aa32_ras, cpu)) {
111
--
52
--
112
2.25.1
53
2.34.1
diff view generated by jsdifflib
1
FEAT_GTG is a change tho the ID register ID_AA64MMFR0_EL1 so that it
1
The Cortex-R52 implements the Configuration Base Address Register
2
can report a different set of supported granule (page) sizes for
2
(CBAR), as a read-only register. Add ARM_FEATURE_CBAR_RO to this CPU
3
stage 1 and stage 2 translation tables. As of commit c20281b2a5048
3
type, so that our implementation provides the register and the
4
we already report the granule sizes that way for '-cpu max', and now
4
associated qdev property.
5
we also correctly make attempts to use unimplemented granule sizes
6
fail, so we can report the support of the feature in the
7
documentation.
8
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
11
Message-id: 20221003162315.2833797-4-peter.maydell@linaro.org
12
---
9
---
13
docs/system/arm/emulation.rst | 1 +
10
target/arm/tcg/cpu32.c | 1 +
14
1 file changed, 1 insertion(+)
11
1 file changed, 1 insertion(+)
15
12
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/emulation.rst
15
--- a/target/arm/tcg/cpu32.c
19
+++ b/docs/system/arm/emulation.rst
16
+++ b/target/arm/tcg/cpu32.c
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
21
- FEAT_FRINTTS (Floating-point to integer instructions)
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
22
- FEAT_FlagM (Flag manipulation instructions v2)
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
23
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
24
+- FEAT_GTG (Guest translation granule size)
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
25
- FEAT_HCX (Support for the HCRX_EL2 register)
22
cpu->midr = 0x411fd133; /* r1p3 */
26
- FEAT_HPDS (Hierarchical permission disables)
23
cpu->revidr = 0x00000000;
27
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
24
cpu->reset_fpsid = 0x41034023;
28
--
25
--
29
2.25.1
26
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
This is the last use of regime_is_secure; remove it
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
entirely before changing the layout of ARMMMUIdx.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20240206132931.38376-4-peter.maydell@linaro.org
9
---
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 108 insertions(+)
5
12
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-9-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 42 ----------------------------------------
12
target/arm/ptw.c | 44 ++++++++++++++++++++++++++++++++++++++++--
13
2 files changed, 42 insertions(+), 44 deletions(-)
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
15
--- a/target/arm/tcg/cpu32.c
18
+++ b/target/arm/internals.h
16
+++ b/target/arm/tcg/cpu32.c
19
@@ -XXX,XX +XXX,XX @@ static inline bool regime_has_2_ranges(ARMMMUIdx mmu_idx)
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
20
}
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
21
}
19
}
22
20
23
-/* Return true if this address translation regime is secure */
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
24
-static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
25
-{
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
26
- switch (mmu_idx) {
24
+ { .name = "IMP_ATCMREGIONR",
27
- case ARMMMUIdx_E10_0:
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
28
- case ARMMMUIdx_E10_1:
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
29
- case ARMMMUIdx_E10_1_PAN:
27
+ { .name = "IMP_BTCMREGIONR",
30
- case ARMMMUIdx_E20_0:
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
31
- case ARMMMUIdx_E20_2:
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
32
- case ARMMMUIdx_E20_2_PAN:
30
+ { .name = "IMP_CTCMREGIONR",
33
- case ARMMMUIdx_Stage1_E0:
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
34
- case ARMMMUIdx_Stage1_E1:
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
35
- case ARMMMUIdx_Stage1_E1_PAN:
33
+ { .name = "IMP_CSCTLR",
36
- case ARMMMUIdx_E2:
34
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
37
- case ARMMMUIdx_Stage2:
35
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
38
- case ARMMMUIdx_MPrivNegPri:
36
+ { .name = "IMP_BPCTLR",
39
- case ARMMMUIdx_MUserNegPri:
37
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1,
40
- case ARMMMUIdx_MPriv:
38
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
41
- case ARMMMUIdx_MUser:
39
+ { .name = "IMP_MEMPROTCLR",
42
- return false;
40
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 2,
43
- case ARMMMUIdx_SE3:
41
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
44
- case ARMMMUIdx_SE10_0:
42
+ { .name = "IMP_SLAVEPCTLR",
45
- case ARMMMUIdx_SE10_1:
43
+ .cp = 15, .opc1 = 0, .crn = 11, .crm = 0, .opc2 = 0,
46
- case ARMMMUIdx_SE10_1_PAN:
44
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
47
- case ARMMMUIdx_SE20_0:
45
+ { .name = "IMP_PERIPHREGIONR",
48
- case ARMMMUIdx_SE20_2:
46
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
49
- case ARMMMUIdx_SE20_2_PAN:
47
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
50
- case ARMMMUIdx_Stage1_SE0:
48
+ { .name = "IMP_FLASHIFREGIONR",
51
- case ARMMMUIdx_Stage1_SE1:
49
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 1,
52
- case ARMMMUIdx_Stage1_SE1_PAN:
50
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
53
- case ARMMMUIdx_SE2:
51
+ { .name = "IMP_BUILDOPTR",
54
- case ARMMMUIdx_Stage2_S:
52
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
55
- case ARMMMUIdx_MSPrivNegPri:
53
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
56
- case ARMMMUIdx_MSUserNegPri:
54
+ { .name = "IMP_PINOPTR",
57
- case ARMMMUIdx_MSPriv:
55
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
58
- case ARMMMUIdx_MSUser:
56
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
59
- return true;
57
+ { .name = "IMP_QOSR",
60
- default:
58
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 1,
61
- g_assert_not_reached();
59
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
62
- }
60
+ { .name = "IMP_BUSTIMEOUTR",
63
-}
61
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 2,
64
-
62
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
65
static inline bool regime_is_pan(CPUARMState *env, ARMMMUIdx mmu_idx)
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)
66
{
127
{
67
switch (mmu_idx) {
128
ARMCPU *cpu = ARM_CPU(obj);
68
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
69
index XXXXXXX..XXXXXXX 100644
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
70
--- a/target/arm/ptw.c
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
71
+++ b/target/arm/ptw.c
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
73
MMUAccessType access_type, ARMMMUIdx mmu_idx,
134
cpu->midr = 0x411fd133; /* r1p3 */
74
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
135
cpu->revidr = 0x00000000;
75
{
136
cpu->reset_fpsid = 0x41034023;
76
+ bool is_secure;
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
138
139
cpu->pmsav7_dregion = 16;
140
cpu->pmsav8r_hdregion = 16;
77
+
141
+
78
+ switch (mmu_idx) {
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
79
+ case ARMMMUIdx_E10_0:
80
+ case ARMMMUIdx_E10_1:
81
+ case ARMMMUIdx_E10_1_PAN:
82
+ case ARMMMUIdx_E20_0:
83
+ case ARMMMUIdx_E20_2:
84
+ case ARMMMUIdx_E20_2_PAN:
85
+ case ARMMMUIdx_Stage1_E0:
86
+ case ARMMMUIdx_Stage1_E1:
87
+ case ARMMMUIdx_Stage1_E1_PAN:
88
+ case ARMMMUIdx_E2:
89
+ case ARMMMUIdx_Stage2:
90
+ case ARMMMUIdx_MPrivNegPri:
91
+ case ARMMMUIdx_MUserNegPri:
92
+ case ARMMMUIdx_MPriv:
93
+ case ARMMMUIdx_MUser:
94
+ is_secure = false;
95
+ break;
96
+ case ARMMMUIdx_SE3:
97
+ case ARMMMUIdx_SE10_0:
98
+ case ARMMMUIdx_SE10_1:
99
+ case ARMMMUIdx_SE10_1_PAN:
100
+ case ARMMMUIdx_SE20_0:
101
+ case ARMMMUIdx_SE20_2:
102
+ case ARMMMUIdx_SE20_2_PAN:
103
+ case ARMMMUIdx_Stage1_SE0:
104
+ case ARMMMUIdx_Stage1_SE1:
105
+ case ARMMMUIdx_Stage1_SE1_PAN:
106
+ case ARMMMUIdx_SE2:
107
+ case ARMMMUIdx_Stage2_S:
108
+ case ARMMMUIdx_MSPrivNegPri:
109
+ case ARMMMUIdx_MSUserNegPri:
110
+ case ARMMMUIdx_MSPriv:
111
+ case ARMMMUIdx_MSUser:
112
+ is_secure = true;
113
+ break;
114
+ default:
115
+ g_assert_not_reached();
116
+ }
117
return get_phys_addr_with_secure(env, address, access_type, mmu_idx,
118
- regime_is_secure(env, mmu_idx),
119
- result, fi);
120
+ is_secure, result, fi);
121
}
143
}
122
144
123
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
145
static void cortex_r5f_initfn(Object *obj)
124
--
146
--
125
2.25.1
147
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
The effect of TGE does not only apply to non-secure state,
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
4
now that Secure EL2 exists.
8
out that real hardware permits this, with the same effect as if the
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.
5
17
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
For convenience of being able to run guest code, permit
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
this UNPREDICTABLE access instead of UNDEFing it.
8
Message-id: 20221001162318.153420-13-richard.henderson@linaro.org
20
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
10
---
24
---
11
target/arm/ptw.c | 4 ++--
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
12
1 file changed, 2 insertions(+), 2 deletions(-)
26
target/arm/tcg/translate.c | 19 +++++++++++------
27
2 files changed, 43 insertions(+), 19 deletions(-)
13
28
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
15
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
31
--- a/target/arm/tcg/op_helper.c
17
+++ b/target/arm/ptw.c
32
+++ b/target/arm/tcg/op_helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
19
case ARMMMUIdx_E10_0:
34
*/
20
case ARMMMUIdx_E10_1:
35
int curmode = env->uncached_cpsr & CPSR_M;
21
case ARMMMUIdx_E10_1_PAN:
36
22
- /* TGE means that NS EL0/1 act as if SCTLR_EL1.M is zero */
37
- if (regno == 17) {
23
- if (!is_secure && (hcr_el2 & HCR_TGE)) {
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
24
+ /* TGE means that EL0/1 act as if SCTLR_EL1.M is zero */
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
25
+ if (hcr_el2 & HCR_TGE) {
40
- goto undef;
26
return true;
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
42
+ /*
43
+ * Handle Hyp target regs first because some are special cases
44
+ * which don't want the usual "not accessible from tgtmode" check.
45
+ */
46
+ switch (regno) {
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
49
+ goto undef;
50
+ }
51
+ break;
52
+ case 13:
53
+ if (curmode != ARM_CPU_MODE_MON) {
54
+ goto undef;
55
+ }
56
+ break;
57
+ default:
58
+ g_assert_not_reached();
59
}
60
return;
61
}
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
63
}
64
}
65
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
68
- if (curmode != ARM_CPU_MODE_MON) {
69
- goto undef;
70
- }
71
- }
72
-
73
return;
74
75
undef:
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
77
78
switch (regno) {
79
case 16: /* SPSRs */
80
- env->banked_spsr[bank_number(tgtmode)] = value;
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
83
+ env->spsr = value;
84
+ } else {
85
+ env->banked_spsr[bank_number(tgtmode)] = value;
86
+ }
87
break;
88
case 17: /* ELR_Hyp */
89
env->elr_el[2] = value;
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
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/tcg/translate.c
107
+++ b/target/arm/tcg/translate.c
108
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
109
break;
110
case ARM_CPU_MODE_HYP:
111
/*
112
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
113
- * (and so we can forbid accesses from EL2 or below). elr_hyp
114
- * can be accessed also from Hyp mode, so forbid accesses from
115
- * EL0 or EL1.
116
+ * r13_hyp can only be accessed from Monitor mode, and so we
117
+ * can forbid accesses from EL2 or below.
118
+ * elr_hyp can be accessed also from Hyp mode, so forbid
119
+ * accesses from EL0 or EL1.
120
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
121
+ * and UNPREDICTABLE if accessed from anything except Monitor
122
+ * mode. However there is some real-world code that will do
123
+ * it because at least some hardware happens to permit the
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;
27
}
133
}
28
break;
134
break;
29
--
135
--
30
2.25.1
136
2.34.1
diff view generated by jsdifflib
New patch
1
We currently guard the CFG3 register read with
2
(scc_partno(s) == 0x524 && scc_partno(s) == 0x547)
3
which is clearly wrong as it is never true.
1
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")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
13
---
14
hw/misc/mps2-scc.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/misc/mps2-scc.c
20
+++ b/hw/misc/mps2-scc.c
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
22
r = s->cfg2;
23
break;
24
case A_CFG3:
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
27
/* CFG3 reserved on AN524 */
28
goto bad_offset;
29
}
30
--
31
2.34.1
32
33
diff view generated by jsdifflib
1
Arm CPUs support some subset of the granule (page) sizes 4K, 16K and
1
The MPS SCC device has a lot of different flavours for the various
2
64K. The guest selects the one it wants using bits in the TCR_ELx
2
different MPS FPGA images, which look mostly similar but have
3
registers. If it tries to program these registers with a value that
3
differences in how particular registers are handled. Currently we
4
is either reserved or which requests a size that the CPU does not
4
deal with this with a lot of open-coded checks on scc_partno(), but
5
implement, the architecture requires that the CPU behaves as if the
5
as we add more board types this is getting a bit hard to read.
6
field was programmed to some size that has been implemented.
7
Currently we don't implement this, and instead let the guest use any
8
granule size, even if the CPU ID register fields say it isn't
9
present.
10
6
11
Make aa64_va_parameters() check against the supported granule size
7
Factor out the conditions into some functions which we can
12
and force use of a different one if it is not implemented.
8
give more descriptive names to.
13
9
14
(A subsequent commit will make ARMVAParameters use the new enum
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
rather than the current pair of using16k/using64k bools.)
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
14
---
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
16
1 file changed, 31 insertions(+), 14 deletions(-)
16
17
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Message-id: 20221003162315.2833797-2-peter.maydell@linaro.org
20
---
21
target/arm/cpu.h | 33 +++++++++++++
22
target/arm/internals.h | 9 ++++
23
target/arm/helper.c | 102 +++++++++++++++++++++++++++++++++++++----
24
3 files changed, 136 insertions(+), 8 deletions(-)
25
26
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
27
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/cpu.h
20
--- a/hw/misc/mps2-scc.c
29
+++ b/target/arm/cpu.h
21
+++ b/hw/misc/mps2-scc.c
30
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
31
return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
23
return extract32(s->id, 4, 8);
32
}
24
}
33
25
34
+static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
26
+/* Is CFG_REG2 present? */
27
+static bool have_cfg2(MPS2SCC *s)
35
+{
28
+{
36
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0;
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
37
+}
30
+}
38
+
31
+
39
+static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
32
+/* Is CFG_REG3 present? */
33
+static bool have_cfg3(MPS2SCC *s)
40
+{
34
+{
41
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1;
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
42
+}
36
+}
43
+
37
+
44
+static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
38
+/* Is CFG_REG5 present? */
39
+static bool have_cfg5(MPS2SCC *s)
45
+{
40
+{
46
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0;
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
47
+}
42
+}
48
+
43
+
49
+static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
44
+/* Is CFG_REG6 present? */
45
+static bool have_cfg6(MPS2SCC *s)
50
+{
46
+{
51
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
47
+ return scc_partno(s) == 0x524;
52
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id));
53
+}
48
+}
54
+
49
+
55
+static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id)
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
56
+{
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
57
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
52
*/
58
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id));
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
59
+}
54
r = s->cfg1;
60
+
55
break;
61
+static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
56
case A_CFG2:
62
+{
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
63
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2);
58
- /* CFG2 reserved on other boards */
64
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
59
+ if (!have_cfg2(s)) {
65
+}
60
goto bad_offset;
66
+
61
}
67
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
62
r = s->cfg2;
68
{
63
break;
69
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
64
case A_CFG3:
70
diff --git a/target/arm/internals.h b/target/arm/internals.h
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
71
index XXXXXXX..XXXXXXX 100644
66
- /* CFG3 reserved on AN524 */
72
--- a/target/arm/internals.h
67
+ if (!have_cfg3(s)) {
73
+++ b/target/arm/internals.h
68
goto bad_offset;
74
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
69
}
75
return valid;
70
/* These are user-settable DIP switches on the board. We don't
76
}
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
77
72
r = s->cfg4;
78
+/* Granule size (i.e. page size) */
73
break;
79
+typedef enum ARMGranuleSize {
74
case A_CFG5:
80
+ /* Same order as TG0 encoding */
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
81
+ Gran4K,
76
- /* CFG5 reserved on other boards */
82
+ Gran64K,
77
+ if (!have_cfg5(s)) {
83
+ Gran16K,
78
goto bad_offset;
84
+ GranInvalid,
79
}
85
+} ARMGranuleSize;
80
r = s->cfg5;
86
+
81
break;
87
/*
82
case A_CFG6:
88
* Parameters of a given virtual address, as extracted from the
83
- if (scc_partno(s) != 0x524) {
89
* translation control register (TCR) for a given regime.
84
- /* CFG6 reserved on other boards */
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
+ if (!have_cfg6(s)) {
91
index XXXXXXX..XXXXXXX 100644
86
goto bad_offset;
92
--- a/target/arm/helper.c
87
}
93
+++ b/target/arm/helper.c
88
r = s->cfg6;
94
@@ -XXX,XX +XXX,XX @@ static int aa64_va_parameter_tcma(uint64_t tcr, ARMMMUIdx mmu_idx)
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
95
}
90
}
96
}
91
break;
97
92
case A_CFG2:
98
+static ARMGranuleSize tg0_to_gran_size(int tg)
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
99
+{
94
- /* CFG2 reserved on other boards */
100
+ switch (tg) {
95
+ if (!have_cfg2(s)) {
101
+ case 0:
96
goto bad_offset;
102
+ return Gran4K;
97
}
103
+ case 1:
98
/* AN524: QSPI Select signal */
104
+ return Gran64K;
99
s->cfg2 = value;
105
+ case 2:
100
break;
106
+ return Gran16K;
101
case A_CFG5:
107
+ default:
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
108
+ return GranInvalid;
103
- /* CFG5 reserved on other boards */
109
+ }
104
+ if (!have_cfg5(s)) {
110
+}
105
goto bad_offset;
111
+
106
}
112
+static ARMGranuleSize tg1_to_gran_size(int tg)
107
/* AN524: ACLK frequency in Hz */
113
+{
108
s->cfg5 = value;
114
+ switch (tg) {
109
break;
115
+ case 1:
110
case A_CFG6:
116
+ return Gran16K;
111
- if (scc_partno(s) != 0x524) {
117
+ case 2:
112
- /* CFG6 reserved on other boards */
118
+ return Gran4K;
113
+ if (!have_cfg6(s)) {
119
+ case 3:
114
goto bad_offset;
120
+ return Gran64K;
115
}
121
+ default:
116
/* AN524: Clock divider for BRAM */
122
+ return GranInvalid;
123
+ }
124
+}
125
+
126
+static inline bool have4k(ARMCPU *cpu, bool stage2)
127
+{
128
+ return stage2 ? cpu_isar_feature(aa64_tgran4_2, cpu)
129
+ : cpu_isar_feature(aa64_tgran4, cpu);
130
+}
131
+
132
+static inline bool have16k(ARMCPU *cpu, bool stage2)
133
+{
134
+ return stage2 ? cpu_isar_feature(aa64_tgran16_2, cpu)
135
+ : cpu_isar_feature(aa64_tgran16, cpu);
136
+}
137
+
138
+static inline bool have64k(ARMCPU *cpu, bool stage2)
139
+{
140
+ return stage2 ? cpu_isar_feature(aa64_tgran64_2, cpu)
141
+ : cpu_isar_feature(aa64_tgran64, cpu);
142
+}
143
+
144
+static ARMGranuleSize sanitize_gran_size(ARMCPU *cpu, ARMGranuleSize gran,
145
+ bool stage2)
146
+{
147
+ switch (gran) {
148
+ case Gran4K:
149
+ if (have4k(cpu, stage2)) {
150
+ return gran;
151
+ }
152
+ break;
153
+ case Gran16K:
154
+ if (have16k(cpu, stage2)) {
155
+ return gran;
156
+ }
157
+ break;
158
+ case Gran64K:
159
+ if (have64k(cpu, stage2)) {
160
+ return gran;
161
+ }
162
+ break;
163
+ case GranInvalid:
164
+ break;
165
+ }
166
+ /*
167
+ * If the guest selects a granule size that isn't implemented,
168
+ * the architecture requires that we behave as if it selected one
169
+ * that is (with an IMPDEF choice of which one to pick). We choose
170
+ * to implement the smallest supported granule size.
171
+ */
172
+ if (have4k(cpu, stage2)) {
173
+ return Gran4K;
174
+ }
175
+ if (have16k(cpu, stage2)) {
176
+ return Gran16K;
177
+ }
178
+ assert(have64k(cpu, stage2));
179
+ return Gran64K;
180
+}
181
+
182
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
183
ARMMMUIdx mmu_idx, bool data)
184
{
185
uint64_t tcr = regime_tcr(env, mmu_idx);
186
bool epd, hpd, using16k, using64k, tsz_oob, ds;
187
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
188
+ ARMGranuleSize gran;
189
ARMCPU *cpu = env_archcpu(env);
190
+ bool stage2 = mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S;
191
192
if (!regime_has_2_ranges(mmu_idx)) {
193
select = 0;
194
tsz = extract32(tcr, 0, 6);
195
- using64k = extract32(tcr, 14, 1);
196
- using16k = extract32(tcr, 15, 1);
197
- if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
198
+ gran = tg0_to_gran_size(extract32(tcr, 14, 2));
199
+ if (stage2) {
200
/* VTCR_EL2 */
201
hpd = false;
202
} else {
203
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
204
select = extract64(va, 55, 1);
205
if (!select) {
206
tsz = extract32(tcr, 0, 6);
207
+ gran = tg0_to_gran_size(extract32(tcr, 14, 2));
208
epd = extract32(tcr, 7, 1);
209
sh = extract32(tcr, 12, 2);
210
- using64k = extract32(tcr, 14, 1);
211
- using16k = extract32(tcr, 15, 1);
212
hpd = extract64(tcr, 41, 1);
213
} else {
214
- int tg = extract32(tcr, 30, 2);
215
- using16k = tg == 1;
216
- using64k = tg == 3;
217
tsz = extract32(tcr, 16, 6);
218
+ gran = tg1_to_gran_size(extract32(tcr, 30, 2));
219
epd = extract32(tcr, 23, 1);
220
sh = extract32(tcr, 28, 2);
221
hpd = extract64(tcr, 42, 1);
222
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
223
ds = extract64(tcr, 59, 1);
224
}
225
226
+ gran = sanitize_gran_size(cpu, gran, stage2);
227
+ using64k = gran == Gran64K;
228
+ using16k = gran == Gran16K;
229
+
230
if (cpu_isar_feature(aa64_st, cpu)) {
231
max_tsz = 48 - using64k;
232
} else {
233
--
117
--
234
2.25.1
118
2.34.1
119
120
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
2
2
minor differences in the behaviour of the CFG registers depending on
3
Pass the correct stage2 mmu_idx to regime_translation_disabled,
3
the image. In many cases we don't really care about the functionality
4
which we computed afterward.
4
controlled by these registers and a reads-as-written or similar
5
5
behaviour is sufficient for the moment.
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
For the AN536 the required behaviour is:
8
Message-id: 20221001162318.153420-4-richard.henderson@linaro.org
8
9
* A_CFG0 has CPU reset and halt bits
10
- implement as reads-as-written for the moment
11
* A_CFG1 has flash or ATCM address 0 remap handling
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.
34
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
10
---
39
---
11
target/arm/ptw.c | 6 +++---
40
include/hw/misc/mps2-scc.h | 1 +
12
1 file changed, 3 insertions(+), 3 deletions(-)
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
13
42
2 files changed, 92 insertions(+), 10 deletions(-)
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
43
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
15
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
46
--- a/include/hw/misc/mps2-scc.h
17
+++ b/target/arm/ptw.c
47
+++ b/include/hw/misc/mps2-scc.h
18
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
19
hwaddr addr, bool *is_secure,
49
uint32_t cfg4;
20
ARMMMUFaultInfo *fi)
50
uint32_t cfg5;
21
{
51
uint32_t cfg6;
22
+ ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
52
+ uint32_t cfg7;
23
+
53
uint32_t cfgdata_rtn;
24
if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
54
uint32_t cfgdata_out;
25
- !regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
55
uint32_t cfgctrl;
26
- ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
27
- : ARMMMUIdx_Stage2;
57
index XXXXXXX..XXXXXXX 100644
28
+ !regime_translation_disabled(env, s2_mmu_idx)) {
58
--- a/hw/misc/mps2-scc.c
29
GetPhysAddrResult s2 = {};
59
+++ b/hw/misc/mps2-scc.c
30
int ret;
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
61
REG32(CFG4, 0x10)
62
REG32(CFG5, 0x14)
63
REG32(CFG6, 0x18)
64
+REG32(CFG7, 0x1c)
65
REG32(CFGDATA_RTN, 0xa0)
66
REG32(CFGDATA_OUT, 0xa4)
67
REG32(CFGCTRL, 0xa8)
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
69
/* Is CFG_REG2 present? */
70
static bool have_cfg2(MPS2SCC *s)
71
{
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
74
+ scc_partno(s) == 0x536;
75
}
76
77
/* Is CFG_REG3 present? */
78
static bool have_cfg3(MPS2SCC *s)
79
{
80
- return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
81
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
82
+ scc_partno(s) != 0x536;
83
}
84
85
/* Is CFG_REG5 present? */
86
static bool have_cfg5(MPS2SCC *s)
87
{
88
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
89
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
90
+ scc_partno(s) == 0x536;
91
}
92
93
/* Is CFG_REG6 present? */
94
static bool have_cfg6(MPS2SCC *s)
95
{
96
- return scc_partno(s) == 0x524;
97
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x536;
98
+}
99
+
100
+/* Is CFG_REG7 present? */
101
+static bool have_cfg7(MPS2SCC *s)
102
+{
103
+ return scc_partno(s) == 0x536;
104
+}
105
+
106
+/* Does CFG_REG0 drive the 'remap' GPIO output? */
107
+static bool cfg0_is_remap(MPS2SCC *s)
108
+{
109
+ return scc_partno(s) != 0x536;
110
+}
111
+
112
+/* Is CFG_REG1 driving a set of LEDs? */
113
+static bool cfg1_is_leds(MPS2SCC *s)
114
+{
115
+ return scc_partno(s) != 0x536;
116
}
117
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)) {
143
+ goto bad_offset;
144
+ }
145
+ r = s->cfg7;
146
+ break;
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)) {
208
+ goto bad_offset;
209
+ }
210
+ /* AN536: Core 1 vector table base address */
211
s->cfg6 = value;
212
break;
213
case A_CFGDATA_OUT:
214
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_finalize(Object *obj)
215
g_free(s->oscclk_reset);
216
}
217
218
+static bool cfg7_needed(void *opaque)
219
+{
220
+ MPS2SCC *s = opaque;
221
+
222
+ return have_cfg7(s);
223
+}
224
+
225
+static const VMStateDescription vmstate_cfg7 = {
226
+ .name = "mps2-scc/cfg7",
227
+ .version_id = 1,
228
+ .minimum_version_id = 1,
229
+ .needed = cfg7_needed,
230
+ .fields = (const VMStateField[]) {
231
+ VMSTATE_UINT32(cfg7, MPS2SCC),
232
+ VMSTATE_END_OF_LIST()
233
+ }
234
+};
235
+
236
static const VMStateDescription mps2_scc_vmstate = {
237
.name = "mps2-scc",
238
.version_id = 3,
239
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
240
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
241
0, vmstate_info_uint32, uint32_t),
242
VMSTATE_END_OF_LIST()
243
+ },
244
+ .subsections = (const VMStateDescription * const []) {
245
+ &vmstate_cfg7,
246
+ NULL
247
}
248
};
31
249
32
--
250
--
33
2.25.1
251
2.34.1
252
253
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The AN536 is another FPGA image for the MPS3 development board. Unlike
2
2
the existing FPGA images we already model, this board uses a Cortex-R
3
The starting security state comes with the translation regime,
3
family CPU, and it does not use any equivalent to the M-profile
4
not the current state of arm_is_secure_below_el3().
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
5
It's therefore more convenient for us to model it as a completely
6
Create a new local variable, s2walk_secure, which does not need
6
separate C file.
7
to be written back to result->attrs.secure -- we compute that
7
8
value later, after the S2 walk is complete.
8
This commit adds the basic skeleton of the board model, and the
9
9
code to create all the RAM and ROM. We assume that we're probably
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
going to want to add more images in future, so use the same
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
base class/subclass setup that mps2-tz.c uses, even though at
12
Message-id: 20221001162318.153420-2-richard.henderson@linaro.org
12
the moment there's only a single subclass.
13
14
Following commits will add the CPUs and the peripherals.
15
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Message-id: 20240206132931.38376-9-peter.maydell@linaro.org
14
---
19
---
15
target/arm/ptw.c | 18 +++++++++---------
20
MAINTAINERS | 3 +-
16
1 file changed, 9 insertions(+), 9 deletions(-)
21
configs/devices/arm-softmmu/default.mak | 1 +
17
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
18
diff --git a/target/arm/ptw.c b/target/arm/ptw.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
19
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/ptw.c
30
--- a/MAINTAINERS
21
+++ b/target/arm/ptw.c
31
+++ b/MAINTAINERS
22
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
23
hwaddr ipa;
33
F: hw/pci-host/designware.c
24
int s1_prot;
34
F: include/hw/pci-host/designware.h
25
int ret;
35
26
- bool ipa_secure;
36
-MPS2
27
+ bool ipa_secure, s2walk_secure;
37
+MPS2 / MPS3
28
ARMCacheAttrs cacheattrs1;
38
M: Peter Maydell <peter.maydell@linaro.org>
29
ARMMMUIdx s2_mmu_idx;
39
L: qemu-arm@nongnu.org
30
bool is_el0;
40
S: Maintained
31
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
41
F: hw/arm/mps2.c
32
42
F: hw/arm/mps2-tz.c
33
ipa = result->phys;
43
+F: hw/arm/mps3r.c
34
ipa_secure = result->attrs.secure;
44
F: hw/misc/mps2-*.c
35
- if (arm_is_secure_below_el3(env)) {
45
F: include/hw/misc/mps2-*.h
36
- if (ipa_secure) {
46
F: hw/arm/armsse.c
37
- result->attrs.secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
47
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
38
- } else {
48
index XXXXXXX..XXXXXXX 100644
39
- result->attrs.secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
49
--- a/configs/devices/arm-softmmu/default.mak
40
- }
50
+++ b/configs/devices/arm-softmmu/default.mak
41
+ if (is_secure) {
51
@@ -XXX,XX +XXX,XX @@ CONFIG_ARM_VIRT=y
42
+ /* Select TCR based on the NS bit from the S1 walk. */
52
# CONFIG_INTEGRATOR=n
43
+ s2walk_secure = !(ipa_secure
53
# CONFIG_FSL_IMX31=n
44
+ ? env->cp15.vstcr_el2 & VSTCR_SW
54
# CONFIG_MUSICPAL=n
45
+ : env->cp15.vtcr_el2 & VTCR_NSW);
55
+# CONFIG_MPS3R=n
46
} else {
56
# CONFIG_MUSCA=n
47
assert(!ipa_secure);
57
# CONFIG_CHEETAH=n
48
+ s2walk_secure = false;
58
# CONFIG_SX1=n
49
}
59
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
50
60
new file mode 100644
51
- s2_mmu_idx = (result->attrs.secure
61
index XXXXXXX..XXXXXXX
52
+ s2_mmu_idx = (s2walk_secure
62
--- /dev/null
53
? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2);
63
+++ b/hw/arm/mps3r.c
54
is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
64
@@ -XXX,XX +XXX,XX @@
55
65
+/*
56
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
66
+ * Arm MPS3 board emulation for Cortex-R-based FPGA images.
57
result->cacheattrs);
67
+ * (For M-profile images see mps2.c and mps2tz.c.)
58
68
+ *
59
/* Check if IPA translates to secure or non-secure PA space. */
69
+ * Copyright (c) 2017 Linaro Limited
60
- if (arm_is_secure_below_el3(env)) {
70
+ * Written by Peter Maydell
61
+ if (is_secure) {
71
+ *
62
if (ipa_secure) {
72
+ * This program is free software; you can redistribute it and/or modify
63
result->attrs.secure =
73
+ * it under the terms of the GNU General Public License version 2 or
64
!(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW));
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'))
65
--
332
--
66
2.25.1
333
2.34.1
334
335
diff view generated by jsdifflib
1
Now we have an enum for the granule size, use it in the
1
Create the CPUs, the GIC, and the per-CPU RAM block for
2
ARMVAParameters struct instead of the using16k/using64k bools.
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: 20221003162315.2833797-3-peter.maydell@linaro.org
7
---
6
---
8
target/arm/internals.h | 23 +++++++++++++++++++++--
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
9
target/arm/helper.c | 39 ++++++++++++++++++++++++++++-----------
8
1 file changed, 177 insertions(+), 3 deletions(-)
10
target/arm/ptw.c | 8 +-------
11
3 files changed, 50 insertions(+), 20 deletions(-)
12
9
13
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
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/internals.h
12
--- a/hw/arm/mps3r.c
16
+++ b/target/arm/internals.h
13
+++ b/hw/arm/mps3r.c
17
@@ -XXX,XX +XXX,XX @@ typedef enum ARMGranuleSize {
14
@@ -XXX,XX +XXX,XX @@
18
GranInvalid,
15
#include "qemu/osdep.h"
19
} ARMGranuleSize;
16
#include "qemu/units.h"
20
17
#include "qapi/error.h"
21
+/**
18
+#include "qapi/qmp/qlist.h"
22
+ * arm_granule_bits: Return address size of the granule in bits
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;
61
}
62
63
+/*
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).
23
+ *
72
+ *
24
+ * Return the address size of the granule in bits. This corresponds
73
+ * Note that the default secondary boot code would not work here anyway
25
+ * to the pseudocode TGxGranuleBits().
74
+ * as it assumes a GICv2, and we have a GICv3.
26
+ */
75
+ */
27
+static inline int arm_granule_bits(ARMGranuleSize gran)
76
+static void mps3r_write_secondary_boot(ARMCPU *cpu,
77
+ const struct arm_boot_info *info)
28
+{
78
+{
29
+ switch (gran) {
79
+ /*
30
+ case Gran64K:
80
+ * Power the secondary CPU off. This means we don't need to write any
31
+ return 16;
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
32
+ case Gran16K:
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
33
+ return 14;
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
34
+ case Gran4K:
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
35
+ return 12;
85
+ */
36
+ default:
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
37
+ g_assert_not_reached();
87
+ if (cs != first_cpu) {
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
89
+ &error_abort);
90
+ }
38
+ }
91
+ }
39
+}
92
+}
40
+
93
+
41
/*
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
42
* Parameters of a given virtual address, as extracted from the
95
+ const struct arm_boot_info *info)
43
* translation control register (TCR) for a given regime.
44
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
45
bool tbi : 1;
46
bool epd : 1;
47
bool hpd : 1;
48
- bool using16k : 1;
49
- bool using64k : 1;
50
bool tsz_oob : 1; /* tsz has been clamped to legal range */
51
bool ds : 1;
52
+ ARMGranuleSize gran : 2;
53
} ARMVAParameters;
54
55
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
56
diff --git a/target/arm/helper.c b/target/arm/helper.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/helper.c
59
+++ b/target/arm/helper.c
60
@@ -XXX,XX +XXX,XX @@ typedef struct {
61
uint64_t length;
62
} TLBIRange;
63
64
+static ARMGranuleSize tlbi_range_tg_to_gran_size(int tg)
65
+{
96
+{
97
+ /* We don't need to do anything here because the CPU will be off */
98
+}
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);
66
+ /*
118
+ /*
67
+ * Note that the TLBI range TG field encoding differs from both
119
+ * Wire the outputs from each CPU's generic timer and the GICv3
68
+ * TG0 and TG1 encodings.
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.
69
+ */
122
+ */
70
+ switch (tg) {
123
+ for (int i = 0; i < machine->smp.cpus; i++) {
71
+ case 1:
124
+ DeviceState *cpudev = DEVICE(mms->cpu[i]);
72
+ return Gran4K;
125
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&mms->gic);
73
+ case 2:
126
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
74
+ return Gran16K;
127
+ int irq;
75
+ case 3:
128
+ /*
76
+ return Gran64K;
129
+ * Mapping from the output timer irq lines from the CPU to the
77
+ default:
130
+ * GIC PPI inputs used for this board. This isn't a BSA board,
78
+ return GranInvalid;
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));
79
+ }
161
+ }
80
+}
162
+}
81
+
163
+
82
static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
164
static void mps3r_common_init(MachineState *machine)
83
uint64_t value)
84
{
165
{
85
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
86
uint64_t select = sextract64(value, 36, 1);
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
87
ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
88
TLBIRange ret = { };
169
memory_region_add_subregion(sysmem, ri->base, mr);
89
+ ARMGranuleSize gran;
90
91
page_size_granule = extract64(value, 46, 2);
92
+ gran = tlbi_range_tg_to_gran_size(page_size_granule);
93
94
/* The granule encoded in value must match the granule in use. */
95
- if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) {
96
+ if (gran != param.gran) {
97
qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
98
page_size_granule);
99
return ret;
100
}
170
}
101
171
+
102
- page_shift = (page_size_granule - 1) * 2 + 12;
172
+ assert(machine->smp.cpus <= MPS3R_CPU_MAX);
103
+ page_shift = arm_granule_bits(gran);
173
+ for (int i = 0; i < machine->smp.cpus; i++) {
104
num = extract64(value, 39, 5);
174
+ g_autofree char *sysmem_name = g_strdup_printf("cpu-%d-memory", i);
105
scale = extract64(value, 44, 2);
175
+ g_autofree char *ramname = g_strdup_printf("cpu-%d-memory", i);
106
exponent = (5 * scale) + 1;
176
+ g_autofree char *alias_name = g_strdup_printf("sysmem-alias-%d", i);
107
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
177
+
108
ARMMMUIdx mmu_idx, bool data)
178
+ /*
109
{
179
+ * Each CPU has some private RAM/peripherals, so create the container
110
uint64_t tcr = regime_tcr(env, mmu_idx);
180
+ * which will house those, with the whole-machine system memory being
111
- bool epd, hpd, using16k, using64k, tsz_oob, ds;
181
+ * used where there's no CPU-specific device. Note that we need the
112
+ bool epd, hpd, tsz_oob, ds;
182
+ * sysmem_alias aliases because we can't put one MR (the original
113
int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
183
+ * 'sysmem') into more than one other MR.
114
ARMGranuleSize gran;
184
+ */
115
ARMCPU *cpu = env_archcpu(env);
185
+ memory_region_init(&mms->cpu_sysmem[i], OBJECT(machine),
116
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
186
+ sysmem_name, UINT64_MAX);
117
}
187
+ memory_region_init_alias(&mms->sysmem_alias[i], OBJECT(machine),
118
188
+ alias_name, sysmem, 0, UINT64_MAX);
119
gran = sanitize_gran_size(cpu, gran, stage2);
189
+ memory_region_add_subregion_overlap(&mms->cpu_sysmem[i], 0,
120
- using64k = gran == Gran64K;
190
+ &mms->sysmem_alias[i], -1);
121
- using16k = gran == Gran16K;
191
+
122
192
+ mms->cpu[i] = object_new(machine->cpu_type);
123
if (cpu_isar_feature(aa64_st, cpu)) {
193
+ object_property_set_link(mms->cpu[i], "memory",
124
- max_tsz = 48 - using64k;
194
+ OBJECT(&mms->cpu_sysmem[i]), &error_abort);
125
+ max_tsz = 48 - (gran == Gran64K);
195
+ object_property_set_int(mms->cpu[i], "reset-cbar",
126
} else {
196
+ PERIPHBASE, &error_abort);
127
max_tsz = 39;
197
+ qdev_realize(DEVICE(mms->cpu[i]), NULL, &error_fatal);
128
}
198
+ object_unref(mms->cpu[i]);
129
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
199
+
130
* adjust the effective value of DS, as documented.
200
+ /* Per-CPU RAM */
131
*/
201
+ memory_region_init_ram(&mms->cpu_ram[i], NULL, ramname,
132
min_tsz = 16;
202
+ 0x1000, &error_fatal);
133
- if (using64k) {
203
+ memory_region_add_subregion(&mms->cpu_sysmem[i], 0xe7c01000,
134
+ if (gran == Gran64K) {
204
+ &mms->cpu_ram[i]);
135
if (cpu_isar_feature(aa64_lva, cpu)) {
205
+ }
136
min_tsz = 12;
206
+
137
}
207
+ create_gic(mms, sysmem);
138
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
208
+
139
switch (mmu_idx) {
209
+ mms->bootinfo.ram_size = machine->ram_size;
140
case ARMMMUIdx_Stage2:
210
+ mms->bootinfo.board_id = -1;
141
case ARMMMUIdx_Stage2_S:
211
+ mms->bootinfo.loader_start = mmc->loader_start;
142
- if (using16k) {
212
+ mms->bootinfo.write_secondary_boot = mps3r_write_secondary_boot;
143
+ if (gran == Gran16K) {
213
+ mms->bootinfo.secondary_cpu_reset_hook = mps3r_secondary_cpu_reset;
144
ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
214
+ arm_load_kernel(ARM_CPU(mms->cpu[0]), machine, &mms->bootinfo);
145
} else {
146
ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
147
}
148
break;
149
default:
150
- if (using16k) {
151
+ if (gran == Gran16K) {
152
ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
153
} else {
154
ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
155
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
156
.tbi = tbi,
157
.epd = epd,
158
.hpd = hpd,
159
- .using16k = using16k,
160
- .using64k = using64k,
161
.tsz_oob = tsz_oob,
162
.ds = ds,
163
+ .gran = gran,
164
};
165
}
215
}
166
216
167
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
168
index XXXXXXX..XXXXXXX 100644
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
169
--- a/target/arm/ptw.c
219
/* Found the entry for "system memory" */
170
+++ b/target/arm/ptw.c
220
mc->default_ram_size = p->size;
171
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
221
mc->default_ram_id = p->name;
222
+ mmc->loader_start = p->base;
223
return;
172
}
224
}
173
}
225
}
174
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
175
- if (param.using64k) {
227
};
176
- stride = 13;
228
177
- } else if (param.using16k) {
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
178
- stride = 11;
230
- mc->default_cpus = 2;
179
- } else {
231
- mc->min_cpus = mc->default_cpus;
180
- stride = 9;
232
- mc->max_cpus = mc->default_cpus;
181
- }
233
+ /*
182
+ stride = arm_granule_bits(param.gran) - 3;
234
+ * In the real FPGA image there are always two cores, but the standard
183
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
184
/*
236
+ * that the second core is held in reset and halted. Many images built for
185
* Note that QEMU ignores shareability and cacheability attributes,
237
+ * the board do not expect the second core to run at startup (especially
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
240
+ *
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
242
+ * with the default being -smp 1. This seems a more intuitive UI for
243
+ * QEMU users than, for instance, having a machine property to allow
244
+ * the user to set the initial value of the SYSCON 0x000 register.
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;
186
--
252
--
187
2.25.1
253
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Connect and wire them all up; this involves some OR gates where
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
multiple overflow interrupts are wired into one GIC input.
5
Message-id: 20221001162318.153420-19-richard.henderson@linaro.org
9
6
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>
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
7
---
13
---
8
target/arm/ptw.c | 138 +++++++++++++++++++++++++----------------------
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
9
1 file changed, 74 insertions(+), 64 deletions(-)
15
1 file changed, 94 insertions(+)
10
16
11
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/ptw.c
19
--- a/hw/arm/mps3r.c
14
+++ b/target/arm/ptw.c
20
+++ b/hw/arm/mps3r.c
15
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
21
@@ -XXX,XX +XXX,XX @@
16
return ret;
22
#include "qapi/qmp/qlist.h"
23
#include "exec/address-spaces.h"
24
#include "cpu.h"
25
+#include "sysemu/sysemu.h"
26
#include "hw/boards.h"
27
+#include "hw/or-irq.h"
28
#include "hw/qdev-properties.h"
29
#include "hw/arm/boot.h"
30
#include "hw/arm/bsa.h"
31
+#include "hw/char/cmsdk-apb-uart.h"
32
#include "hw/intc/arm_gicv3.h"
33
34
/* Define the layout of RAM and ROM in a board */
35
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
36
37
#define MPS3R_RAM_MAX 9
38
#define MPS3R_CPU_MAX 2
39
+#define MPS3R_UART_MAX 4 /* shared UART count */
40
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.
62
+ */
63
+#define CLK_FRQ 50000000
64
+
65
static const RAMInfo an536_raminfo[] = {
66
{
67
.name = "ATCM",
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
69
}
17
}
70
}
18
71
19
+/*
72
+/*
20
+ * MMU disabled. S1 addresses within aa64 translation regimes are
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
21
+ * still checked for bounds -- see AArch64.S1DisabledOutput().
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
22
+ */
75
+ */
23
+static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
24
+ MMUAccessType access_type,
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
25
+ ARMMMUIdx mmu_idx, bool is_secure,
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
26
+ GetPhysAddrResult *result,
79
+ qemu_irq combirq)
27
+ ARMMMUFaultInfo *fi)
28
+{
80
+{
29
+ uint64_t hcr;
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
30
+ uint8_t memattr;
82
+ SysBusDevice *sbd;
31
+
83
+
32
+ if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
84
+ assert(uartno < ARRAY_SIZE(mms->uart));
33
+ int r_el = regime_el(env, mmu_idx);
85
+ object_initialize_child(OBJECT(mms), s, &mms->uart[uartno],
34
+ if (arm_el_is_aa64(env, r_el)) {
86
+ TYPE_CMSDK_APB_UART);
35
+ int pamax = arm_pamax(env_archcpu(env));
87
+ qdev_prop_set_uint32(DEVICE(&mms->uart[uartno]), "pclk-frq", CLK_FRQ);
36
+ uint64_t tcr = env->cp15.tcr_el[r_el];
88
+ qdev_prop_set_chr(DEVICE(&mms->uart[uartno]), "chardev", serial_hd(uartno));
37
+ int addrtop, tbi;
89
+ sbd = SYS_BUS_DEVICE(&mms->uart[uartno]);
38
+
90
+ sysbus_realize(sbd, &error_fatal);
39
+ tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
91
+ memory_region_add_subregion(mem, baseaddr,
40
+ if (access_type == MMU_INST_FETCH) {
92
+ sysbus_mmio_get_region(sbd, 0));
41
+ tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
93
+ sysbus_connect_irq(sbd, 0, txirq);
42
+ }
94
+ sysbus_connect_irq(sbd, 1, rxirq);
43
+ tbi = (tbi >> extract64(address, 55, 1)) & 1;
95
+ sysbus_connect_irq(sbd, 2, txoverirq);
44
+ addrtop = (tbi ? 55 : 63);
96
+ sysbus_connect_irq(sbd, 3, rxoverirq);
45
+
97
+ sysbus_connect_irq(sbd, 4, combirq);
46
+ if (extract64(address, pamax, addrtop - pamax + 1) != 0) {
47
+ fi->type = ARMFault_AddressSize;
48
+ fi->level = 0;
49
+ fi->stage2 = false;
50
+ return 1;
51
+ }
52
+
53
+ /*
54
+ * When TBI is disabled, we've just validated that all of the
55
+ * bits above PAMax are zero, so logically we only need to
56
+ * clear the top byte for TBI. But it's clearer to follow
57
+ * the pseudocode set of addrdesc.paddress.
58
+ */
59
+ address = extract64(address, 0, 52);
60
+ }
61
+ }
62
+
63
+ result->phys = address;
64
+ result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
65
+ result->page_size = TARGET_PAGE_SIZE;
66
+
67
+ /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
68
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
69
+ result->cacheattrs.shareability = 0;
70
+ result->cacheattrs.is_s2_format = false;
71
+ if (hcr & HCR_DC) {
72
+ if (hcr & HCR_DCT) {
73
+ memattr = 0xf0; /* Tagged, Normal, WB, RWA */
74
+ } else {
75
+ memattr = 0xff; /* Normal, WB, RWA */
76
+ }
77
+ } else if (access_type == MMU_INST_FETCH) {
78
+ if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
79
+ memattr = 0xee; /* Normal, WT, RA, NT */
80
+ } else {
81
+ memattr = 0x44; /* Normal, NC, No */
82
+ }
83
+ result->cacheattrs.shareability = 2; /* outer sharable */
84
+ } else {
85
+ memattr = 0x00; /* Device, nGnRnE */
86
+ }
87
+ result->cacheattrs.attrs = memattr;
88
+ return 0;
89
+}
98
+}
90
+
99
+
91
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
100
static void mps3r_common_init(MachineState *machine)
92
MMUAccessType access_type, ARMMMUIdx mmu_idx,
101
{
93
bool is_secure, GetPhysAddrResult *result,
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
94
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
95
/* Definitely a real MMU, not an MPU */
104
MemoryRegion *sysmem = get_system_memory();
96
105
+ DeviceState *gicdev;
97
if (regime_translation_disabled(env, mmu_idx, is_secure)) {
106
98
- uint64_t hcr;
107
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
99
- uint8_t memattr;
108
MemoryRegion *mr = mr_for_raminfo(mms, ri);
100
-
109
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
101
- /*
102
- * MMU disabled. S1 addresses within aa64 translation regimes are
103
- * still checked for bounds -- see AArch64.TranslateAddressS1Off.
104
- */
105
- if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
106
- int r_el = regime_el(env, mmu_idx);
107
- if (arm_el_is_aa64(env, r_el)) {
108
- int pamax = arm_pamax(env_archcpu(env));
109
- uint64_t tcr = env->cp15.tcr_el[r_el];
110
- int addrtop, tbi;
111
-
112
- tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
113
- if (access_type == MMU_INST_FETCH) {
114
- tbi &= ~aa64_va_parameter_tbid(tcr, mmu_idx);
115
- }
116
- tbi = (tbi >> extract64(address, 55, 1)) & 1;
117
- addrtop = (tbi ? 55 : 63);
118
-
119
- if (extract64(address, pamax, addrtop - pamax + 1) != 0) {
120
- fi->type = ARMFault_AddressSize;
121
- fi->level = 0;
122
- fi->stage2 = false;
123
- return 1;
124
- }
125
-
126
- /*
127
- * When TBI is disabled, we've just validated that all of the
128
- * bits above PAMax are zero, so logically we only need to
129
- * clear the top byte for TBI. But it's clearer to follow
130
- * the pseudocode set of addrdesc.paddress.
131
- */
132
- address = extract64(address, 0, 52);
133
- }
134
- }
135
- result->phys = address;
136
- result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
137
- result->page_size = TARGET_PAGE_SIZE;
138
-
139
- /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
140
- hcr = arm_hcr_el2_eff_secstate(env, is_secure);
141
- result->cacheattrs.shareability = 0;
142
- result->cacheattrs.is_s2_format = false;
143
- if (hcr & HCR_DC) {
144
- if (hcr & HCR_DCT) {
145
- memattr = 0xf0; /* Tagged, Normal, WB, RWA */
146
- } else {
147
- memattr = 0xff; /* Normal, WB, RWA */
148
- }
149
- } else if (access_type == MMU_INST_FETCH) {
150
- if (regime_sctlr(env, mmu_idx) & SCTLR_I) {
151
- memattr = 0xee; /* Normal, WT, RA, NT */
152
- } else {
153
- memattr = 0x44; /* Normal, NC, No */
154
- }
155
- result->cacheattrs.shareability = 2; /* outer sharable */
156
- } else {
157
- memattr = 0x00; /* Device, nGnRnE */
158
- }
159
- result->cacheattrs.attrs = memattr;
160
- return 0;
161
+ return get_phys_addr_disabled(env, address, access_type, mmu_idx,
162
+ is_secure, result, fi);
163
}
110
}
164
-
111
165
if (regime_using_lpae_format(env, mmu_idx)) {
112
create_gic(mms, sysmem);
166
return get_phys_addr_lpae(env, address, access_type, mmu_idx,
113
+ gicdev = DEVICE(&mms->gic);
167
is_secure, false, result, fi);
114
+
115
+ /*
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
118
+ */
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
122
+ DeviceState *orgate;
123
+
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
126
+ TYPE_OR_IRQ);
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
129
+ qdev_realize(orgate, NULL, &error_fatal);
130
+ qdev_connect_gpio_out(orgate, 0,
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
132
+
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
135
+ qdev_get_gpio_in(gicdev, intidbase + 16), /* rx */
136
+ qdev_get_gpio_in(orgate, 0), /* txover */
137
+ qdev_get_gpio_in(orgate, 1), /* rxover */
138
+ qdev_get_gpio_in(gicdev, intidbase + 18) /* combined */);
139
+ }
140
+ /*
141
+ * UARTs 2 to 5 are whole-system; all overflow IRQs are ORed
142
+ * together into IRQ 17
143
+ */
144
+ object_initialize_child(OBJECT(mms), "uart-oflow-orgate",
145
+ &mms->uart_oflow, TYPE_OR_IRQ);
146
+ qdev_prop_set_uint32(DEVICE(&mms->uart_oflow), "num-lines",
147
+ MPS3R_UART_MAX * 2);
148
+ qdev_realize(DEVICE(&mms->uart_oflow), NULL, &error_fatal);
149
+ qdev_connect_gpio_out(DEVICE(&mms->uart_oflow), 0,
150
+ qdev_get_gpio_in(gicdev, 17));
151
+
152
+ for (int i = 0; i < MPS3R_UART_MAX; i++) {
153
+ hwaddr baseaddr = 0xe0205000 + i * 0x1000;
154
+ int rxirq = 5 + i * 2, txirq = 6 + i * 2, combirq = 13 + i;
155
+
156
+ create_uart(mms, i + MPS3R_CPU_MAX, sysmem, baseaddr,
157
+ qdev_get_gpio_in(gicdev, txirq),
158
+ qdev_get_gpio_in(gicdev, rxirq),
159
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2),
160
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2 + 1),
161
+ qdev_get_gpio_in(gicdev, combirq));
162
+ }
163
164
mms->bootinfo.ram_size = machine->ram_size;
165
mms->bootinfo.board_id = -1;
168
--
166
--
169
2.25.1
167
2.34.1
168
169
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
Remove the use of regime_is_secure from get_phys_addr_lpae,
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
using the new parameter instead.
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
8
---
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 59 insertions(+)
5
11
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221001162318.153420-3-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/ptw.c | 20 ++++++++++----------
12
1 file changed, 10 insertions(+), 10 deletions(-)
13
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
14
--- a/hw/arm/mps3r.c
17
+++ b/target/arm/ptw.c
15
+++ b/hw/arm/mps3r.c
18
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
19
17
#include "sysemu/sysemu.h"
20
static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
18
#include "hw/boards.h"
21
MMUAccessType access_type, ARMMMUIdx mmu_idx,
19
#include "hw/or-irq.h"
22
- bool s1_is_el0, GetPhysAddrResult *result,
20
+#include "hw/qdev-clock.h"
23
- ARMMMUFaultInfo *fi)
21
#include "hw/qdev-properties.h"
24
+ bool is_secure, bool s1_is_el0,
22
#include "hw/arm/boot.h"
25
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
23
#include "hw/arm/bsa.h"
26
__attribute__((nonnull));
24
#include "hw/char/cmsdk-apb-uart.h"
27
25
+#include "hw/i2c/arm_sbcon_i2c.h"
28
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
26
#include "hw/intc/arm_gicv3.h"
29
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
27
+#include "hw/misc/unimp.h"
30
GetPhysAddrResult s2 = {};
28
+#include "hw/timer/cmsdk-apb-dualtimer.h"
31
int ret;
29
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
32
30
33
- ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, false,
31
/* Define the layout of RAM and ROM in a board */
34
- &s2, fi);
32
typedef struct RAMInfo {
35
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
33
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
36
+ *is_secure, false, &s2, fi);
34
CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
37
if (ret) {
35
OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
38
assert(fi->type != ARMFault_None);
36
OrIRQState uart_oflow;
39
fi->s2addr = addr;
37
+ CMSDKAPBWatchdog watchdog;
40
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
38
+ CMSDKAPBDualTimer dualtimer;
41
*/
39
+ ArmSbconI2CState i2c[5];
42
static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
40
+ Clock *clk;
43
MMUAccessType access_type, ARMMMUIdx mmu_idx,
41
};
44
- bool s1_is_el0, GetPhysAddrResult *result,
42
45
- ARMMMUFaultInfo *fi)
43
#define TYPE_MPS3R_MACHINE "mps3r"
46
+ bool is_secure, bool s1_is_el0,
44
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
47
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
45
MemoryRegion *sysmem = get_system_memory();
48
{
46
DeviceState *gicdev;
49
ARMCPU *cpu = env_archcpu(env);
47
50
/* Read an LPAE long-descriptor translation table. */
48
+ mms->clk = clock_new(OBJECT(machine), "CLK");
51
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
49
+ clock_set_hz(mms->clk, CLK_FRQ);
52
* remain non-secure. We implement this by just ORing in the NSTable/NS
50
+
53
* bits at each step.
51
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
54
*/
52
MemoryRegion *mr = mr_for_raminfo(mms, ri);
55
- tableattrs = regime_is_secure(env, mmu_idx) ? 0 : (1 << 4);
53
memory_region_add_subregion(sysmem, ri->base, mr);
56
+ tableattrs = is_secure ? 0 : (1 << 4);
54
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
57
for (;;) {
55
qdev_get_gpio_in(gicdev, combirq));
58
uint64_t descriptor;
59
bool nstable;
60
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
61
memset(result, 0, sizeof(*result));
62
63
ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx,
64
- is_el0, result, fi);
65
+ s2walk_secure, is_el0, result, fi);
66
fi->s2addr = ipa;
67
68
/* Combine the S1 and S2 perms. */
69
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
70
}
56
}
71
57
72
if (regime_using_lpae_format(env, mmu_idx)) {
58
+ for (int i = 0; i < 4; i++) {
73
- return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
59
+ /* CMSDK GPIO controllers */
74
- result, fi);
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
75
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx,
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
76
+ is_secure, false, result, fi);
62
+ }
77
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
63
+
78
return get_phys_addr_v6(env, address, access_type, mmu_idx,
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
79
is_secure, result, fi);
65
+ TYPE_CMSDK_APB_WATCHDOG);
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
67
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
68
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
69
+ qdev_get_gpio_in(gicdev, 0));
70
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0xe0100000);
71
+
72
+ object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
73
+ TYPE_CMSDK_APB_DUALTIMER);
74
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->clk);
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
76
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
77
+ qdev_get_gpio_in(gicdev, 3));
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 1,
79
+ qdev_get_gpio_in(gicdev, 1));
80
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 2,
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.
100
+ */
101
+ qbus_mark_full(qdev_get_child_bus(DEVICE(&mms->i2c[i]), "i2c"));
102
+ }
103
+ }
104
+
105
mms->bootinfo.ram_size = machine->ram_size;
106
mms->bootinfo.board_id = -1;
107
mms->bootinfo.loader_start = mmc->loader_start;
80
--
108
--
81
2.25.1
109
2.34.1
82
110
83
111
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add the remaining devices (or unimplemented-device stubs) for
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
3
QSPI write-config block, and ethernet.
2
4
3
Use arm_hcr_el2_eff_secstate instead of arm_hcr_el2_eff, so
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
that we use is_secure instead of the current security state.
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
These AT* operations have been broken since arm_hcr_el2_eff
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
6
gained a check for "el2 enabled" for Secure EL2.
8
---
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 74 insertions(+)
7
11
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20221001162318.153420-18-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/ptw.c | 8 ++++----
14
1 file changed, 4 insertions(+), 4 deletions(-)
15
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/ptw.c
14
--- a/hw/arm/mps3r.c
19
+++ b/target/arm/ptw.c
15
+++ b/hw/arm/mps3r.c
20
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
16
@@ -XXX,XX +XXX,XX @@
17
#include "hw/char/cmsdk-apb-uart.h"
18
#include "hw/i2c/arm_sbcon_i2c.h"
19
#include "hw/intc/arm_gicv3.h"
20
+#include "hw/misc/mps2-scc.h"
21
+#include "hw/misc/mps2-fpgaio.h"
22
#include "hw/misc/unimp.h"
23
+#include "hw/net/lan9118.h"
24
+#include "hw/rtc/pl031.h"
25
+#include "hw/ssi/pl022.h"
26
#include "hw/timer/cmsdk-apb-dualtimer.h"
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
28
29
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
30
CMSDKAPBWatchdog watchdog;
31
CMSDKAPBDualTimer dualtimer;
32
ArmSbconI2CState i2c[5];
33
+ PL022State spi[3];
34
+ MPS2SCC scc;
35
+ MPS2FPGAIO fpgaio;
36
+ UnimplementedDeviceState i2s_audio;
37
+ PL031State rtc;
38
Clock *clk;
39
};
40
41
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an536_raminfo[] = {
42
}
43
};
44
45
+static const int an536_oscclk[] = {
46
+ 24000000, /* 24MHz reference for RTC and timers */
47
+ 50000000, /* 50MHz ACLK */
48
+ 50000000, /* 50MHz MCLK */
49
+ 50000000, /* 50MHz GPUCLK */
50
+ 24576000, /* 24.576MHz AUDCLK */
51
+ 23750000, /* 23.75MHz HDLCDCLK */
52
+ 100000000, /* 100MHz DDR4_REF_CLK */
53
+};
54
+
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
56
const RAMInfo *raminfo)
57
{
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
60
MemoryRegion *sysmem = get_system_memory();
61
DeviceState *gicdev;
62
+ QList *oscclk;
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)
21
}
67
}
22
}
68
}
23
69
24
- hcr_el2 = arm_hcr_el2_eff(env);
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
25
+ hcr_el2 = arm_hcr_el2_eff_secstate(env, is_secure);
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
26
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
27
switch (mmu_idx) {
73
+
28
case ARMMMUIdx_Stage2:
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
29
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
30
return ~0;
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
31
}
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
32
78
+ qdev_get_gpio_in(gicdev, 22 + i));
33
- hcr = arm_hcr_el2_eff(env);
79
+ }
34
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
80
+
35
if ((hcr & HCR_PTW) && ptw_attrs_are_device(hcr, s2.cacheattrs)) {
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
36
/*
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
37
* PTW set and S1 walk touched S2 Device memory:
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
38
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
39
}
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
40
86
+ oscclk = qlist_new();
41
/* Combine the S1 and S2 cache attributes. */
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
42
- hcr = arm_hcr_el2_eff(env);
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
43
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
89
+ }
44
if (hcr & HCR_DC) {
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
45
/*
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
46
* HCR.DC forces the first stage attributes to
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
47
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
93
+
48
result->page_size = TARGET_PAGE_SIZE;
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
49
95
+
50
/* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
51
- hcr = arm_hcr_el2_eff(env);
97
+ TYPE_MPS2_FPGAIO);
52
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
53
result->cacheattrs.shareability = 0;
99
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "num-leds", 10);
54
result->cacheattrs.is_s2_format = false;
100
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-switches", true);
55
if (hcr & HCR_DC) {
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;
56
--
126
--
57
2.25.1
127
2.34.1
128
129
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
Add documentation for the mps3-an536 board type.
2
2
3
openpower.xyz was retired some time ago. The OpenBMC Jenkins is where
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
images can be found these days.
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
6
---
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
8
1 file changed, 34 insertions(+), 3 deletions(-)
5
9
6
Signed-off-by: Joel Stanley <joel@jms.id.au>
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20221004050042.22681-1-joel@jms.id.au
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
docs/system/arm/nuvoton.rst | 4 ++--
14
1 file changed, 2 insertions(+), 2 deletions(-)
15
16
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/nuvoton.rst
12
--- a/docs/system/arm/mps2.rst
19
+++ b/docs/system/arm/nuvoton.rst
13
+++ b/docs/system/arm/mps2.rst
20
@@ -XXX,XX +XXX,XX @@ Boot options
14
@@ -XXX,XX +XXX,XX @@
21
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
22
The Nuvoton machines can boot from an OpenBMC firmware image, or directly into
16
-=========================================================================================================================================================
23
a kernel using the ``-kernel`` option. OpenBMC images for ``quanta-gsj`` and
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
24
-possibly others can be downloaded from the OpenPOWER jenkins :
18
+=========================================================================================================================================================================
25
+possibly others can be downloaded from the OpenBMC jenkins :
19
26
20
-These board models all use Arm M-profile CPUs.
27
- https://openpower.xyz/
21
+These board models use Arm M-profile or R-profile CPUs.
28
+ https://jenkins.openbmc.org/
22
29
23
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
30
The firmware image should be attached as an MTD drive. Example :
24
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
31
25
@@ -XXX,XX +XXX,XX @@ FPGA image.
26
27
QEMU models the following FPGA images:
28
29
+FPGA images using M-profile CPUs:
30
+
31
``mps2-an385``
32
Cortex-M3 as documented in Arm Application Note AN385
33
``mps2-an386``
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
35
``mps3-an547``
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
37
38
+FPGA images using R-profile CPUs:
39
+
40
+``mps3-an536``
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
42
+
43
Differences between QEMU and real hardware:
44
45
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
46
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
47
flash, but only as simple ROM, so attempting to rewrite the flash
48
from the guest will fail
49
- QEMU does not model the USB controller in MPS3 boards
50
+- AN536 does not support runtime control of CPU reset and halt via
51
+ the SCC CFG_REG0 register.
52
+- AN536 does not support enabling or disabling the flash and ATCM
53
+ interfaces via the SCC CFG_REG1 register.
54
+- AN536 does not support setting of the initial vector table
55
+ base address via the SCC CFG_REG6 and CFG_REG7 register config,
56
+ and does not provide a mechanism for specifying these values at
57
+ startup, so all guest images must be built to start from TCM
58
+ (i.e. to expect the interrupt vector base at 0 from reset).
59
+- AN536 defaults to only creating a single CPU; this is the equivalent
60
+ of the way the real FPGA image usually runs with the second Cortex-R52
61
+ held in halt via the initial SCC CFG_REG0 register setting. You can
62
+ create the second CPU with ``-smp 2``; both CPUs will then start
63
+ execution immediately on startup.
64
+
65
+Note that for the AN536 the first UART is accessible only by
66
+CPU0, and the second UART is accessible only by CPU1. The
67
+first UART accessible shared between both CPUs is the third
68
+UART. Guest software might therefore be built to use either
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
""""""""""""""""""""""""
32
--
77
--
33
2.25.1
78
2.34.1
34
79
35
80
diff view generated by jsdifflib