1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
1
Some arm patches; my to-review queue is by no means empty, but
2
this is a big enough set of patches to be getting on with...
2
3
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit cb9c6a8e5ad6a1f0ce164d352e3102df46986e22:
6
7
7
The following changes since commit 2ef486e76d64436be90f7359a3071fb2a56ce835:
8
.gitlab-ci.d/windows: Work-around timeout and OpenGL problems of the MSYS2 jobs (2023-01-04 18:58:33 +0000)
8
9
Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into staging (2020-05-03 14:12:56 +0100)
10
9
11
are available in the Git repository at:
10
are available in the Git repository at:
12
11
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230105
14
13
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
14
for you to fetch changes up to 93c9678de9dc7d2e68f9e8477da072bac30ef132:
16
15
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
16
hw/net: Fix read of uninitialized memory in imx_fec. (2023-01-05 15:33:00 +0000)
18
17
19
----------------------------------------------------------------
18
----------------------------------------------------------------
20
target-arm queue:
19
target-arm queue:
21
* Start of conversion of Neon insns to decodetree
20
* Implement AArch32 ARMv8-R support
22
* versal board: support SD and RTC
21
* Add Cortex-R52 CPU
23
* Implement ARMv8.2-TTS2UXN
22
* fix handling of HLT semihosting in system mode
24
* Make VQDMULL undefined when U=1
23
* hw/timer/ixm_epit: cleanup and fix bug in compare handling
25
* Some minor code cleanups
24
* target/arm: Coding style fixes
25
* target/arm: Clean up includes
26
* nseries: minor code cleanups
27
* target/arm: align exposed ID registers with Linux
28
* hw/arm/smmu-common: remove unnecessary inlines
29
* i.MX7D: Handle GPT timers
30
* i.MX7D: Connect IRQs to GPIO devices
31
* i.MX6UL: Add a specific GPT timer instance
32
* hw/net: Fix read of uninitialized memory in imx_fec
26
33
27
----------------------------------------------------------------
34
----------------------------------------------------------------
28
Edgar E. Iglesias (11):
35
Alex Bennée (1):
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
36
target/arm: fix handling of HLT semihosting in system mode
30
hw/arm: versal: Move misplaced comment
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
32
hw/arm: versal: Embed the UARTs into the SoC type
33
hw/arm: versal: Embed the GEMs into the SoC type
34
hw/arm: versal: Embed the ADMAs into the SoC type
35
hw/arm: versal: Embed the APUs into the SoC type
36
hw/arm: versal: Add support for SD
37
hw/arm: versal: Add support for the RTC
38
hw/arm: versal-virt: Add support for SD
39
hw/arm: versal-virt: Add support for the RTC
40
37
41
Fredrik Strupe (1):
38
Axel Heider (8):
42
target/arm: Make VQDMULL undefined when U=1
39
hw/timer/imx_epit: improve comments
40
hw/timer/imx_epit: cleanup CR defines
41
hw/timer/imx_epit: define SR_OCIF
42
hw/timer/imx_epit: update interrupt state on CR write access
43
hw/timer/imx_epit: hard reset initializes CR with 0
44
hw/timer/imx_epit: factor out register write handlers
45
hw/timer/imx_epit: remove explicit fields cnt and freq
46
hw/timer/imx_epit: fix compare timer handling
43
47
44
Peter Maydell (25):
48
Claudio Fontana (1):
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
49
target/arm: cleanup cpu includes
46
target/arm: Use enum constant in get_phys_addr_lpae() call
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
48
target/arm: Implement ARMv8.2-TTS2UXN
49
target/arm: Use correct variable for setting 'max' cpu's ID_AA64DFR0
50
target/arm/translate-vfp.inc.c: Remove duplicate simd_r32 check
51
target/arm: Don't allow Thumb Neon insns without FEATURE_NEON
52
target/arm: Add stubs for AArch32 Neon decodetree
53
target/arm: Convert VCMLA (vector) to decodetree
54
target/arm: Convert VCADD (vector) to decodetree
55
target/arm: Convert V[US]DOT (vector) to decodetree
56
target/arm: Convert VFM[AS]L (vector) to decodetree
57
target/arm: Convert VCMLA (scalar) to decodetree
58
target/arm: Convert V[US]DOT (scalar) to decodetree
59
target/arm: Convert VFM[AS]L (scalar) to decodetree
60
target/arm: Convert Neon load/store multiple structures to decodetree
61
target/arm: Convert Neon 'load single structure to all lanes' to decodetree
62
target/arm: Convert Neon 'load/store single structure' to decodetree
63
target/arm: Convert Neon 3-reg-same VADD/VSUB to decodetree
64
target/arm: Convert Neon 3-reg-same logic ops to decodetree
65
target/arm: Convert Neon 3-reg-same VMAX/VMIN to decodetree
66
target/arm: Convert Neon 3-reg-same comparisons to decodetree
67
target/arm: Convert Neon 3-reg-same VQADD/VQSUB to decodetree
68
target/arm: Convert Neon 3-reg-same VMUL, VMLA, VMLS, VSHL to decodetree
69
target/arm: Move gen_ function typedefs to translate.h
70
50
71
Philippe Mathieu-Daudé (2):
51
Fabiano Rosas (5):
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
52
target/arm: Fix checkpatch comment style warnings in helper.c
73
target/arm: Use uint64_t for midr field in CPU state struct
53
target/arm: Fix checkpatch space errors in helper.c
54
target/arm: Fix checkpatch brace errors in helper.c
55
target/arm: Remove unused includes from m_helper.c
56
target/arm: Remove unused includes from helper.c
74
57
75
include/hw/arm/xlnx-versal.h | 31 +-
58
Jean-Christophe Dubois (4):
76
target/arm/cpu-param.h | 2 +-
59
i.MX7D: Connect GPT timers to IRQ
77
target/arm/cpu.h | 38 ++-
60
i.MX7D: Compute clock frequency for the fixed frequency clocks.
78
target/arm/translate-a64.h | 9 -
61
i.MX6UL: Add a specific GPT timer instance for the i.MX6UL
79
target/arm/translate.h | 26 ++
62
i.MX7D: Connect IRQs to GPIO devices.
80
target/arm/neon-dp.decode | 86 +++++
81
target/arm/neon-ls.decode | 52 +++
82
target/arm/neon-shared.decode | 66 ++++
83
hw/arm/mps2-tz.c | 2 +-
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
85
hw/arm/xlnx-versal.c | 115 +++++--
86
target/arm/cpu.c | 3 +-
87
target/arm/cpu64.c | 8 +-
88
target/arm/helper.c | 183 ++++------
89
target/arm/translate-a64.c | 17 -
90
target/arm/translate-neon.inc.c | 714 +++++++++++++++++++++++++++++++++++++++
91
target/arm/translate-vfp.inc.c | 6 -
92
target/arm/translate.c | 716 +++-------------------------------------
93
target/arm/Makefile.objs | 18 +
94
19 files changed, 1302 insertions(+), 864 deletions(-)
95
create mode 100644 target/arm/neon-dp.decode
96
create mode 100644 target/arm/neon-ls.decode
97
create mode 100644 target/arm/neon-shared.decode
98
create mode 100644 target/arm/translate-neon.inc.c
99
63
64
Peter Maydell (1):
65
target/arm:Set lg_page_size to 0 if either S1 or S2 asks for it
66
67
Philippe Mathieu-Daudé (5):
68
hw/input/tsc2xxx: Constify set_transform()'s MouseTransformInfo arg
69
hw/arm/nseries: Constify various read-only arrays
70
hw/arm/nseries: Silent -Wmissing-field-initializers warning
71
hw/arm/smmu-common: Reduce smmu_inv_notifiers_mr() scope
72
hw/arm/smmu-common: Avoid using inlined functions with external linkage
73
74
Stephen Longfield (1):
75
hw/net: Fix read of uninitialized memory in imx_fec.
76
77
Tobias Röhmel (7):
78
target/arm: Don't add all MIDR aliases for cores that implement PMSA
79
target/arm: Make RVBAR available for all ARMv8 CPUs
80
target/arm: Make stage_2_format for cache attributes optional
81
target/arm: Enable TTBCR_EAE for ARMv8-R AArch32
82
target/arm: Add PMSAv8r registers
83
target/arm: Add PMSAv8r functionality
84
target/arm: Add ARM Cortex-R52 CPU
85
86
Zhuojia Shen (1):
87
target/arm: align exposed ID registers with Linux
88
89
include/hw/arm/fsl-imx7.h | 20 +
90
include/hw/arm/smmu-common.h | 3 -
91
include/hw/input/tsc2xxx.h | 4 +-
92
include/hw/timer/imx_epit.h | 8 +-
93
include/hw/timer/imx_gpt.h | 1 +
94
target/arm/cpu.h | 6 +
95
target/arm/internals.h | 4 +
96
hw/arm/fsl-imx6ul.c | 2 +-
97
hw/arm/fsl-imx7.c | 41 +-
98
hw/arm/nseries.c | 28 +-
99
hw/arm/smmu-common.c | 15 +-
100
hw/input/tsc2005.c | 2 +-
101
hw/input/tsc210x.c | 3 +-
102
hw/misc/imx6ul_ccm.c | 6 -
103
hw/misc/imx7_ccm.c | 49 ++-
104
hw/net/imx_fec.c | 8 +-
105
hw/timer/imx_epit.c | 376 +++++++++-------
106
hw/timer/imx_gpt.c | 25 ++
107
target/arm/cpu.c | 35 +-
108
target/arm/cpu64.c | 6 -
109
target/arm/cpu_tcg.c | 42 ++
110
target/arm/debug_helper.c | 3 +
111
target/arm/helper.c | 871 +++++++++++++++++++++++++++++---------
112
target/arm/m_helper.c | 16 -
113
target/arm/machine.c | 28 ++
114
target/arm/ptw.c | 152 +++++--
115
target/arm/tlb_helper.c | 4 +
116
target/arm/translate.c | 2 +-
117
tests/tcg/aarch64/sysregs.c | 24 +-
118
tests/tcg/aarch64/Makefile.target | 7 +-
119
30 files changed, 1330 insertions(+), 461 deletions(-)
120
diff view generated by jsdifflib
1
Somewhere along theline we accidentally added a duplicate
1
In get_phys_addr_twostage() we set the lg_page_size of the result to
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
2
the maximum of the stage 1 and stage 2 page sizes. This works for
3
(probably an artifact of a patchseries rebase). Remove it.
3
the case where we do want to create a TLB entry, because we know the
4
common TLB code only creates entries of the TARGET_PAGE_SIZE and
5
asking for a size larger than that only means that invalidations
6
invalidate the whole larger area. However, if lg_page_size is
7
smaller than TARGET_PAGE_SIZE this effectively means "don't create a
8
TLB entry"; in this case if either S1 or S2 said "this covers less
9
than a page and can't go in a TLB" then the final result also should
10
be marked that way. Set the resulting page size to 0 if either
11
stage asked for a less-than-a-page entry, and expand the comment
12
to explain what's going on.
13
14
This has no effect for VMSA because currently the VMSA lookup always
15
returns results that cover at least TARGET_PAGE_SIZE; however when we
16
add v8R support it will reuse this code path, and for v8R the S1 and
17
S2 results can be smaller than TARGET_PAGE_SIZE.
4
18
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20221212142708.610090-1-peter.maydell@linaro.org
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
9
---
22
---
10
target/arm/translate-vfp.inc.c | 6 ------
23
target/arm/ptw.c | 16 +++++++++++++---
11
1 file changed, 6 deletions(-)
24
1 file changed, 13 insertions(+), 3 deletions(-)
12
25
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
26
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.inc.c
28
--- a/target/arm/ptw.c
16
+++ b/target/arm/translate-vfp.inc.c
29
+++ b/target/arm/ptw.c
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
18
return false;
19
}
31
}
20
32
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
33
/*
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
34
- * Use the maximum of the S1 & S2 page size, so that invalidation
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
35
- * of pages > TARGET_PAGE_SIZE works correctly.
24
- return false;
36
+ * If either S1 or S2 returned a result smaller than TARGET_PAGE_SIZE,
25
- }
37
+ * this means "don't put this in the TLB"; in this case, return a
26
-
38
+ * result with lg_page_size == 0 to achieve that. Otherwise,
27
if (!vfp_access_check(s)) {
39
+ * use the maximum of the S1 & S2 page size, so that invalidation
28
return true;
40
+ * of pages > TARGET_PAGE_SIZE works correctly. (This works even though
41
+ * we know the combined result permissions etc only cover the minimum
42
+ * of the S1 and S2 page size, because we know that the common TLB code
43
+ * never actually creates TLB entries bigger than TARGET_PAGE_SIZE,
44
+ * and passing a larger page size value only affects invalidations.)
45
*/
46
- if (result->f.lg_page_size < s1_lgpgsz) {
47
+ if (result->f.lg_page_size < TARGET_PAGE_BITS ||
48
+ s1_lgpgsz < TARGET_PAGE_BITS) {
49
+ result->f.lg_page_size = 0;
50
+ } else if (result->f.lg_page_size < s1_lgpgsz) {
51
result->f.lg_page_size = s1_lgpgsz;
29
}
52
}
53
30
--
54
--
31
2.20.1
55
2.25.1
32
33
diff view generated by jsdifflib
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
3-reg-same grouping to decodetree.
3
2
3
Cores with PMSA have the MPUIR register which has the
4
same encoding as the MIDR alias with opc2=4. So we only
5
add that alias if we are not realizing a core that
6
implements PMSA.
7
8
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20221206102504.165775-2-tobias.roehmel@rwth-aachen.de
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
7
---
13
---
8
target/arm/neon-dp.decode | 9 +++++++
14
target/arm/helper.c | 13 +++++++++----
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
15
1 file changed, 9 insertions(+), 4 deletions(-)
10
target/arm/translate.c | 28 +++------------------
11
3 files changed, 56 insertions(+), 25 deletions(-)
12
16
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
19
--- a/target/arm/helper.c
16
+++ b/target/arm/neon-dp.decode
20
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
21
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
22
.access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
23
.fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
20
24
.readfn = midr_read },
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
25
- /* crn = 0 op1 = 0 crm = 0 op2 = 4,7 : AArch32 aliases of MIDR */
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
26
- { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
23
+
27
- .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
28
- .access = PL1_R, .resetvalue = cpu->midr },
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
29
+ /* crn = 0 op1 = 0 crm = 0 op2 = 7 : AArch32 aliases of MIDR */
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
30
{ .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
31
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7,
28
32
.access = PL1_R, .resetvalue = cpu->midr },
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
33
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
34
.accessfn = access_aa64_tid1,
31
+
35
.type = ARM_CP_CONST, .resetvalue = cpu->revidr },
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
36
};
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
37
+ ARMCPRegInfo id_v8_midr_alias_cp_reginfo = {
34
+
38
+ .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
39
+ .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
40
+ .access = PL1_R, .resetvalue = cpu->midr
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
41
+ };
38
index XXXXXXX..XXXXXXX 100644
42
ARMCPRegInfo id_cp_reginfo[] = {
39
--- a/target/arm/translate-neon.inc.c
43
/* These are common to v8 and pre-v8 */
40
+++ b/target/arm/translate-neon.inc.c
44
{ .name = "CTR",
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
46
}
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
47
if (arm_feature(env, ARM_FEATURE_V8)) {
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
48
define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo);
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
49
+ if (!arm_feature(env, ARM_FEATURE_PMSA)) {
46
50
+ define_one_arm_cp_reg(cpu, &id_v8_midr_alias_cp_reginfo);
47
#define DO_3SAME_CMP(INSN, COND) \
51
+ }
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
52
} else {
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
53
define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
53
+
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
56
+{
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
58
+ 0, gen_helper_gvec_pmul_b);
59
+}
60
+
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
62
+{
63
+ if (a->size != 0) {
64
+ return false;
65
+ }
66
+ return do_3same(s, a, gen_VMUL_p_3s);
67
+}
68
+
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
72
+ uint32_t oprsz, uint32_t maxsz) \
73
+ { \
74
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
75
+ oprsz, maxsz, &OPARRAY[vece]); \
76
+ } \
77
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
78
+
79
+
80
+DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
81
+DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
82
+
83
+#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
84
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
85
+ uint32_t rn_ofs, uint32_t rm_ofs, \
86
+ uint32_t oprsz, uint32_t maxsz) \
87
+ { \
88
+ /* Note the operation is vshl vd,vm,vn */ \
89
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
90
+ oprsz, maxsz, &OPARRAY[vece]); \
91
+ } \
92
+ DO_3SAME(INSN, gen_##INSN##_3s)
93
+
94
+DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
95
+DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
}
102
return 1;
103
104
- case NEON_3R_VMUL: /* VMUL */
105
- if (u) {
106
- /* Polynomial case allows only P8. */
107
- if (size != 0) {
108
- return 1;
109
- }
110
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
111
- 0, gen_helper_gvec_pmul_b);
112
- } else {
113
- tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
114
- vec_size, vec_size);
115
- }
116
- return 0;
117
-
118
- case NEON_3R_VML: /* VMLA, VMLS */
119
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
120
- u ? &mls_op[size] : &mla_op[size]);
121
- return 0;
122
-
123
- case NEON_3R_VSHL:
124
- /* Note the operation is vshl vd,vm,vn */
125
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
126
- u ? &ushl_op[size] : &sshl_op[size]);
127
- return 0;
128
-
129
case NEON_3R_VADD_VSUB:
130
case NEON_3R_LOGIC:
131
case NEON_3R_VMAX:
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
133
case NEON_3R_VCGE:
134
case NEON_3R_VQADD:
135
case NEON_3R_VQSUB:
136
+ case NEON_3R_VMUL:
137
+ case NEON_3R_VML:
138
+ case NEON_3R_VSHL:
139
/* Already handled by decodetree */
140
return 1;
141
}
54
}
142
--
55
--
143
2.20.1
56
2.25.1
144
57
145
58
diff view generated by jsdifflib
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
translation table descriptors from just bit [54] to bits [54:53],
3
allowing stage 2 to control execution permissions separately for EL0
4
and EL1. Implement the new semantics of the XN field and enable
5
the feature for our 'max' CPU.
6
2
3
RVBAR shadows RVBAR_ELx where x is the highest exception
4
level if the highest EL is not EL3. This patch also allows
5
ARMv8 CPUs to change the reset address with
6
the rvbar property.
7
8
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20221206102504.165775-3-tobias.roehmel@rwth-aachen.de
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
11
---
12
---
12
target/arm/cpu.h | 15 +++++++++++++++
13
target/arm/cpu.c | 6 +++++-
13
target/arm/cpu.c | 1 +
14
target/arm/helper.c | 21 ++++++++++++++-------
14
target/arm/cpu64.c | 2 ++
15
2 files changed, 19 insertions(+), 8 deletions(-)
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
16
4 files changed, 49 insertions(+), 6 deletions(-)
17
16
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
24
}
25
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
27
+{
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
29
+}
30
+
31
/*
32
* 64-bit feature tests via id registers.
33
*/
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
36
}
37
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
39
+{
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
41
+}
42
+
43
/*
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
45
*/
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
48
}
49
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
51
+{
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
53
+}
54
+
55
/*
56
* Forward to the above feature tests given an ARMCPU pointer.
57
*/
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
59
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/cpu.c
19
--- a/target/arm/cpu.c
61
+++ b/target/arm/cpu.c
20
+++ b/target/arm/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj)
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
22
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
23
CPACR, CP11, 3);
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
67
cpu->isar.id_mmfr4 = t;
68
}
69
#endif
24
#endif
70
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
25
+ if (arm_feature(env, ARM_FEATURE_V8)) {
71
index XXXXXXX..XXXXXXX 100644
26
+ env->cp15.rvbar = cpu->rvbar_prop;
72
--- a/target/arm/cpu64.c
27
+ env->regs[15] = cpu->rvbar_prop;
73
+++ b/target/arm/cpu64.c
28
+ }
74
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
29
}
75
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
30
76
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
31
#if defined(CONFIG_USER_ONLY)
77
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
32
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
78
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
33
qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property);
79
cpu->isar.id_aa64mmfr1 = t;
34
}
80
35
81
t = cpu->isar.id_aa64mmfr2;
36
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
37
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
83
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
38
object_property_add_uint64_ptr(obj, "rvbar",
84
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
39
&cpu->rvbar_prop,
85
u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
40
OBJ_PROP_FLAG_READWRITE);
86
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
87
cpu->isar.id_mmfr4 = u;
88
89
u = cpu->isar.id_aa64dfr0;
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/helper.c
43
--- a/target/arm/helper.c
93
+++ b/target/arm/helper.c
44
+++ b/target/arm/helper.c
94
@@ -XXX,XX +XXX,XX @@ simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
95
*
46
if (!arm_feature(env, ARM_FEATURE_EL3) &&
96
* @env: CPUARMState
47
!arm_feature(env, ARM_FEATURE_EL2)) {
97
* @s2ap: The 2-bit stage2 access permissions (S2AP)
48
ARMCPRegInfo rvbar = {
98
- * @xn: XN (execute-never) bit
49
- .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64,
99
+ * @xn: XN (execute-never) bits
50
+ .name = "RVBAR_EL1", .state = ARM_CP_STATE_BOTH,
100
+ * @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
51
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
101
*/
52
.access = PL1_R,
102
-static int get_S2prot(CPUARMState *env, int s2ap, int xn)
53
.fieldoffset = offsetof(CPUARMState, cp15.rvbar),
103
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
54
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
104
{
55
}
105
int prot = 0;
56
/* RVBAR_EL2 is only implemented if EL2 is the highest EL */
106
57
if (!arm_feature(env, ARM_FEATURE_EL3)) {
107
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
58
- ARMCPRegInfo rvbar = {
108
if (s2ap & 2) {
59
- .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
109
prot |= PAGE_WRITE;
60
- .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
110
}
61
- .access = PL2_R,
111
- if (!xn) {
62
- .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
63
+ ARMCPRegInfo rvbar[] = {
113
+
64
+ {
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
65
+ .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
115
+ switch (xn) {
66
+ .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
116
+ case 0:
67
+ .access = PL2_R,
117
prot |= PAGE_EXEC;
68
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
118
+ break;
69
+ },
119
+ case 1:
70
+ { .name = "RVBAR", .type = ARM_CP_ALIAS,
120
+ if (s1_is_el0) {
71
+ .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
121
+ prot |= PAGE_EXEC;
72
+ .access = PL2_R,
122
+ }
73
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
123
+ break;
74
+ },
124
+ case 2:
75
};
125
+ break;
76
- define_one_arm_cp_reg(cpu, &rvbar);
126
+ case 3:
77
+ define_arm_cp_regs(cpu, rvbar);
127
+ if (!s1_is_el0) {
128
+ prot |= PAGE_EXEC;
129
+ }
130
+ break;
131
+ default:
132
+ g_assert_not_reached();
133
+ }
134
+ } else {
135
+ if (!extract32(xn, 1, 1)) {
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
137
+ prot |= PAGE_EXEC;
138
+ }
139
}
78
}
140
}
79
}
141
return prot;
80
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
143
}
144
145
ap = extract32(attrs, 4, 2);
146
- xn = extract32(attrs, 12, 1);
147
148
if (mmu_idx == ARMMMUIdx_Stage2) {
149
ns = true;
150
- *prot = get_S2prot(env, ap, xn);
151
+ xn = extract32(attrs, 11, 2);
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
153
} else {
154
ns = extract32(attrs, 3, 1);
155
+ xn = extract32(attrs, 12, 1);
156
pxn = extract32(attrs, 11, 1);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
158
}
159
--
81
--
160
2.20.1
82
2.25.1
161
83
162
84
diff view generated by jsdifflib
1
We're going to want at least some of the NeonGen* typedefs
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
for the refactored 32-bit Neon decoder, so move them all
3
to translate.h since it makes more sense to keep them in
4
one group.
5
2
3
The v8R PMSAv8 has a two-stage MPU translation process, but, unlike
4
VMSAv8, the stage 2 attributes are in the same format as the stage 1
5
attributes (8-bit MAIR format). Rather than converting the MAIR
6
format to the format used for VMSA stage 2 (bits [5:2] of a VMSA
7
stage 2 descriptor) and then converting back to do the attribute
8
combination, allow combined_attrs_nofwb() to accept s2 attributes
9
that are already in the MAIR format.
10
11
We move the assert() to combined_attrs_fwb(), because that function
12
really does require a VMSA stage 2 attribute format. (We will never
13
get there for v8R, because PMSAv8 does not implement FEAT_S2FWB.)
14
15
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20221206102504.165775-4-tobias.roehmel@rwth-aachen.de
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200430181003.21682-23-peter.maydell@linaro.org
9
---
19
---
10
target/arm/translate.h | 17 +++++++++++++++++
20
target/arm/ptw.c | 10 ++++++++--
11
target/arm/translate-a64.c | 17 -----------------
21
1 file changed, 8 insertions(+), 2 deletions(-)
12
2 files changed, 17 insertions(+), 17 deletions(-)
13
22
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
23
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
25
--- a/target/arm/ptw.c
17
+++ b/target/arm/translate.h
26
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
27
@@ -XXX,XX +XXX,XX @@ static uint8_t combined_attrs_nofwb(uint64_t hcr,
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
28
{
20
uint32_t, uint32_t, uint32_t);
29
uint8_t s1lo, s2lo, s1hi, s2hi, s2_mair_attrs, ret_attrs;
21
30
22
+/* Function prototype for gen_ functions for calling Neon helpers */
31
- s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
32
+ if (s2.is_s2_format) {
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
33
+ s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
34
+ } else {
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
35
+ s2_mair_attrs = s2.attrs;
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
36
+ }
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
37
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
38
s1lo = extract32(s1.attrs, 0, 4);
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
39
s2lo = extract32(s2_mair_attrs, 0, 4);
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
40
@@ -XXX,XX +XXX,XX @@ static uint8_t force_cacheattr_nibble_wb(uint8_t attr)
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
41
*/
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
42
static uint8_t combined_attrs_fwb(ARMCacheAttrs s1, ARMCacheAttrs s2)
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
43
{
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
44
+ assert(s2.is_s2_format && !s1.is_s2_format);
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
38
+
45
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
46
switch (s2.attrs) {
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
47
case 7:
41
index XXXXXXX..XXXXXXX 100644
48
/* Use stage 1 attributes */
42
--- a/target/arm/translate-a64.c
49
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
43
+++ b/target/arm/translate-a64.c
50
ARMCacheAttrs ret;
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
51
bool tagged = false;
45
AArch64DecodeFn *disas_fn;
52
46
} AArch64DecodeTable;
53
- assert(s2.is_s2_format && !s1.is_s2_format);
47
54
+ assert(!s1.is_s2_format);
48
-/* Function prototype for gen_ functions for calling Neon helpers */
55
ret.is_s2_format = false;
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
56
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
57
if (s1.attrs == 0xf0) {
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
64
-
65
/* initialize TCG globals. */
66
void a64_translate_init(void)
67
{
68
--
58
--
69
2.20.1
59
2.25.1
70
60
71
61
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Note that we don't need the neon_3r_sizes[op] check here because all
3
ARMv8-R AArch32 CPUs behave as if TTBCR.EAE is always 1 even
4
size values are OK for VADD and VSUB; we'll add this when we convert
4
tough they don't have the TTBCR register.
5
the first insn that has size restrictions.
5
See ARM Architecture Reference Manual Supplement - ARMv8, for the ARMv8-R
6
AArch32 architecture profile Version:A.c section C1.2.
6
7
7
For this we need one of the GVecGen*Fn typedefs currently in
8
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
8
translate-a64.h; move them all to translate.h as a block so they
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
are visible to the 32-bit decoder.
10
Message-id: 20221206102504.165775-5-tobias.roehmel@rwth-aachen.de
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/internals.h | 4 ++++
14
target/arm/debug_helper.c | 3 +++
15
target/arm/tlb_helper.c | 4 ++++
16
3 files changed, 11 insertions(+)
10
17
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
diff --git a/target/arm/internals.h b/target/arm/internals.h
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
14
---
15
target/arm/translate-a64.h | 9 --------
16
target/arm/translate.h | 9 ++++++++
17
target/arm/neon-dp.decode | 17 +++++++++++++++
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
19
target/arm/translate.c | 14 ++++--------
20
5 files changed, 68 insertions(+), 19 deletions(-)
21
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
23
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate-a64.h
20
--- a/target/arm/internals.h
25
+++ b/target/arm/translate-a64.h
21
+++ b/target/arm/internals.h
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
22
@@ -XXX,XX +XXX,XX @@ unsigned int arm_pamax(ARMCPU *cpu);
27
23
static inline bool extended_addresses_enabled(CPUARMState *env)
28
bool disas_sve(DisasContext *, uint32_t);
24
{
29
25
uint64_t tcr = env->cp15.tcr_el[arm_is_secure(env) ? 3 : 1];
30
-/* Note that the gvec expanders operate on offsets + sizes. */
26
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
27
+ arm_feature(env, ARM_FEATURE_V8)) {
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
33
- uint32_t, uint32_t);
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
35
- uint32_t, uint32_t, uint32_t);
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
37
- uint32_t, uint32_t, uint32_t);
38
-
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate.h
43
+++ b/target/arm/translate.h
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
45
#define dc_isar_feature(name, ctx) \
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
47
48
+/* Note that the gvec expanders operate on offsets + sizes. */
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
51
+ uint32_t, uint32_t);
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
53
+ uint32_t, uint32_t, uint32_t);
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
55
+ uint32_t, uint32_t, uint32_t);
56
+
57
#endif /* TARGET_ARM_TRANSLATE_H */
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/neon-dp.decode
61
+++ b/target/arm/neon-dp.decode
62
@@ -XXX,XX +XXX,XX @@
63
#
64
# This file is processed by scripts/decodetree.py
65
#
66
+# VFP/Neon register fields; same as vfp.decode
67
+%vm_dp 5:1 0:4
68
+%vn_dp 7:1 16:4
69
+%vd_dp 22:1 12:4
70
71
# Encodings for Neon data processing instructions where the T32 encoding
72
# is a simple transformation of the A32 encoding.
73
@@ -XXX,XX +XXX,XX @@
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
75
# This file works on the A32 encoding only; calling code for T32 has to
76
# transform the insn into the A32 version first.
77
+
78
+######################################################################
79
+# 3-reg-same grouping:
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
81
+######################################################################
82
+
83
+&3same vm vn vd q size
84
+
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
87
+
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
93
+++ b/target/arm/translate-neon.inc.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
95
96
return true;
97
}
98
+
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
100
+{
101
+ int vec_size = a->q ? 16 : 8;
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
105
+
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
107
+ return false;
108
+ }
109
+
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
113
+ return false;
114
+ }
115
+
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
117
+ return false;
118
+ }
119
+
120
+ if (!vfp_access_check(s)) {
121
+ return true;
28
+ return true;
122
+ }
29
+ }
123
+
30
return arm_el_is_aa64(env, 1) ||
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
31
(arm_feature(env, ARM_FEATURE_LPAE) && (tcr & TTBCR_EAE));
125
+ return true;
32
}
126
+}
33
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
127
+
34
index XXXXXXX..XXXXXXX 100644
128
+#define DO_3SAME(INSN, FUNC) \
35
--- a/target/arm/debug_helper.c
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
36
+++ b/target/arm/debug_helper.c
130
+ { \
37
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_debug_exception_fsr(CPUARMState *env)
131
+ return do_3same(s, a, FUNC); \
38
39
if (target_el == 2 || arm_el_is_aa64(env, target_el)) {
40
using_lpae = true;
41
+ } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
42
+ arm_feature(env, ARM_FEATURE_V8)) {
43
+ using_lpae = true;
44
} else {
45
if (arm_feature(env, ARM_FEATURE_LPAE) &&
46
(env->cp15.tcr_el[target_el] & TTBCR_EAE)) {
47
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/tlb_helper.c
50
+++ b/target/arm/tlb_helper.c
51
@@ -XXX,XX +XXX,XX @@ bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
52
if (el == 2 || arm_el_is_aa64(env, el)) {
53
return true;
54
}
55
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
56
+ arm_feature(env, ARM_FEATURE_V8)) {
57
+ return true;
132
+ }
58
+ }
133
+
59
if (arm_feature(env, ARM_FEATURE_LPAE)
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
60
&& (regime_tcr(env, mmu_idx) & TTBCR_EAE)) {
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
61
return true;
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/translate.c
139
+++ b/target/arm/translate.c
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
141
}
142
return 0;
143
144
- case NEON_3R_VADD_VSUB:
145
- if (u) {
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
147
- vec_size, vec_size);
148
- } else {
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
150
- vec_size, vec_size);
151
- }
152
- return 0;
153
-
154
case NEON_3R_VQADD:
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
156
rn_ofs, rm_ofs, vec_size, vec_size,
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
159
u ? &ushl_op[size] : &sshl_op[size]);
160
return 0;
161
+
162
+ case NEON_3R_VADD_VSUB:
163
+ /* Already handled by decodetree */
164
+ return 1;
165
}
166
167
if (size == 3) {
168
--
62
--
169
2.20.1
63
2.25.1
170
64
171
65
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
3
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
4
Message-id: 20221206102504.165775-6-tobias.roehmel@rwth-aachen.de
5
uint32_t.
6
7
This fixes an error when compiling with -Werror=conversion
8
because we were manipulating the register value using a
9
local uint64_t variable:
10
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
12
target/arm/cpu64.c:628:21: error: conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Werror=conversion]
13
628 | cpu->midr = t;
14
| ^
15
16
and future-proofs us against a possible future architecture
17
change using some of the top 32 bits.
18
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
6
---
27
target/arm/cpu.h | 2 +-
7
target/arm/cpu.h | 6 +
28
target/arm/cpu.c | 2 +-
8
target/arm/cpu.c | 28 +++-
29
2 files changed, 2 insertions(+), 2 deletions(-)
9
target/arm/helper.c | 302 +++++++++++++++++++++++++++++++++++++++++++
10
target/arm/machine.c | 28 ++++
11
4 files changed, 360 insertions(+), 4 deletions(-)
30
12
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
15
--- a/target/arm/cpu.h
34
+++ b/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
17
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
36
uint64_t id_aa64dfr0;
18
};
37
uint64_t id_aa64dfr1;
19
uint64_t sctlr_el[4];
38
} isar;
20
};
39
- uint32_t midr;
21
+ uint64_t vsctlr; /* Virtualization System control register. */
40
+ uint64_t midr;
22
uint64_t cpacr_el1; /* Architectural feature access control register */
41
uint32_t revidr;
23
uint64_t cptr_el[4]; /* ARMv8 feature trap registers */
42
uint32_t reset_fpsid;
24
uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */
43
uint32_t ctr;
25
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
26
*/
27
uint32_t *rbar[M_REG_NUM_BANKS];
28
uint32_t *rlar[M_REG_NUM_BANKS];
29
+ uint32_t *hprbar;
30
+ uint32_t *hprlar;
31
uint32_t mair0[M_REG_NUM_BANKS];
32
uint32_t mair1[M_REG_NUM_BANKS];
33
+ uint32_t hprselr;
34
} pmsav8;
35
36
/* v8M SAU */
37
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
38
bool has_mpu;
39
/* PMSAv7 MPU number of supported regions */
40
uint32_t pmsav7_dregion;
41
+ /* PMSAv8 MPU number of supported hyp regions */
42
+ uint32_t pmsav8r_hdregion;
43
/* v8M SAU number of supported regions */
44
uint32_t sau_sregion;
45
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.c
48
--- a/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
49
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
50
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj)
49
static Property arm_cpu_properties[] = {
51
sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
52
}
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
53
}
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
54
+
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
55
+ if (cpu->pmsav8r_hdregion > 0) {
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
56
+ memset(env->pmsav8.hprbar, 0,
55
mp_affinity, ARM64_AFFINITY_INVALID),
57
+ sizeof(*env->pmsav8.hprbar) * cpu->pmsav8r_hdregion);
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
58
+ memset(env->pmsav8.hprlar, 0,
59
+ sizeof(*env->pmsav8.hprlar) * cpu->pmsav8r_hdregion);
60
+ }
61
+
62
env->pmsav7.rnr[M_REG_NS] = 0;
63
env->pmsav7.rnr[M_REG_S] = 0;
64
env->pmsav8.mair0[M_REG_NS] = 0;
65
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
66
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
67
* to false or by setting pmsav7-dregion to 0.
68
*/
69
- if (!cpu->has_mpu) {
70
- cpu->pmsav7_dregion = 0;
71
- }
72
- if (cpu->pmsav7_dregion == 0) {
73
+ if (!cpu->has_mpu || cpu->pmsav7_dregion == 0) {
74
cpu->has_mpu = false;
75
+ cpu->pmsav7_dregion = 0;
76
+ cpu->pmsav8r_hdregion = 0;
77
}
78
79
if (arm_feature(env, ARM_FEATURE_PMSA) &&
80
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
81
env->pmsav7.dracr = g_new0(uint32_t, nr);
82
}
83
}
84
+
85
+ if (cpu->pmsav8r_hdregion > 0xff) {
86
+ error_setg(errp, "PMSAv8 MPU EL2 #regions invalid %" PRIu32,
87
+ cpu->pmsav8r_hdregion);
88
+ return;
89
+ }
90
+
91
+ if (cpu->pmsav8r_hdregion) {
92
+ env->pmsav8.hprbar = g_new0(uint32_t,
93
+ cpu->pmsav8r_hdregion);
94
+ env->pmsav8.hprlar = g_new0(uint32_t,
95
+ cpu->pmsav8r_hdregion);
96
+ }
97
}
98
99
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
100
diff --git a/target/arm/helper.c b/target/arm/helper.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/helper.c
103
+++ b/target/arm/helper.c
104
@@ -XXX,XX +XXX,XX @@ static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri,
105
raw_write(env, ri, value);
106
}
107
108
+static void prbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
109
+ uint64_t value)
110
+{
111
+ ARMCPU *cpu = env_archcpu(env);
112
+
113
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
114
+ env->pmsav8.rbar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]] = value;
115
+}
116
+
117
+static uint64_t prbar_read(CPUARMState *env, const ARMCPRegInfo *ri)
118
+{
119
+ return env->pmsav8.rbar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]];
120
+}
121
+
122
+static void prlar_write(CPUARMState *env, const ARMCPRegInfo *ri,
123
+ uint64_t value)
124
+{
125
+ ARMCPU *cpu = env_archcpu(env);
126
+
127
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
128
+ env->pmsav8.rlar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]] = value;
129
+}
130
+
131
+static uint64_t prlar_read(CPUARMState *env, const ARMCPRegInfo *ri)
132
+{
133
+ return env->pmsav8.rlar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]];
134
+}
135
+
136
+static void prselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
137
+ uint64_t value)
138
+{
139
+ ARMCPU *cpu = env_archcpu(env);
140
+
141
+ /*
142
+ * Ignore writes that would select not implemented region.
143
+ * This is architecturally UNPREDICTABLE.
144
+ */
145
+ if (value >= cpu->pmsav7_dregion) {
146
+ return;
147
+ }
148
+
149
+ env->pmsav7.rnr[M_REG_NS] = value;
150
+}
151
+
152
+static void hprbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
153
+ uint64_t value)
154
+{
155
+ ARMCPU *cpu = env_archcpu(env);
156
+
157
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
158
+ env->pmsav8.hprbar[env->pmsav8.hprselr] = value;
159
+}
160
+
161
+static uint64_t hprbar_read(CPUARMState *env, const ARMCPRegInfo *ri)
162
+{
163
+ return env->pmsav8.hprbar[env->pmsav8.hprselr];
164
+}
165
+
166
+static void hprlar_write(CPUARMState *env, const ARMCPRegInfo *ri,
167
+ uint64_t value)
168
+{
169
+ ARMCPU *cpu = env_archcpu(env);
170
+
171
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
172
+ env->pmsav8.hprlar[env->pmsav8.hprselr] = value;
173
+}
174
+
175
+static uint64_t hprlar_read(CPUARMState *env, const ARMCPRegInfo *ri)
176
+{
177
+ return env->pmsav8.hprlar[env->pmsav8.hprselr];
178
+}
179
+
180
+static void hprenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
+ uint64_t value)
182
+{
183
+ uint32_t n;
184
+ uint32_t bit;
185
+ ARMCPU *cpu = env_archcpu(env);
186
+
187
+ /* Ignore writes to unimplemented regions */
188
+ int rmax = MIN(cpu->pmsav8r_hdregion, 32);
189
+ value &= MAKE_64BIT_MASK(0, rmax);
190
+
191
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
192
+
193
+ /* Register alias is only valid for first 32 indexes */
194
+ for (n = 0; n < rmax; ++n) {
195
+ bit = extract32(value, n, 1);
196
+ env->pmsav8.hprlar[n] = deposit32(
197
+ env->pmsav8.hprlar[n], 0, 1, bit);
198
+ }
199
+}
200
+
201
+static uint64_t hprenr_read(CPUARMState *env, const ARMCPRegInfo *ri)
202
+{
203
+ uint32_t n;
204
+ uint32_t result = 0x0;
205
+ ARMCPU *cpu = env_archcpu(env);
206
+
207
+ /* Register alias is only valid for first 32 indexes */
208
+ for (n = 0; n < MIN(cpu->pmsav8r_hdregion, 32); ++n) {
209
+ if (env->pmsav8.hprlar[n] & 0x1) {
210
+ result |= (0x1 << n);
211
+ }
212
+ }
213
+ return result;
214
+}
215
+
216
+static void hprselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
217
+ uint64_t value)
218
+{
219
+ ARMCPU *cpu = env_archcpu(env);
220
+
221
+ /*
222
+ * Ignore writes that would select not implemented region.
223
+ * This is architecturally UNPREDICTABLE.
224
+ */
225
+ if (value >= cpu->pmsav8r_hdregion) {
226
+ return;
227
+ }
228
+
229
+ env->pmsav8.hprselr = value;
230
+}
231
+
232
+static void pmsav8r_regn_write(CPUARMState *env, const ARMCPRegInfo *ri,
233
+ uint64_t value)
234
+{
235
+ ARMCPU *cpu = env_archcpu(env);
236
+ uint8_t index = (extract32(ri->opc0, 0, 1) << 4) |
237
+ (extract32(ri->crm, 0, 3) << 1) | extract32(ri->opc2, 2, 1);
238
+
239
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
240
+
241
+ if (ri->opc1 & 4) {
242
+ if (index >= cpu->pmsav8r_hdregion) {
243
+ return;
244
+ }
245
+ if (ri->opc2 & 0x1) {
246
+ env->pmsav8.hprlar[index] = value;
247
+ } else {
248
+ env->pmsav8.hprbar[index] = value;
249
+ }
250
+ } else {
251
+ if (index >= cpu->pmsav7_dregion) {
252
+ return;
253
+ }
254
+ if (ri->opc2 & 0x1) {
255
+ env->pmsav8.rlar[M_REG_NS][index] = value;
256
+ } else {
257
+ env->pmsav8.rbar[M_REG_NS][index] = value;
258
+ }
259
+ }
260
+}
261
+
262
+static uint64_t pmsav8r_regn_read(CPUARMState *env, const ARMCPRegInfo *ri)
263
+{
264
+ ARMCPU *cpu = env_archcpu(env);
265
+ uint8_t index = (extract32(ri->opc0, 0, 1) << 4) |
266
+ (extract32(ri->crm, 0, 3) << 1) | extract32(ri->opc2, 2, 1);
267
+
268
+ if (ri->opc1 & 4) {
269
+ if (index >= cpu->pmsav8r_hdregion) {
270
+ return 0x0;
271
+ }
272
+ if (ri->opc2 & 0x1) {
273
+ return env->pmsav8.hprlar[index];
274
+ } else {
275
+ return env->pmsav8.hprbar[index];
276
+ }
277
+ } else {
278
+ if (index >= cpu->pmsav7_dregion) {
279
+ return 0x0;
280
+ }
281
+ if (ri->opc2 & 0x1) {
282
+ return env->pmsav8.rlar[M_REG_NS][index];
283
+ } else {
284
+ return env->pmsav8.rbar[M_REG_NS][index];
285
+ }
286
+ }
287
+}
288
+
289
+static const ARMCPRegInfo pmsav8r_cp_reginfo[] = {
290
+ { .name = "PRBAR",
291
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 0,
292
+ .access = PL1_RW, .type = ARM_CP_NO_RAW,
293
+ .accessfn = access_tvm_trvm,
294
+ .readfn = prbar_read, .writefn = prbar_write },
295
+ { .name = "PRLAR",
296
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 1,
297
+ .access = PL1_RW, .type = ARM_CP_NO_RAW,
298
+ .accessfn = access_tvm_trvm,
299
+ .readfn = prlar_read, .writefn = prlar_write },
300
+ { .name = "PRSELR", .resetvalue = 0,
301
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 2, .opc2 = 1,
302
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
303
+ .writefn = prselr_write,
304
+ .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]) },
305
+ { .name = "HPRBAR", .resetvalue = 0,
306
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 0,
307
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
308
+ .readfn = hprbar_read, .writefn = hprbar_write },
309
+ { .name = "HPRLAR",
310
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 1,
311
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
312
+ .readfn = hprlar_read, .writefn = hprlar_write },
313
+ { .name = "HPRSELR", .resetvalue = 0,
314
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 2, .opc2 = 1,
315
+ .access = PL2_RW,
316
+ .writefn = hprselr_write,
317
+ .fieldoffset = offsetof(CPUARMState, pmsav8.hprselr) },
318
+ { .name = "HPRENR",
319
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 1, .opc2 = 1,
320
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
321
+ .readfn = hprenr_read, .writefn = hprenr_write },
322
+};
323
+
324
static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
325
/* Reset for all these registers is handled in arm_cpu_reset(),
326
* because the PMSAv7 is also used by M-profile CPUs, which do
327
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
328
.access = PL1_R, .type = ARM_CP_CONST,
329
.resetvalue = cpu->pmsav7_dregion << 8
330
};
331
+ /* HMPUIR is specific to PMSA V8 */
332
+ ARMCPRegInfo id_hmpuir_reginfo = {
333
+ .name = "HMPUIR",
334
+ .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 4,
335
+ .access = PL2_R, .type = ARM_CP_CONST,
336
+ .resetvalue = cpu->pmsav8r_hdregion
337
+ };
338
static const ARMCPRegInfo crn0_wi_reginfo = {
339
.name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
340
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
341
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
342
define_arm_cp_regs(cpu, id_cp_reginfo);
343
if (!arm_feature(env, ARM_FEATURE_PMSA)) {
344
define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
345
+ } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
346
+ arm_feature(env, ARM_FEATURE_V8)) {
347
+ uint32_t i = 0;
348
+ char *tmp_string;
349
+
350
+ define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
351
+ define_one_arm_cp_reg(cpu, &id_hmpuir_reginfo);
352
+ define_arm_cp_regs(cpu, pmsav8r_cp_reginfo);
353
+
354
+ /* Register alias is only valid for first 32 indexes */
355
+ for (i = 0; i < MIN(cpu->pmsav7_dregion, 32); ++i) {
356
+ uint8_t crm = 0b1000 | extract32(i, 1, 3);
357
+ uint8_t opc1 = extract32(i, 4, 1);
358
+ uint8_t opc2 = extract32(i, 0, 1) << 2;
359
+
360
+ tmp_string = g_strdup_printf("PRBAR%u", i);
361
+ ARMCPRegInfo tmp_prbarn_reginfo = {
362
+ .name = tmp_string, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
363
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
364
+ .access = PL1_RW, .resetvalue = 0,
365
+ .accessfn = access_tvm_trvm,
366
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
367
+ };
368
+ define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo);
369
+ g_free(tmp_string);
370
+
371
+ opc2 = extract32(i, 0, 1) << 2 | 0x1;
372
+ tmp_string = g_strdup_printf("PRLAR%u", i);
373
+ ARMCPRegInfo tmp_prlarn_reginfo = {
374
+ .name = tmp_string, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
375
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
376
+ .access = PL1_RW, .resetvalue = 0,
377
+ .accessfn = access_tvm_trvm,
378
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
379
+ };
380
+ define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo);
381
+ g_free(tmp_string);
382
+ }
383
+
384
+ /* Register alias is only valid for first 32 indexes */
385
+ for (i = 0; i < MIN(cpu->pmsav8r_hdregion, 32); ++i) {
386
+ uint8_t crm = 0b1000 | extract32(i, 1, 3);
387
+ uint8_t opc1 = 0b100 | extract32(i, 4, 1);
388
+ uint8_t opc2 = extract32(i, 0, 1) << 2;
389
+
390
+ tmp_string = g_strdup_printf("HPRBAR%u", i);
391
+ ARMCPRegInfo tmp_hprbarn_reginfo = {
392
+ .name = tmp_string,
393
+ .type = ARM_CP_NO_RAW,
394
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
395
+ .access = PL2_RW, .resetvalue = 0,
396
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
397
+ };
398
+ define_one_arm_cp_reg(cpu, &tmp_hprbarn_reginfo);
399
+ g_free(tmp_string);
400
+
401
+ opc2 = extract32(i, 0, 1) << 2 | 0x1;
402
+ tmp_string = g_strdup_printf("HPRLAR%u", i);
403
+ ARMCPRegInfo tmp_hprlarn_reginfo = {
404
+ .name = tmp_string,
405
+ .type = ARM_CP_NO_RAW,
406
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
407
+ .access = PL2_RW, .resetvalue = 0,
408
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
409
+ };
410
+ define_one_arm_cp_reg(cpu, &tmp_hprlarn_reginfo);
411
+ g_free(tmp_string);
412
+ }
413
} else if (arm_feature(env, ARM_FEATURE_V7)) {
414
define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
415
}
416
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
417
sctlr.type |= ARM_CP_SUPPRESS_TB_END;
418
}
419
define_one_arm_cp_reg(cpu, &sctlr);
420
+
421
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
422
+ arm_feature(env, ARM_FEATURE_V8)) {
423
+ ARMCPRegInfo vsctlr = {
424
+ .name = "VSCTLR", .state = ARM_CP_STATE_AA32,
425
+ .cp = 15, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
426
+ .access = PL2_RW, .resetvalue = 0x0,
427
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.vsctlr),
428
+ };
429
+ define_one_arm_cp_reg(cpu, &vsctlr);
430
+ }
431
}
432
433
if (cpu_isar_feature(aa64_lor, cpu)) {
434
diff --git a/target/arm/machine.c b/target/arm/machine.c
435
index XXXXXXX..XXXXXXX 100644
436
--- a/target/arm/machine.c
437
+++ b/target/arm/machine.c
438
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_needed(void *opaque)
439
arm_feature(env, ARM_FEATURE_V8);
440
}
441
442
+static bool pmsav8r_needed(void *opaque)
443
+{
444
+ ARMCPU *cpu = opaque;
445
+ CPUARMState *env = &cpu->env;
446
+
447
+ return arm_feature(env, ARM_FEATURE_PMSA) &&
448
+ arm_feature(env, ARM_FEATURE_V8) &&
449
+ !arm_feature(env, ARM_FEATURE_M);
450
+}
451
+
452
+static const VMStateDescription vmstate_pmsav8r = {
453
+ .name = "cpu/pmsav8/pmsav8r",
454
+ .version_id = 1,
455
+ .minimum_version_id = 1,
456
+ .needed = pmsav8r_needed,
457
+ .fields = (VMStateField[]) {
458
+ VMSTATE_VARRAY_UINT32(env.pmsav8.hprbar, ARMCPU,
459
+ pmsav8r_hdregion, 0, vmstate_info_uint32, uint32_t),
460
+ VMSTATE_VARRAY_UINT32(env.pmsav8.hprlar, ARMCPU,
461
+ pmsav8r_hdregion, 0, vmstate_info_uint32, uint32_t),
462
+ VMSTATE_END_OF_LIST()
463
+ },
464
+};
465
+
466
static const VMStateDescription vmstate_pmsav8 = {
467
.name = "cpu/pmsav8",
468
.version_id = 1,
469
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav8 = {
470
VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
471
VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),
472
VMSTATE_END_OF_LIST()
473
+ },
474
+ .subsections = (const VMStateDescription * []) {
475
+ &vmstate_pmsav8r,
476
+ NULL
477
}
478
};
479
57
--
480
--
58
2.20.1
481
2.25.1
59
482
60
483
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Add support for SD.
3
Add PMSAv8r translation.
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Message-id: 20221206102504.165775-7-tobias.roehmel@rwth-aachen.de
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
10
target/arm/ptw.c | 126 ++++++++++++++++++++++++++++++++++++++---------
12
1 file changed, 46 insertions(+)
11
1 file changed, 104 insertions(+), 22 deletions(-)
13
12
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
13
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
15
--- a/target/arm/ptw.c
17
+++ b/hw/arm/xlnx-versal-virt.c
16
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
19
#include "hw/arm/sysbus-fdt.h"
18
20
#include "hw/arm/fdt.h"
19
if (arm_feature(env, ARM_FEATURE_M)) {
21
#include "cpu.h"
20
return env->v7m.mpu_ctrl[is_secure] & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
22
+#include "hw/qdev-properties.h"
21
- } else {
23
#include "hw/arm/xlnx-versal.h"
22
- return regime_sctlr(env, mmu_idx) & SCTLR_BR;
24
23
}
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
24
+
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
25
+ if (mmu_idx == ARMMMUIdx_Stage2) {
27
}
26
+ return false;
27
+ }
28
+
29
+ return regime_sctlr(env, mmu_idx) & SCTLR_BR;
28
}
30
}
29
31
30
+static void fdt_add_sd_nodes(VersalVirt *s)
32
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
33
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
34
return !(result->f.prot & (1 << access_type));
35
}
36
37
+static uint32_t *regime_rbar(CPUARMState *env, ARMMMUIdx mmu_idx,
38
+ uint32_t secure)
31
+{
39
+{
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
40
+ if (regime_el(env, mmu_idx) == 2) {
33
+ const char compat[] = "arasan,sdhci-8.9a";
41
+ return env->pmsav8.hprbar;
34
+ int i;
42
+ } else {
35
+
43
+ return env->pmsav8.rbar[secure];
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
39
+
40
+ qemu_fdt_add_subnode(s->fdt, name);
41
+
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
44
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
45
+ clocknames, sizeof(clocknames));
46
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
47
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 2,
48
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
49
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
50
+ 2, addr, 2, MM_PMC_SD0_SIZE);
51
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
52
+ g_free(name);
53
+ }
44
+ }
54
+}
45
+}
55
+
46
+
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
47
+static uint32_t *regime_rlar(CPUARMState *env, ARMMMUIdx mmu_idx,
57
{
48
+ uint32_t secure)
58
Error *err = NULL;
49
+{
59
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
50
+ if (regime_el(env, mmu_idx) == 2) {
60
}
51
+ return env->pmsav8.hprlar;
52
+ } else {
53
+ return env->pmsav8.rlar[secure];
54
+ }
55
+}
56
+
57
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
58
MMUAccessType access_type, ARMMMUIdx mmu_idx,
59
bool secure, GetPhysAddrResult *result,
60
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
61
bool hit = false;
62
uint32_t addr_page_base = address & TARGET_PAGE_MASK;
63
uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
64
+ int region_counter;
65
+
66
+ if (regime_el(env, mmu_idx) == 2) {
67
+ region_counter = cpu->pmsav8r_hdregion;
68
+ } else {
69
+ region_counter = cpu->pmsav7_dregion;
70
+ }
71
72
result->f.lg_page_size = TARGET_PAGE_BITS;
73
result->f.phys_addr = address;
74
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
75
*mregion = -1;
76
}
77
78
+ if (mmu_idx == ARMMMUIdx_Stage2) {
79
+ fi->stage2 = true;
80
+ }
81
+
82
/*
83
* Unlike the ARM ARM pseudocode, we don't need to check whether this
84
* was an exception vector read from the vector table (which is always
85
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
86
hit = true;
87
}
88
89
- for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
90
+ uint32_t bitmask;
91
+ if (arm_feature(env, ARM_FEATURE_M)) {
92
+ bitmask = 0x1f;
93
+ } else {
94
+ bitmask = 0x3f;
95
+ fi->level = 0;
96
+ }
97
+
98
+ for (n = region_counter - 1; n >= 0; n--) {
99
/* region search */
100
/*
101
- * Note that the base address is bits [31:5] from the register
102
- * with bits [4:0] all zeroes, but the limit address is bits
103
- * [31:5] from the register with bits [4:0] all ones.
104
+ * Note that the base address is bits [31:x] from the register
105
+ * with bits [x-1:0] all zeroes, but the limit address is bits
106
+ * [31:x] from the register with bits [x:0] all ones. Where x is
107
+ * 5 for Cortex-M and 6 for Cortex-R
108
*/
109
- uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
110
- uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
111
+ uint32_t base = regime_rbar(env, mmu_idx, secure)[n] & ~bitmask;
112
+ uint32_t limit = regime_rlar(env, mmu_idx, secure)[n] | bitmask;
113
114
- if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
115
+ if (!(regime_rlar(env, mmu_idx, secure)[n] & 0x1)) {
116
/* Region disabled */
117
continue;
118
}
119
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
120
* PMSAv7 where highest-numbered-region wins)
121
*/
122
fi->type = ARMFault_Permission;
123
- fi->level = 1;
124
+ if (arm_feature(env, ARM_FEATURE_M)) {
125
+ fi->level = 1;
126
+ }
127
return true;
128
}
129
130
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
131
}
132
133
if (!hit) {
134
- /* background fault */
135
- fi->type = ARMFault_Background;
136
+ if (arm_feature(env, ARM_FEATURE_M)) {
137
+ fi->type = ARMFault_Background;
138
+ } else {
139
+ fi->type = ARMFault_Permission;
140
+ }
141
return true;
142
}
143
144
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
145
/* hit using the background region */
146
get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot);
147
} else {
148
- uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
149
- uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
150
+ uint32_t matched_rbar = regime_rbar(env, mmu_idx, secure)[matchregion];
151
+ uint32_t matched_rlar = regime_rlar(env, mmu_idx, secure)[matchregion];
152
+ uint32_t ap = extract32(matched_rbar, 1, 2);
153
+ uint32_t xn = extract32(matched_rbar, 0, 1);
154
bool pxn = false;
155
156
if (arm_feature(env, ARM_FEATURE_V8_1M)) {
157
- pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
158
+ pxn = extract32(matched_rlar, 4, 1);
159
}
160
161
if (m_is_system_region(env, address)) {
162
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
163
xn = 1;
164
}
165
166
- result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
167
+ if (regime_el(env, mmu_idx) == 2) {
168
+ result->f.prot = simple_ap_to_rw_prot_is_user(ap,
169
+ mmu_idx != ARMMMUIdx_E2);
170
+ } else {
171
+ result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
172
+ }
173
+
174
+ if (!arm_feature(env, ARM_FEATURE_M)) {
175
+ uint8_t attrindx = extract32(matched_rlar, 1, 3);
176
+ uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
177
+ uint8_t sh = extract32(matched_rlar, 3, 2);
178
+
179
+ if (regime_sctlr(env, mmu_idx) & SCTLR_WXN &&
180
+ result->f.prot & PAGE_WRITE && mmu_idx != ARMMMUIdx_Stage2) {
181
+ xn = 0x1;
182
+ }
183
+
184
+ if ((regime_el(env, mmu_idx) == 1) &&
185
+ regime_sctlr(env, mmu_idx) & SCTLR_UWXN && ap == 0x1) {
186
+ pxn = 0x1;
187
+ }
188
+
189
+ result->cacheattrs.is_s2_format = false;
190
+ result->cacheattrs.attrs = extract64(mair, attrindx * 8, 8);
191
+ result->cacheattrs.shareability = sh;
192
+ }
193
+
194
if (result->f.prot && !xn && !(pxn && !is_user)) {
195
result->f.prot |= PAGE_EXEC;
196
}
197
- /*
198
- * We don't need to look the attribute up in the MAIR0/MAIR1
199
- * registers because that only tells us about cacheability.
200
- */
201
+
202
if (mregion) {
203
*mregion = matchregion;
204
}
205
}
206
207
fi->type = ARMFault_Permission;
208
- fi->level = 1;
209
+ if (arm_feature(env, ARM_FEATURE_M)) {
210
+ fi->level = 1;
211
+ }
212
return !(result->f.prot & (1 << access_type));
61
}
213
}
62
214
63
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
215
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
64
+{
216
cacheattrs1 = result->cacheattrs;
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
217
memset(result, 0, sizeof(*result));
66
+ DeviceState *card;
218
67
+
219
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type, is_el0, result, fi);
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
220
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
221
+ ret = get_phys_addr_pmsav8(env, ipa, access_type,
70
+ &error_fatal);
222
+ ptw->in_mmu_idx, is_secure, result, fi);
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
223
+ } else {
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
224
+ ret = get_phys_addr_lpae(env, ptw, ipa, access_type,
73
+}
225
+ is_el0, result, fi);
74
+
226
+ }
75
static void versal_virt_init(MachineState *machine)
227
fi->s2addr = ipa;
76
{
228
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
229
/* Combine the S1 and S2 perms. */
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
79
+ int i;
80
81
/*
82
* If the user provides an Operating System to be loaded, we expect them
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
84
fdt_add_gic_nodes(s);
85
fdt_add_timer_nodes(s);
86
fdt_add_zdma_nodes(s);
87
+ fdt_add_sd_nodes(s);
88
fdt_add_cpu_nodes(s, psci_conduit);
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
92
memory_region_add_subregion_overlap(get_system_memory(),
93
0, &s->soc.fpd.apu.mr, 0);
94
95
+ /* Plugin SD cards. */
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
98
+ }
99
+
100
s->binfo.ram_size = machine->ram_size;
101
s->binfo.loader_start = 0x0;
102
s->binfo.get_dtb = versal_virt_get_dtb;
103
--
230
--
104
2.20.1
231
2.25.1
105
232
106
233
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Add support for the RTC.
3
All constants are taken from the ARM Cortex-R52 Processor TRM Revision: r1p3
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Message-id: 20221206102504.165775-8-tobias.roehmel@rwth-aachen.de
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
hw/arm/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
10
target/arm/cpu_tcg.c | 42 ++++++++++++++++++++++++++++++++++++++++++
12
1 file changed, 22 insertions(+)
11
1 file changed, 42 insertions(+)
13
12
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
13
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
15
--- a/target/arm/cpu_tcg.c
17
+++ b/hw/arm/xlnx-versal-virt.c
16
+++ b/target/arm/cpu_tcg.c
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
19
}
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
20
}
19
}
21
20
22
+static void fdt_add_rtc_node(VersalVirt *s)
21
+static void cortex_r52_initfn(Object *obj)
23
+{
22
+{
24
+ const char compat[] = "xlnx,zynqmp-rtc";
23
+ ARMCPU *cpu = ARM_CPU(obj);
25
+ const char interrupt_names[] = "alarm\0sec";
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
27
+
24
+
28
+ qemu_fdt_add_subnode(s->fdt, name);
25
+ set_feature(&cpu->env, ARM_FEATURE_V8);
26
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
27
+ set_feature(&cpu->env, ARM_FEATURE_PMSA);
28
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
29
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
30
+ cpu->midr = 0x411fd133; /* r1p3 */
31
+ cpu->revidr = 0x00000000;
32
+ cpu->reset_fpsid = 0x41034023;
33
+ cpu->isar.mvfr0 = 0x10110222;
34
+ cpu->isar.mvfr1 = 0x12111111;
35
+ cpu->isar.mvfr2 = 0x00000043;
36
+ cpu->ctr = 0x8144c004;
37
+ cpu->reset_sctlr = 0x30c50838;
38
+ cpu->isar.id_pfr0 = 0x00000131;
39
+ cpu->isar.id_pfr1 = 0x10111001;
40
+ cpu->isar.id_dfr0 = 0x03010006;
41
+ cpu->id_afr0 = 0x00000000;
42
+ cpu->isar.id_mmfr0 = 0x00211040;
43
+ cpu->isar.id_mmfr1 = 0x40000000;
44
+ cpu->isar.id_mmfr2 = 0x01200000;
45
+ cpu->isar.id_mmfr3 = 0xf0102211;
46
+ cpu->isar.id_mmfr4 = 0x00000010;
47
+ cpu->isar.id_isar0 = 0x02101110;
48
+ cpu->isar.id_isar1 = 0x13112111;
49
+ cpu->isar.id_isar2 = 0x21232142;
50
+ cpu->isar.id_isar3 = 0x01112131;
51
+ cpu->isar.id_isar4 = 0x00010142;
52
+ cpu->isar.id_isar5 = 0x00010001;
53
+ cpu->isar.dbgdidr = 0x77168000;
54
+ cpu->clidr = (1 << 27) | (1 << 24) | 0x3;
55
+ cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
56
+ cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
29
+
57
+
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
58
+ cpu->pmsav7_dregion = 16;
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
59
+ cpu->pmsav8r_hdregion = 16;
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
36
+ interrupt_names, sizeof(interrupt_names));
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
40
+ g_free(name);
41
+}
60
+}
42
+
61
+
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
62
static void cortex_r5f_initfn(Object *obj)
44
{
63
{
45
Error *err = NULL;
64
ARMCPU *cpu = ARM_CPU(obj);
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
65
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
47
fdt_add_timer_nodes(s);
66
.class_init = arm_v7m_class_init },
48
fdt_add_zdma_nodes(s);
67
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
49
fdt_add_sd_nodes(s);
68
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
50
+ fdt_add_rtc_node(s);
69
+ { .name = "cortex-r52", .initfn = cortex_r52_initfn },
51
fdt_add_cpu_nodes(s, psci_conduit);
70
{ .name = "ti925t", .initfn = ti925t_initfn },
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
71
{ .name = "sa1100", .initfn = sa1100_initfn },
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
72
{ .name = "sa1110", .initfn = sa1110_initfn },
54
--
73
--
55
2.20.1
74
2.25.1
56
75
57
76
diff view generated by jsdifflib
1
From: Fredrik Strupe <fredrik@strupe.net>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
3
The check semihosting_enabled() wants to know if the guest is
4
U=1 is unallocated.
4
currently in user mode. Unlike the other cases the test was inverted
5
causing us to block semihosting calls in non-EL0 modes.
5
6
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
7
Cc: qemu-stable@nongnu.org
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
8
Fixes: 19b26317e9 (target/arm: Honour -semihosting-config userspace=on)
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@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/translate.c | 2 +-
13
target/arm/translate.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
13
15
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
18
--- a/target/arm/translate.c
17
+++ b/target/arm/translate.c
19
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
20
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
19
{0, 0, 0, 0}, /* VMLSL */
21
* semihosting, to provide some semblance of security
20
{0, 0, 0, 9}, /* VQDMLSL */
22
* (and for consistency with our 32-bit semihosting).
21
{0, 0, 0, 0}, /* Integer VMULL */
23
*/
22
- {0, 0, 0, 1}, /* VQDMULL */
24
- if (semihosting_enabled(s->current_el != 0) &&
23
+ {0, 0, 0, 9}, /* VQDMULL */
25
+ if (semihosting_enabled(s->current_el == 0) &&
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
26
(imm == (s->thumb ? 0x3c : 0xf000))) {
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
27
gen_exception_internal_insn(s, EXCP_SEMIHOST);
26
};
28
return;
27
--
29
--
28
2.20.1
30
2.25.1
29
31
30
32
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Add support for SD.
3
Fix typos, add background information
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
9
hw/timer/imx_epit.c | 20 ++++++++++++++++----
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
10
1 file changed, 16 insertions(+), 4 deletions(-)
14
2 files changed, 43 insertions(+)
15
11
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
12
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
14
--- a/hw/timer/imx_epit.c
19
+++ b/include/hw/arm/xlnx-versal.h
15
+++ b/hw/timer/imx_epit.c
20
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void imx_epit_set_freq(IMXEPITState *s)
21
22
#include "hw/sysbus.h"
23
#include "hw/arm/boot.h"
24
+#include "hw/sd/sdhci.h"
25
#include "hw/intc/arm_gicv3.h"
26
#include "hw/char/pl011.h"
27
#include "hw/dma/xlnx-zdma.h"
28
@@ -XXX,XX +XXX,XX @@
29
#define XLNX_VERSAL_NR_UARTS 2
30
#define XLNX_VERSAL_NR_GEMS 2
31
#define XLNX_VERSAL_NR_ADMAS 8
32
+#define XLNX_VERSAL_NR_SDS 2
33
#define XLNX_VERSAL_NR_IRQS 192
34
35
typedef struct Versal {
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
37
} iou;
38
} lpd;
39
40
+ /* The Platform Management Controller subsystem. */
41
+ struct {
42
+ struct {
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
44
+ } iou;
45
+ } pmc;
46
+
47
struct {
48
MemoryRegion *mr_ddr;
49
uint32_t psci_conduit;
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
51
#define VERSAL_GEM1_IRQ_0 58
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
53
#define VERSAL_ADMA_IRQ_0 60
54
+#define VERSAL_SD0_IRQ_0 126
55
56
/* Architecturally reserved IRQs suitable for virtualization. */
57
#define VERSAL_RSVD_IRQ_FIRST 111
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
59
#define MM_FPD_CRF 0xfd1a0000U
60
#define MM_FPD_CRF_SIZE 0x140000
61
62
+#define MM_PMC_SD0 0xf1040000U
63
+#define MM_PMC_SD0_SIZE 0x10000
64
#define MM_PMC_CRP 0xf1260000U
65
#define MM_PMC_CRP_SIZE 0x10000
66
#endif
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/xlnx-versal.c
70
+++ b/hw/arm/xlnx-versal.c
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
72
}
17
}
73
}
18
}
74
19
75
+#define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
20
+/*
76
+static void versal_create_sds(Versal *s, qemu_irq *pic)
21
+ * This is called both on hardware (device) reset and software reset.
77
+{
22
+ */
78
+ int i;
23
static void imx_epit_reset(DeviceState *dev)
79
+
24
{
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
25
IMXEPITState *s = IMX_EPIT(dev);
81
+ DeviceState *dev;
26
82
+ MemoryRegion *mr;
27
- /*
83
+
28
- * Soft reset doesn't touch some bits; hard reset clears them
84
+ sysbus_init_child_obj(OBJECT(s), "sd[*]",
29
- */
85
+ &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]),
30
+ /* Soft reset doesn't touch some bits; hard reset clears them */
86
+ TYPE_SYSBUS_SDHCI);
31
s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
87
+ dev = DEVICE(&s->pmc.iou.sd[i]);
32
s->sr = 0;
88
+
33
s->lr = EPIT_TIMER_MAX;
89
+ object_property_set_uint(OBJECT(dev),
34
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
90
+ 3, "sd-spec-version", &error_fatal);
35
ptimer_transaction_begin(s->timer_cmp);
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
36
ptimer_transaction_begin(s->timer_reload);
92
+ &error_fatal);
37
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
38
+ /* Update the frequency. Has been done already in case of a reset. */
94
+ qdev_init_nofail(dev);
39
if (!(s->cr & CR_SWR)) {
95
+
40
imx_epit_set_freq(s);
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
41
}
97
+ memory_region_add_subregion(&s->mr_ps,
42
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
43
break;
99
+
44
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
45
case 1: /* SR - ACK*/
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
46
- /* writing 1 to OCIF clear the OCIF bit */
102
+ }
47
+ /* writing 1 to OCIF clears the OCIF bit */
103
+}
48
if (value & 0x01) {
104
+
49
s->sr = 0;
105
/* This takes the board allocated linear DDR memory and creates aliases
50
imx_epit_update_int(s);
106
* for each split DDR range/aperture on the Versal address map.
51
@@ -XXX,XX +XXX,XX @@ static void imx_epit_realize(DeviceState *dev, Error **errp)
107
*/
52
0x00001000);
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
53
sysbus_init_mmio(sbd, &s->iomem);
109
versal_create_uarts(s, pic);
54
110
versal_create_gems(s, pic);
55
+ /*
111
versal_create_admas(s, pic);
56
+ * The reload timer keeps running when the peripheral is enabled. It is a
112
+ versal_create_sds(s, pic);
57
+ * kind of wall clock that does not generate any interrupts. The callback
113
versal_map_ddr(s);
58
+ * needs to be provided, but it does nothing as the ptimer already supports
114
versal_unimp(s);
59
+ * all necessary reloading functionality.
60
+ */
61
s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_LEGACY);
62
63
+ /*
64
+ * The compare timer is running only when the peripheral configuration is
65
+ * in a state that will generate compare interrupts.
66
+ */
67
s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
68
}
115
69
116
--
70
--
117
2.20.1
71
2.25.1
118
119
diff view generated by jsdifflib
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
1
From: Axel Heider <axel.heider@hensoldt.net>
2
to decodetree.
3
2
3
remove unused defines, add needed defines
4
5
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
7
---
8
---
8
target/arm/neon-dp.decode | 6 ++++++
9
include/hw/timer/imx_epit.h | 4 ++--
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
10
hw/timer/imx_epit.c | 4 ++--
10
target/arm/translate.c | 14 ++------------
11
2 files changed, 4 insertions(+), 4 deletions(-)
11
3 files changed, 23 insertions(+), 12 deletions(-)
12
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
15
--- a/include/hw/timer/imx_epit.h
16
+++ b/target/arm/neon-dp.decode
16
+++ b/include/hw/timer/imx_epit.h
17
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
18
#define CR_OCIEN (1 << 2)
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
19
#define CR_RLD (1 << 3)
20
20
#define CR_PRESCALE_SHIFT (4)
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
21
-#define CR_PRESCALE_MASK (0xfff)
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
22
+#define CR_PRESCALE_BITS (12)
23
+
23
#define CR_SWR (1 << 16)
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
24
#define CR_IOVW (1 << 17)
25
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
25
#define CR_DBGEN (1 << 18)
26
26
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
27
#define CR_DOZEN (1 << 20)
28
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
28
#define CR_STOPEN (1 << 21)
29
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
29
#define CR_CLKSRC_SHIFT (24)
30
30
-#define CR_CLKSRC_MASK (0x3 << CR_CLKSRC_SHIFT)
31
+VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
31
+#define CR_CLKSRC_BITS (2)
32
+VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
32
33
+
33
#define EPIT_TIMER_MAX 0XFFFFFFFFUL
34
VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
34
35
VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
35
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
36
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
37
--- a/hw/timer/imx_epit.c
40
+++ b/target/arm/translate-neon.inc.c
38
+++ b/hw/timer/imx_epit.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
39
@@ -XXX,XX +XXX,XX @@ static void imx_epit_set_freq(IMXEPITState *s)
42
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
40
uint32_t clksrc;
43
}
41
uint32_t prescaler;
44
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
42
45
+
43
- clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
46
+#define DO_3SAME_GVEC4(INSN, OPARRAY) \
44
- prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
47
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
45
+ clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
48
+ uint32_t rn_ofs, uint32_t rm_ofs, \
46
+ prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
49
+ uint32_t oprsz, uint32_t maxsz) \
47
50
+ { \
48
s->freq = imx_ccm_get_clock_frequency(s->ccm,
51
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
49
imx_epit_clocks[clksrc]) / prescaler;
52
+ rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
53
+ } \
54
+ DO_3SAME(INSN, gen_##INSN##_3s)
55
+
56
+DO_3SAME_GVEC4(VQADD_S, sqadd_op)
57
+DO_3SAME_GVEC4(VQADD_U, uqadd_op)
58
+DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
59
+DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
}
66
return 1;
67
68
- case NEON_3R_VQADD:
69
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
70
- rn_ofs, rm_ofs, vec_size, vec_size,
71
- (u ? uqadd_op : sqadd_op) + size);
72
- return 0;
73
-
74
- case NEON_3R_VQSUB:
75
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
76
- rn_ofs, rm_ofs, vec_size, vec_size,
77
- (u ? uqsub_op : sqsub_op) + size);
78
- return 0;
79
-
80
case NEON_3R_VMUL: /* VMUL */
81
if (u) {
82
/* Polynomial case allows only P8. */
83
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
case NEON_3R_VTST_VCEQ:
85
case NEON_3R_VCGT:
86
case NEON_3R_VCGE:
87
+ case NEON_3R_VQADD:
88
+ case NEON_3R_VQSUB:
89
/* Already handled by decodetree */
90
return 1;
91
}
92
--
50
--
93
2.20.1
51
2.25.1
94
95
diff view generated by jsdifflib
1
Convert the Neon comparison ops in the 3-reg-same grouping
1
From: Axel Heider <axel.heider@hensoldt.net>
2
to decodetree.
3
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
7
---
5
---
8
target/arm/neon-dp.decode | 8 ++++++++
6
include/hw/timer/imx_epit.h | 2 ++
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
7
hw/timer/imx_epit.c | 12 ++++++------
10
target/arm/translate.c | 23 +++--------------------
8
2 files changed, 8 insertions(+), 6 deletions(-)
11
3 files changed, 33 insertions(+), 20 deletions(-)
12
9
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
10
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
12
--- a/include/hw/timer/imx_epit.h
16
+++ b/target/arm/neon-dp.decode
13
+++ b/include/hw/timer/imx_epit.h
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
14
@@ -XXX,XX +XXX,XX @@
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
15
#define CR_CLKSRC_SHIFT (24)
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
16
#define CR_CLKSRC_BITS (2)
20
17
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
18
+#define SR_OCIF (1 << 0)
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
25
+
19
+
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
20
#define EPIT_TIMER_MAX 0XFFFFFFFFUL
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
21
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
22
#define TYPE_IMX_EPIT "imx.epit"
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
23
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
30
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
33
+
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
25
--- a/hw/timer/imx_epit.c
39
+++ b/target/arm/translate-neon.inc.c
26
+++ b/hw/timer/imx_epit.c
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
27
@@ -XXX,XX +XXX,XX @@ static const IMXClk imx_epit_clocks[] = {
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
28
*/
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
29
static void imx_epit_update_int(IMXEPITState *s)
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
30
{
44
+
31
- if (s->sr && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
45
+#define DO_3SAME_CMP(INSN, COND) \
32
+ if ((s->sr & SR_OCIF) && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
33
qemu_irq_raise(s->irq);
47
+ uint32_t rn_ofs, uint32_t rm_ofs, \
34
} else {
48
+ uint32_t oprsz, uint32_t maxsz) \
35
qemu_irq_lower(s->irq);
49
+ { \
36
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
50
+ tcg_gen_gvec_cmp(COND, vece, rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz); \
37
break;
51
+ } \
38
52
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
39
case 1: /* SR - ACK*/
53
+
40
- /* writing 1 to OCIF clears the OCIF bit */
54
+DO_3SAME_CMP(VCGT_S, TCG_COND_GT)
41
- if (value & 0x01) {
55
+DO_3SAME_CMP(VCGT_U, TCG_COND_GTU)
42
- s->sr = 0;
56
+DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
43
+ /* writing 1 to SR.OCIF clears this bit and turns the interrupt off */
57
+DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
44
+ if (value & SR_OCIF) {
58
+DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
45
+ s->sr = 0; /* SR.OCIF is the only bit in this register anyway */
59
+
46
imx_epit_update_int(s);
60
+static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
47
}
61
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
48
break;
62
+{
49
@@ -XXX,XX +XXX,XX @@ static void imx_epit_cmp(void *opaque)
63
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
50
IMXEPITState *s = IMX_EPIT(opaque);
64
+}
51
65
+DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
52
DPRINTF("sr was %d\n", s->sr);
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
u ? &mls_op[size] : &mla_op[size]);
72
return 0;
73
74
- case NEON_3R_VTST_VCEQ:
75
- if (u) { /* VCEQ */
76
- tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
77
- vec_size, vec_size);
78
- } else { /* VTST */
79
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
80
- vec_size, vec_size, &cmtst_op[size]);
81
- }
82
- return 0;
83
-
53
-
84
- case NEON_3R_VCGT:
54
- s->sr = 1;
85
- tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
55
+ /* Set interrupt status bit SR.OCIF and update the interrupt state */
86
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
56
+ s->sr |= SR_OCIF;
87
- return 0;
57
imx_epit_update_int(s);
88
-
58
}
89
- case NEON_3R_VCGE:
59
90
- tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
91
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
92
- return 0;
93
-
94
case NEON_3R_VSHL:
95
/* Note the operation is vshl vd,vm,vn */
96
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
case NEON_3R_LOGIC:
99
case NEON_3R_VMAX:
100
case NEON_3R_VMIN:
101
+ case NEON_3R_VTST_VCEQ:
102
+ case NEON_3R_VCGT:
103
+ case NEON_3R_VCGE:
104
/* Already handled by decodetree */
105
return 1;
106
}
107
--
60
--
108
2.20.1
61
2.25.1
109
110
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
The interrupt state can change due to:
4
- reset clears both SR.OCIF and CR.OCIE
5
- write to CR.EN or CR.OCIE
6
7
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
6
---
10
---
7
target/arm/neon-dp.decode | 5 +++++
11
hw/timer/imx_epit.c | 16 ++++++++++++----
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
12
1 file changed, 12 insertions(+), 4 deletions(-)
9
target/arm/translate.c | 21 ++-------------------
10
3 files changed, 21 insertions(+), 19 deletions(-)
11
13
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
16
--- a/hw/timer/imx_epit.c
15
+++ b/target/arm/neon-dp.decode
17
+++ b/hw/timer/imx_epit.c
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
18
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
19
if (s->cr & CR_SWR) {
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
20
/* handle the reset */
19
21
imx_epit_reset(DEVICE(s));
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
22
- /*
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
23
- * TODO: could we 'break' here? following operations appear
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
24
- * to duplicate the work imx_epit_reset() already did.
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
25
- */
26
}
27
28
+ /*
29
+ * The interrupt state can change due to:
30
+ * - reset clears both SR.OCIF and CR.OCIE
31
+ * - write to CR.EN or CR.OCIE
32
+ */
33
+ imx_epit_update_int(s);
24
+
34
+
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
35
+ /*
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
36
+ * TODO: could we 'break' here for reset? following operations appear
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
+ * to duplicate the work imx_epit_reset() already did.
28
index XXXXXXX..XXXXXXX 100644
38
+ */
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VEOR, tcg_gen_gvec_xor)
32
DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
33
DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
34
DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
35
+
39
+
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
40
ptimer_transaction_begin(s->timer_cmp);
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
41
ptimer_transaction_begin(s->timer_reload);
38
+ { \
42
39
+ if (a->size == 3) { \
40
+ return false; \
41
+ } \
42
+ return do_3same(s, a, FUNC); \
43
+ }
44
+
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/translate.c
52
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
55
return 0;
56
57
- case NEON_3R_VMAX:
58
- if (u) {
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
60
- vec_size, vec_size);
61
- } else {
62
- tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
63
- vec_size, vec_size);
64
- }
65
- return 0;
66
- case NEON_3R_VMIN:
67
- if (u) {
68
- tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
69
- vec_size, vec_size);
70
- } else {
71
- tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
72
- vec_size, vec_size);
73
- }
74
- return 0;
75
-
76
case NEON_3R_VSHL:
77
/* Note the operation is vshl vd,vm,vn */
78
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
79
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
80
81
case NEON_3R_VADD_VSUB:
82
case NEON_3R_LOGIC:
83
+ case NEON_3R_VMAX:
84
+ case NEON_3R_VMIN:
85
/* Already handled by decodetree */
86
return 1;
87
}
88
--
43
--
89
2.20.1
44
2.25.1
90
91
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Embed the ADMAs into the SoC type.
3
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
6
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
7
hw/timer/imx_epit.c | 20 ++++++++++++++------
14
hw/arm/xlnx-versal.c | 14 +++++++-------
8
1 file changed, 14 insertions(+), 6 deletions(-)
15
2 files changed, 9 insertions(+), 8 deletions(-)
16
9
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
10
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
12
--- a/hw/timer/imx_epit.c
20
+++ b/include/hw/arm/xlnx-versal.h
13
+++ b/hw/timer/imx_epit.c
21
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void imx_epit_set_freq(IMXEPITState *s)
22
#include "hw/arm/boot.h"
15
/*
23
#include "hw/intc/arm_gicv3.h"
16
* This is called both on hardware (device) reset and software reset.
24
#include "hw/char/pl011.h"
17
*/
25
+#include "hw/dma/xlnx-zdma.h"
18
-static void imx_epit_reset(DeviceState *dev)
26
#include "hw/net/cadence_gem.h"
19
+static void imx_epit_reset(IMXEPITState *s, bool is_hard_reset)
27
20
{
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
21
- IMXEPITState *s = IMX_EPIT(dev);
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
22
-
30
struct {
23
/* Soft reset doesn't touch some bits; hard reset clears them */
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
24
- s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
25
+ if (is_hard_reset) {
33
- SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
26
+ s->cr = 0;
34
+ XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
27
+ } else {
35
} iou;
28
+ s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
36
} lpd;
29
+ }
37
30
s->sr = 0;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
31
s->lr = EPIT_TIMER_MAX;
39
index XXXXXXX..XXXXXXX 100644
32
s->cmp = 0;
40
--- a/hw/arm/xlnx-versal.c
33
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
41
+++ b/hw/arm/xlnx-versal.c
34
s->cr = value & 0x03ffffff;
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
35
if (s->cr & CR_SWR) {
43
DeviceState *dev;
36
/* handle the reset */
44
MemoryRegion *mr;
37
- imx_epit_reset(DEVICE(s));
45
38
+ imx_epit_reset(s, false);
46
- dev = qdev_create(NULL, "xlnx.zdma");
39
}
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
40
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
41
/*
49
- &error_abort);
42
@@ -XXX,XX +XXX,XX @@ static void imx_epit_realize(DeviceState *dev, Error **errp)
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
43
s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
51
+ sysbus_init_child_obj(OBJECT(s), name,
44
}
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
45
53
+ TYPE_XLNX_ZDMA);
46
+static void imx_epit_dev_reset(DeviceState *dev)
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
47
+{
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
48
+ IMXEPITState *s = IMX_EPIT(dev);
56
qdev_init_nofail(dev);
49
+ imx_epit_reset(s, true);
57
50
+}
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
51
+
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
52
static void imx_epit_class_init(ObjectClass *klass, void *data)
60
memory_region_add_subregion(&s->mr_ps,
53
{
61
MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
54
DeviceClass *dc = DEVICE_CLASS(klass);
62
55
63
- sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
56
dc->realize = imx_epit_realize;
64
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
57
- dc->reset = imx_epit_reset;
65
g_free(name);
58
+ dc->reset = imx_epit_dev_reset;
66
}
59
dc->vmsd = &vmstate_imx_timer_epit;
60
dc->desc = "i.MX periodic timer";
67
}
61
}
68
--
62
--
69
2.20.1
63
2.25.1
70
71
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
hw/arm: versal: Add support for the RTC.
3
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
6
---
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
7
hw/timer/imx_epit.c | 215 ++++++++++++++++++++++++--------------------
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
8
1 file changed, 117 insertions(+), 98 deletions(-)
14
2 files changed, 29 insertions(+)
15
9
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
10
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
12
--- a/hw/timer/imx_epit.c
19
+++ b/include/hw/arm/xlnx-versal.h
13
+++ b/hw/timer/imx_epit.c
20
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
21
#include "hw/char/pl011.h"
22
#include "hw/dma/xlnx-zdma.h"
23
#include "hw/net/cadence_gem.h"
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
25
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
29
struct {
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
31
} iou;
32
+
33
+ XlnxZynqMPRTC rtc;
34
} pmc;
35
36
struct {
37
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
38
#define VERSAL_GEM1_IRQ_0 58
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
40
#define VERSAL_ADMA_IRQ_0 60
41
+#define VERSAL_RTC_APB_ERR_IRQ 121
42
#define VERSAL_SD0_IRQ_0 126
43
+#define VERSAL_RTC_ALARM_IRQ 142
44
+#define VERSAL_RTC_SECONDS_IRQ 143
45
46
/* Architecturally reserved IRQs suitable for virtualization. */
47
#define VERSAL_RSVD_IRQ_FIRST 111
48
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
49
#define MM_PMC_SD0_SIZE 0x10000
50
#define MM_PMC_CRP 0xf1260000U
51
#define MM_PMC_CRP_SIZE 0x10000
52
+#define MM_PMC_RTC 0xf12a0000
53
+#define MM_PMC_RTC_SIZE 0x10000
54
#endif
55
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/xlnx-versal.c
58
+++ b/hw/arm/xlnx-versal.c
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
60
}
15
}
61
}
16
}
62
17
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
18
+static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
64
+{
19
+{
65
+ SysBusDevice *sbd;
20
+ uint32_t oldcr = s->cr;
66
+ MemoryRegion *mr;
21
+
67
+
22
+ s->cr = value & 0x03ffffff;
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
23
+
69
+ TYPE_XLNX_ZYNQMP_RTC);
24
+ if (s->cr & CR_SWR) {
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
25
+ /* handle the reset */
71
+ qdev_init_nofail(DEVICE(sbd));
26
+ imx_epit_reset(s, false);
72
+
27
+ }
73
+ mr = sysbus_mmio_get_region(sbd, 0);
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
75
+
28
+
76
+ /*
29
+ /*
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
30
+ * The interrupt state can change due to:
78
+ * supports them.
31
+ * - reset clears both SR.OCIF and CR.OCIE
32
+ * - write to CR.EN or CR.OCIE
79
+ */
33
+ */
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
34
+ imx_epit_update_int(s);
81
+}
35
+
82
+
36
+ /*
83
/* This takes the board allocated linear DDR memory and creates aliases
37
+ * TODO: could we 'break' here for reset? following operations appear
84
* for each split DDR range/aperture on the Versal address map.
38
+ * to duplicate the work imx_epit_reset() already did.
85
*/
39
+ */
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
40
+
87
versal_create_gems(s, pic);
41
+ ptimer_transaction_begin(s->timer_cmp);
88
versal_create_admas(s, pic);
42
+ ptimer_transaction_begin(s->timer_reload);
89
versal_create_sds(s, pic);
43
+
90
+ versal_create_rtc(s, pic);
44
+ /* Update the frequency. Has been done already in case of a reset. */
91
versal_map_ddr(s);
45
+ if (!(s->cr & CR_SWR)) {
92
versal_unimp(s);
46
+ imx_epit_set_freq(s);
93
47
+ }
48
+
49
+ if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
50
+ if (s->cr & CR_ENMOD) {
51
+ if (s->cr & CR_RLD) {
52
+ ptimer_set_limit(s->timer_reload, s->lr, 1);
53
+ ptimer_set_limit(s->timer_cmp, s->lr, 1);
54
+ } else {
55
+ ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
56
+ ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
57
+ }
58
+ }
59
+
60
+ imx_epit_reload_compare_timer(s);
61
+ ptimer_run(s->timer_reload, 0);
62
+ if (s->cr & CR_OCIEN) {
63
+ ptimer_run(s->timer_cmp, 0);
64
+ } else {
65
+ ptimer_stop(s->timer_cmp);
66
+ }
67
+ } else if (!(s->cr & CR_EN)) {
68
+ /* stop both timers */
69
+ ptimer_stop(s->timer_reload);
70
+ ptimer_stop(s->timer_cmp);
71
+ } else if (s->cr & CR_OCIEN) {
72
+ if (!(oldcr & CR_OCIEN)) {
73
+ imx_epit_reload_compare_timer(s);
74
+ ptimer_run(s->timer_cmp, 0);
75
+ }
76
+ } else {
77
+ ptimer_stop(s->timer_cmp);
78
+ }
79
+
80
+ ptimer_transaction_commit(s->timer_cmp);
81
+ ptimer_transaction_commit(s->timer_reload);
82
+}
83
+
84
+static void imx_epit_write_sr(IMXEPITState *s, uint32_t value)
85
+{
86
+ /* writing 1 to SR.OCIF clears this bit and turns the interrupt off */
87
+ if (value & SR_OCIF) {
88
+ s->sr = 0; /* SR.OCIF is the only bit in this register anyway */
89
+ imx_epit_update_int(s);
90
+ }
91
+}
92
+
93
+static void imx_epit_write_lr(IMXEPITState *s, uint32_t value)
94
+{
95
+ s->lr = value;
96
+
97
+ ptimer_transaction_begin(s->timer_cmp);
98
+ ptimer_transaction_begin(s->timer_reload);
99
+ if (s->cr & CR_RLD) {
100
+ /* Also set the limit if the LRD bit is set */
101
+ /* If IOVW bit is set then set the timer value */
102
+ ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
103
+ ptimer_set_limit(s->timer_cmp, s->lr, 0);
104
+ } else if (s->cr & CR_IOVW) {
105
+ /* If IOVW bit is set then set the timer value */
106
+ ptimer_set_count(s->timer_reload, s->lr);
107
+ }
108
+ /*
109
+ * Commit the change to s->timer_reload, so it can propagate. Otherwise
110
+ * the timer interrupt may not fire properly. The commit must happen
111
+ * before calling imx_epit_reload_compare_timer(), which reads
112
+ * s->timer_reload internally again.
113
+ */
114
+ ptimer_transaction_commit(s->timer_reload);
115
+ imx_epit_reload_compare_timer(s);
116
+ ptimer_transaction_commit(s->timer_cmp);
117
+}
118
+
119
+static void imx_epit_write_cmp(IMXEPITState *s, uint32_t value)
120
+{
121
+ s->cmp = value;
122
+
123
+ ptimer_transaction_begin(s->timer_cmp);
124
+ imx_epit_reload_compare_timer(s);
125
+ ptimer_transaction_commit(s->timer_cmp);
126
+}
127
+
128
static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
129
unsigned size)
130
{
131
IMXEPITState *s = IMX_EPIT(opaque);
132
- uint64_t oldcr;
133
134
DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(offset >> 2),
135
(uint32_t)value);
136
137
switch (offset >> 2) {
138
case 0: /* CR */
139
-
140
- oldcr = s->cr;
141
- s->cr = value & 0x03ffffff;
142
- if (s->cr & CR_SWR) {
143
- /* handle the reset */
144
- imx_epit_reset(s, false);
145
- }
146
-
147
- /*
148
- * The interrupt state can change due to:
149
- * - reset clears both SR.OCIF and CR.OCIE
150
- * - write to CR.EN or CR.OCIE
151
- */
152
- imx_epit_update_int(s);
153
-
154
- /*
155
- * TODO: could we 'break' here for reset? following operations appear
156
- * to duplicate the work imx_epit_reset() already did.
157
- */
158
-
159
- ptimer_transaction_begin(s->timer_cmp);
160
- ptimer_transaction_begin(s->timer_reload);
161
-
162
- /* Update the frequency. Has been done already in case of a reset. */
163
- if (!(s->cr & CR_SWR)) {
164
- imx_epit_set_freq(s);
165
- }
166
-
167
- if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
168
- if (s->cr & CR_ENMOD) {
169
- if (s->cr & CR_RLD) {
170
- ptimer_set_limit(s->timer_reload, s->lr, 1);
171
- ptimer_set_limit(s->timer_cmp, s->lr, 1);
172
- } else {
173
- ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
174
- ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
175
- }
176
- }
177
-
178
- imx_epit_reload_compare_timer(s);
179
- ptimer_run(s->timer_reload, 0);
180
- if (s->cr & CR_OCIEN) {
181
- ptimer_run(s->timer_cmp, 0);
182
- } else {
183
- ptimer_stop(s->timer_cmp);
184
- }
185
- } else if (!(s->cr & CR_EN)) {
186
- /* stop both timers */
187
- ptimer_stop(s->timer_reload);
188
- ptimer_stop(s->timer_cmp);
189
- } else if (s->cr & CR_OCIEN) {
190
- if (!(oldcr & CR_OCIEN)) {
191
- imx_epit_reload_compare_timer(s);
192
- ptimer_run(s->timer_cmp, 0);
193
- }
194
- } else {
195
- ptimer_stop(s->timer_cmp);
196
- }
197
-
198
- ptimer_transaction_commit(s->timer_cmp);
199
- ptimer_transaction_commit(s->timer_reload);
200
+ imx_epit_write_cr(s, (uint32_t)value);
201
break;
202
203
- case 1: /* SR - ACK*/
204
- /* writing 1 to SR.OCIF clears this bit and turns the interrupt off */
205
- if (value & SR_OCIF) {
206
- s->sr = 0; /* SR.OCIF is the only bit in this register anyway */
207
- imx_epit_update_int(s);
208
- }
209
+ case 1: /* SR */
210
+ imx_epit_write_sr(s, (uint32_t)value);
211
break;
212
213
- case 2: /* LR - set ticks */
214
- s->lr = value;
215
-
216
- ptimer_transaction_begin(s->timer_cmp);
217
- ptimer_transaction_begin(s->timer_reload);
218
- if (s->cr & CR_RLD) {
219
- /* Also set the limit if the LRD bit is set */
220
- /* If IOVW bit is set then set the timer value */
221
- ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
222
- ptimer_set_limit(s->timer_cmp, s->lr, 0);
223
- } else if (s->cr & CR_IOVW) {
224
- /* If IOVW bit is set then set the timer value */
225
- ptimer_set_count(s->timer_reload, s->lr);
226
- }
227
- /*
228
- * Commit the change to s->timer_reload, so it can propagate. Otherwise
229
- * the timer interrupt may not fire properly. The commit must happen
230
- * before calling imx_epit_reload_compare_timer(), which reads
231
- * s->timer_reload internally again.
232
- */
233
- ptimer_transaction_commit(s->timer_reload);
234
- imx_epit_reload_compare_timer(s);
235
- ptimer_transaction_commit(s->timer_cmp);
236
+ case 2: /* LR */
237
+ imx_epit_write_lr(s, (uint32_t)value);
238
break;
239
240
case 3: /* CMP */
241
- s->cmp = value;
242
-
243
- ptimer_transaction_begin(s->timer_cmp);
244
- imx_epit_reload_compare_timer(s);
245
- ptimer_transaction_commit(s->timer_cmp);
246
-
247
+ imx_epit_write_cmp(s, (uint32_t)value);
248
break;
249
250
default:
251
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
252
HWADDR_PRIx "\n", TYPE_IMX_EPIT, __func__, offset);
253
-
254
break;
255
}
256
}
257
+
258
static void imx_epit_cmp(void *opaque)
259
{
260
IMXEPITState *s = IMX_EPIT(opaque);
94
--
261
--
95
2.20.1
262
2.25.1
96
97
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Embed the APUs into the SoC type.
3
The CNT register is a read-only register. There is no need to
4
store it's value, it can be calculated on demand.
5
The calculated frequency is needed temporarily only.
4
6
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
7
Note that this is a migration compatibility break for all boards
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
types that use the EPIT peripheral.
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
include/hw/arm/xlnx-versal.h | 2 +-
14
include/hw/timer/imx_epit.h | 2 -
14
hw/arm/xlnx-versal-virt.c | 4 ++--
15
hw/timer/imx_epit.c | 73 ++++++++++++++-----------------------
15
hw/arm/xlnx-versal.c | 19 +++++--------------
16
2 files changed, 28 insertions(+), 47 deletions(-)
16
3 files changed, 8 insertions(+), 17 deletions(-)
17
17
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/xlnx-versal.h
20
--- a/include/hw/timer/imx_epit.h
21
+++ b/include/hw/arm/xlnx-versal.h
21
+++ b/include/hw/timer/imx_epit.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
22
@@ -XXX,XX +XXX,XX @@ struct IMXEPITState {
23
struct {
23
uint32_t sr;
24
struct {
24
uint32_t lr;
25
MemoryRegion mr;
25
uint32_t cmp;
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
26
- uint32_t cnt;
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
27
28
GICv3State gic;
28
- uint32_t freq;
29
} apu;
29
qemu_irq irq;
30
} fpd;
30
};
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
31
32
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
32
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/xlnx-versal-virt.c
34
--- a/hw/timer/imx_epit.c
34
+++ b/hw/arm/xlnx-versal-virt.c
35
+++ b/hw/timer/imx_epit.c
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
36
@@ -XXX,XX +XXX,XX @@ static void imx_epit_update_int(IMXEPITState *s)
36
s->binfo.get_dtb = versal_virt_get_dtb;
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
38
if (machine->kernel_filename) {
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
41
} else {
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
44
&s->binfo);
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
46
* Offset things by 4K. */
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/xlnx-versal.c
50
+++ b/hw/arm/xlnx-versal.c
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
52
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
54
Object *obj;
55
- char *name;
56
-
57
- obj = object_new(XLNX_VERSAL_ACPU_TYPE);
58
- if (!obj) {
59
- error_report("Unable to create apu.cpu[%d] of type %s",
60
- i, XLNX_VERSAL_ACPU_TYPE);
61
- exit(EXIT_FAILURE);
62
- }
63
-
64
- name = g_strdup_printf("apu-cpu[%d]", i);
65
- object_property_add_child(OBJECT(s), name, obj, &error_fatal);
66
- g_free(name);
67
68
+ object_initialize_child(OBJECT(s), "apu-cpu[*]",
69
+ &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]),
70
+ XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL);
71
+ obj = OBJECT(&s->fpd.apu.cpu[i]);
72
object_property_set_int(obj, s->cfg.psci_conduit,
73
"psci-conduit", &error_abort);
74
if (i) {
75
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
76
object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
77
&error_abort);
78
object_property_set_bool(obj, true, "realized", &error_fatal);
79
- s->fpd.apu.cpu[i] = ARM_CPU(obj);
80
}
37
}
81
}
38
}
82
39
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
40
-/*
41
- * Must be called from within a ptimer_transaction_begin/commit block
42
- * for both s->timer_cmp and s->timer_reload.
43
- */
44
-static void imx_epit_set_freq(IMXEPITState *s)
45
+static uint32_t imx_epit_get_freq(IMXEPITState *s)
46
{
47
- uint32_t clksrc;
48
- uint32_t prescaler;
49
-
50
- clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
51
- prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
52
-
53
- s->freq = imx_ccm_get_clock_frequency(s->ccm,
54
- imx_epit_clocks[clksrc]) / prescaler;
55
-
56
- DPRINTF("Setting ptimer frequency to %u\n", s->freq);
57
-
58
- if (s->freq) {
59
- ptimer_set_freq(s->timer_reload, s->freq);
60
- ptimer_set_freq(s->timer_cmp, s->freq);
61
- }
62
+ uint32_t clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
63
+ uint32_t prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
64
+ uint32_t f_in = imx_ccm_get_clock_frequency(s->ccm, imx_epit_clocks[clksrc]);
65
+ uint32_t freq = f_in / prescaler;
66
+ DPRINTF("ptimer frequency is %u\n", freq);
67
+ return freq;
68
}
69
70
/*
71
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reset(IMXEPITState *s, bool is_hard_reset)
72
s->sr = 0;
73
s->lr = EPIT_TIMER_MAX;
74
s->cmp = 0;
75
- s->cnt = 0;
76
ptimer_transaction_begin(s->timer_cmp);
77
ptimer_transaction_begin(s->timer_reload);
78
- /* stop both timers */
79
+
80
+ /*
81
+ * The reset switches off the input clock, so even if the CR.EN is still
82
+ * set, the timers are no longer running.
83
+ */
84
+ assert(imx_epit_get_freq(s) == 0);
85
ptimer_stop(s->timer_cmp);
86
ptimer_stop(s->timer_reload);
87
- /* compute new frequency */
88
- imx_epit_set_freq(s);
89
/* init both timers to EPIT_TIMER_MAX */
90
ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
91
ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
92
- if (s->freq && (s->cr & CR_EN)) {
93
- /* if the timer is still enabled, restart it */
94
- ptimer_run(s->timer_reload, 0);
95
- }
96
ptimer_transaction_commit(s->timer_cmp);
97
ptimer_transaction_commit(s->timer_reload);
98
}
99
100
-static uint32_t imx_epit_update_count(IMXEPITState *s)
101
-{
102
- s->cnt = ptimer_get_count(s->timer_reload);
103
-
104
- return s->cnt;
105
-}
106
-
107
static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
108
{
109
IMXEPITState *s = IMX_EPIT(opaque);
110
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
111
break;
112
113
case 4: /* CNT */
114
- imx_epit_update_count(s);
115
- reg_value = s->cnt;
116
+ reg_value = ptimer_get_count(s->timer_reload);
117
break;
118
119
default:
120
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
121
{
122
if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN)) {
123
/* if the compare feature is on and timers are running */
124
- uint32_t tmp = imx_epit_update_count(s);
125
+ uint32_t tmp = ptimer_get_count(s->timer_reload);
126
uint64_t next;
127
if (tmp > s->cmp) {
128
/* It'll fire in this round of the timer */
129
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
130
131
static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
132
{
133
+ uint32_t freq = 0;
134
uint32_t oldcr = s->cr;
135
136
s->cr = value & 0x03ffffff;
137
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
138
ptimer_transaction_begin(s->timer_cmp);
139
ptimer_transaction_begin(s->timer_reload);
140
141
- /* Update the frequency. Has been done already in case of a reset. */
142
+ /*
143
+ * Update the frequency. In case of a reset the input clock was
144
+ * switched off, so this can be skipped.
145
+ */
146
if (!(s->cr & CR_SWR)) {
147
- imx_epit_set_freq(s);
148
+ freq = imx_epit_get_freq(s);
149
+ if (freq) {
150
+ ptimer_set_freq(s->timer_reload, freq);
151
+ ptimer_set_freq(s->timer_cmp, freq);
152
+ }
84
}
153
}
85
154
86
for (i = 0; i < nr_apu_cpus; i++) {
155
- if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
156
+ if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
157
if (s->cr & CR_ENMOD) {
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
158
if (s->cr & CR_RLD) {
90
qemu_irq maint_irq;
159
ptimer_set_limit(s->timer_reload, s->lr, 1);
91
int ti;
160
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps imx_epit_ops = {
161
162
static const VMStateDescription vmstate_imx_timer_epit = {
163
.name = TYPE_IMX_EPIT,
164
- .version_id = 2,
165
- .minimum_version_id = 2,
166
+ .version_id = 3,
167
+ .minimum_version_id = 3,
168
.fields = (VMStateField[]) {
169
VMSTATE_UINT32(cr, IMXEPITState),
170
VMSTATE_UINT32(sr, IMXEPITState),
171
VMSTATE_UINT32(lr, IMXEPITState),
172
VMSTATE_UINT32(cmp, IMXEPITState),
173
- VMSTATE_UINT32(cnt, IMXEPITState),
174
- VMSTATE_UINT32(freq, IMXEPITState),
175
VMSTATE_PTIMER(timer_reload, IMXEPITState),
176
VMSTATE_PTIMER(timer_cmp, IMXEPITState),
177
VMSTATE_END_OF_LIST()
92
--
178
--
93
2.20.1
179
2.25.1
94
95
diff view generated by jsdifflib
1
Convert the Neon "load/store single structure to one lane" insns to
1
From: Axel Heider <axel.heider@hensoldt.net>
2
decodetree.
3
2
4
As this is the last set of insns in the neon load/store group,
3
- fix #1263 for CR writes
5
we can remove the whole disas_neon_ls_insn() function.
4
- rework compare time handling
5
- The compare timer has to run even if CR.OCIEN is not set,
6
as SR.OCIF must be updated.
7
- The compare timer fires exactly once when the
8
compare value is less than the current value, but the
9
reload values is less than the compare value.
10
- The compare timer will never fire if the reload value is
11
less than the compare value. Disable it in this case.
6
12
13
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
14
[PMM: fixed minor style nits]
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200430181003.21682-14-peter.maydell@linaro.org
10
---
17
---
11
target/arm/neon-ls.decode | 11 +++
18
hw/timer/imx_epit.c | 192 ++++++++++++++++++++++++++------------------
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
19
1 file changed, 116 insertions(+), 76 deletions(-)
13
target/arm/translate.c | 147 --------------------------------
14
3 files changed, 100 insertions(+), 147 deletions(-)
15
20
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
21
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-ls.decode
23
--- a/hw/timer/imx_epit.c
19
+++ b/target/arm/neon-ls.decode
24
+++ b/hw/timer/imx_epit.c
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
21
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
23
vd=%vd_dp
24
+
25
+# Neon load/store single structure to one lane
26
+%imm1_5_p1 5:1 !function=plus1
27
+%imm1_6_p1 6:1 !function=plus1
28
+
29
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
30
+ vd=%vd_dp size=0 stride=1
31
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
32
+ vd=%vd_dp size=1 stride=%imm1_5_p1
33
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
34
+ vd=%vd_dp size=2 stride=%imm1_6_p1
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
40
* It might be possible to convert it to a standalone .c file eventually.
26
* Originally written by Hans Jiang
41
*/
27
* Updated by Peter Chubb
42
28
* Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
43
+static inline int plus1(DisasContext *s, int x)
29
+ * Updated by Axel Heider
44
+{
30
*
45
+ return x + 1;
31
* This code is licensed under GPL version 2 or later. See
46
+}
32
* the COPYING file in the top-level directory.
47
+
33
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
48
/* Include the generated Neon decoder */
34
return reg_value;
49
#include "decode-neon-dp.inc.c"
35
}
50
#include "decode-neon-ls.inc.c"
36
51
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
37
-/* Must be called from ptimer_transaction_begin/commit block for s->timer_cmp */
52
38
-static void imx_epit_reload_compare_timer(IMXEPITState *s)
53
return true;
39
+/*
54
}
40
+ * Must be called from a ptimer_transaction_begin/commit block for
55
+
41
+ * s->timer_cmp, but outside of a transaction block of s->timer_reload,
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
42
+ * so the proper counter value is read.
57
+{
43
+ */
58
+ /* Neon load/store single structure to one lane */
44
+static void imx_epit_update_compare_timer(IMXEPITState *s)
59
+ int reg;
45
{
60
+ int nregs = a->n + 1;
46
- if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN)) {
61
+ int vd = a->vd;
47
- /* if the compare feature is on and timers are running */
62
+ TCGv_i32 addr, tmp;
48
- uint32_t tmp = ptimer_get_count(s->timer_reload);
63
+
49
- uint64_t next;
64
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
50
- if (tmp > s->cmp) {
65
+ return false;
51
- /* It'll fire in this round of the timer */
52
- next = tmp - s->cmp;
53
- } else { /* catch it next time around */
54
- next = tmp - s->cmp + ((s->cr & CR_RLD) ? EPIT_TIMER_MAX : s->lr);
55
+ uint64_t counter = 0;
56
+ bool is_oneshot = false;
57
+ /*
58
+ * The compare timer only has to run if the timer peripheral is active
59
+ * and there is an input clock, Otherwise it can be switched off.
60
+ */
61
+ bool is_active = (s->cr & CR_EN) && imx_epit_get_freq(s);
62
+ if (is_active) {
63
+ /*
64
+ * Calculate next timeout for compare timer. Reading the reload
65
+ * counter returns proper results only if pending transactions
66
+ * on it are committed here. Otherwise stale values are be read.
67
+ */
68
+ counter = ptimer_get_count(s->timer_reload);
69
+ uint64_t limit = ptimer_get_limit(s->timer_cmp);
70
+ /*
71
+ * The compare timer is a periodic timer if the limit is at least
72
+ * the compare value. Otherwise it may fire at most once in the
73
+ * current round.
74
+ */
75
+ bool is_oneshot = (limit >= s->cmp);
76
+ if (counter >= s->cmp) {
77
+ /* The compare timer fires in the current round. */
78
+ counter -= s->cmp;
79
+ } else if (!is_oneshot) {
80
+ /*
81
+ * The compare timer fires after a reload, as it is below the
82
+ * compare value already in this round. Note that the counter
83
+ * value calculated below can be above the 32-bit limit, which
84
+ * is legal here because the compare timer is an internal
85
+ * helper ptimer only.
86
+ */
87
+ counter += limit - s->cmp;
88
+ } else {
89
+ /*
90
+ * The compare timer won't fire in this round, and the limit is
91
+ * set to a value below the compare value. This practically means
92
+ * it will never fire, so it can be switched off.
93
+ */
94
+ is_active = false;
95
}
96
- ptimer_set_count(s->timer_cmp, next);
97
}
98
+
99
+ /*
100
+ * Set the compare timer and let it run, or stop it. This is agnostic
101
+ * of CR.OCIEN bit, as this bit affects interrupt generation only. The
102
+ * compare timer needs to run even if no interrupts are to be generated,
103
+ * because the SR.OCIF bit must be updated also.
104
+ * Note that the timer might already be stopped or be running with
105
+ * counter values. However, finding out when an update is needed and
106
+ * when not is not trivial. It's much easier applying the setting again,
107
+ * as this does not harm either and the overhead is negligible.
108
+ */
109
+ if (is_active) {
110
+ ptimer_set_count(s->timer_cmp, counter);
111
+ ptimer_run(s->timer_cmp, is_oneshot ? 1 : 0);
112
+ } else {
113
+ ptimer_stop(s->timer_cmp);
66
+ }
114
+ }
67
+
115
+
68
+ /* UNDEF accesses to D16-D31 if they don't exist */
116
}
69
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
117
70
+ return false;
118
static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
71
+ }
119
{
72
+
120
- uint32_t freq = 0;
73
+ /* Catch the UNDEF cases. This is unavoidably a bit messy. */
121
uint32_t oldcr = s->cr;
74
+ switch (nregs) {
122
75
+ case 1:
123
s->cr = value & 0x03ffffff;
76
+ if (((a->align & (1 << a->size)) != 0) ||
124
77
+ (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
125
if (s->cr & CR_SWR) {
78
+ return false;
126
- /* handle the reset */
127
+ /*
128
+ * Reset clears CR.SWR again. It does not touch CR.EN, but the timers
129
+ * are still stopped because the input clock is disabled.
130
+ */
131
imx_epit_reset(s, false);
132
+ } else {
133
+ uint32_t freq;
134
+ uint32_t toggled_cr_bits = oldcr ^ s->cr;
135
+ /* re-initialize the limits if CR.RLD has changed */
136
+ bool set_limit = toggled_cr_bits & CR_RLD;
137
+ /* set the counter if the timer got just enabled and CR.ENMOD is set */
138
+ bool is_switched_on = (toggled_cr_bits & s->cr) & CR_EN;
139
+ bool set_counter = is_switched_on && (s->cr & CR_ENMOD);
140
+
141
+ ptimer_transaction_begin(s->timer_cmp);
142
+ ptimer_transaction_begin(s->timer_reload);
143
+ freq = imx_epit_get_freq(s);
144
+ if (freq) {
145
+ ptimer_set_freq(s->timer_reload, freq);
146
+ ptimer_set_freq(s->timer_cmp, freq);
79
+ }
147
+ }
80
+ break;
148
+
81
+ case 3:
149
+ if (set_limit || set_counter) {
82
+ if ((a->align & 1) != 0) {
150
+ uint64_t limit = (s->cr & CR_RLD) ? s->lr : EPIT_TIMER_MAX;
83
+ return false;
151
+ ptimer_set_limit(s->timer_reload, limit, set_counter ? 1 : 0);
152
+ if (set_limit) {
153
+ ptimer_set_limit(s->timer_cmp, limit, 0);
154
+ }
84
+ }
155
+ }
85
+ /* fall through */
156
+ /*
86
+ case 2:
157
+ * If there is an input clock and the peripheral is enabled, then
87
+ if (a->size == 2 && (a->align & 2) != 0) {
158
+ * ensure the wall clock timer is ticking. Otherwise stop the timers.
88
+ return false;
159
+ * The compare timer will be updated later.
160
+ */
161
+ if (freq && (s->cr & CR_EN)) {
162
+ ptimer_run(s->timer_reload, 0);
163
+ } else {
164
+ ptimer_stop(s->timer_reload);
89
+ }
165
+ }
90
+ break;
166
+ /* Commit changes to reload timer, so they can propagate. */
91
+ case 4:
167
+ ptimer_transaction_commit(s->timer_reload);
92
+ if ((a->size == 2) && ((a->align & 3) == 3)) {
168
+ /* Update compare timer based on the committed reload timer value. */
93
+ return false;
169
+ imx_epit_update_compare_timer(s);
94
+ }
170
+ ptimer_transaction_commit(s->timer_cmp);
95
+ break;
171
}
96
+ default:
172
97
+ abort();
173
/*
98
+ }
174
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
99
+ if ((vd + a->stride * (nregs - 1)) > 31) {
175
* - write to CR.EN or CR.OCIE
100
+ /*
176
*/
101
+ * Attempts to write off the end of the register file are
177
imx_epit_update_int(s);
102
+ * UNPREDICTABLE; we choose to UNDEF because otherwise we would
178
-
103
+ * access off the end of the array that holds the register data.
179
- /*
104
+ */
180
- * TODO: could we 'break' here for reset? following operations appear
105
+ return false;
181
- * to duplicate the work imx_epit_reset() already did.
106
+ }
182
- */
107
+
183
-
108
+ if (!vfp_access_check(s)) {
184
- ptimer_transaction_begin(s->timer_cmp);
109
+ return true;
185
- ptimer_transaction_begin(s->timer_reload);
110
+ }
186
-
111
+
187
- /*
112
+ tmp = tcg_temp_new_i32();
188
- * Update the frequency. In case of a reset the input clock was
113
+ addr = tcg_temp_new_i32();
189
- * switched off, so this can be skipped.
114
+ load_reg_var(s, addr, a->rn);
190
- */
115
+ /*
191
- if (!(s->cr & CR_SWR)) {
116
+ * TODO: if we implemented alignment exceptions, we should check
192
- freq = imx_epit_get_freq(s);
117
+ * addr against the alignment encoded in a->align here.
193
- if (freq) {
118
+ */
194
- ptimer_set_freq(s->timer_reload, freq);
119
+ for (reg = 0; reg < nregs; reg++) {
195
- ptimer_set_freq(s->timer_cmp, freq);
120
+ if (a->l) {
196
- }
121
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
122
+ s->be_data | a->size);
123
+ neon_store_element(vd, a->reg_idx, a->size, tmp);
124
+ } else { /* Store */
125
+ neon_load_element(tmp, vd, a->reg_idx, a->size);
126
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
127
+ s->be_data | a->size);
128
+ }
129
+ vd += a->stride;
130
+ tcg_gen_addi_i32(addr, addr, 1 << a->size);
131
+ }
132
+ tcg_temp_free_i32(addr);
133
+ tcg_temp_free_i32(tmp);
134
+
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
136
+
137
+ return true;
138
+}
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
142
+++ b/target/arm/translate.c
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
144
tcg_temp_free_i32(rd);
145
}
146
147
-
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
149
- instruction is invalid. */
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
151
-{
152
- int rd, rn, rm;
153
- int nregs;
154
- int stride;
155
- int size;
156
- int reg;
157
- int load;
158
- TCGv_i32 addr;
159
- TCGv_i32 tmp;
160
-
161
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
- return 1;
163
- }
197
- }
164
-
198
-
165
- /* FIXME: this access check should not take precedence over UNDEF
199
- if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
166
- * for invalid encodings; we will generate incorrect syndrome information
200
- if (s->cr & CR_ENMOD) {
167
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
201
- if (s->cr & CR_RLD) {
202
- ptimer_set_limit(s->timer_reload, s->lr, 1);
203
- ptimer_set_limit(s->timer_cmp, s->lr, 1);
204
- } else {
205
- ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
206
- ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
207
- }
208
- }
209
-
210
- imx_epit_reload_compare_timer(s);
211
- ptimer_run(s->timer_reload, 0);
212
- if (s->cr & CR_OCIEN) {
213
- ptimer_run(s->timer_cmp, 0);
214
- } else {
215
- ptimer_stop(s->timer_cmp);
216
- }
217
- } else if (!(s->cr & CR_EN)) {
218
- /* stop both timers */
219
- ptimer_stop(s->timer_reload);
220
- ptimer_stop(s->timer_cmp);
221
- } else if (s->cr & CR_OCIEN) {
222
- if (!(oldcr & CR_OCIEN)) {
223
- imx_epit_reload_compare_timer(s);
224
- ptimer_run(s->timer_cmp, 0);
225
- }
226
- } else {
227
- ptimer_stop(s->timer_cmp);
228
- }
229
-
230
- ptimer_transaction_commit(s->timer_cmp);
231
- ptimer_transaction_commit(s->timer_reload);
232
}
233
234
static void imx_epit_write_sr(IMXEPITState *s, uint32_t value)
235
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_lr(IMXEPITState *s, uint32_t value)
236
/* If IOVW bit is set then set the timer value */
237
ptimer_set_count(s->timer_reload, s->lr);
238
}
239
- /*
240
- * Commit the change to s->timer_reload, so it can propagate. Otherwise
241
- * the timer interrupt may not fire properly. The commit must happen
242
- * before calling imx_epit_reload_compare_timer(), which reads
243
- * s->timer_reload internally again.
168
- */
244
- */
169
- if (s->fp_excp_el) {
245
+ /* Commit the changes to s->timer_reload, so they can propagate. */
170
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
246
ptimer_transaction_commit(s->timer_reload);
171
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
247
- imx_epit_reload_compare_timer(s);
172
- return 0;
248
+ /* Update the compare timer based on the committed reload timer value. */
173
- }
249
+ imx_epit_update_compare_timer(s);
174
-
250
ptimer_transaction_commit(s->timer_cmp);
175
- if (!s->vfp_enabled)
251
}
176
- return 1;
252
177
- VFP_DREG_D(rd, insn);
253
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_cmp(IMXEPITState *s, uint32_t value)
178
- rn = (insn >> 16) & 0xf;
254
{
179
- rm = insn & 0xf;
255
s->cmp = value;
180
- load = (insn & (1 << 21)) != 0;
256
181
- if ((insn & (1 << 23)) == 0) {
257
+ /* Update the compare timer based on the committed reload timer value. */
182
- /* Load store all elements -- handled already by decodetree */
258
ptimer_transaction_begin(s->timer_cmp);
183
- return 1;
259
- imx_epit_reload_compare_timer(s);
184
- } else {
260
+ imx_epit_update_compare_timer(s);
185
- size = (insn >> 10) & 3;
261
ptimer_transaction_commit(s->timer_cmp);
186
- if (size == 3) {
262
}
187
- /* Load single element to all lanes -- handled by decodetree */
263
188
- return 1;
264
@@ -XXX,XX +XXX,XX @@ static void imx_epit_cmp(void *opaque)
189
- } else {
265
{
190
- /* Single element. */
266
IMXEPITState *s = IMX_EPIT(opaque);
191
- int idx = (insn >> 4) & 0xf;
267
192
- int reg_idx;
268
+ /* The cmp ptimer can't be running when the peripheral is disabled */
193
- switch (size) {
269
+ assert(s->cr & CR_EN);
194
- case 0:
270
+
195
- reg_idx = (insn >> 5) & 7;
271
DPRINTF("sr was %d\n", s->sr);
196
- stride = 1;
272
/* Set interrupt status bit SR.OCIF and update the interrupt state */
197
- break;
273
s->sr |= SR_OCIF;
198
- case 1:
199
- reg_idx = (insn >> 6) & 3;
200
- stride = (insn & (1 << 5)) ? 2 : 1;
201
- break;
202
- case 2:
203
- reg_idx = (insn >> 7) & 1;
204
- stride = (insn & (1 << 6)) ? 2 : 1;
205
- break;
206
- default:
207
- abort();
208
- }
209
- nregs = ((insn >> 8) & 3) + 1;
210
- /* Catch the UNDEF cases. This is unavoidably a bit messy. */
211
- switch (nregs) {
212
- case 1:
213
- if (((idx & (1 << size)) != 0) ||
214
- (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
215
- return 1;
216
- }
217
- break;
218
- case 3:
219
- if ((idx & 1) != 0) {
220
- return 1;
221
- }
222
- /* fall through */
223
- case 2:
224
- if (size == 2 && (idx & 2) != 0) {
225
- return 1;
226
- }
227
- break;
228
- case 4:
229
- if ((size == 2) && ((idx & 3) == 3)) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- abort();
235
- }
236
- if ((rd + stride * (nregs - 1)) > 31) {
237
- /* Attempts to write off the end of the register file
238
- * are UNPREDICTABLE; we choose to UNDEF because otherwise
239
- * the neon_load_reg() would write off the end of the array.
240
- */
241
- return 1;
242
- }
243
- tmp = tcg_temp_new_i32();
244
- addr = tcg_temp_new_i32();
245
- load_reg_var(s, addr, rn);
246
- for (reg = 0; reg < nregs; reg++) {
247
- if (load) {
248
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
249
- s->be_data | size);
250
- neon_store_element(rd, reg_idx, size, tmp);
251
- } else { /* Store */
252
- neon_load_element(tmp, rd, reg_idx, size);
253
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
254
- s->be_data | size);
255
- }
256
- rd += stride;
257
- tcg_gen_addi_i32(addr, addr, 1 << size);
258
- }
259
- tcg_temp_free_i32(addr);
260
- tcg_temp_free_i32(tmp);
261
- stride = nregs * (1 << size);
262
- }
263
- }
264
- if (rm != 15) {
265
- TCGv_i32 base;
266
-
267
- base = load_reg(s, rn);
268
- if (rm == 13) {
269
- tcg_gen_addi_i32(base, base, stride);
270
- } else {
271
- TCGv_i32 index;
272
- index = load_reg(s, rm);
273
- tcg_gen_add_i32(base, base, index);
274
- tcg_temp_free_i32(index);
275
- }
276
- store_reg(s, rn, base);
277
- }
278
- return 0;
279
-}
280
-
281
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
282
{
283
switch (size) {
284
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
285
}
286
return;
287
}
288
- if ((insn & 0x0f100000) == 0x04000000) {
289
- /* NEON load/store. */
290
- if (disas_neon_ls_insn(s, insn)) {
291
- goto illegal_op;
292
- }
293
- return;
294
- }
295
if ((insn & 0x0e000f00) == 0x0c000100) {
296
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
297
/* iWMMXt register transfer. */
298
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
299
}
300
break;
301
case 12:
302
- if ((insn & 0x01100000) == 0x01000000) {
303
- if (disas_neon_ls_insn(s, insn)) {
304
- goto illegal_op;
305
- }
306
- break;
307
- }
308
goto illegal_op;
309
default:
310
illegal_op:
311
--
274
--
312
2.20.1
275
2.25.1
313
314
diff view generated by jsdifflib
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
1
From: Fabiano Rosas <farosas@suse.de>
2
whether the stage 1 access is for EL0 or not, because whether
3
exec permission is given can depend on whether this is an EL0
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
5
the call sites can pass this information in.
6
2
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
3
Fix these:
8
add one so we have a place to put the documentation of the
9
semantics of the new s1_is_el0 argument.
10
4
5
WARNING: Block comments use a leading /* on a separate line
6
WARNING: Block comments use * on subsequent lines
7
WARNING: Block comments use a trailing */ on a separate line
8
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Reviewed-by: Claudio Fontana <cfontana@suse.de>
11
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
12
Message-id: 20221213190537.511-2-farosas@suse.de
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
15
---
14
---
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
15
target/arm/helper.c | 323 +++++++++++++++++++++++++++++---------------
17
1 file changed, 28 insertions(+), 1 deletion(-)
16
1 file changed, 215 insertions(+), 108 deletions(-)
18
17
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
20
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
21
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
24
23
static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
25
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
24
uint64_t v)
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
25
{
27
+ bool s1_is_el0,
26
- /* Raw write of a coprocessor register (as needed for migration, etc).
28
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
27
+ /*
29
target_ulong *page_size_ptr,
28
+ * Raw write of a coprocessor register (as needed for migration, etc).
30
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
29
* Note that constant registers are treated as write-ignored; the
31
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
30
* caller should check for success by whether a readback gives the
31
* value written.
32
@@ -XXX,XX +XXX,XX @@ static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
33
34
static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
35
{
36
- /* Return true if the regdef would cause an assertion if you called
37
+ /*
38
+ * Return true if the regdef would cause an assertion if you called
39
* read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a
40
* program bug for it not to have the NO_RAW flag).
41
* NB that returning false here doesn't necessarily mean that calling
42
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu)
43
if (ri->type & ARM_CP_NO_RAW) {
44
continue;
32
}
45
}
33
46
- /* Write value and confirm it reads back as written
34
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
47
+ /*
35
+ false,
48
+ * Write value and confirm it reads back as written
36
&s2pa, &txattrs, &s2prot, &s2size, fi,
49
* (to catch read-only registers and partially read-only
37
pcacheattrs);
50
* registers where the incoming migration value doesn't match)
38
if (ret) {
51
*/
39
@@ -XXX,XX +XXX,XX @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
52
@@ -XXX,XX +XXX,XX @@ static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
53
54
void init_cpreg_list(ARMCPU *cpu)
55
{
56
- /* Initialise the cpreg_tuples[] array based on the cp_regs hash.
57
+ /*
58
+ * Initialise the cpreg_tuples[] array based on the cp_regs hash.
59
* Note that we require cpreg_tuples[] to be sorted by key ID.
60
*/
61
GList *keys;
62
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_el3_aa32ns(CPUARMState *env,
63
return CP_ACCESS_OK;
64
}
65
66
-/* Some secure-only AArch32 registers trap to EL3 if used from
67
+/*
68
+ * Some secure-only AArch32 registers trap to EL3 if used from
69
* Secure EL1 (but are just ordinary UNDEF in other non-EL3 contexts).
70
* Note that an access from Secure EL1 can only happen if EL3 is AArch64.
71
* We assume that the .access field is set to PL1_RW.
72
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
73
return CP_ACCESS_TRAP_UNCATEGORIZED;
74
}
75
76
-/* Check for traps to performance monitor registers, which are controlled
77
+/*
78
+ * Check for traps to performance monitor registers, which are controlled
79
* by MDCR_EL2.TPM for EL2 and MDCR_EL3.TPM for EL3.
80
*/
81
static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
82
@@ -XXX,XX +XXX,XX @@ static void fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
83
ARMCPU *cpu = env_archcpu(env);
84
85
if (raw_read(env, ri) != value) {
86
- /* Unlike real hardware the qemu TLB uses virtual addresses,
87
+ /*
88
+ * Unlike real hardware the qemu TLB uses virtual addresses,
89
* not modified virtual addresses, so this causes a TLB flush.
90
*/
91
tlb_flush(CPU(cpu));
92
@@ -XXX,XX +XXX,XX @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
93
94
if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_PMSA)
95
&& !extended_addresses_enabled(env)) {
96
- /* For VMSA (when not using the LPAE long descriptor page table
97
+ /*
98
+ * For VMSA (when not using the LPAE long descriptor page table
99
* format) this register includes the ASID, so do a TLB flush.
100
* For PMSA it is purely a process ID and no action is needed.
101
*/
102
@@ -XXX,XX +XXX,XX @@ static void tlbiipas2is_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
103
}
104
105
static const ARMCPRegInfo cp_reginfo[] = {
106
- /* Define the secure and non-secure FCSE identifier CP registers
107
+ /*
108
+ * Define the secure and non-secure FCSE identifier CP registers
109
* separately because there is no secure bank in V8 (no _EL3). This allows
110
* the secure register to be properly reset and migrated. There is also no
111
* v8 EL1 version of the register so the non-secure instance stands alone.
112
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
113
.access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
114
.fieldoffset = offsetof(CPUARMState, cp15.fcseidr_s),
115
.resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
116
- /* Define the secure and non-secure context identifier CP registers
117
+ /*
118
+ * Define the secure and non-secure context identifier CP registers
119
* separately because there is no secure bank in V8 (no _EL3). This allows
120
* the secure register to be properly reset and migrated. In the
121
* non-secure case, the 32-bit register will have reset and migration
122
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
123
};
124
125
static const ARMCPRegInfo not_v8_cp_reginfo[] = {
126
- /* NB: Some of these registers exist in v8 but with more precise
127
+ /*
128
+ * NB: Some of these registers exist in v8 but with more precise
129
* definitions that don't use CP_ANY wildcards (mostly in v8_cp_reginfo[]).
130
*/
131
/* MMU Domain access control / MPU write buffer control */
132
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
133
.writefn = dacr_write, .raw_writefn = raw_write,
134
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
135
offsetoflow32(CPUARMState, cp15.dacr_ns) } },
136
- /* ARMv7 allocates a range of implementation defined TLB LOCKDOWN regs.
137
+ /*
138
+ * ARMv7 allocates a range of implementation defined TLB LOCKDOWN regs.
139
* For v6 and v5, these mappings are overly broad.
140
*/
141
{ .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 0,
142
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
143
};
144
145
static const ARMCPRegInfo not_v6_cp_reginfo[] = {
146
- /* Not all pre-v6 cores implemented this WFI, so this is slightly
147
+ /*
148
+ * Not all pre-v6 cores implemented this WFI, so this is slightly
149
* over-broad.
150
*/
151
{ .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2,
152
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v6_cp_reginfo[] = {
153
};
154
155
static const ARMCPRegInfo not_v7_cp_reginfo[] = {
156
- /* Standard v6 WFI (also used in some pre-v6 cores); not in v7 (which
157
+ /*
158
+ * Standard v6 WFI (also used in some pre-v6 cores); not in v7 (which
159
* is UNPREDICTABLE; we choose to NOP as most implementations do).
160
*/
161
{ .name = "WFI_v6", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
162
.access = PL1_W, .type = ARM_CP_WFI },
163
- /* L1 cache lockdown. Not architectural in v6 and earlier but in practice
164
+ /*
165
+ * L1 cache lockdown. Not architectural in v6 and earlier but in practice
166
* implemented in 926, 946, 1026, 1136, 1176 and 11MPCore. StrongARM and
167
* OMAPCP will override this space.
168
*/
169
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
170
{ .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = CP_ANY,
171
.access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
172
.resetvalue = 0 },
173
- /* We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR;
174
+ /*
175
+ * We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR;
176
* implementing it as RAZ means the "debug architecture version" bits
177
* will read as a reserved value, which should cause Linux to not try
178
* to use the debug hardware.
179
*/
180
{ .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
181
.access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
182
- /* MMU TLB control. Note that the wildcarding means we cover not just
183
+ /*
184
+ * MMU TLB control. Note that the wildcarding means we cover not just
185
* the unified TLB ops but also the dside/iside/inner-shareable variants.
186
*/
187
{ .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY,
188
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
189
190
/* In ARMv8 most bits of CPACR_EL1 are RES0. */
191
if (!arm_feature(env, ARM_FEATURE_V8)) {
192
- /* ARMv7 defines bits for unimplemented coprocessors as RAZ/WI.
193
+ /*
194
+ * ARMv7 defines bits for unimplemented coprocessors as RAZ/WI.
195
* ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP.
196
* TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell.
197
*/
198
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
199
value |= R_CPACR_ASEDIS_MASK;
200
}
201
202
- /* VFPv3 and upwards with NEON implement 32 double precision
203
+ /*
204
+ * VFPv3 and upwards with NEON implement 32 double precision
205
* registers (D0-D31).
206
*/
207
if (!cpu_isar_feature(aa32_simd_r32, env_archcpu(env))) {
208
@@ -XXX,XX +XXX,XX @@ static uint64_t cpacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
209
210
static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
211
{
212
- /* Call cpacr_write() so that we reset with the correct RAO bits set
213
+ /*
214
+ * Call cpacr_write() so that we reset with the correct RAO bits set
215
* for our CPU features.
216
*/
217
cpacr_write(env, ri, 0);
218
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
219
{ .name = "MVA_prefetch",
220
.cp = 15, .crn = 7, .crm = 13, .opc1 = 0, .opc2 = 1,
221
.access = PL1_W, .type = ARM_CP_NOP },
222
- /* We need to break the TB after ISB to execute self-modifying code
223
+ /*
224
+ * We need to break the TB after ISB to execute self-modifying code
225
* correctly and also to take any pending interrupts immediately.
226
* So use arm_cp_write_ignore() function instead of ARM_CP_NOP flag.
227
*/
228
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
229
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s),
230
offsetof(CPUARMState, cp15.ifar_ns) },
231
.resetvalue = 0, },
232
- /* Watchpoint Fault Address Register : should actually only be present
233
+ /*
234
+ * Watchpoint Fault Address Register : should actually only be present
235
* for 1136, 1176, 11MPCore.
236
*/
237
{ .name = "WFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
238
@@ -XXX,XX +XXX,XX @@ static bool event_supported(uint16_t number)
239
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
240
bool isread)
241
{
242
- /* Performance monitor registers user accessibility is controlled
243
+ /*
244
+ * Performance monitor registers user accessibility is controlled
245
* by PMUSERENR. MDCR_EL2.TPM and MDCR_EL3.TPM allow configurable
246
* trapping to EL2 or EL3 for other accesses.
247
*/
248
@@ -XXX,XX +XXX,XX @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
249
(MDCR_HPME | MDCR_HPMD | MDCR_HPMN | MDCR_HCCD | MDCR_HLP)
250
#define MDCR_EL3_PMU_ENABLE_BITS (MDCR_SPME | MDCR_SCCD)
251
252
-/* Returns true if the counter (pass 31 for PMCCNTR) should count events using
253
+/*
254
+ * Returns true if the counter (pass 31 for PMCCNTR) should count events using
255
* the current EL, security state, and register configuration.
256
*/
257
static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
258
@@ -XXX,XX +XXX,XX @@ static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
259
static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
260
uint64_t value)
261
{
262
- /* The value of PMSELR.SEL affects the behavior of PMXEVTYPER and
263
+ /*
264
+ * The value of PMSELR.SEL affects the behavior of PMXEVTYPER and
265
* PMXEVCNTR. We allow [0..31] to be written to PMSELR here; in the
266
* meanwhile, we check PMSELR.SEL when PMXEVTYPER and PMXEVCNTR are
267
* accessed.
268
@@ -XXX,XX +XXX,XX @@ static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
269
env->cp15.c14_pmevtyper[counter] = value & PMXEVTYPER_MASK;
270
pmevcntr_op_finish(env, counter);
271
}
272
- /* Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when
273
+ /*
274
+ * Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when
275
* PMSELR value is equal to or greater than the number of implemented
276
* counters, but not equal to 0x1f. We opt to behave as a RAZ/WI.
277
*/
278
@@ -XXX,XX +XXX,XX @@ static uint64_t pmevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri,
279
}
280
return ret;
281
} else {
282
- /* We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
283
- * are CONSTRAINED UNPREDICTABLE. */
284
+ /*
285
+ * We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
286
+ * are CONSTRAINED UNPREDICTABLE.
287
+ */
288
return 0;
289
}
290
}
291
@@ -XXX,XX +XXX,XX @@ static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
292
static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
293
uint64_t value)
294
{
295
- /* Note that even though the AArch64 view of this register has bits
296
+ /*
297
+ * Note that even though the AArch64 view of this register has bits
298
* [10:0] all RES0 we can only mask the bottom 5, to comply with the
299
* architectural requirements for bits which are RES0 only in some
300
* contexts. (ARMv8 would permit us to do no masking at all, but ARMv7
301
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
302
if (!arm_feature(env, ARM_FEATURE_EL2)) {
303
valid_mask &= ~SCR_HCE;
304
305
- /* On ARMv7, SMD (or SCD as it is called in v7) is only
306
+ /*
307
+ * On ARMv7, SMD (or SCD as it is called in v7) is only
308
* supported if EL2 exists. The bit is UNK/SBZP when
309
* EL2 is unavailable. In QEMU ARMv7, we force it to always zero
310
* when EL2 is unavailable.
311
@@ -XXX,XX +XXX,XX @@ static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
312
{
313
ARMCPU *cpu = env_archcpu(env);
314
315
- /* Acquire the CSSELR index from the bank corresponding to the CCSIDR
316
+ /*
317
+ * Acquire the CSSELR index from the bank corresponding to the CCSIDR
318
* bank
319
*/
320
uint32_t index = A32_BANKED_REG_GET(env, csselr,
321
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
322
/* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */
323
{ .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
324
.access = PL1_W, .type = ARM_CP_NOP },
325
- /* Performance monitors are implementation defined in v7,
326
+ /*
327
+ * Performance monitors are implementation defined in v7,
328
* but with an ARM recommended set of registers, which we
329
* follow.
330
*
331
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
332
.writefn = csselr_write, .resetvalue = 0,
333
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
334
offsetof(CPUARMState, cp15.csselr_ns) } },
335
- /* Auxiliary ID register: this actually has an IMPDEF value but for now
336
+ /*
337
+ * Auxiliary ID register: this actually has an IMPDEF value but for now
338
* just RAZ for all cores:
339
*/
340
{ .name = "AIDR", .state = ARM_CP_STATE_BOTH,
341
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
342
.access = PL1_R, .type = ARM_CP_CONST,
343
.accessfn = access_aa64_tid1,
344
.resetvalue = 0 },
345
- /* Auxiliary fault status registers: these also are IMPDEF, and we
346
+ /*
347
+ * Auxiliary fault status registers: these also are IMPDEF, and we
348
* choose to RAZ/WI for all cores.
349
*/
350
{ .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH,
351
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
352
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
353
.access = PL1_RW, .accessfn = access_tvm_trvm,
354
.type = ARM_CP_CONST, .resetvalue = 0 },
355
- /* MAIR can just read-as-written because we don't implement caches
356
+ /*
357
+ * MAIR can just read-as-written because we don't implement caches
358
* and so don't need to care about memory attributes.
359
*/
360
{ .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
361
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
362
.opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0,
363
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[3]),
364
.resetvalue = 0 },
365
- /* For non-long-descriptor page tables these are PRRR and NMRR;
366
+ /*
367
+ * For non-long-descriptor page tables these are PRRR and NMRR;
368
* regardless they still act as reads-as-written for QEMU.
369
*/
370
- /* MAIR0/1 are defined separately from their 64-bit counterpart which
371
+ /*
372
+ * MAIR0/1 are defined separately from their 64-bit counterpart which
373
* allows them to assign the correct fieldoffset based on the endianness
374
* handled in the field definitions.
375
*/
376
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
377
static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri,
378
bool isread)
379
{
380
- /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero.
381
+ /*
382
+ * CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero.
383
* Writable only at the highest implemented exception level.
384
*/
385
int el = arm_current_el(env);
386
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
387
const ARMCPRegInfo *ri,
388
bool isread)
389
{
390
- /* The AArch64 register view of the secure physical timer is
391
+ /*
392
+ * The AArch64 register view of the secure physical timer is
393
* always accessible from EL3, and configurably accessible from
394
* Secure EL1.
395
*/
396
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
397
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
398
399
if (gt->ctl & 1) {
400
- /* Timer enabled: calculate and set current ISTATUS, irq, and
401
+ /*
402
+ * Timer enabled: calculate and set current ISTATUS, irq, and
403
* reset timer to when ISTATUS next has to change
404
*/
405
uint64_t offset = timeridx == GTIMER_VIRT ?
406
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
407
/* Next transition is when we hit cval */
408
nexttick = gt->cval + offset;
409
}
410
- /* Note that the desired next expiry time might be beyond the
411
+ /*
412
+ * Note that the desired next expiry time might be beyond the
413
* signed-64-bit range of a QEMUTimer -- in this case we just
414
* set the timer for as far in the future as possible. When the
415
* timer expires we will reset the timer for any remaining period.
416
@@ -XXX,XX +XXX,XX @@ static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
417
/* Enable toggled */
418
gt_recalc_timer(cpu, timeridx);
419
} else if ((oldval ^ value) & 2) {
420
- /* IMASK toggled: don't need to recalculate,
421
+ /*
422
+ * IMASK toggled: don't need to recalculate,
423
* just set the interrupt line based on ISTATUS
424
*/
425
int irqstate = (oldval & 4) && !(value & 2);
426
@@ -XXX,XX +XXX,XX @@ static void arm_gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *opaque)
427
}
428
429
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
430
- /* Note that CNTFRQ is purely reads-as-written for the benefit
431
+ /*
432
+ * Note that CNTFRQ is purely reads-as-written for the benefit
433
* of software; writing it doesn't actually change the timer frequency.
434
* Our reset value matches the fixed frequency we implement the timer at.
435
*/
436
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
437
.readfn = gt_virt_redir_cval_read, .raw_readfn = raw_read,
438
.writefn = gt_virt_redir_cval_write, .raw_writefn = raw_write,
439
},
440
- /* Secure timer -- this is actually restricted to only EL3
441
+ /*
442
+ * Secure timer -- this is actually restricted to only EL3
443
* and configurably Secure-EL1 via the accessfn.
444
*/
445
{ .name = "CNTPS_TVAL_EL1", .state = ARM_CP_STATE_AA64,
446
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
447
448
#else
449
450
-/* In user-mode most of the generic timer registers are inaccessible
451
+/*
452
+ * In user-mode most of the generic timer registers are inaccessible
453
* however modern kernels (4.12+) allow access to cntvct_el0
454
*/
455
456
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
457
{
458
ARMCPU *cpu = env_archcpu(env);
459
460
- /* Currently we have no support for QEMUTimer in linux-user so we
461
+ /*
462
+ * Currently we have no support for QEMUTimer in linux-user so we
463
* can't call gt_get_countervalue(env), instead we directly
464
* call the lower level functions.
465
*/
466
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
467
bool isread)
468
{
469
if (ri->opc2 & 4) {
470
- /* The ATS12NSO* operations must trap to EL3 or EL2 if executed in
471
+ /*
472
+ * The ATS12NSO* operations must trap to EL3 or EL2 if executed in
473
* Secure EL1 (which can only happen if EL3 is AArch64).
474
* They are simply UNDEF if executed from NS EL1.
475
* They function normally from EL2 or EL3.
476
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
477
}
478
}
479
} else {
480
- /* fsr is a DFSR/IFSR value for the short descriptor
481
+ /*
482
+ * fsr is a DFSR/IFSR value for the short descriptor
483
* translation table format (with WnR always clear).
484
* Convert it to a 32-bit PAR.
485
*/
486
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav8r_cp_reginfo[] = {
487
};
488
489
static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
490
- /* Reset for all these registers is handled in arm_cpu_reset(),
491
+ /*
492
+ * Reset for all these registers is handled in arm_cpu_reset(),
493
* because the PMSAv7 is also used by M-profile CPUs, which do
494
* not register cpregs but still need the state to be reset.
495
*/
496
@@ -XXX,XX +XXX,XX @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
497
}
498
499
if (arm_feature(env, ARM_FEATURE_LPAE)) {
500
- /* With LPAE the TTBCR could result in a change of ASID
501
+ /*
502
+ * With LPAE the TTBCR could result in a change of ASID
503
* via the TTBCR.A1 bit, so do a TLB flush.
504
*/
505
tlb_flush(CPU(cpu));
506
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
507
offsetoflow32(CPUARMState, cp15.tcr_el[1])} },
508
};
509
510
-/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing
511
+/*
512
+ * Note that unlike TTBCR, writing to TTBCR2 does not require flushing
513
* qemu tlbs nor adjusting cached masks.
514
*/
515
static const ARMCPRegInfo ttbcr2_reginfo = {
516
@@ -XXX,XX +XXX,XX @@ static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
517
static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
518
uint64_t value)
519
{
520
- /* On OMAP there are registers indicating the max/min index of dcache lines
521
+ /*
522
+ * On OMAP there are registers indicating the max/min index of dcache lines
523
* containing a dirty line; cache flush operations have to reset these.
524
*/
525
env->cp15.c15_i_max = 0x000;
526
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
527
.crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
528
.type = ARM_CP_NO_RAW,
529
.readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
530
- /* TODO: Peripheral port remap register:
531
+ /*
532
+ * TODO: Peripheral port remap register:
533
* On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller
534
* base address at $rn & ~0xfff and map size of 0x200 << ($rn & 0xfff),
535
* when MMU is off.
536
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo xscale_cp_reginfo[] = {
537
.cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW,
538
.fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr),
539
.resetvalue = 0, },
540
- /* XScale specific cache-lockdown: since we have no cache we NOP these
541
+ /*
542
+ * XScale specific cache-lockdown: since we have no cache we NOP these
543
* and hope the guest does not really rely on cache behaviour.
544
*/
545
{ .name = "XSCALE_LOCK_ICACHE_LINE",
546
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo xscale_cp_reginfo[] = {
547
};
548
549
static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
550
- /* RAZ/WI the whole crn=15 space, when we don't have a more specific
551
+ /*
552
+ * RAZ/WI the whole crn=15 space, when we don't have a more specific
553
* implementation of this implementation-defined space.
554
* Ideally this should eventually disappear in favour of actually
555
* implementing the correct behaviour for all cores.
556
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
557
};
558
559
static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
560
- /* The cache test-and-clean instructions always return (1 << 30)
561
+ /*
562
+ * The cache test-and-clean instructions always return (1 << 30)
563
* to indicate that there are no dirty cache lines.
564
*/
565
{ .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 3,
566
@@ -XXX,XX +XXX,XX @@ static uint64_t mpidr_read_val(CPUARMState *env)
567
568
if (arm_feature(env, ARM_FEATURE_V7MP)) {
569
mpidr |= (1U << 31);
570
- /* Cores which are uniprocessor (non-coherent)
571
+ /*
572
+ * Cores which are uniprocessor (non-coherent)
573
* but still implement the MP extensions set
574
* bit 30. (For instance, Cortex-R5).
575
*/
576
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tocu(CPUARMState *env, const ARMCPRegInfo *ri,
577
return do_cacheop_pou_access(env, HCR_TOCU | HCR_TPU);
578
}
579
580
-/* See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions
581
+/*
582
+ * See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions
583
* Page D4-1736 (DDI0487A.b)
584
*/
585
586
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
587
static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
588
uint64_t value)
589
{
590
- /* Invalidate by VA, EL2
591
+ /*
592
+ * Invalidate by VA, EL2
593
* Currently handles both VAE2 and VALE2, since we don't support
594
* flush-last-level-only.
595
*/
596
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
597
static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
598
uint64_t value)
599
{
600
- /* Invalidate by VA, EL3
601
+ /*
602
+ * Invalidate by VA, EL3
603
* Currently handles both VAE3 and VALE3, since we don't support
604
* flush-last-level-only.
605
*/
606
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
607
static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
608
uint64_t value)
609
{
610
- /* Invalidate by VA, EL1&0 (AArch64 version).
611
+ /*
612
+ * Invalidate by VA, EL1&0 (AArch64 version).
613
* Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
614
* since we don't support flush-for-specific-ASID-only or
615
* flush-last-level-only.
616
@@ -XXX,XX +XXX,XX @@ static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
617
bool isread)
618
{
619
if (!(env->pstate & PSTATE_SP)) {
620
- /* Access to SP_EL0 is undefined if it's being used as
621
+ /*
622
+ * Access to SP_EL0 is undefined if it's being used as
623
* the stack pointer.
624
*/
625
return CP_ACCESS_TRAP_UNCATEGORIZED;
626
@@ -XXX,XX +XXX,XX @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
627
}
628
629
if (raw_read(env, ri) == value) {
630
- /* Skip the TLB flush if nothing actually changed; Linux likes
631
+ /*
632
+ * Skip the TLB flush if nothing actually changed; Linux likes
633
* to do a lot of pointless SCTLR writes.
634
*/
635
return;
636
@@ -XXX,XX +XXX,XX @@ static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
637
}
638
639
static const ARMCPRegInfo v8_cp_reginfo[] = {
640
- /* Minimal set of EL0-visible registers. This will need to be expanded
641
+ /*
642
+ * Minimal set of EL0-visible registers. This will need to be expanded
643
* significantly for system emulation of AArch64 CPUs.
644
*/
645
{ .name = "NZCV", .state = ARM_CP_STATE_AA64,
646
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
647
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
648
.access = PL1_RW,
649
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
650
- /* We rely on the access checks not allowing the guest to write to the
651
+ /*
652
+ * We rely on the access checks not allowing the guest to write to the
653
* state field when SPSel indicates that it's being used as the stack
654
* pointer.
655
*/
656
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
657
if (arm_feature(env, ARM_FEATURE_EL3)) {
658
valid_mask &= ~HCR_HCD;
659
} else if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
660
- /* Architecturally HCR.TSC is RES0 if EL3 is not implemented.
661
+ /*
662
+ * Architecturally HCR.TSC is RES0 if EL3 is not implemented.
663
* However, if we're using the SMC PSCI conduit then QEMU is
664
* effectively acting like EL3 firmware and so the guest at
665
* EL2 should retain the ability to prevent EL1 from being
666
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
667
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
668
.writefn = tlbi_aa64_vae2is_write },
669
#ifndef CONFIG_USER_ONLY
670
- /* Unlike the other EL2-related AT operations, these must
671
+ /*
672
+ * Unlike the other EL2-related AT operations, these must
673
* UNDEF from EL3 if EL2 is not implemented, which is why we
674
* define them here rather than with the rest of the AT ops.
675
*/
676
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
677
.access = PL2_W, .accessfn = at_s1e2_access,
678
.type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC | ARM_CP_EL3_NO_EL2_UNDEF,
679
.writefn = ats_write64 },
680
- /* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE
681
+ /*
682
+ * The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE
683
* if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3
684
* with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose
685
* to behave as if SCR.NS was 1.
686
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
687
.writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
688
{ .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
689
.opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
690
- /* ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the
691
+ /*
692
+ * ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the
693
* reset values as IMPDEF. We choose to reset to 3 to comply with
694
* both ARMv7 and ARMv8.
695
*/
696
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
697
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
698
bool isread)
699
{
700
- /* The NSACR is RW at EL3, and RO for NS EL1 and NS EL2.
701
+ /*
702
+ * The NSACR is RW at EL3, and RO for NS EL1 and NS EL2.
703
* At Secure EL1 it traps to EL3 or EL2.
704
*/
705
if (arm_current_el(env) == 3) {
706
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
707
}
708
}
709
710
-/* We don't know until after realize whether there's a GICv3
711
+/*
712
+ * We don't know until after realize whether there's a GICv3
713
* attached, and that is what registers the gicv3 sysregs.
714
* So we have to fill in the GIC fields in ID_PFR/ID_PFR1_EL1/ID_AA64PFR0_EL1
715
* at runtime.
716
@@ -XXX,XX +XXX,XX @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
717
}
718
#endif
719
720
-/* Shared logic between LORID and the rest of the LOR* registers.
721
+/*
722
+ * Shared logic between LORID and the rest of the LOR* registers.
723
* Secure state exclusion has already been dealt with.
724
*/
725
static CPAccessResult access_lor_ns(CPUARMState *env,
726
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
727
728
define_arm_cp_regs(cpu, cp_reginfo);
729
if (!arm_feature(env, ARM_FEATURE_V8)) {
730
- /* Must go early as it is full of wildcards that may be
731
+ /*
732
+ * Must go early as it is full of wildcards that may be
733
* overridden by later definitions.
734
*/
735
define_arm_cp_regs(cpu, not_v8_cp_reginfo);
736
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
737
.access = PL1_R, .type = ARM_CP_CONST,
738
.accessfn = access_aa32_tid3,
739
.resetvalue = cpu->isar.id_pfr0 },
740
- /* ID_PFR1 is not a plain ARM_CP_CONST because we don't know
741
+ /*
742
+ * ID_PFR1 is not a plain ARM_CP_CONST because we don't know
743
* the value of the GIC field until after we define these regs.
744
*/
745
{ .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH,
746
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
747
748
define_arm_cp_regs(cpu, el3_regs);
749
}
750
- /* The behaviour of NSACR is sufficiently various that we don't
751
+ /*
752
+ * The behaviour of NSACR is sufficiently various that we don't
753
* try to describe it in a single reginfo:
754
* if EL3 is 64 bit, then trap to EL3 from S EL1,
755
* reads as constant 0xc00 from NS EL1 and NS EL2
756
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
757
if (cpu_isar_feature(aa32_jazelle, cpu)) {
758
define_arm_cp_regs(cpu, jazelle_regs);
759
}
760
- /* Slightly awkwardly, the OMAP and StrongARM cores need all of
761
+ /*
762
+ * Slightly awkwardly, the OMAP and StrongARM cores need all of
763
* cp15 crn=0 to be writes-ignored, whereas for other cores they should
764
* be read-only (ie write causes UNDEF exception).
765
*/
766
{
767
ARMCPRegInfo id_pre_v8_midr_cp_reginfo[] = {
768
- /* Pre-v8 MIDR space.
769
+ /*
770
+ * Pre-v8 MIDR space.
771
* Note that the MIDR isn't a simple constant register because
772
* of the TI925 behaviour where writes to another register can
773
* cause the MIDR value to change.
774
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
775
if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
776
arm_feature(env, ARM_FEATURE_STRONGARM)) {
777
size_t i;
778
- /* Register the blanket "writes ignored" value first to cover the
779
+ /*
780
+ * Register the blanket "writes ignored" value first to cover the
781
* whole space. Then update the specific ID registers to allow write
782
* access, so that they ignore writes rather than causing them to
783
* UNDEF.
784
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
785
.raw_writefn = raw_write,
786
};
787
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
788
- /* Normally we would always end the TB on an SCTLR write, but Linux
789
+ /*
790
+ * Normally we would always end the TB on an SCTLR write, but Linux
791
* arch/arm/mach-pxa/sleep.S expects two instructions following
792
* an MMU enable to execute from cache. Imitate this behaviour.
793
*/
794
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
795
void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
796
const ARMCPRegInfo *r, void *opaque)
797
{
798
- /* Define implementations of coprocessor registers.
799
+ /*
800
+ * Define implementations of coprocessor registers.
801
* We store these in a hashtable because typically
802
* there are less than 150 registers in a space which
803
* is 16*16*16*8*8 = 262144 in size.
804
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
805
default:
806
g_assert_not_reached();
807
}
808
- /* The AArch64 pseudocode CheckSystemAccess() specifies that op1
809
+ /*
810
+ * The AArch64 pseudocode CheckSystemAccess() specifies that op1
811
* encodes a minimum access level for the register. We roll this
812
* runtime check into our general permission check code, so check
813
* here that the reginfo's specified permissions are strict enough
814
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
815
assert((r->access & ~mask) == 0);
816
}
817
818
- /* Check that the register definition has enough info to handle
819
+ /*
820
+ * Check that the register definition has enough info to handle
821
* reads and writes if they are permitted.
822
*/
823
if (!(r->type & (ARM_CP_SPECIAL_MASK | ARM_CP_CONST))) {
824
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
825
continue;
826
}
827
if (state == ARM_CP_STATE_AA32) {
828
- /* Under AArch32 CP registers can be common
829
+ /*
830
+ * Under AArch32 CP registers can be common
831
* (same for secure and non-secure world) or banked.
832
*/
833
char *name;
834
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
835
g_assert_not_reached();
836
}
837
} else {
838
- /* AArch64 registers get mapped to non-secure instance
839
- * of AArch32 */
840
+ /*
841
+ * AArch64 registers get mapped to non-secure instance
842
+ * of AArch32
843
+ */
844
add_cpreg_to_hashtable(cpu, r, opaque, state,
845
ARM_CP_SECSTATE_NS,
846
crm, opc1, opc2, r->name);
847
@@ -XXX,XX +XXX,XX @@ void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
848
849
static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
850
{
851
- /* Return true if it is not valid for us to switch to
852
+ /*
853
+ * Return true if it is not valid for us to switch to
854
* this CPU mode (ie all the UNPREDICTABLE cases in
855
* the ARM ARM CPSRWriteByInstr pseudocode).
856
*/
857
@@ -XXX,XX +XXX,XX @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
858
case ARM_CPU_MODE_UND:
859
case ARM_CPU_MODE_IRQ:
860
case ARM_CPU_MODE_FIQ:
861
- /* Note that we don't implement the IMPDEF NSACR.RFR which in v7
862
+ /*
863
+ * Note that we don't implement the IMPDEF NSACR.RFR which in v7
864
* allows FIQ mode to be Secure-only. (In v8 this doesn't exist.)
865
*/
866
- /* If HCR.TGE is set then changes from Monitor to NS PL1 via MSR
867
+ /*
868
+ * If HCR.TGE is set then changes from Monitor to NS PL1 via MSR
869
* and CPS are treated as illegal mode changes.
870
*/
871
if (write_type == CPSRWriteByInstr &&
872
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
873
env->GE = (val >> 16) & 0xf;
874
}
875
876
- /* In a V7 implementation that includes the security extensions but does
877
+ /*
878
+ * In a V7 implementation that includes the security extensions but does
879
* not include Virtualization Extensions the SCR.FW and SCR.AW bits control
880
* whether non-secure software is allowed to change the CPSR_F and CPSR_A
881
* bits respectively.
882
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
883
changed_daif = (env->daif ^ val) & mask;
884
885
if (changed_daif & CPSR_A) {
886
- /* Check to see if we are allowed to change the masking of async
887
+ /*
888
+ * Check to see if we are allowed to change the masking of async
889
* abort exceptions from a non-secure state.
890
*/
891
if (!(env->cp15.scr_el3 & SCR_AW)) {
892
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
893
}
894
895
if (changed_daif & CPSR_F) {
896
- /* Check to see if we are allowed to change the masking of FIQ
897
+ /*
898
+ * Check to see if we are allowed to change the masking of FIQ
899
* exceptions from a non-secure state.
900
*/
901
if (!(env->cp15.scr_el3 & SCR_FW)) {
902
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
903
mask &= ~CPSR_F;
904
}
905
906
- /* Check whether non-maskable FIQ (NMFI) support is enabled.
907
+ /*
908
+ * Check whether non-maskable FIQ (NMFI) support is enabled.
909
* If this bit is set software is not allowed to mask
910
* FIQs, but is allowed to set CPSR_F to 0.
911
*/
912
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
913
if (write_type != CPSRWriteRaw &&
914
((env->uncached_cpsr ^ val) & mask & CPSR_M)) {
915
if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) {
916
- /* Note that we can only get here in USR mode if this is a
917
+ /*
918
+ * Note that we can only get here in USR mode if this is a
919
* gdb stub write; for this case we follow the architectural
920
* behaviour for guest writes in USR mode of ignoring an attempt
921
* to switch mode. (Those are caught by translate.c for writes
922
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
923
*/
924
mask &= ~CPSR_M;
925
} else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
926
- /* Attempt to switch to an invalid mode: this is UNPREDICTABLE in
927
+ /*
928
+ * Attempt to switch to an invalid mode: this is UNPREDICTABLE in
929
* v7, and has defined behaviour in v8:
930
* + leave CPSR.M untouched
931
* + allow changes to the other CPSR fields
932
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode)
933
env->regs[14] = env->banked_r14[r14_bank_number(mode)];
934
}
935
936
-/* Physical Interrupt Target EL Lookup Table
937
+/*
938
+ * Physical Interrupt Target EL Lookup Table
939
*
940
* [ From ARM ARM section G1.13.4 (Table G1-15) ]
941
*
942
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
943
if (arm_feature(env, ARM_FEATURE_EL3)) {
944
rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
945
} else {
946
- /* Either EL2 is the highest EL (and so the EL2 register width
947
+ /*
948
+ * Either EL2 is the highest EL (and so the EL2 register width
949
* is given by is64); or there is no EL2 or EL3, in which case
950
* the value of 'rw' does not affect the table lookup anyway.
951
*/
952
@@ -XXX,XX +XXX,XX @@ void aarch64_sync_64_to_32(CPUARMState *env)
953
env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23];
954
}
955
956
- /* Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ
957
+ /*
958
+ * Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ
959
* mode, then we can copy to r8-r14. Otherwise, we copy to the
960
* FIQ bank for r8-r14.
961
*/
962
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
963
/* High vectors. When enabled, base address cannot be remapped. */
964
addr += 0xffff0000;
965
} else {
966
- /* ARM v7 architectures provide a vector base address register to remap
967
+ /*
968
+ * ARM v7 architectures provide a vector base address register to remap
969
* the interrupt vector table.
970
* This register is only followed in non-monitor mode, and is banked.
971
* Note: only bits 31:5 are valid.
972
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
973
aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
974
975
if (cur_el < new_el) {
976
- /* Entry vector offset depends on whether the implemented EL
977
+ /*
978
+ * Entry vector offset depends on whether the implemented EL
979
* immediately lower than the target level is using AArch32 or AArch64
980
*/
981
bool is_aa64;
982
@@ -XXX,XX +XXX,XX @@ static void handle_semihosting(CPUState *cs)
983
}
984
#endif
985
986
-/* Handle a CPU exception for A and R profile CPUs.
987
+/*
988
+ * Handle a CPU exception for A and R profile CPUs.
989
* Do any appropriate logging, handle PSCI calls, and then hand off
990
* to the AArch64-entry or AArch32-entry function depending on the
991
* target exception level's register width.
992
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
993
}
994
#endif
995
996
- /* Hooks may change global state so BQL should be held, also the
997
+ /*
998
+ * Hooks may change global state so BQL should be held, also the
999
* BQL needs to be held for any modification of
1000
* cs->interrupt_request.
1001
*/
1002
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
40
};
1003
};
41
}
1004
}
42
1005
43
+/**
1006
-/* Note that signed overflow is undefined in C. The following routines are
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
1007
- careful to use unsigned types where modulo arithmetic is required.
45
+ *
1008
- Failure to do so _will_ break on newer gcc. */
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
1009
+/*
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
1010
+ * Note that signed overflow is undefined in C. The following routines are
48
+ * information on why the translation aborted, in the format of a long-format
1011
+ * careful to use unsigned types where modulo arithmetic is required.
49
+ * DFSR/IFSR fault register, with the following caveats:
1012
+ * Failure to do so _will_ break on newer gcc.
50
+ * * the WnR bit is never set (the caller must do this).
51
+ *
52
+ * @env: CPUARMState
53
+ * @address: virtual address to get physical address for
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
55
+ * @mmu_idx: MMU index indicating required translation regime
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
60
+ * @attrs: set to the memory transaction attributes to use
61
+ * @prot: set to the permissions for the page containing phys_ptr
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
63
+ * @fi: set to fault info if the translation fails
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
65
+ */
1013
+ */
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
1014
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
1015
/* Signed saturating arithmetic. */
68
+ bool s1_is_el0,
1016
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
1017
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
70
target_ulong *page_size_ptr,
1018
return (a & mask) | (b & ~mask);
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
1019
}
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
1020
73
1021
-/* CRC helpers.
74
/* S1 is done. Now do S2 translation. */
1022
+/*
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
1023
+ * CRC helpers.
76
+ mmu_idx == ARMMMUIdx_E10_0,
1024
* The upper bytes of val (above the number specified by 'bytes') must have
77
phys_ptr, attrs, &s2_prot,
1025
* been zeroed out by the caller.
78
page_size, fi,
1026
*/
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
1027
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
1028
return crc32c(acc, buf, bytes) ^ 0xffffffff;
81
}
1029
}
82
1030
83
if (regime_using_lpae_format(env, mmu_idx)) {
1031
-/* Return the exception level to which FP-disabled exceptions should
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
1032
+/*
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
1033
+ * Return the exception level to which FP-disabled exceptions should
86
phys_ptr, attrs, prot, page_size,
1034
* be taken, or 0 if FP is enabled.
87
fi, cacheattrs);
1035
*/
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
1036
int fp_exception_el(CPUARMState *env, int cur_el)
1037
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
1038
#ifndef CONFIG_USER_ONLY
1039
uint64_t hcr_el2;
1040
1041
- /* CPACR and the CPTR registers don't exist before v6, so FP is
1042
+ /*
1043
+ * CPACR and the CPTR registers don't exist before v6, so FP is
1044
* always accessible
1045
*/
1046
if (!arm_feature(env, ARM_FEATURE_V6)) {
1047
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
1048
1049
hcr_el2 = arm_hcr_el2_eff(env);
1050
1051
- /* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
1052
+ /*
1053
+ * The CPACR controls traps to EL1, or PL1 if we're 32 bit:
1054
* 0, 2 : trap EL0 and EL1/PL1 accesses
1055
* 1 : trap only EL0 accesses
1056
* 3 : trap no accesses
89
--
1057
--
90
2.20.1
1058
2.25.1
91
92
diff view generated by jsdifflib
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
1
From: Fabiano Rosas <farosas@suse.de>
2
TLB. However we never actually use the TLB -- all stage 2 lookups
3
are done by direct calls to get_phys_addr_lpae() followed by a
4
physical address load via address_space_ld*().
5
2
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
3
Fix the following:
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
8
MMU indexes.
9
4
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
5
ERROR: spaces required around that '|' (ctx:VxV)
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
6
ERROR: space required before the open parenthesis '('
12
permission bits to the stage 2 descriptors which define execute
7
ERROR: spaces required around that '+' (ctx:VxB)
13
permission separatel for EL0 and EL1; supporting that while keeping
8
ERROR: space prohibited between function name and open parenthesis '('
14
Stage2 in a QEMU TLB would require us to use separate TLBs for
15
"Stage2 for an EL0 access" and "Stage2 for an EL1 access", which is a
16
lot of extra complication given we aren't even using the QEMU TLB.
17
9
18
In the process of updating the comment on our MMU index use,
10
(the last two still have some occurrences in macros which I left
19
fix a couple of other minor errors:
11
behind because it might impact readability)
20
* NS EL2 EL2&0 was missing from the list in the comment
21
* some text hadn't been updated from when we bumped NB_MMU_MODES
22
above 8
23
12
13
Signed-off-by: Fabiano Rosas <farosas@suse.de>
14
Reviewed-by: Claudio Fontana <cfontana@suse.de>
15
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
16
Message-id: 20221213190537.511-3-farosas@suse.de
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20200330210400.11724-2-peter.maydell@linaro.org
28
---
18
---
29
target/arm/cpu-param.h | 2 +-
19
target/arm/helper.c | 42 +++++++++++++++++++++---------------------
30
target/arm/cpu.h | 21 +++++---
20
1 file changed, 21 insertions(+), 21 deletions(-)
31
target/arm/helper.c | 112 ++++-------------------------------------
32
3 files changed, 27 insertions(+), 108 deletions(-)
33
21
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
37
+++ b/target/arm/cpu-param.h
38
@@ -XXX,XX +XXX,XX @@
39
# define TARGET_PAGE_BITS_MIN 10
40
#endif
41
42
-#define NB_MMU_MODES 12
43
+#define NB_MMU_MODES 11
44
45
#endif
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
51
* handling via the TLB. The only way to do a stage 1 translation without
52
* the immediate stage 2 translation is via the ATS or AT system insns,
53
* which can be slow-pathed and always do a page table walk.
54
+ * The only use of stage 2 translations is either as part of an s1+2
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
56
+ * and in both those cases we don't use the TLB.
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
58
* translation regimes, because they map reasonably well to each other
59
* and they can't both be active at the same time.
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
62
* NS EL1 EL1&0 stage 1+2 +PAN
63
* NS EL0 EL2&0
64
+ * NS EL2 EL2&0
65
* NS EL2 EL2&0 +PAN
66
* NS EL2 (aka NS PL2)
67
* S EL0 EL1&0 (aka S PL0)
68
* S EL1 EL1&0 (not used if EL3 is 32 bit)
69
* S EL1 EL1&0 +PAN
70
* S EL3 (aka S PL1)
71
- * NS EL1&0 stage 2
72
*
73
- * for a total of 12 different mmu_idx.
74
+ * for a total of 11 different mmu_idx.
75
*
76
* R profile CPUs have an MPU, but can use the same set of MMU indexes
77
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
78
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
79
* are not quite the same -- different CPU types (most notably M profile
80
* vs A/R profile) would like to use MMU indexes with different semantics,
81
* but since we don't ever need to use all of those in a single CPU we
82
- * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
83
+ * can avoid having to set NB_MMU_MODES to "total number of A profile MMU
84
+ * modes + total number of M profile MMU modes". The lower bits of
85
* ARMMMUIdx are the core TLB mmu index, and the higher bits are always
86
* the same for any particular CPU.
87
* Variables of type ARMMUIdx are always full values, and the core
88
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
89
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
90
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
91
92
- ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
93
-
94
/*
95
* These are not allocated TLBs and are used only for AT system
96
* instructions or for the first stage of an S12 page table walk.
97
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
98
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
99
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
100
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
101
+ /*
102
+ * Not allocated a TLB: used only for second stage of an S12 page
103
+ * table walk, or for descriptor loads during first stage of an S1
104
+ * page table walk. Note that if we ever want to have a TLB for this
105
+ * then various TLB flush insns which currently are no-ops or flush
106
+ * only stage 1 MMU indexes will need to change to flush stage 2.
107
+ */
108
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
109
110
/*
111
* M-profile.
112
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
113
TO_CORE_BIT(SE10_1),
114
TO_CORE_BIT(SE10_1_PAN),
115
TO_CORE_BIT(SE3),
116
- TO_CORE_BIT(Stage2),
117
118
TO_CORE_BIT(MUser),
119
TO_CORE_BIT(MPriv),
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
121
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
122
--- a/target/arm/helper.c
24
--- a/target/arm/helper.c
123
+++ b/target/arm/helper.c
25
+++ b/target/arm/helper.c
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
26
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_list(gpointer key, gpointer opaque)
125
tlb_flush_by_mmuidx(cs,
27
uint32_t regidx = (uintptr_t)key;
126
ARMMMUIdxBit_E10_1 |
28
const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
127
ARMMMUIdxBit_E10_1_PAN |
29
128
- ARMMMUIdxBit_E10_0 |
30
- if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
129
- ARMMMUIdxBit_Stage2);
31
+ if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_ALIAS))) {
130
+ ARMMMUIdxBit_E10_0);
32
cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
131
}
33
/* The value array need not be initialized at this point */
132
34
cpu->cpreg_array_len++;
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
35
@@ -XXX,XX +XXX,XX @@ static void count_cpreg(gpointer key, gpointer opaque)
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
36
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
37
ri = g_hash_table_lookup(cpu->cp_regs, key);
136
ARMMMUIdxBit_E10_1 |
38
137
ARMMMUIdxBit_E10_1_PAN |
39
- if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
138
- ARMMMUIdxBit_E10_0 |
40
+ if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_ALIAS))) {
139
- ARMMMUIdxBit_Stage2);
41
cpu->cpreg_array_len++;
140
+ ARMMMUIdxBit_E10_0);
141
}
142
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
- uint64_t value)
145
-{
146
- /* Invalidate by IPA. This has to invalidate any structures that
147
- * contain only stage 2 translation information, but does not need
148
- * to apply to structures that contain combined stage 1 and stage 2
149
- * translation information.
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
151
- */
152
- CPUState *cs = env_cpu(env);
153
- uint64_t pageaddr;
154
-
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
156
- return;
157
- }
158
-
159
- pageaddr = sextract64(value << 12, 0, 40);
160
-
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
162
-}
163
-
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
165
- uint64_t value)
166
-{
167
- CPUState *cs = env_cpu(env);
168
- uint64_t pageaddr;
169
-
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
171
- return;
172
- }
173
-
174
- pageaddr = sextract64(value << 12, 0, 40);
175
-
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
177
- ARMMMUIdxBit_Stage2);
178
-}
179
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
uint64_t value)
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
tlb_flush_by_mmuidx(cs,
184
ARMMMUIdxBit_E10_1 |
185
ARMMMUIdxBit_E10_1_PAN |
186
- ARMMMUIdxBit_E10_0 |
187
- ARMMMUIdxBit_Stage2);
188
+ ARMMMUIdxBit_E10_0);
189
raw_write(env, ri, value);
190
}
42
}
191
}
43
}
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
44
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
193
return ARMMMUIdxBit_SE10_1 |
45
.resetfn = arm_cp_reset_ignore },
194
ARMMMUIdxBit_SE10_1_PAN |
46
{ .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
195
ARMMMUIdxBit_SE10_0;
47
.opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
48
- .access = PL0_R|PL1_W,
197
- return ARMMMUIdxBit_E10_1 |
49
+ .access = PL0_R | PL1_W,
198
- ARMMMUIdxBit_E10_1_PAN |
50
.fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]),
199
- ARMMMUIdxBit_E10_0 |
51
.resetvalue = 0},
200
- ARMMMUIdxBit_Stage2;
52
{ .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
201
} else {
53
- .access = PL0_R|PL1_W,
202
return ARMMMUIdxBit_E10_1 |
54
+ .access = PL0_R | PL1_W,
203
ARMMMUIdxBit_E10_1_PAN |
55
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
56
offsetoflow32(CPUARMState, cp15.tpidruro_ns) },
205
ARMMMUIdxBit_SE3);
57
.resetfn = arm_cp_reset_ignore },
206
}
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
207
59
.resetvalue = 0 },
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
60
/* The cache ops themselves: these all NOP for QEMU */
209
- uint64_t value)
61
{ .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0,
210
-{
62
- .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
211
- /* Invalidate by IPA. This has to invalidate any structures that
63
+ .access = PL1_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
212
- * contain only stage 2 translation information, but does not need
64
{ .name = "IDCR", .cp = 15, .crm = 6, .opc1 = 0,
213
- * to apply to structures that contain combined stage 1 and stage 2
65
- .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
214
- * translation information.
66
+ .access = PL1_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
67
{ .name = "CDCR", .cp = 15, .crm = 12, .opc1 = 0,
216
- */
68
- .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
217
- ARMCPU *cpu = env_archcpu(env);
69
+ .access = PL0_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
218
- CPUState *cs = CPU(cpu);
70
{ .name = "PIR", .cp = 15, .crm = 12, .opc1 = 1,
219
- uint64_t pageaddr;
71
- .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
220
-
72
+ .access = PL0_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
73
{ .name = "PDR", .cp = 15, .crm = 12, .opc1 = 2,
222
- return;
74
- .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
223
- }
75
+ .access = PL0_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
224
-
76
{ .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0,
225
- pageaddr = sextract64(value << 12, 0, 48);
77
- .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
226
-
78
+ .access = PL1_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
79
};
228
-}
80
229
-
81
static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
82
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
231
- uint64_t value)
83
ARMCPRegInfo cbar = {
232
-{
84
.name = "CBAR",
233
- CPUState *cs = env_cpu(env);
85
.cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,
234
- uint64_t pageaddr;
86
- .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar,
235
-
87
+ .access = PL1_R | PL3_W, .resetvalue = cpu->reset_cbar,
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
88
.fieldoffset = offsetof(CPUARMState,
237
- return;
89
cp15.c15_config_base_address)
238
- }
90
};
239
-
91
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode)
240
- pageaddr = sextract64(value << 12, 0, 48);
92
return;
241
-
93
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
94
if (old_mode == ARM_CPU_MODE_FIQ) {
243
- ARMMMUIdxBit_Stage2);
95
- memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
244
-}
96
- memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
245
-
97
+ memcpy(env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
98
+ memcpy(env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
247
bool isread)
99
} else if (mode == ARM_CPU_MODE_FIQ) {
248
{
100
- memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
101
- memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
250
.writefn = tlbi_aa64_vae1_write },
102
+ memcpy(env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
103
+ memcpy(env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
104
}
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
105
254
- .writefn = tlbi_aa64_ipas2e1is_write },
106
i = bank_number(old_mode);
255
+ .access = PL2_W, .type = ARM_CP_NOP },
107
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
108
RESULT(sum, n, 16); \
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
109
if (sum >= 0) \
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
110
ge |= 3 << (n * 2); \
259
- .writefn = tlbi_aa64_ipas2e1is_write },
111
- } while(0)
260
+ .access = PL2_W, .type = ARM_CP_NOP },
112
+ } while (0)
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
113
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
114
#define SARITH8(a, b, n, op) do { \
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
115
int32_t sum; \
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
116
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
265
.writefn = tlbi_aa64_alle1is_write },
117
RESULT(sum, n, 8); \
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
118
if (sum >= 0) \
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
119
ge |= 1 << n; \
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
120
- } while(0)
269
- .writefn = tlbi_aa64_ipas2e1_write },
121
+ } while (0)
270
+ .access = PL2_W, .type = ARM_CP_NOP },
122
271
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
123
272
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
124
#define ADD16(a, b, n) SARITH16(a, b, n, +)
273
- .access = PL2_W, .type = ARM_CP_NO_RAW,
125
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
274
- .writefn = tlbi_aa64_ipas2e1_write },
126
RESULT(sum, n, 16); \
275
+ .access = PL2_W, .type = ARM_CP_NOP },
127
if ((sum >> 16) == 1) \
276
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
128
ge |= 3 << (n * 2); \
277
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
129
- } while(0)
278
.access = PL2_W, .type = ARM_CP_NO_RAW,
130
+ } while (0)
279
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
131
280
.writefn = tlbimva_hyp_is_write },
132
#define ADD8(a, b, n) do { \
281
{ .name = "TLBIIPAS2",
133
uint32_t sum; \
282
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
134
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
283
- .type = ARM_CP_NO_RAW, .access = PL2_W,
135
RESULT(sum, n, 8); \
284
- .writefn = tlbiipas2_write },
136
if ((sum >> 8) == 1) \
285
+ .type = ARM_CP_NOP, .access = PL2_W },
137
ge |= 1 << n; \
286
{ .name = "TLBIIPAS2IS",
138
- } while(0)
287
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
139
+ } while (0)
288
- .type = ARM_CP_NO_RAW, .access = PL2_W,
140
289
- .writefn = tlbiipas2_is_write },
141
#define SUB16(a, b, n) do { \
290
+ .type = ARM_CP_NOP, .access = PL2_W },
142
uint32_t sum; \
291
{ .name = "TLBIIPAS2L",
143
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
292
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
144
RESULT(sum, n, 16); \
293
- .type = ARM_CP_NO_RAW, .access = PL2_W,
145
if ((sum >> 16) == 0) \
294
- .writefn = tlbiipas2_write },
146
ge |= 3 << (n * 2); \
295
+ .type = ARM_CP_NOP, .access = PL2_W },
147
- } while(0)
296
{ .name = "TLBIIPAS2LIS",
148
+ } while (0)
297
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
149
298
- .type = ARM_CP_NO_RAW, .access = PL2_W,
150
#define SUB8(a, b, n) do { \
299
- .writefn = tlbiipas2_is_write },
151
uint32_t sum; \
300
+ .type = ARM_CP_NOP, .access = PL2_W },
152
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
301
/* 32 bit cache operations */
153
RESULT(sum, n, 8); \
302
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
154
if ((sum >> 8) == 0) \
303
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
155
ge |= 1 << n; \
156
- } while(0)
157
+ } while (0)
158
159
#define PFX u
160
#define ARITH_GE
304
--
161
--
305
2.20.1
162
2.25.1
306
307
diff view generated by jsdifflib
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Fix this:
4
ERROR: braces {} are necessary for all arms of this statement
5
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
7
Reviewed-by: Claudio Fontana <cfontana@suse.de>
8
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
9
Message-id: 20221213190537.511-4-farosas@suse.de
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
6
---
11
---
7
target/arm/neon-shared.decode | 5 +++++
12
target/arm/helper.c | 67 ++++++++++++++++++++++++++++-----------------
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
13
1 file changed, 42 insertions(+), 25 deletions(-)
9
target/arm/translate.c | 26 +--------------------
10
3 files changed, 46 insertions(+), 25 deletions(-)
11
14
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
17
--- a/target/arm/helper.c
15
+++ b/target/arm/neon-shared.decode
18
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
19
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
20
env->CF = (val >> 29) & 1;
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
21
env->VF = (val << 3) & 0x80000000;
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
22
}
20
+
23
- if (mask & CPSR_Q)
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
24
+ if (mask & CPSR_Q) {
22
+ vn=%vn_dp vd=%vd_dp size=0
25
env->QF = ((val & CPSR_Q) != 0);
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
26
- if (mask & CPSR_T)
24
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
27
+ }
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
+ if (mask & CPSR_T) {
26
index XXXXXXX..XXXXXXX 100644
29
env->thumb = ((val & CPSR_T) != 0);
27
--- a/target/arm/translate-neon.inc.c
30
+ }
28
+++ b/target/arm/translate-neon.inc.c
31
if (mask & CPSR_IT_0_1) {
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
32
env->condexec_bits &= ~3;
30
gen_helper_gvec_fmlal_a32);
33
env->condexec_bits |= (val >> 25) & 3;
31
return true;
34
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode)
35
int i;
36
37
old_mode = env->uncached_cpsr & CPSR_M;
38
- if (mode == old_mode)
39
+ if (mode == old_mode) {
40
return;
41
+ }
42
43
if (old_mode == ARM_CPU_MODE_FIQ) {
44
memcpy(env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
45
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
46
new_mode = ARM_CPU_MODE_UND;
47
addr = 0x04;
48
mask = CPSR_I;
49
- if (env->thumb)
50
+ if (env->thumb) {
51
offset = 2;
52
- else
53
+ } else {
54
offset = 4;
55
+ }
56
break;
57
case EXCP_SWI:
58
new_mode = ARM_CPU_MODE_SVC;
59
@@ -XXX,XX +XXX,XX @@ static inline uint16_t add16_sat(uint16_t a, uint16_t b)
60
61
res = a + b;
62
if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
63
- if (a & 0x8000)
64
+ if (a & 0x8000) {
65
res = 0x8000;
66
- else
67
+ } else {
68
res = 0x7fff;
69
+ }
70
}
71
return res;
32
}
72
}
33
+
73
@@ -XXX,XX +XXX,XX @@ static inline uint8_t add8_sat(uint8_t a, uint8_t b)
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
74
35
+{
75
res = a + b;
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
76
if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
37
+ int opr_sz;
77
- if (a & 0x80)
38
+ TCGv_ptr fpst;
78
+ if (a & 0x80) {
39
+
79
res = 0x80;
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
80
- else
41
+ return false;
81
+ } else {
82
res = 0x7f;
83
+ }
84
}
85
return res;
86
}
87
@@ -XXX,XX +XXX,XX @@ static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
88
89
res = a - b;
90
if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
91
- if (a & 0x8000)
92
+ if (a & 0x8000) {
93
res = 0x8000;
94
- else
95
+ } else {
96
res = 0x7fff;
97
+ }
98
}
99
return res;
100
}
101
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
102
103
res = a - b;
104
if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
105
- if (a & 0x80)
106
+ if (a & 0x80) {
107
res = 0x80;
108
- else
109
+ } else {
110
res = 0x7f;
111
+ }
112
}
113
return res;
114
}
115
@@ -XXX,XX +XXX,XX @@ static inline uint16_t add16_usat(uint16_t a, uint16_t b)
116
{
117
uint16_t res;
118
res = a + b;
119
- if (res < a)
120
+ if (res < a) {
121
res = 0xffff;
42
+ }
122
+ }
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
123
return res;
44
+ return false;
124
}
125
126
static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
127
{
128
- if (a > b)
129
+ if (a > b) {
130
return a - b;
131
- else
132
+ } else {
133
return 0;
45
+ }
134
+ }
46
+
135
}
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
136
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
137
static inline uint8_t add8_usat(uint8_t a, uint8_t b)
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
138
{
50
+ return false;
139
uint8_t res;
140
res = a + b;
141
- if (res < a)
142
+ if (res < a) {
143
res = 0xff;
51
+ }
144
+ }
52
+
145
return res;
53
+ if ((a->vd | a->vn) & a->q) {
146
}
54
+ return false;
147
148
static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
149
{
150
- if (a > b)
151
+ if (a > b) {
152
return a - b;
153
- else
154
+ } else {
155
return 0;
55
+ }
156
+ }
56
+
157
}
57
+ if (!vfp_access_check(s)) {
158
58
+ return true;
159
#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
160
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
161
162
static inline uint8_t do_usad(uint8_t a, uint8_t b)
163
{
164
- if (a > b)
165
+ if (a > b) {
166
return a - b;
167
- else
168
+ } else {
169
return b - a;
59
+ }
170
+ }
60
+
171
}
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
172
62
+ : gen_helper_gvec_fcmlah_idx);
173
/* Unsigned sum of absolute byte differences. */
63
+ opr_sz = (1 + a->q) * 8;
174
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
64
+ fpst = get_fpstatus_ptr(1);
175
uint32_t mask;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
176
66
+ vfp_reg_offset(1, a->vn),
177
mask = 0;
67
+ vfp_reg_offset(1, a->vm),
178
- if (flags & 1)
68
+ fpst, opr_sz, opr_sz,
179
+ if (flags & 1) {
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
180
mask |= 0xff;
70
+ tcg_temp_free_ptr(fpst);
181
- if (flags & 2)
71
+ return true;
182
+ }
72
+}
183
+ if (flags & 2) {
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
184
mask |= 0xff00;
74
index XXXXXXX..XXXXXXX 100644
185
- if (flags & 4)
75
--- a/target/arm/translate.c
186
+ }
76
+++ b/target/arm/translate.c
187
+ if (flags & 4) {
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
188
mask |= 0xff0000;
78
bool is_long = false, q = extract32(insn, 6, 1);
189
- if (flags & 8)
79
bool ptr_is_env = false;
190
+ }
80
191
+ if (flags & 8) {
81
- if ((insn & 0xff000f10) == 0xfe000800) {
192
mask |= 0xff000000;
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
193
+ }
83
- int rot = extract32(insn, 20, 2);
194
return (a & mask) | (b & ~mask);
84
- int size = extract32(insn, 23, 1);
195
}
85
- int index;
86
-
87
- if (!dc_isar_feature(aa32_vcma, s)) {
88
- return 1;
89
- }
90
- if (size == 0) {
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
92
- return 1;
93
- }
94
- /* For fp16, rm is just Vm, and index is M. */
95
- rm = extract32(insn, 0, 4);
96
- index = extract32(insn, 5, 1);
97
- } else {
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
99
- VFP_DREG_M(rm, insn);
100
- index = 0;
101
- }
102
- data = (index << 2) | rot;
103
- fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
104
- : gen_helper_gvec_fcmlah_idx);
105
- } else if ((insn & 0xffb00f00) == 0xfe200d00) {
106
+ if ((insn & 0xffb00f00) == 0xfe200d00) {
107
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
108
int u = extract32(insn, 4, 1);
109
196
110
--
197
--
111
2.20.1
198
2.25.1
112
113
diff view generated by jsdifflib
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
1
From: Fabiano Rosas <farosas@suse.de>
2
Note that for the logic ops the 'size' field forms part of their
3
decode and the actual operations are always bitwise.
4
2
3
Signed-off-by: Fabiano Rosas <farosas@suse.de>
4
Reviewed-by: Claudio Fontana <cfontana@suse.de>
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
6
Message-id: 20221213190537.511-5-farosas@suse.de
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
8
---
8
---
9
target/arm/neon-dp.decode | 12 +++++++++++
9
target/arm/m_helper.c | 16 ----------------
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
10
1 file changed, 16 deletions(-)
11
target/arm/translate.c | 38 +--------------------------------
12
3 files changed, 32 insertions(+), 37 deletions(-)
13
11
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
12
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
14
--- a/target/arm/m_helper.c
17
+++ b/target/arm/neon-dp.decode
15
+++ b/target/arm/m_helper.c
18
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
17
*/
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
18
21
19
#include "qemu/osdep.h"
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
20
-#include "qemu/units.h"
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
21
-#include "target/arm/idau.h"
24
+
22
-#include "trace.h"
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
23
#include "cpu.h"
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
24
#include "internals.h"
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
25
-#include "exec/gdbstub.h"
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
26
#include "exec/helper-proto.h"
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
27
-#include "qemu/host-utils.h"
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
28
#include "qemu/main-loop.h"
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
29
#include "qemu/bitops.h"
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
30
-#include "qemu/crc32c.h"
33
+
31
-#include "qemu/qemu-print.h"
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
32
#include "qemu/log.h"
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
33
#include "exec/exec-all.h"
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
-#include <zlib.h> /* For crc32 */
37
index XXXXXXX..XXXXXXX 100644
35
-#include "semihosting/semihost.h"
38
--- a/target/arm/translate-neon.inc.c
36
-#include "sysemu/cpus.h"
39
+++ b/target/arm/translate-neon.inc.c
37
-#include "sysemu/kvm.h"
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
38
-#include "qemu/range.h"
41
39
-#include "qapi/qapi-commands-machine-target.h"
42
DO_3SAME(VADD, tcg_gen_gvec_add)
40
-#include "qapi/error.h"
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
41
-#include "qemu/guest-random.h"
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
42
#ifdef CONFIG_TCG
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
43
-#include "arm_ldst.h"
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
44
#include "exec/cpu_ldst.h"
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
45
#include "semihosting/common-semi.h"
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
46
#endif
49
+
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
54
+ uint32_t oprsz, uint32_t maxsz) \
55
+ { \
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
57
+ } \
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
59
+
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.c
66
+++ b/target/arm/translate.c
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
68
}
69
return 1;
70
71
- case NEON_3R_LOGIC: /* Logic ops. */
72
- switch ((u << 2) | size) {
73
- case 0: /* VAND */
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
75
- vec_size, vec_size);
76
- break;
77
- case 1: /* VBIC */
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
79
- vec_size, vec_size);
80
- break;
81
- case 2: /* VORR */
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
83
- vec_size, vec_size);
84
- break;
85
- case 3: /* VORN */
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
87
- vec_size, vec_size);
88
- break;
89
- case 4: /* VEOR */
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
91
- vec_size, vec_size);
92
- break;
93
- case 5: /* VBSL */
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
95
- vec_size, vec_size);
96
- break;
97
- case 6: /* VBIT */
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
99
- vec_size, vec_size);
100
- break;
101
- case 7: /* VBIF */
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
103
- vec_size, vec_size);
104
- break;
105
- }
106
- return 0;
107
-
108
case NEON_3R_VQADD:
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
110
rn_ofs, rm_ofs, vec_size, vec_size,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
114
case NEON_3R_VADD_VSUB:
115
+ case NEON_3R_LOGIC:
116
/* Already handled by decodetree */
117
return 1;
118
}
119
--
47
--
120
2.20.1
48
2.25.1
121
122
diff view generated by jsdifflib
1
Convert the Neon "load single structure to all lanes" insns to
1
From: Fabiano Rosas <farosas@suse.de>
2
decodetree.
3
2
3
Signed-off-by: Fabiano Rosas <farosas@suse.de>
4
Reviewed-by: Claudio Fontana <cfontana@suse.de>
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
6
Message-id: 20221213190537.511-6-farosas@suse.de
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
7
---
8
---
8
target/arm/neon-ls.decode | 5 +++
9
target/arm/helper.c | 7 -------
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
10
1 file changed, 7 deletions(-)
10
target/arm/translate.c | 55 +------------------------
11
3 files changed, 80 insertions(+), 53 deletions(-)
12
11
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-ls.decode
14
--- a/target/arm/helper.c
16
+++ b/target/arm/neon-ls.decode
15
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
18
17
*/
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
18
20
vd=%vd_dp
19
#include "qemu/osdep.h"
21
+
20
-#include "qemu/units.h"
22
+# Neon load single element to all lanes
21
#include "qemu/log.h"
23
+
22
#include "trace.h"
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
23
#include "cpu.h"
25
+ vd=%vd_dp
24
#include "internals.h"
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
#include "exec/helper-proto.h"
27
index XXXXXXX..XXXXXXX 100644
26
-#include "qemu/host-utils.h"
28
--- a/target/arm/translate-neon.inc.c
27
#include "qemu/main-loop.h"
29
+++ b/target/arm/translate-neon.inc.c
28
#include "qemu/timer.h"
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
29
#include "qemu/bitops.h"
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
30
@@ -XXX,XX +XXX,XX @@
32
return true;
31
#include "exec/exec-all.h"
33
}
32
#include <zlib.h> /* For crc32 */
34
+
33
#include "hw/irq.h"
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
34
-#include "semihosting/semihost.h"
36
+{
35
-#include "sysemu/cpus.h"
37
+ /* Neon load single structure to all lanes */
36
#include "sysemu/cpu-timers.h"
38
+ int reg, stride, vec_size;
37
#include "sysemu/kvm.h"
39
+ int vd = a->vd;
38
-#include "qemu/range.h"
40
+ int size = a->size;
39
#include "qapi/qapi-commands-machine-target.h"
41
+ int nregs = a->n + 1;
40
#include "qapi/error.h"
42
+ TCGv_i32 addr, tmp;
41
#include "qemu/guest-random.h"
43
+
42
#ifdef CONFIG_TCG
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
43
-#include "arm_ldst.h"
45
+ return false;
44
-#include "exec/cpu_ldst.h"
46
+ }
45
#include "semihosting/common-semi.h"
47
+
46
#endif
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
47
#include "cpregs.h"
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if (size == 3) {
54
+ if (nregs != 4 || a->a == 0) {
55
+ return false;
56
+ }
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
58
+ size = 2;
59
+ }
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
61
+ return false;
62
+ }
63
+ if (nregs == 3 && a->a == 1) {
64
+ return false;
65
+ }
66
+
67
+ if (!vfp_access_check(s)) {
68
+ return true;
69
+ }
70
+
71
+ /*
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
74
+ */
75
+ stride = a->t ? 2 : 1;
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
77
+
78
+ tmp = tcg_temp_new_i32();
79
+ addr = tcg_temp_new_i32();
80
+ load_reg_var(s, addr, a->rn);
81
+ for (reg = 0; reg < nregs; reg++) {
82
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
83
+ s->be_data | size);
84
+ if ((vd & 1) && vec_size == 16) {
85
+ /*
86
+ * We cannot write 16 bytes at once because the
87
+ * destination is unaligned.
88
+ */
89
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
90
+ 8, 8, tmp);
91
+ tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
92
+ neon_reg_offset(vd, 0), 8, 8);
93
+ } else {
94
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
95
+ vec_size, vec_size, tmp);
96
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
98
+ vd += stride;
99
+ }
100
+ tcg_temp_free_i32(tmp);
101
+ tcg_temp_free_i32(addr);
102
+
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
104
+
105
+ return true;
106
+}
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
112
int size;
113
int reg;
114
int load;
115
- int vec_size;
116
TCGv_i32 addr;
117
TCGv_i32 tmp;
118
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
120
} else {
121
size = (insn >> 10) & 3;
122
if (size == 3) {
123
- /* Load single element to all lanes. */
124
- int a = (insn >> 4) & 1;
125
- if (!load) {
126
- return 1;
127
- }
128
- size = (insn >> 6) & 3;
129
- nregs = ((insn >> 8) & 3) + 1;
130
-
131
- if (size == 3) {
132
- if (nregs != 4 || a == 0) {
133
- return 1;
134
- }
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
136
- size = 2;
137
- }
138
- if (nregs == 1 && a == 1 && size == 0) {
139
- return 1;
140
- }
141
- if (nregs == 3 && a == 1) {
142
- return 1;
143
- }
144
- addr = tcg_temp_new_i32();
145
- load_reg_var(s, addr, rn);
146
-
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
149
- */
150
- stride = (insn & (1 << 5)) ? 2 : 1;
151
- vec_size = nregs == 1 ? stride * 8 : 8;
152
-
153
- tmp = tcg_temp_new_i32();
154
- for (reg = 0; reg < nregs; reg++) {
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
156
- s->be_data | size);
157
- if ((rd & 1) && vec_size == 16) {
158
- /* We cannot write 16 bytes at once because the
159
- * destination is unaligned.
160
- */
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
162
- 8, 8, tmp);
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
164
- neon_reg_offset(rd, 0), 8, 8);
165
- } else {
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
167
- vec_size, vec_size, tmp);
168
- }
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
170
- rd += stride;
171
- }
172
- tcg_temp_free_i32(tmp);
173
- tcg_temp_free_i32(addr);
174
- stride = (1 << size) * nregs;
175
+ /* Load single element to all lanes -- handled by decodetree */
176
+ return 1;
177
} else {
178
/* Single element. */
179
int idx = (insn >> 4) & 0xf;
180
--
48
--
181
2.20.1
49
2.25.1
182
183
diff view generated by jsdifflib
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
1
From: Claudio Fontana <cfontana@suse.de>
2
registers. The intended pattern is that for 64-bit ID registers we
3
use FIELD_DP64 and the uint64_t 't' register, while 32-bit ID
4
registers use FIELD_DP32 and the uint32_t 'u' register. For
5
ID_AA64DFR0 we accidentally used 'u', meaning that the top 32 bits of
6
this 64-bit ID register would end up always zero. Luckily at the
7
moment that's what they should be anyway, so this bug has no visible
8
effects.
9
2
10
Use the right-sized variable.
3
Remove some unused headers.
11
4
12
Fixes: 3bec78447a958d481991
5
Signed-off-by: Claudio Fontana <cfontana@suse.de>
6
Acked-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Claudio Fontana <cfontana@suse.de>
8
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Message-id: 20221213190537.511-7-farosas@suse.de
11
[added back some includes that are still needed at this point]
12
Signed-off-by: Fabiano Rosas <farosas@suse.de>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200423110915.10527-1-peter.maydell@linaro.org
17
---
14
---
18
target/arm/cpu64.c | 6 +++---
15
target/arm/cpu.c | 1 -
19
1 file changed, 3 insertions(+), 3 deletions(-)
16
target/arm/cpu64.c | 6 ------
17
2 files changed, 7 deletions(-)
20
18
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@
24
#include "target/arm/idau.h"
25
#include "qemu/module.h"
26
#include "qapi/error.h"
27
-#include "qapi/visitor.h"
28
#include "cpu.h"
29
#ifdef CONFIG_TCG
30
#include "hw/core/tcg-cpu-ops.h"
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
22
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu64.c
33
--- a/target/arm/cpu64.c
24
+++ b/target/arm/cpu64.c
34
+++ b/target/arm/cpu64.c
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
@@ -XXX,XX +XXX,XX @@
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
36
#include "qemu/osdep.h"
27
cpu->isar.id_mmfr4 = u;
37
#include "qapi/error.h"
28
38
#include "cpu.h"
29
- u = cpu->isar.id_aa64dfr0;
39
-#ifdef CONFIG_TCG
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
40
-#include "hw/core/tcg-cpu-ops.h"
31
- cpu->isar.id_aa64dfr0 = u;
41
-#endif /* CONFIG_TCG */
32
+ t = cpu->isar.id_aa64dfr0;
42
#include "qemu/module.h"
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
43
-#if !defined(CONFIG_USER_ONLY)
34
+ cpu->isar.id_aa64dfr0 = t;
44
-#include "hw/loader.h"
35
45
-#endif
36
u = cpu->isar.id_dfr0;
46
#include "sysemu/kvm.h"
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
47
#include "sysemu/hvf.h"
48
#include "kvm_arm.h"
38
--
49
--
39
2.20.1
50
2.25.1
40
41
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Embed the GEMs into the SoC type.
3
The pointed MouseTransformInfo structure is accessed read-only.
4
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20221220142520.24094-2-philmd@linaro.org
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
10
include/hw/input/tsc2xxx.h | 4 ++--
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
11
hw/input/tsc2005.c | 2 +-
15
2 files changed, 10 insertions(+), 8 deletions(-)
12
hw/input/tsc210x.c | 3 +--
13
3 files changed, 4 insertions(+), 5 deletions(-)
16
14
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
15
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
17
--- a/include/hw/input/tsc2xxx.h
20
+++ b/include/hw/arm/xlnx-versal.h
18
+++ b/include/hw/input/tsc2xxx.h
21
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ uWireSlave *tsc2102_init(qemu_irq pint);
22
#include "hw/arm/boot.h"
20
uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
23
#include "hw/intc/arm_gicv3.h"
21
I2SCodec *tsc210x_codec(uWireSlave *chip);
24
#include "hw/char/pl011.h"
22
uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
25
+#include "hw/net/cadence_gem.h"
23
-void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
26
24
+void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info);
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
25
void tsc210x_key_event(uWireSlave *chip, int key, int down);
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
26
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
27
/* tsc2005.c */
30
28
void *tsc2005_init(qemu_irq pintdav);
31
struct {
29
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
30
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
31
+void tsc2005_set_transform(void *opaque, const MouseTransformInfo *info);
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
32
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
33
#endif
36
} iou;
34
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
37
} lpd;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
36
--- a/hw/input/tsc2005.c
41
+++ b/hw/arm/xlnx-versal.c
37
+++ b/hw/input/tsc2005.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
38
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav)
43
DeviceState *dev;
39
* from the touchscreen. Assuming 12-bit precision was used during
44
MemoryRegion *mr;
40
* tslib calibration.
45
41
*/
46
- dev = qdev_create(NULL, "cadence_gem");
42
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info)
47
- s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
43
+void tsc2005_set_transform(void *opaque, const MouseTransformInfo *info)
48
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
44
{
49
+ sysbus_init_child_obj(OBJECT(s), name,
45
TSC2005State *s = (TSC2005State *) opaque;
50
+ &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]),
46
51
+ TYPE_CADENCE_GEM);
47
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
52
+ dev = DEVICE(&s->lpd.iou.gem[i]);
48
index XXXXXXX..XXXXXXX 100644
53
if (nd->used) {
49
--- a/hw/input/tsc210x.c
54
qemu_check_nic_model(nd, "cadence_gem");
50
+++ b/hw/input/tsc210x.c
55
qdev_set_nic_properties(dev, nd);
51
@@ -XXX,XX +XXX,XX @@ I2SCodec *tsc210x_codec(uWireSlave *chip)
56
}
52
* from the touchscreen. Assuming 12-bit precision was used during
57
- object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
53
* tslib calibration.
58
+ object_property_set_int(OBJECT(dev),
54
*/
59
2, "num-priority-queues",
55
-void tsc210x_set_transform(uWireSlave *chip,
60
&error_abort);
56
- MouseTransformInfo *info)
61
- object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
57
+void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info)
62
+ object_property_set_link(OBJECT(dev),
58
{
63
OBJECT(&s->mr_ps), "dma",
59
TSC210xState *s = (TSC210xState *) chip->opaque;
64
&error_abort);
60
#if 0
65
qdev_init_nofail(dev);
66
67
- mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
68
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
69
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
70
71
- sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
73
g_free(name);
74
}
75
}
76
--
61
--
77
2.20.1
62
2.25.1
78
63
79
64
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Embed the UARTs into the SoC type.
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20221220142520.24094-3-philmd@linaro.org
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-5-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
7
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
8
hw/arm/nseries.c | 18 +++++++++---------
14
hw/arm/xlnx-versal.c | 12 ++++++------
9
1 file changed, 9 insertions(+), 9 deletions(-)
15
2 files changed, 8 insertions(+), 7 deletions(-)
16
10
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
11
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
13
--- a/hw/arm/nseries.c
20
+++ b/include/hw/arm/xlnx-versal.h
14
+++ b/hw/arm/nseries.c
21
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
22
#include "hw/sysbus.h"
23
#include "hw/arm/boot.h"
24
#include "hw/intc/arm_gicv3.h"
25
+#include "hw/char/pl011.h"
26
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
MemoryRegion mr_ocm;
31
32
struct {
33
- SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
34
+ PL011State uart[XLNX_VERSAL_NR_UARTS];
35
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
36
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
37
} iou;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@
43
#include "kvm_arm.h"
44
#include "hw/misc/unimp.h"
45
#include "hw/arm/xlnx-versal.h"
46
-#include "hw/char/pl011.h"
47
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
49
#define GEM_REVISION 0x40070106
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
51
DeviceState *dev;
52
MemoryRegion *mr;
53
54
- dev = qdev_create(NULL, TYPE_PL011);
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
56
+ sysbus_init_child_obj(OBJECT(s), name,
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
58
+ TYPE_PL011);
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
62
qdev_init_nofail(dev);
63
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
67
68
- sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
69
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
70
g_free(name);
71
}
72
}
16
}
17
18
/* Touchscreen and keypad controller */
19
-static MouseTransformInfo n800_pointercal = {
20
+static const MouseTransformInfo n800_pointercal = {
21
.x = 800,
22
.y = 480,
23
.a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },
24
};
25
26
-static MouseTransformInfo n810_pointercal = {
27
+static const MouseTransformInfo n810_pointercal = {
28
.x = 800,
29
.y = 480,
30
.a = { 15041, 148, -4731056, 171, -10238, 35933380, 65536 },
31
@@ -XXX,XX +XXX,XX @@ static void n810_key_event(void *opaque, int keycode)
32
33
#define M    0
34
35
-static int n810_keys[0x80] = {
36
+static const int n810_keys[0x80] = {
37
[0x01] = 16,    /* Q */
38
[0x02] = 37,    /* K */
39
[0x03] = 24,    /* O */
40
@@ -XXX,XX +XXX,XX @@ static void n8x0_usb_setup(struct n800_s *s)
41
/* Setup done before the main bootloader starts by some early setup code
42
* - used when we want to run the main bootloader in emulation. This
43
* isn't documented. */
44
-static uint32_t n800_pinout[104] = {
45
+static const uint32_t n800_pinout[104] = {
46
0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0,
47
0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808,
48
0x08080808, 0x180800c4, 0x00b80000, 0x08080808,
49
@@ -XXX,XX +XXX,XX @@ static void n8x0_boot_init(void *opaque)
50
#define OMAP_TAG_CBUS        0x4e03
51
#define OMAP_TAG_EM_ASIC_BB5    0x4e04
52
53
-static struct omap_gpiosw_info_s {
54
+static const struct omap_gpiosw_info_s {
55
const char *name;
56
int line;
57
int type;
58
@@ -XXX,XX +XXX,XX @@ static struct omap_gpiosw_info_s {
59
{ NULL }
60
};
61
62
-static struct omap_partition_info_s {
63
+static const struct omap_partition_info_s {
64
uint32_t offset;
65
uint32_t size;
66
int mask;
67
@@ -XXX,XX +XXX,XX @@ static struct omap_partition_info_s {
68
{ 0, 0, 0, NULL }
69
};
70
71
-static uint8_t n8x0_bd_addr[6] = { N8X0_BD_ADDR };
72
+static const uint8_t n8x0_bd_addr[6] = { N8X0_BD_ADDR };
73
74
static int n8x0_atag_setup(void *p, int model)
75
{
76
uint8_t *b;
77
uint16_t *w;
78
uint32_t *l;
79
- struct omap_gpiosw_info_s *gpiosw;
80
- struct omap_partition_info_s *partition;
81
+ const struct omap_gpiosw_info_s *gpiosw;
82
+ const struct omap_partition_info_s *partition;
83
const char *tag;
84
85
w = p;
73
--
86
--
74
2.20.1
87
2.25.1
75
88
76
89
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Move misplaced comment.
3
Silent when compiling with -Wextra:
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
../hw/arm/nseries.c:1081:12: warning: missing field 'line' initializer [-Wmissing-field-initializers]
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
{ NULL }
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
^
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
9
Message-id: 20200427181649.26851-3-edgar.iglesias@gmail.com
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20221220142520.24094-4-philmd@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/arm/xlnx-versal.c | 2 +-
14
hw/arm/nseries.c | 10 ++++------
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 4 insertions(+), 6 deletions(-)
14
16
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
17
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
19
--- a/hw/arm/nseries.c
18
+++ b/hw/arm/xlnx-versal.c
20
+++ b/hw/arm/nseries.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
21
@@ -XXX,XX +XXX,XX @@ static const struct omap_gpiosw_info_s {
20
22
"headphone", N8X0_HEADPHONE_GPIO,
21
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
23
OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
22
if (!obj) {
24
},
23
- /* Secondary CPUs start in PSCI powered-down state */
25
- { NULL }
24
error_report("Unable to create apu.cpu[%d] of type %s",
26
+ { /* end of list */ }
25
i, XLNX_VERSAL_ACPU_TYPE);
27
}, n810_gpiosw_info[] = {
26
exit(EXIT_FAILURE);
28
{
27
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
29
"gps_reset", N810_GPS_RESET_GPIO,
28
object_property_set_int(obj, s->cfg.psci_conduit,
30
@@ -XXX,XX +XXX,XX @@ static const struct omap_gpiosw_info_s {
29
"psci-conduit", &error_abort);
31
"slide", N810_SLIDE_GPIO,
30
if (i) {
32
OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
31
+ /* Secondary CPUs start in PSCI powered-down state */
33
},
32
object_property_set_bool(obj, true,
34
- { NULL }
33
"start-powered-off", &error_abort);
35
+ { /* end of list */ }
34
}
36
};
37
38
static const struct omap_partition_info_s {
39
@@ -XXX,XX +XXX,XX @@ static const struct omap_partition_info_s {
40
{ 0x00080000, 0x00200000, 0x0, "kernel" },
41
{ 0x00280000, 0x00200000, 0x3, "initfs" },
42
{ 0x00480000, 0x0fb80000, 0x3, "rootfs" },
43
-
44
- { 0, 0, 0, NULL }
45
+ { /* end of list */ }
46
}, n810_part_info[] = {
47
{ 0x00000000, 0x00020000, 0x3, "bootloader" },
48
{ 0x00020000, 0x00060000, 0x0, "config" },
49
{ 0x00080000, 0x00220000, 0x0, "kernel" },
50
{ 0x002a0000, 0x00400000, 0x0, "initfs" },
51
{ 0x006a0000, 0x0f960000, 0x0, "rootfs" },
52
-
53
- { 0, 0, 0, NULL }
54
+ { /* end of list */ }
55
};
56
57
static const uint8_t n8x0_bd_addr[6] = { N8X0_BD_ADDR };
35
--
58
--
36
2.20.1
59
2.25.1
37
60
38
61
diff view generated by jsdifflib
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
1
From: Zhuojia Shen <chaosdefinition@hotmail.com>
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
2
3
call it in S1_ptw_translate().
3
In CPUID registers exposed to userspace, some registers were missing
4
4
and some fields were not exposed. This patch aligns exposed ID
5
registers and their fields with what the upstream kernel currently
6
exposes.
7
8
Specifically, the following new ID registers/fields are exposed to
9
userspace:
10
11
ID_AA64PFR1_EL1.BT: bits 3-0
12
ID_AA64PFR1_EL1.MTE: bits 11-8
13
ID_AA64PFR1_EL1.SME: bits 27-24
14
15
ID_AA64ZFR0_EL1.SVEver: bits 3-0
16
ID_AA64ZFR0_EL1.AES: bits 7-4
17
ID_AA64ZFR0_EL1.BitPerm: bits 19-16
18
ID_AA64ZFR0_EL1.BF16: bits 23-20
19
ID_AA64ZFR0_EL1.SHA3: bits 35-32
20
ID_AA64ZFR0_EL1.SM4: bits 43-40
21
ID_AA64ZFR0_EL1.I8MM: bits 47-44
22
ID_AA64ZFR0_EL1.F32MM: bits 55-52
23
ID_AA64ZFR0_EL1.F64MM: bits 59-56
24
25
ID_AA64SMFR0_EL1.F32F32: bit 32
26
ID_AA64SMFR0_EL1.B16F32: bit 34
27
ID_AA64SMFR0_EL1.F16F32: bit 35
28
ID_AA64SMFR0_EL1.I8I32: bits 39-36
29
ID_AA64SMFR0_EL1.F64F64: bit 48
30
ID_AA64SMFR0_EL1.I16I64: bits 55-52
31
ID_AA64SMFR0_EL1.FA64: bit 63
32
33
ID_AA64MMFR0_EL1.ECV: bits 63-60
34
35
ID_AA64MMFR1_EL1.AFP: bits 47-44
36
37
ID_AA64MMFR2_EL1.AT: bits 35-32
38
39
ID_AA64ISAR0_EL1.RNDR: bits 63-60
40
41
ID_AA64ISAR1_EL1.FRINTTS: bits 35-32
42
ID_AA64ISAR1_EL1.BF16: bits 47-44
43
ID_AA64ISAR1_EL1.DGH: bits 51-48
44
ID_AA64ISAR1_EL1.I8MM: bits 55-52
45
46
ID_AA64ISAR2_EL1.WFxT: bits 3-0
47
ID_AA64ISAR2_EL1.RPRES: bits 7-4
48
ID_AA64ISAR2_EL1.GPA3: bits 11-8
49
ID_AA64ISAR2_EL1.APA3: bits 15-12
50
51
The code is also refactored to use symbolic names for ID register fields
52
for better readability and maintainability.
53
54
The test case in tests/tcg/aarch64/sysregs.c is also updated to match
55
the intended behavior.
56
57
Signed-off-by: Zhuojia Shen <chaosdefinition@hotmail.com>
58
Message-id: DS7PR12MB6309FB585E10772928F14271ACE79@DS7PR12MB6309.namprd12.prod.outlook.com
59
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
60
[PMM: use Sn_n_Cn_Cn_n syntax to work with older assemblers
61
that don't recognize id_aa64isar2_el1 and id_aa64mmfr2_el1]
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
62
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.org
9
---
63
---
10
target/arm/helper.c | 5 +++--
64
target/arm/helper.c | 96 +++++++++++++++++++++++++------
11
1 file changed, 3 insertions(+), 2 deletions(-)
65
tests/tcg/aarch64/sysregs.c | 24 ++++++--
66
tests/tcg/aarch64/Makefile.target | 7 ++-
67
3 files changed, 103 insertions(+), 24 deletions(-)
12
68
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
69
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
71
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
72
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
18
pcacheattrs = &cacheattrs;
74
#ifdef CONFIG_USER_ONLY
19
}
75
static const ARMCPRegUserSpaceInfo v8_user_idregs[] = {
20
76
{ .name = "ID_AA64PFR0_EL1",
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
77
- .exported_bits = 0x000f000f00ff0000,
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
78
- .fixed_bits = 0x0000000000000011 },
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
79
+ .exported_bits = R_ID_AA64PFR0_FP_MASK |
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
80
+ R_ID_AA64PFR0_ADVSIMD_MASK |
25
+ pcacheattrs);
81
+ R_ID_AA64PFR0_SVE_MASK |
26
if (ret) {
82
+ R_ID_AA64PFR0_DIT_MASK,
27
assert(fi->type != ARMFault_None);
83
+ .fixed_bits = (0x1u << R_ID_AA64PFR0_EL0_SHIFT) |
28
fi->s2addr = addr;
84
+ (0x1u << R_ID_AA64PFR0_EL1_SHIFT) },
85
{ .name = "ID_AA64PFR1_EL1",
86
- .exported_bits = 0x00000000000000f0 },
87
+ .exported_bits = R_ID_AA64PFR1_BT_MASK |
88
+ R_ID_AA64PFR1_SSBS_MASK |
89
+ R_ID_AA64PFR1_MTE_MASK |
90
+ R_ID_AA64PFR1_SME_MASK },
91
{ .name = "ID_AA64PFR*_EL1_RESERVED",
92
- .is_glob = true },
93
- { .name = "ID_AA64ZFR0_EL1" },
94
+ .is_glob = true },
95
+ { .name = "ID_AA64ZFR0_EL1",
96
+ .exported_bits = R_ID_AA64ZFR0_SVEVER_MASK |
97
+ R_ID_AA64ZFR0_AES_MASK |
98
+ R_ID_AA64ZFR0_BITPERM_MASK |
99
+ R_ID_AA64ZFR0_BFLOAT16_MASK |
100
+ R_ID_AA64ZFR0_SHA3_MASK |
101
+ R_ID_AA64ZFR0_SM4_MASK |
102
+ R_ID_AA64ZFR0_I8MM_MASK |
103
+ R_ID_AA64ZFR0_F32MM_MASK |
104
+ R_ID_AA64ZFR0_F64MM_MASK },
105
+ { .name = "ID_AA64SMFR0_EL1",
106
+ .exported_bits = R_ID_AA64SMFR0_F32F32_MASK |
107
+ R_ID_AA64SMFR0_B16F32_MASK |
108
+ R_ID_AA64SMFR0_F16F32_MASK |
109
+ R_ID_AA64SMFR0_I8I32_MASK |
110
+ R_ID_AA64SMFR0_F64F64_MASK |
111
+ R_ID_AA64SMFR0_I16I64_MASK |
112
+ R_ID_AA64SMFR0_FA64_MASK },
113
{ .name = "ID_AA64MMFR0_EL1",
114
- .fixed_bits = 0x00000000ff000000 },
115
- { .name = "ID_AA64MMFR1_EL1" },
116
+ .exported_bits = R_ID_AA64MMFR0_ECV_MASK,
117
+ .fixed_bits = (0xfu << R_ID_AA64MMFR0_TGRAN64_SHIFT) |
118
+ (0xfu << R_ID_AA64MMFR0_TGRAN4_SHIFT) },
119
+ { .name = "ID_AA64MMFR1_EL1",
120
+ .exported_bits = R_ID_AA64MMFR1_AFP_MASK },
121
+ { .name = "ID_AA64MMFR2_EL1",
122
+ .exported_bits = R_ID_AA64MMFR2_AT_MASK },
123
{ .name = "ID_AA64MMFR*_EL1_RESERVED",
124
- .is_glob = true },
125
+ .is_glob = true },
126
{ .name = "ID_AA64DFR0_EL1",
127
- .fixed_bits = 0x0000000000000006 },
128
- { .name = "ID_AA64DFR1_EL1" },
129
+ .fixed_bits = (0x6u << R_ID_AA64DFR0_DEBUGVER_SHIFT) },
130
+ { .name = "ID_AA64DFR1_EL1" },
131
{ .name = "ID_AA64DFR*_EL1_RESERVED",
132
- .is_glob = true },
133
+ .is_glob = true },
134
{ .name = "ID_AA64AFR*",
135
- .is_glob = true },
136
+ .is_glob = true },
137
{ .name = "ID_AA64ISAR0_EL1",
138
- .exported_bits = 0x00fffffff0fffff0 },
139
+ .exported_bits = R_ID_AA64ISAR0_AES_MASK |
140
+ R_ID_AA64ISAR0_SHA1_MASK |
141
+ R_ID_AA64ISAR0_SHA2_MASK |
142
+ R_ID_AA64ISAR0_CRC32_MASK |
143
+ R_ID_AA64ISAR0_ATOMIC_MASK |
144
+ R_ID_AA64ISAR0_RDM_MASK |
145
+ R_ID_AA64ISAR0_SHA3_MASK |
146
+ R_ID_AA64ISAR0_SM3_MASK |
147
+ R_ID_AA64ISAR0_SM4_MASK |
148
+ R_ID_AA64ISAR0_DP_MASK |
149
+ R_ID_AA64ISAR0_FHM_MASK |
150
+ R_ID_AA64ISAR0_TS_MASK |
151
+ R_ID_AA64ISAR0_RNDR_MASK },
152
{ .name = "ID_AA64ISAR1_EL1",
153
- .exported_bits = 0x000000f0ffffffff },
154
+ .exported_bits = R_ID_AA64ISAR1_DPB_MASK |
155
+ R_ID_AA64ISAR1_APA_MASK |
156
+ R_ID_AA64ISAR1_API_MASK |
157
+ R_ID_AA64ISAR1_JSCVT_MASK |
158
+ R_ID_AA64ISAR1_FCMA_MASK |
159
+ R_ID_AA64ISAR1_LRCPC_MASK |
160
+ R_ID_AA64ISAR1_GPA_MASK |
161
+ R_ID_AA64ISAR1_GPI_MASK |
162
+ R_ID_AA64ISAR1_FRINTTS_MASK |
163
+ R_ID_AA64ISAR1_SB_MASK |
164
+ R_ID_AA64ISAR1_BF16_MASK |
165
+ R_ID_AA64ISAR1_DGH_MASK |
166
+ R_ID_AA64ISAR1_I8MM_MASK },
167
+ { .name = "ID_AA64ISAR2_EL1",
168
+ .exported_bits = R_ID_AA64ISAR2_WFXT_MASK |
169
+ R_ID_AA64ISAR2_RPRES_MASK |
170
+ R_ID_AA64ISAR2_GPA3_MASK |
171
+ R_ID_AA64ISAR2_APA3_MASK },
172
{ .name = "ID_AA64ISAR*_EL1_RESERVED",
173
- .is_glob = true },
174
+ .is_glob = true },
175
};
176
modify_arm_cp_regs(v8_idregs, v8_user_idregs);
177
#endif
178
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
179
#ifdef CONFIG_USER_ONLY
180
static const ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
181
{ .name = "MIDR_EL1",
182
- .exported_bits = 0x00000000ffffffff },
183
- { .name = "REVIDR_EL1" },
184
+ .exported_bits = R_MIDR_EL1_REVISION_MASK |
185
+ R_MIDR_EL1_PARTNUM_MASK |
186
+ R_MIDR_EL1_ARCHITECTURE_MASK |
187
+ R_MIDR_EL1_VARIANT_MASK |
188
+ R_MIDR_EL1_IMPLEMENTER_MASK },
189
+ { .name = "REVIDR_EL1" },
190
};
191
modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
192
#endif
193
diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c
194
index XXXXXXX..XXXXXXX 100644
195
--- a/tests/tcg/aarch64/sysregs.c
196
+++ b/tests/tcg/aarch64/sysregs.c
197
@@ -XXX,XX +XXX,XX @@
198
#define HWCAP_CPUID (1 << 11)
199
#endif
200
201
+/*
202
+ * Older assemblers don't recognize newer system register names,
203
+ * but we can still access them by the Sn_n_Cn_Cn_n syntax.
204
+ */
205
+#define SYS_ID_AA64ISAR2_EL1 S3_0_C0_C6_2
206
+#define SYS_ID_AA64MMFR2_EL1 S3_0_C0_C7_2
207
+
208
int failed_bit_count;
209
210
/* Read and print system register `id' value */
211
@@ -XXX,XX +XXX,XX @@ int main(void)
212
* minimum valid fields - for the purposes of this check allowed
213
* to have non-zero values.
214
*/
215
- get_cpu_reg_check_mask(id_aa64isar0_el1, _m(00ff,ffff,f0ff,fff0));
216
- get_cpu_reg_check_mask(id_aa64isar1_el1, _m(0000,00f0,ffff,ffff));
217
+ get_cpu_reg_check_mask(id_aa64isar0_el1, _m(f0ff,ffff,f0ff,fff0));
218
+ get_cpu_reg_check_mask(id_aa64isar1_el1, _m(00ff,f0ff,ffff,ffff));
219
+ get_cpu_reg_check_mask(SYS_ID_AA64ISAR2_EL1, _m(0000,0000,0000,ffff));
220
/* TGran4 & TGran64 as pegged to -1 */
221
- get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(0000,0000,ff00,0000));
222
- get_cpu_reg_check_zero(id_aa64mmfr1_el1);
223
+ get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(f000,0000,ff00,0000));
224
+ get_cpu_reg_check_mask(id_aa64mmfr1_el1, _m(0000,f000,0000,0000));
225
+ get_cpu_reg_check_mask(SYS_ID_AA64MMFR2_EL1, _m(0000,000f,0000,0000));
226
/* EL1/EL0 reported as AA64 only */
227
get_cpu_reg_check_mask(id_aa64pfr0_el1, _m(000f,000f,00ff,0011));
228
- get_cpu_reg_check_mask(id_aa64pfr1_el1, _m(0000,0000,0000,00f0));
229
+ get_cpu_reg_check_mask(id_aa64pfr1_el1, _m(0000,0000,0f00,0fff));
230
/* all hidden, DebugVer fixed to 0x6 (ARMv8 debug architecture) */
231
get_cpu_reg_check_mask(id_aa64dfr0_el1, _m(0000,0000,0000,0006));
232
get_cpu_reg_check_zero(id_aa64dfr1_el1);
233
- get_cpu_reg_check_zero(id_aa64zfr0_el1);
234
+ get_cpu_reg_check_mask(id_aa64zfr0_el1, _m(0ff0,ff0f,00ff,00ff));
235
+#ifdef HAS_ARMV9_SME
236
+ get_cpu_reg_check_mask(id_aa64smfr0_el1, _m(80f1,00fd,0000,0000));
237
+#endif
238
239
get_cpu_reg_check_zero(id_aa64afr0_el1);
240
get_cpu_reg_check_zero(id_aa64afr1_el1);
241
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
242
index XXXXXXX..XXXXXXX 100644
243
--- a/tests/tcg/aarch64/Makefile.target
244
+++ b/tests/tcg/aarch64/Makefile.target
245
@@ -XXX,XX +XXX,XX @@ config-cc.mak: Makefile
246
     $(call cc-option,-march=armv8.1-a+sve2, CROSS_CC_HAS_SVE2); \
247
     $(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3); \
248
     $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
249
-     $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE)) 3> config-cc.mak
250
+     $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
251
+     $(call cc-option,-march=armv9-a+sme, CROSS_CC_HAS_ARMV9_SME)) 3> config-cc.mak
252
-include config-cc.mak
253
254
# Pauth Tests
255
@@ -XXX,XX +XXX,XX @@ endif
256
ifneq ($(CROSS_CC_HAS_SVE),)
257
# System Registers Tests
258
AARCH64_TESTS += sysregs
259
+ifneq ($(CROSS_CC_HAS_ARMV9_SME),)
260
+sysregs: CFLAGS+=-march=armv9-a+sme -DHAS_ARMV9_SME
261
+else
262
sysregs: CFLAGS+=-march=armv8.1-a+sve
263
+endif
264
265
# SVE ioctl test
266
AARCH64_TESTS += sve-ioctls
29
--
267
--
30
2.20.1
268
2.25.1
31
32
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Remove inclusion of arm_gicv3_common.h, this already gets
3
This function is not used anywhere outside this file,
4
included via xlnx-versal.h.
4
so we can make the function "static void".
5
5
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.com
9
Message-id: 20221216214924.4711-2-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/arm/xlnx-versal.c | 1 -
12
include/hw/arm/smmu-common.h | 3 ---
13
1 file changed, 1 deletion(-)
13
hw/arm/smmu-common.c | 2 +-
14
2 files changed, 1 insertion(+), 4 deletions(-)
14
15
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
16
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
18
--- a/include/hw/arm/smmu-common.h
18
+++ b/hw/arm/xlnx-versal.c
19
+++ b/include/hw/arm/smmu-common.h
19
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
20
#include "hw/arm/boot.h"
21
/* Unmap the range of all the notifiers registered to any IOMMU mr */
21
#include "kvm_arm.h"
22
void smmu_inv_notifiers_all(SMMUState *s);
22
#include "hw/misc/unimp.h"
23
23
-#include "hw/intc/arm_gicv3_common.h"
24
-/* Unmap the range of all the notifiers registered to @mr */
24
#include "hw/arm/xlnx-versal.h"
25
-void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr);
25
#include "hw/char/pl011.h"
26
-
27
#endif /* HW_ARM_SMMU_COMMON_H */
28
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/smmu-common.c
31
+++ b/hw/arm/smmu-common.c
32
@@ -XXX,XX +XXX,XX @@ static void smmu_unmap_notifier_range(IOMMUNotifier *n)
33
}
34
35
/* Unmap all notifiers attached to @mr */
36
-inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
37
+static void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
38
{
39
IOMMUNotifier *n;
26
40
27
--
41
--
28
2.20.1
42
2.25.1
29
43
30
44
diff view generated by jsdifflib
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
to decodetree. These are the last ones in the group so we can remove
3
all the legacy decode for the group.
4
2
5
Note that in disas_thumb2_insn() the parts of this encoding space
3
When using Clang ("Apple clang version 14.0.0 (clang-1400.0.29.202)")
6
where the decodetree decoder returns false will correctly be directed
4
and building with -Wall we get:
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
5
6
hw/arm/smmu-common.c:173:33: warning: static function 'smmu_hash_remove_by_asid_iova' is used in an inline function with external linkage [-Wstatic-in-inline]
7
hw/arm/smmu-common.h:170:1: note: use 'static' to give inline function 'smmu_iotlb_inv_iova' internal linkage
8
void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
9
^
10
static
11
12
None of our code base require / use inlined functions with external
13
linkage. Some places use internal inlining in the hot path. These
14
two functions are certainly not in any hot path and don't justify
15
any inlining, so these are likely oversights rather than intentional.
16
17
Reported-by: Stefan Weil <sw@weilnetz.de>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Eric Auger <eric.auger@redhat.com>
22
Message-id: 20221216214924.4711-3-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-11-peter.maydell@linaro.org
13
---
24
---
14
target/arm/neon-shared.decode | 7 +++
25
hw/arm/smmu-common.c | 13 ++++++-------
15
target/arm/translate-neon.inc.c | 32 ++++++++++
26
1 file changed, 6 insertions(+), 7 deletions(-)
16
target/arm/translate.c | 107 +-------------------------------
17
3 files changed, 40 insertions(+), 106 deletions(-)
18
27
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
28
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
20
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
30
--- a/hw/arm/smmu-common.c
22
+++ b/target/arm/neon-shared.decode
31
+++ b/hw/arm/smmu-common.c
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
32
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *new)
24
33
g_hash_table_insert(bs->iotlb, key, new);
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
+
28
+%vfml_scalar_q0_rm 0:3 5:1
29
+%vfml_scalar_q1_index 5:1 3:1
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
37
+++ b/target/arm/translate-neon.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
39
tcg_temp_free_ptr(fpst);
40
return true;
41
}
34
}
42
+
35
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
36
-inline void smmu_iotlb_inv_all(SMMUState *s)
44
+{
37
+void smmu_iotlb_inv_all(SMMUState *s)
45
+ int opr_sz;
38
{
46
+
39
trace_smmu_iotlb_inv_all();
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
40
g_hash_table_remove_all(s->iotlb);
48
+ return false;
41
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_hash_remove_by_asid_iova(gpointer key, gpointer value,
49
+ }
42
((entry->iova & ~info->mask) == info->iova);
50
+
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
54
+ return false;
55
+ }
56
+
57
+ if (a->vd & a->q) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ opr_sz = (1 + a->q) * 8;
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
67
+ vfp_reg_offset(a->q, a->vn),
68
+ vfp_reg_offset(a->q, a->rm),
69
+ cpu_env, opr_sz, opr_sz,
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
71
+ gen_helper_gvec_fmlal_idx_a32);
72
+ return true;
73
+}
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/translate.c
77
+++ b/target/arm/translate.c
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
79
}
43
}
80
44
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
45
-inline void
82
-#define VFP_SREG(insn, bigbit, smallbit) \
46
-smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
47
- uint8_t tg, uint64_t num_pages, uint8_t ttl)
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
48
+void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
49
+ uint8_t tg, uint64_t num_pages, uint8_t ttl)
86
reg = (((insn) >> (bigbit)) & 0x0f) \
50
{
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
51
/* if tg is not set we use 4KB range invalidation */
88
reg = ((insn) >> (bigbit)) & 0x0f; \
52
uint8_t granule = tg ? tg * 2 + 10 : 12;
89
}} while (0)
53
@@ -XXX,XX +XXX,XX @@ smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
90
54
&info);
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
97
98
static void gen_neon_dup_low16(TCGv_i32 var)
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
100
return 0;
101
}
55
}
102
56
103
-/* Advanced SIMD two registers and a scalar extension.
57
-inline void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
58
+void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
108
- *
109
- */
110
-
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
112
-{
113
- gen_helper_gvec_3 *fn_gvec = NULL;
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
115
- int rd, rn, rm, opr_sz, data;
116
- int off_rn, off_rm;
117
- bool is_long = false, q = extract32(insn, 6, 1);
118
- bool ptr_is_env = false;
119
-
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
122
- int is_s = extract32(insn, 20, 1);
123
- int vm20 = extract32(insn, 0, 3);
124
- int vm3 = extract32(insn, 3, 1);
125
- int m = extract32(insn, 5, 1);
126
- int index;
127
-
128
- if (!dc_isar_feature(aa32_fhm, s)) {
129
- return 1;
130
- }
131
- if (q) {
132
- rm = vm20;
133
- index = m * 2 + vm3;
134
- } else {
135
- rm = vm20 * 2 + m;
136
- index = vm3;
137
- }
138
- is_long = true;
139
- data = (index << 2) | is_s; /* is_2 == 0 */
140
- fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
141
- ptr_is_env = true;
142
- } else {
143
- return 1;
144
- }
145
-
146
- VFP_DREG_D(rd, insn);
147
- if (rd & q) {
148
- return 1;
149
- }
150
- if (q || !is_long) {
151
- VFP_DREG_N(rn, insn);
152
- if (rn & q & !is_long) {
153
- return 1;
154
- }
155
- off_rn = vfp_reg_offset(1, rn);
156
- off_rm = vfp_reg_offset(1, rm);
157
- } else {
158
- rn = VFP_SREG_N(insn);
159
- off_rn = vfp_reg_offset(0, rn);
160
- off_rm = vfp_reg_offset(0, rm);
161
- }
162
- if (s->fp_excp_el) {
163
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
165
- return 0;
166
- }
167
- if (!s->vfp_enabled) {
168
- return 1;
169
- }
170
-
171
- opr_sz = (1 + q) * 8;
172
- if (fn_gvec_ptr) {
173
- TCGv_ptr ptr;
174
- if (ptr_is_env) {
175
- ptr = cpu_env;
176
- } else {
177
- ptr = get_fpstatus_ptr(1);
178
- }
179
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
180
- opr_sz, opr_sz, data, fn_gvec_ptr);
181
- if (!ptr_is_env) {
182
- tcg_temp_free_ptr(ptr);
183
- }
184
- } else {
185
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
186
- opr_sz, opr_sz, data, fn_gvec);
187
- }
188
- return 0;
189
-}
190
-
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
192
{
59
{
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
60
trace_smmu_iotlb_inv_asid(asid);
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
61
g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid, &asid);
195
}
62
@@ -XXX,XX +XXX,XX @@ error:
196
}
63
*
197
}
64
* return 0 on success
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
65
*/
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
66
-inline int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
67
- SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
201
- goto illegal_op;
68
+int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
202
- }
69
+ SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
203
- return;
70
{
204
}
71
if (!cfg->aa64) {
205
goto illegal_op;
72
/*
206
}
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
208
}
209
break;
210
}
211
- if ((insn & 0xff000a00) == 0xfe000800
212
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
213
- /* The Thumb2 and ARM encodings are identical. */
214
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
215
- goto illegal_op;
216
- }
217
- } else if (((insn >> 24) & 3) == 3) {
218
+ if (((insn >> 24) & 3) == 3) {
219
/* Translate into the equivalent ARM encoding. */
220
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
221
if (disas_neon_data_insn(s, insn)) {
222
--
73
--
223
2.20.1
74
2.25.1
224
75
225
76
diff view generated by jsdifflib
1
Add the infrastructure for building and invoking a decodetree decoder
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
for the AArch32 Neon encodings. At the moment the new decoder covers
3
nothing, so we always fall back to the existing hand-written decode.
4
2
5
We follow the same pattern we did for the VFP decodetree conversion
3
So far the GPT timers were unable to raise IRQs to the processor.
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
8
which we #include into translate.c.
9
4
10
In order to share the decode files between A32 and T32, we
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
11
split Neon into 3 parts:
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
* data-processing
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
* load-store
8
---
14
* 'shared' encodings
9
include/hw/arm/fsl-imx7.h | 5 +++++
10
hw/arm/fsl-imx7.c | 10 ++++++++++
11
2 files changed, 15 insertions(+)
15
12
16
The first two groups of instructions have similar but not identical
13
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
17
A32 and T32 encodings, so we need to manually transform the T32
14
index XXXXXXX..XXXXXXX 100644
18
encoding into the A32 one before calling the decoder; the third group
15
--- a/include/hw/arm/fsl-imx7.h
19
covers the Neon instructions which are identical in A32 and T32.
16
+++ b/include/hw/arm/fsl-imx7.h
20
17
@@ -XXX,XX +XXX,XX @@ enum FslIMX7IRQs {
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
FSL_IMX7_USB2_IRQ = 42,
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
FSL_IMX7_USB3_IRQ = 40,
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
20
24
---
21
+ FSL_IMX7_GPT1_IRQ = 55,
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
22
+ FSL_IMX7_GPT2_IRQ = 54,
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
23
+ FSL_IMX7_GPT3_IRQ = 53,
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
24
+ FSL_IMX7_GPT4_IRQ = 52,
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
30
target/arm/Makefile.objs | 18 +++++++++++++++++
31
6 files changed, 169 insertions(+), 2 deletions(-)
32
create mode 100644 target/arm/neon-dp.decode
33
create mode 100644 target/arm/neon-ls.decode
34
create mode 100644 target/arm/neon-shared.decode
35
create mode 100644 target/arm/translate-neon.inc.c
36
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/target/arm/neon-dp.decode
42
@@ -XXX,XX +XXX,XX @@
43
+# AArch32 Neon data-processing instruction descriptions
44
+#
45
+# Copyright (c) 2020 Linaro, Ltd
46
+#
47
+# This library is free software; you can redistribute it and/or
48
+# modify it under the terms of the GNU Lesser General Public
49
+# License as published by the Free Software Foundation; either
50
+# version 2 of the License, or (at your option) any later version.
51
+#
52
+# This library is distributed in the hope that it will be useful,
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
55
+# Lesser General Public License for more details.
56
+#
57
+# You should have received a copy of the GNU Lesser General Public
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
59
+
25
+
60
+#
26
FSL_IMX7_WDOG1_IRQ = 78,
61
+# This file is processed by scripts/decodetree.py
27
FSL_IMX7_WDOG2_IRQ = 79,
62
+#
28
FSL_IMX7_WDOG3_IRQ = 10,
29
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/fsl-imx7.c
32
+++ b/hw/arm/fsl-imx7.c
33
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
34
FSL_IMX7_GPT4_ADDR,
35
};
36
37
+ static const int FSL_IMX7_GPTn_IRQ[FSL_IMX7_NUM_GPTS] = {
38
+ FSL_IMX7_GPT1_IRQ,
39
+ FSL_IMX7_GPT2_IRQ,
40
+ FSL_IMX7_GPT3_IRQ,
41
+ FSL_IMX7_GPT4_IRQ,
42
+ };
63
+
43
+
64
+# Encodings for Neon data processing instructions where the T32 encoding
44
s->gpt[i].ccm = IMX_CCM(&s->ccm);
65
+# is a simple transformation of the A32 encoding.
45
sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), &error_abort);
66
+# More specifically, this file covers instructions where the A32 encoding is
46
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, FSL_IMX7_GPTn_ADDR[i]);
67
+# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
47
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
68
+# and the T32 encoding is
48
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
69
+# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
49
+ FSL_IMX7_GPTn_IRQ[i]));
70
+# This file works on the A32 encoding only; calling code for T32 has to
71
+# transform the insn into the A32 version first.
72
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
77
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
79
+#
80
+# Copyright (c) 2020 Linaro, Ltd
81
+#
82
+# This library is free software; you can redistribute it and/or
83
+# modify it under the terms of the GNU Lesser General Public
84
+# License as published by the Free Software Foundation; either
85
+# version 2 of the License, or (at your option) any later version.
86
+#
87
+# This library is distributed in the hope that it will be useful,
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90
+# Lesser General Public License for more details.
91
+#
92
+# You should have received a copy of the GNU Lesser General Public
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
94
+
95
+#
96
+# This file is processed by scripts/decodetree.py
97
+#
98
+
99
+# Encodings for Neon load/store instructions where the T32 encoding
100
+# is a simple transformation of the A32 encoding.
101
+# More specifically, this file covers instructions where the A32 encoding is
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
103
+# and the T32 encoding is
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
105
+# This file works on the A32 encoding only; calling code for T32 has to
106
+# transform the insn into the A32 version first.
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
112
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
114
+#
115
+# Copyright (c) 2020 Linaro, Ltd
116
+#
117
+# This library is free software; you can redistribute it and/or
118
+# modify it under the terms of the GNU Lesser General Public
119
+# License as published by the Free Software Foundation; either
120
+# version 2 of the License, or (at your option) any later version.
121
+#
122
+# This library is distributed in the hope that it will be useful,
123
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+# Lesser General Public License for more details.
126
+#
127
+# You should have received a copy of the GNU Lesser General Public
128
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+
130
+#
131
+# This file is processed by scripts/decodetree.py
132
+#
133
+
134
+# Encodings for Neon instructions whose encoding is the same for
135
+# both A32 and T32.
136
+
137
+# More specifically, this covers:
138
+# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
139
+# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
140
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
141
new file mode 100644
142
index XXXXXXX..XXXXXXX
143
--- /dev/null
144
+++ b/target/arm/translate-neon.inc.c
145
@@ -XXX,XX +XXX,XX @@
146
+/*
147
+ * ARM translation: AArch32 Neon instructions
148
+ *
149
+ * Copyright (c) 2003 Fabrice Bellard
150
+ * Copyright (c) 2005-2007 CodeSourcery
151
+ * Copyright (c) 2007 OpenedHand, Ltd.
152
+ * Copyright (c) 2020 Linaro, Ltd.
153
+ *
154
+ * This library is free software; you can redistribute it and/or
155
+ * modify it under the terms of the GNU Lesser General Public
156
+ * License as published by the Free Software Foundation; either
157
+ * version 2 of the License, or (at your option) any later version.
158
+ *
159
+ * This library is distributed in the hope that it will be useful,
160
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
161
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
162
+ * Lesser General Public License for more details.
163
+ *
164
+ * You should have received a copy of the GNU Lesser General Public
165
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
166
+ */
167
+
168
+/*
169
+ * This file is intended to be included from translate.c; it uses
170
+ * some macros and definitions provided by that file.
171
+ * It might be possible to convert it to a standalone .c file eventually.
172
+ */
173
+
174
+/* Include the generated Neon decoder */
175
+#include "decode-neon-dp.inc.c"
176
+#include "decode-neon-ls.inc.c"
177
+#include "decode-neon-shared.inc.c"
178
diff --git a/target/arm/translate.c b/target/arm/translate.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/target/arm/translate.c
181
+++ b/target/arm/translate.c
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
183
184
#define ARM_CP_RW_BIT (1 << 20)
185
186
-/* Include the VFP decoder */
187
+/* Include the VFP and Neon decoders */
188
#include "translate-vfp.inc.c"
189
+#include "translate-neon.inc.c"
190
191
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
192
{
193
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
194
/* Unconditional instructions. */
195
/* TODO: Perhaps merge these into one decodetree output file. */
196
if (disas_a32_uncond(s, insn) ||
197
- disas_vfp_uncond(s, insn)) {
198
+ disas_vfp_uncond(s, insn) ||
199
+ disas_neon_dp(s, insn) ||
200
+ disas_neon_ls(s, insn) ||
201
+ disas_neon_shared(s, insn)) {
202
return;
203
}
204
/* fall back to legacy decoder */
205
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
206
ARCH(6T2);
207
}
50
}
208
51
209
+ if ((insn & 0xef000000) == 0xef000000) {
52
for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
210
+ /*
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
212
+ * transform into
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
214
+ */
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
217
+
218
+ if (disas_neon_dp(s, a32_insn)) {
219
+ return;
220
+ }
221
+ }
222
+
223
+ if ((insn & 0xff100000) == 0xf9000000) {
224
+ /*
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
226
+ * transform into
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
228
+ */
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
230
+
231
+ if (disas_neon_ls(s, a32_insn)) {
232
+ return;
233
+ }
234
+ }
235
+
236
/*
237
* TODO: Perhaps merge these into one decodetree output file.
238
* Note disas_vfp is written for a32 with cond field in the
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
240
*/
241
if (disas_t32(s, insn) ||
242
disas_vfp_uncond(s, insn) ||
243
+ disas_neon_shared(s, insn) ||
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
245
return;
246
}
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
248
index XXXXXXX..XXXXXXX 100644
249
--- a/target/arm/Makefile.objs
250
+++ b/target/arm/Makefile.objs
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
253
     "GEN", $(TARGET_DIR)$@)
254
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
256
+    $(call quiet-command,\
257
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
258
+     "GEN", $(TARGET_DIR)$@)
259
+
260
+target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
261
+    $(call quiet-command,\
262
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
263
+     "GEN", $(TARGET_DIR)$@)
264
+
265
+target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
266
+    $(call quiet-command,\
267
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
268
+     "GEN", $(TARGET_DIR)$@)
269
+
270
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
271
    $(call quiet-command,\
272
     $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
273
@@ -XXX,XX +XXX,XX @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
274
     "GEN", $(TARGET_DIR)$@)
275
276
target/arm/translate-sve.o: target/arm/decode-sve.inc.c
277
+target/arm/translate.o: target/arm/decode-neon-shared.inc.c
278
+target/arm/translate.o: target/arm/decode-neon-dp.inc.c
279
+target/arm/translate.o: target/arm/decode-neon-ls.inc.c
280
target/arm/translate.o: target/arm/decode-vfp.inc.c
281
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
282
target/arm/translate.o: target/arm/decode-a32.inc.c
283
--
53
--
284
2.20.1
54
2.25.1
285
286
diff view generated by jsdifflib
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
insn in the legacy decoder for the 3same_ext group, so we can
3
delete the legacy decoder function for the group entirely.
4
2
5
Note that in disas_thumb2_insn() the parts of this encoding space
3
CCM derived clocks will have to be added later.
6
where the decodetree decoder returns false will correctly be directed
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
4
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-8-peter.maydell@linaro.org
13
---
8
---
14
target/arm/neon-shared.decode | 6 +++
9
hw/misc/imx7_ccm.c | 49 +++++++++++++++++++++++++++++++++++++---------
15
target/arm/translate-neon.inc.c | 31 +++++++++++
10
1 file changed, 40 insertions(+), 9 deletions(-)
16
target/arm/translate.c | 92 +--------------------------------
17
3 files changed, 38 insertions(+), 91 deletions(-)
18
11
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
12
diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
14
--- a/hw/misc/imx7_ccm.c
22
+++ b/target/arm/neon-shared.decode
15
+++ b/hw/misc/imx7_ccm.c
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
16
@@ -XXX,XX +XXX,XX @@
24
# VUDOT and VSDOT
17
#include "hw/misc/imx7_ccm.h"
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
18
#include "migration/vmstate.h"
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
19
20
+#include "trace.h"
27
+
21
+
28
+# VFM[AS]L
22
+#define CKIH_FREQ 24000000 /* 24MHz crystal input */
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
32
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
36
+++ b/target/arm/translate-neon.inc.c
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
38
opr_sz, opr_sz, 0, fn_gvec);
39
return true;
40
}
41
+
23
+
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
24
static void imx7_analog_reset(DeviceState *dev)
43
+{
25
{
44
+ int opr_sz;
26
IMX7AnalogState *s = IMX7_ANALOG(dev);
27
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx7_ccm = {
28
static uint32_t imx7_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
29
{
30
/*
31
- * This function is "consumed" by GPT emulation code, however on
32
- * i.MX7 each GPT block can have their own clock root. This means
33
- * that this functions needs somehow to know requester's identity
34
- * and the way to pass it: be it via additional IMXClk constants
35
- * or by adding another argument to this method needs to be
36
- * figured out
37
+ * This function is "consumed" by GPT emulation code. Some clocks
38
+ * have fixed frequencies and we can provide requested frequency
39
+ * easily. However for CCM provided clocks (like IPG) each GPT
40
+ * timer can have its own clock root.
41
+ * This means we need additionnal information when calling this
42
+ * function to know the requester's identity.
43
*/
44
- qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Not implemented\n",
45
- TYPE_IMX7_CCM, __func__);
46
- return 0;
47
+ uint32_t freq = 0;
45
+
48
+
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
49
+ switch (clock) {
47
+ return false;
50
+ case CLK_NONE:
51
+ break;
52
+ case CLK_32k:
53
+ freq = CKIL_FREQ;
54
+ break;
55
+ case CLK_HIGH:
56
+ freq = CKIH_FREQ;
57
+ break;
58
+ case CLK_IPG:
59
+ case CLK_IPG_HIGH:
60
+ /*
61
+ * For now we don't have a way to figure out the device this
62
+ * function is called for. Until then the IPG derived clocks
63
+ * are left unimplemented.
64
+ */
65
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Clock %d Not implemented\n",
66
+ TYPE_IMX7_CCM, __func__, clock);
67
+ break;
68
+ default:
69
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
70
+ TYPE_IMX7_CCM, __func__, clock);
71
+ break;
48
+ }
72
+ }
49
+
73
+
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
74
+ trace_ccm_clock_freq(clock, freq);
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
52
+ (a->vd & 0x10)) {
53
+ return false;
54
+ }
55
+
75
+
56
+ if (a->vd & a->q) {
76
+ return freq;
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
62
+ }
63
+
64
+ opr_sz = (1 + a->q) * 8;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(a->q, a->vn),
67
+ vfp_reg_offset(a->q, a->vm),
68
+ cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
69
+ gen_helper_gvec_fmlal_a32);
70
+ return true;
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
return 0;
78
}
77
}
79
78
80
-/* Advanced SIMD three registers of the same length extension.
79
static void imx7_ccm_class_init(ObjectClass *klass, void *data)
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
85
- */
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
87
-{
88
- gen_helper_gvec_3 *fn_gvec = NULL;
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
90
- int rd, rn, rm, opr_sz;
91
- int data = 0;
92
- int off_rn, off_rm;
93
- bool is_long = false, q = extract32(insn, 6, 1);
94
- bool ptr_is_env = false;
95
-
96
- if ((insn & 0xff300f10) == 0xfc200810) {
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
98
- int is_s = extract32(insn, 23, 1);
99
- if (!dc_isar_feature(aa32_fhm, s)) {
100
- return 1;
101
- }
102
- is_long = true;
103
- data = is_s; /* is_2 == 0 */
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
105
- ptr_is_env = true;
106
- } else {
107
- return 1;
108
- }
109
-
110
- VFP_DREG_D(rd, insn);
111
- if (rd & q) {
112
- return 1;
113
- }
114
- if (q || !is_long) {
115
- VFP_DREG_N(rn, insn);
116
- VFP_DREG_M(rm, insn);
117
- if ((rn | rm) & q & !is_long) {
118
- return 1;
119
- }
120
- off_rn = vfp_reg_offset(1, rn);
121
- off_rm = vfp_reg_offset(1, rm);
122
- } else {
123
- rn = VFP_SREG_N(insn);
124
- rm = VFP_SREG_M(insn);
125
- off_rn = vfp_reg_offset(0, rn);
126
- off_rm = vfp_reg_offset(0, rm);
127
- }
128
-
129
- if (s->fp_excp_el) {
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
132
- return 0;
133
- }
134
- if (!s->vfp_enabled) {
135
- return 1;
136
- }
137
-
138
- opr_sz = (1 + q) * 8;
139
- if (fn_gvec_ptr) {
140
- TCGv_ptr ptr;
141
- if (ptr_is_env) {
142
- ptr = cpu_env;
143
- } else {
144
- ptr = get_fpstatus_ptr(1);
145
- }
146
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
147
- opr_sz, opr_sz, data, fn_gvec_ptr);
148
- if (!ptr_is_env) {
149
- tcg_temp_free_ptr(ptr);
150
- }
151
- } else {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
153
- opr_sz, opr_sz, data, fn_gvec);
154
- }
155
- return 0;
156
-}
157
-
158
/* Advanced SIMD two registers and a scalar extension.
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
162
}
163
}
164
}
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
167
- if (disas_neon_insn_3same_ext(s, insn)) {
168
- goto illegal_op;
169
- }
170
- return;
171
} else if ((insn & 0x0f000a00) == 0x0e000800
172
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
173
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
174
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
175
}
176
break;
177
}
178
- if ((insn & 0xfe000a00) == 0xfc000800
179
+ if ((insn & 0xff000a00) == 0xfe000800
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
181
/* The Thumb2 and ARM encodings are identical. */
182
- if (disas_neon_insn_3same_ext(s, insn)) {
183
- goto illegal_op;
184
- }
185
- } else if ((insn & 0xff000a00) == 0xfe000800
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
187
- /* The Thumb2 and ARM encodings are identical. */
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
189
goto illegal_op;
190
}
191
--
80
--
192
2.20.1
81
2.25.1
193
194
diff view generated by jsdifflib
1
Convert the Neon "load/store multiple structures" insns to decodetree.
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
The i.MX6UL doesn't support CLK_HIGH ou CLK_HIGH_DIV clock source.
4
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
6
---
8
---
7
target/arm/neon-ls.decode | 7 ++
9
include/hw/timer/imx_gpt.h | 1 +
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
10
hw/arm/fsl-imx6ul.c | 2 +-
9
target/arm/translate.c | 91 +----------------------
11
hw/misc/imx6ul_ccm.c | 6 ------
10
3 files changed, 133 insertions(+), 89 deletions(-)
12
hw/timer/imx_gpt.c | 25 +++++++++++++++++++++++++
13
4 files changed, 27 insertions(+), 7 deletions(-)
11
14
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
15
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-ls.decode
17
--- a/include/hw/timer/imx_gpt.h
15
+++ b/target/arm/neon-ls.decode
18
+++ b/include/hw/timer/imx_gpt.h
16
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
20
#define TYPE_IMX25_GPT "imx25.gpt"
18
# This file works on the A32 encoding only; calling code for T32 has to
21
#define TYPE_IMX31_GPT "imx31.gpt"
19
# transform the insn into the A32 version first.
22
#define TYPE_IMX6_GPT "imx6.gpt"
20
+
23
+#define TYPE_IMX6UL_GPT "imx6ul.gpt"
21
+%vd_dp 22:1 12:4
24
#define TYPE_IMX7_GPT "imx7.gpt"
22
+
25
23
+# Neon load/store multiple structures
26
#define TYPE_IMX_GPT TYPE_IMX25_GPT
24
+
27
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
26
+ vd=%vd_dp
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
29
--- a/hw/arm/fsl-imx6ul.c
30
+++ b/target/arm/translate-neon.inc.c
30
+++ b/hw/arm/fsl-imx6ul.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
31
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
32
gen_helper_gvec_fmlal_idx_a32);
32
*/
33
return true;
33
for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
34
}
34
snprintf(name, NAME_SIZE, "gpt%d", i);
35
+
35
- object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX7_GPT);
36
+static struct {
36
+ object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX6UL_GPT);
37
+ int nregs;
37
}
38
+ int interleave;
38
39
+ int spacing;
39
/*
40
+} const neon_ls_element_type[11] = {
40
diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
41
+ {1, 4, 1},
41
index XXXXXXX..XXXXXXX 100644
42
+ {1, 4, 2},
42
--- a/hw/misc/imx6ul_ccm.c
43
+ {4, 1, 1},
43
+++ b/hw/misc/imx6ul_ccm.c
44
+ {2, 2, 2},
44
@@ -XXX,XX +XXX,XX @@ static uint32_t imx6ul_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
45
+ {1, 3, 1},
45
case CLK_32k:
46
+ {1, 3, 2},
46
freq = CKIL_FREQ;
47
+ {3, 1, 1},
47
break;
48
+ {1, 1, 1},
48
- case CLK_HIGH:
49
+ {1, 2, 1},
49
- freq = CKIH_FREQ;
50
+ {1, 2, 2},
50
- break;
51
+ {2, 1, 1}
51
- case CLK_HIGH_DIV:
52
- freq = CKIH_FREQ / 8;
53
- break;
54
default:
55
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
56
TYPE_IMX6UL_CCM, __func__, clock);
57
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/timer/imx_gpt.c
60
+++ b/hw/timer/imx_gpt.c
61
@@ -XXX,XX +XXX,XX @@ static const IMXClk imx6_gpt_clocks[] = {
62
CLK_HIGH, /* 111 reference clock */
63
};
64
65
+static const IMXClk imx6ul_gpt_clocks[] = {
66
+ CLK_NONE, /* 000 No clock source */
67
+ CLK_IPG, /* 001 ipg_clk, 532MHz*/
68
+ CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */
69
+ CLK_EXT, /* 011 External clock */
70
+ CLK_32k, /* 100 ipg_clk_32k */
71
+ CLK_NONE, /* 101 not defined */
72
+ CLK_NONE, /* 110 not defined */
73
+ CLK_NONE, /* 111 not defined */
52
+};
74
+};
53
+
75
+
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
76
static const IMXClk imx7_gpt_clocks[] = {
55
+ int stride)
77
CLK_NONE, /* 000 No clock source */
78
CLK_IPG, /* 001 ipg_clk, 532MHz*/
79
@@ -XXX,XX +XXX,XX @@ static void imx6_gpt_init(Object *obj)
80
s->clocks = imx6_gpt_clocks;
81
}
82
83
+static void imx6ul_gpt_init(Object *obj)
56
+{
84
+{
57
+ if (rm != 15) {
85
+ IMXGPTState *s = IMX_GPT(obj);
58
+ TCGv_i32 base;
59
+
86
+
60
+ base = load_reg(s, rn);
87
+ s->clocks = imx6ul_gpt_clocks;
61
+ if (rm == 13) {
62
+ tcg_gen_addi_i32(base, base, stride);
63
+ } else {
64
+ TCGv_i32 index;
65
+ index = load_reg(s, rm);
66
+ tcg_gen_add_i32(base, base, index);
67
+ tcg_temp_free_i32(index);
68
+ }
69
+ store_reg(s, rn, base);
70
+ }
71
+}
88
+}
72
+
89
+
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
90
static void imx7_gpt_init(Object *obj)
74
+{
91
{
75
+ /* Neon load/store multiple structures */
92
IMXGPTState *s = IMX_GPT(obj);
76
+ int nregs, interleave, spacing, reg, n;
93
@@ -XXX,XX +XXX,XX @@ static const TypeInfo imx6_gpt_info = {
77
+ MemOp endian = s->be_data;
94
.instance_init = imx6_gpt_init,
78
+ int mmu_idx = get_mem_index(s);
95
};
79
+ int size = a->size;
96
80
+ TCGv_i64 tmp64;
97
+static const TypeInfo imx6ul_gpt_info = {
81
+ TCGv_i32 addr, tmp;
98
+ .name = TYPE_IMX6UL_GPT,
99
+ .parent = TYPE_IMX25_GPT,
100
+ .instance_init = imx6ul_gpt_init,
101
+};
82
+
102
+
83
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
103
static const TypeInfo imx7_gpt_info = {
84
+ return false;
104
.name = TYPE_IMX7_GPT,
85
+ }
105
.parent = TYPE_IMX25_GPT,
86
+
106
@@ -XXX,XX +XXX,XX @@ static void imx_gpt_register_types(void)
87
+ /* UNDEF accesses to D16-D31 if they don't exist */
107
type_register_static(&imx25_gpt_info);
88
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
108
type_register_static(&imx31_gpt_info);
89
+ return false;
109
type_register_static(&imx6_gpt_info);
90
+ }
110
+ type_register_static(&imx6ul_gpt_info);
91
+ if (a->itype > 10) {
111
type_register_static(&imx7_gpt_info);
92
+ return false;
93
+ }
94
+ /* Catch UNDEF cases for bad values of align field */
95
+ switch (a->itype & 0xc) {
96
+ case 4:
97
+ if (a->align >= 2) {
98
+ return false;
99
+ }
100
+ break;
101
+ case 8:
102
+ if (a->align == 3) {
103
+ return false;
104
+ }
105
+ break;
106
+ default:
107
+ break;
108
+ }
109
+ nregs = neon_ls_element_type[a->itype].nregs;
110
+ interleave = neon_ls_element_type[a->itype].interleave;
111
+ spacing = neon_ls_element_type[a->itype].spacing;
112
+ if (size == 3 && (interleave | spacing) != 1) {
113
+ return false;
114
+ }
115
+
116
+ if (!vfp_access_check(s)) {
117
+ return true;
118
+ }
119
+
120
+ /* For our purposes, bytes are always little-endian. */
121
+ if (size == 0) {
122
+ endian = MO_LE;
123
+ }
124
+ /*
125
+ * Consecutive little-endian elements from a single register
126
+ * can be promoted to a larger little-endian operation.
127
+ */
128
+ if (interleave == 1 && endian == MO_LE) {
129
+ size = 3;
130
+ }
131
+ tmp64 = tcg_temp_new_i64();
132
+ addr = tcg_temp_new_i32();
133
+ tmp = tcg_const_i32(1 << size);
134
+ load_reg_var(s, addr, a->rn);
135
+ for (reg = 0; reg < nregs; reg++) {
136
+ for (n = 0; n < 8 >> size; n++) {
137
+ int xs;
138
+ for (xs = 0; xs < interleave; xs++) {
139
+ int tt = a->vd + reg + spacing * xs;
140
+
141
+ if (a->l) {
142
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
143
+ neon_store_element64(tt, n, size, tmp64);
144
+ } else {
145
+ neon_load_element64(tmp64, tt, n, size);
146
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
147
+ }
148
+ tcg_gen_add_i32(addr, addr, tmp);
149
+ }
150
+ }
151
+ }
152
+ tcg_temp_free_i32(addr);
153
+ tcg_temp_free_i32(tmp);
154
+ tcg_temp_free_i64(tmp64);
155
+
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
157
+ return true;
158
+}
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate.c
162
+++ b/target/arm/translate.c
163
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
164
}
112
}
165
113
166
167
-static struct {
168
- int nregs;
169
- int interleave;
170
- int spacing;
171
-} const neon_ls_element_type[11] = {
172
- {1, 4, 1},
173
- {1, 4, 2},
174
- {4, 1, 1},
175
- {2, 2, 2},
176
- {1, 3, 1},
177
- {1, 3, 2},
178
- {3, 1, 1},
179
- {1, 1, 1},
180
- {1, 2, 1},
181
- {1, 2, 2},
182
- {2, 1, 1}
183
-};
184
-
185
/* Translate a NEON load/store element instruction. Return nonzero if the
186
instruction is invalid. */
187
static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
188
{
189
int rd, rn, rm;
190
- int op;
191
int nregs;
192
- int interleave;
193
- int spacing;
194
int stride;
195
int size;
196
int reg;
197
int load;
198
- int n;
199
int vec_size;
200
- int mmu_idx;
201
- MemOp endian;
202
TCGv_i32 addr;
203
TCGv_i32 tmp;
204
- TCGv_i32 tmp2;
205
- TCGv_i64 tmp64;
206
207
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
208
return 1;
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
210
rn = (insn >> 16) & 0xf;
211
rm = insn & 0xf;
212
load = (insn & (1 << 21)) != 0;
213
- endian = s->be_data;
214
- mmu_idx = get_mem_index(s);
215
if ((insn & (1 << 23)) == 0) {
216
- /* Load store all elements. */
217
- op = (insn >> 8) & 0xf;
218
- size = (insn >> 6) & 3;
219
- if (op > 10)
220
- return 1;
221
- /* Catch UNDEF cases for bad values of align field */
222
- switch (op & 0xc) {
223
- case 4:
224
- if (((insn >> 5) & 1) == 1) {
225
- return 1;
226
- }
227
- break;
228
- case 8:
229
- if (((insn >> 4) & 3) == 3) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- break;
235
- }
236
- nregs = neon_ls_element_type[op].nregs;
237
- interleave = neon_ls_element_type[op].interleave;
238
- spacing = neon_ls_element_type[op].spacing;
239
- if (size == 3 && (interleave | spacing) != 1) {
240
- return 1;
241
- }
242
- /* For our purposes, bytes are always little-endian. */
243
- if (size == 0) {
244
- endian = MO_LE;
245
- }
246
- /* Consecutive little-endian elements from a single register
247
- * can be promoted to a larger little-endian operation.
248
- */
249
- if (interleave == 1 && endian == MO_LE) {
250
- size = 3;
251
- }
252
- tmp64 = tcg_temp_new_i64();
253
- addr = tcg_temp_new_i32();
254
- tmp2 = tcg_const_i32(1 << size);
255
- load_reg_var(s, addr, rn);
256
- for (reg = 0; reg < nregs; reg++) {
257
- for (n = 0; n < 8 >> size; n++) {
258
- int xs;
259
- for (xs = 0; xs < interleave; xs++) {
260
- int tt = rd + reg + spacing * xs;
261
-
262
- if (load) {
263
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
264
- neon_store_element64(tt, n, size, tmp64);
265
- } else {
266
- neon_load_element64(tmp64, tt, n, size);
267
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
268
- }
269
- tcg_gen_add_i32(addr, addr, tmp2);
270
- }
271
- }
272
- }
273
- tcg_temp_free_i32(addr);
274
- tcg_temp_free_i32(tmp2);
275
- tcg_temp_free_i64(tmp64);
276
- stride = nregs * interleave * 8;
277
+ /* Load store all elements -- handled already by decodetree */
278
+ return 1;
279
} else {
280
size = (insn >> 10) & 3;
281
if (size == 3) {
282
--
114
--
283
2.20.1
115
2.25.1
284
285
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
Fix typo xlnx-ve -> xlnx-versal.
3
IRQs were not associated to the various GPIO devices inside i.MX7D.
4
This patch brings the i.MX7D on par with i.MX6.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20221226101418.415170-1-jcd@tribudubois.net
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/xlnx-versal-virt.c | 2 +-
11
include/hw/arm/fsl-imx7.h | 15 +++++++++++++++
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
hw/arm/fsl-imx7.c | 31 ++++++++++++++++++++++++++++++-
13
2 files changed, 45 insertions(+), 1 deletion(-)
14
14
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
15
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal-virt.c
17
--- a/include/hw/arm/fsl-imx7.h
18
+++ b/hw/arm/xlnx-versal-virt.c
18
+++ b/include/hw/arm/fsl-imx7.h
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
19
@@ -XXX,XX +XXX,XX @@ enum FslIMX7IRQs {
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
20
FSL_IMX7_GPT3_IRQ = 53,
21
FSL_IMX7_GPT4_IRQ = 52,
22
23
+ FSL_IMX7_GPIO1_LOW_IRQ = 64,
24
+ FSL_IMX7_GPIO1_HIGH_IRQ = 65,
25
+ FSL_IMX7_GPIO2_LOW_IRQ = 66,
26
+ FSL_IMX7_GPIO2_HIGH_IRQ = 67,
27
+ FSL_IMX7_GPIO3_LOW_IRQ = 68,
28
+ FSL_IMX7_GPIO3_HIGH_IRQ = 69,
29
+ FSL_IMX7_GPIO4_LOW_IRQ = 70,
30
+ FSL_IMX7_GPIO4_HIGH_IRQ = 71,
31
+ FSL_IMX7_GPIO5_LOW_IRQ = 72,
32
+ FSL_IMX7_GPIO5_HIGH_IRQ = 73,
33
+ FSL_IMX7_GPIO6_LOW_IRQ = 74,
34
+ FSL_IMX7_GPIO6_HIGH_IRQ = 75,
35
+ FSL_IMX7_GPIO7_LOW_IRQ = 76,
36
+ FSL_IMX7_GPIO7_HIGH_IRQ = 77,
37
+
38
FSL_IMX7_WDOG1_IRQ = 78,
39
FSL_IMX7_WDOG2_IRQ = 79,
40
FSL_IMX7_WDOG3_IRQ = 10,
41
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/fsl-imx7.c
44
+++ b/hw/arm/fsl-imx7.c
45
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
46
FSL_IMX7_GPIO7_ADDR,
47
};
48
49
+ static const int FSL_IMX7_GPIOn_LOW_IRQ[FSL_IMX7_NUM_GPIOS] = {
50
+ FSL_IMX7_GPIO1_LOW_IRQ,
51
+ FSL_IMX7_GPIO2_LOW_IRQ,
52
+ FSL_IMX7_GPIO3_LOW_IRQ,
53
+ FSL_IMX7_GPIO4_LOW_IRQ,
54
+ FSL_IMX7_GPIO5_LOW_IRQ,
55
+ FSL_IMX7_GPIO6_LOW_IRQ,
56
+ FSL_IMX7_GPIO7_LOW_IRQ,
57
+ };
58
+
59
+ static const int FSL_IMX7_GPIOn_HIGH_IRQ[FSL_IMX7_NUM_GPIOS] = {
60
+ FSL_IMX7_GPIO1_HIGH_IRQ,
61
+ FSL_IMX7_GPIO2_HIGH_IRQ,
62
+ FSL_IMX7_GPIO3_HIGH_IRQ,
63
+ FSL_IMX7_GPIO4_HIGH_IRQ,
64
+ FSL_IMX7_GPIO5_HIGH_IRQ,
65
+ FSL_IMX7_GPIO6_HIGH_IRQ,
66
+ FSL_IMX7_GPIO7_HIGH_IRQ,
67
+ };
68
+
69
sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), &error_abort);
70
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, FSL_IMX7_GPIOn_ADDR[i]);
71
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
72
+ FSL_IMX7_GPIOn_ADDR[i]);
73
+
74
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
75
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
76
+ FSL_IMX7_GPIOn_LOW_IRQ[i]));
77
+
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
79
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
80
+ FSL_IMX7_GPIOn_HIGH_IRQ[i]));
21
}
81
}
22
82
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
83
/*
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
27
"ddr", &error_abort);
28
--
84
--
29
2.20.1
85
2.25.1
30
31
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Stephen Longfield <slongfield@google.com>
2
2
3
By using the TYPE_* definitions for devices, we can:
3
Size is used at lines 1088/1188 for the loop, which reads the last 4
4
- quickly find where devices are used with 'git-grep'
4
bytes from the crc_ptr so it does need to get increased, however it
5
- easily rename a device (one-line change).
5
shouldn't be increased before the buffer is passed to CRC computation,
6
or the crc32 function will access uninitialized memory.
6
7
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
This was pointed out to me by clg@kaod.org during the code review of
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
9
a similar patch to hw/net/ftgmac100.c
10
11
Change-Id: Ib0464303b191af1e28abeb2f5105eb25aadb5e9b
12
Signed-off-by: Stephen Longfield <slongfield@google.com>
13
Reviewed-by: Patrick Venture <venture@google.com>
14
Message-id: 20221221183202.3788132-1-slongfield@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
hw/arm/mps2-tz.c | 2 +-
18
hw/net/imx_fec.c | 8 ++++----
13
1 file changed, 1 insertion(+), 1 deletion(-)
19
1 file changed, 4 insertions(+), 4 deletions(-)
14
20
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
21
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
23
--- a/hw/net/imx_fec.c
18
+++ b/hw/arm/mps2-tz.c
24
+++ b/hw/net/imx_fec.c
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
25
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
20
exit(EXIT_FAILURE);
26
return 0;
21
}
27
}
22
28
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
29
- /* 4 bytes for the CRC. */
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
30
- size += 4;
25
sizeof(mms->iotkit), mmc->armsse_type);
31
crc = cpu_to_be32(crc32(~0, buf, size));
26
iotkitdev = DEVICE(&mms->iotkit);
32
+ /* Increase size by 4, loop below reads the last 4 bytes from crc_ptr. */
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
33
+ size += 4;
34
crc_ptr = (uint8_t *) &crc;
35
36
/* Huge frames are truncated. */
37
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
38
return 0;
39
}
40
41
- /* 4 bytes for the CRC. */
42
- size += 4;
43
crc = cpu_to_be32(crc32(~0, buf, size));
44
+ /* Increase size by 4, loop below reads the last 4 bytes from crc_ptr. */
45
+ size += 4;
46
crc_ptr = (uint8_t *) &crc;
47
48
if (shift16) {
28
--
49
--
29
2.20.1
50
2.25.1
30
31
diff view generated by jsdifflib
Deleted patch
1
We were accidentally permitting decode of Thumb Neon insns even if
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
3
check was being done before the call to disas_neon_data_insn() and
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
5
Thumb decoder. Push the feature bit check down into the called
6
functions so it is done for both Arm and Thumb encodings.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
12
---
13
target/arm/translate.c | 16 ++++++++--------
14
1 file changed, 8 insertions(+), 8 deletions(-)
15
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
19
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
21
TCGv_i32 tmp2;
22
TCGv_i64 tmp64;
23
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
25
+ return 1;
26
+ }
27
+
28
/* FIXME: this access check should not take precedence over UNDEF
29
* for invalid encodings; we will generate incorrect syndrome information
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
32
TCGv_ptr ptr1, ptr2, ptr3;
33
TCGv_i64 tmp64;
34
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
36
+ return 1;
37
+ }
38
+
39
/* FIXME: this access check should not take precedence over UNDEF
40
* for invalid encodings; we will generate incorrect syndrome information
41
* for attempts to execute invalid vfp/neon encodings with FP disabled.
42
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
43
44
if (((insn >> 25) & 7) == 1) {
45
/* NEON Data processing. */
46
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
- goto illegal_op;
48
- }
49
-
50
if (disas_neon_data_insn(s, insn)) {
51
goto illegal_op;
52
}
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
54
}
55
if ((insn & 0x0f100000) == 0x04000000) {
56
/* NEON load/store. */
57
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
58
- goto illegal_op;
59
- }
60
-
61
if (disas_neon_ls_insn(s, insn)) {
62
goto illegal_op;
63
}
64
--
65
2.20.1
66
67
diff view generated by jsdifflib
Deleted patch
1
Convert the VCMLA (vector) insns in the 3same extension group to
2
decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 11 ++++++++++
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 11 +---------
11
3 files changed, 49 insertions(+), 10 deletions(-)
12
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@
18
# More specifically, this covers:
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
21
+
22
+# VFP/Neon register fields; same as vfp.decode
23
+%vm_dp 5:1 0:4
24
+%vm_sp 0:4 5:1
25
+%vn_dp 7:1 16:4
26
+%vn_sp 16:4 7:1
27
+%vd_dp 22:1 12:4
28
+%vd_sp 12:4 22:1
29
+
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.inc.c
35
+++ b/target/arm/translate-neon.inc.c
36
@@ -XXX,XX +XXX,XX @@
37
#include "decode-neon-dp.inc.c"
38
#include "decode-neon-ls.inc.c"
39
#include "decode-neon-shared.inc.c"
40
+
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
42
+{
43
+ int opr_sz;
44
+ TCGv_ptr fpst;
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
46
+
47
+ if (!dc_isar_feature(aa32_vcma, s)
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
49
+ return false;
50
+ }
51
+
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
55
+ return false;
56
+ }
57
+
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
59
+ return false;
60
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
64
+ }
65
+
66
+ opr_sz = (1 + a->q) * 8;
67
+ fpst = get_fpstatus_ptr(1);
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
70
+ vfp_reg_offset(1, a->vn),
71
+ vfp_reg_offset(1, a->vm),
72
+ fpst, opr_sz, opr_sz, a->rot,
73
+ fn_gvec_ptr);
74
+ tcg_temp_free_ptr(fpst);
75
+ return true;
76
+}
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate.c
80
+++ b/target/arm/translate.c
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
82
bool is_long = false, q = extract32(insn, 6, 1);
83
bool ptr_is_env = false;
84
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
87
- int size = extract32(insn, 20, 1);
88
- data = extract32(insn, 23, 2); /* rot */
89
- if (!dc_isar_feature(aa32_vcma, s)
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
91
- return 1;
92
- }
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
97
int size = extract32(insn, 20, 1);
98
data = extract32(insn, 24, 1); /* rot */
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
Deleted patch
1
Convert the VCADD (vector) insns to decodetree.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 3 +++
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 11 +---------
10
3 files changed, 41 insertions(+), 10 deletions(-)
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@
17
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-neon.inc.c
26
+++ b/target/arm/translate-neon.inc.c
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
28
tcg_temp_free_ptr(fpst);
29
return true;
30
}
31
+
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
33
+{
34
+ int opr_sz;
35
+ TCGv_ptr fpst;
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
37
+
38
+ if (!dc_isar_feature(aa32_vcma, s)
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ opr_sz = (1 + a->q) * 8;
58
+ fpst = get_fpstatus_ptr(1);
59
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
60
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->vm),
63
+ fpst, opr_sz, opr_sz, a->rot,
64
+ fn_gvec_ptr);
65
+ tcg_temp_free_ptr(fpst);
66
+ return true;
67
+}
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/translate.c
71
+++ b/target/arm/translate.c
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
73
bool is_long = false, q = extract32(insn, 6, 1);
74
bool ptr_is_env = false;
75
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
78
- int size = extract32(insn, 20, 1);
79
- data = extract32(insn, 24, 1); /* rot */
80
- if (!dc_isar_feature(aa32_vcma, s)
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
82
- return 1;
83
- }
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
88
bool u = extract32(insn, 4, 1);
89
if (!dc_isar_feature(aa32_dp, s)) {
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
Convert the V[US]DOT (vector) insns to decodetree.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 4 ++++
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 9 +--------
10
3 files changed, 37 insertions(+), 8 deletions(-)
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
17
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+
21
+# VUDOT and VSDOT
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
29
tcg_temp_free_ptr(fpst);
30
return true;
31
}
32
+
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
34
+{
35
+ int opr_sz;
36
+ gen_helper_gvec_3 *fn_gvec;
37
+
38
+ if (!dc_isar_feature(aa32_dp, s)) {
39
+ return false;
40
+ }
41
+
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
45
+ return false;
46
+ }
47
+
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
49
+ return false;
50
+ }
51
+
52
+ if (!vfp_access_check(s)) {
53
+ return true;
54
+ }
55
+
56
+ opr_sz = (1 + a->q) * 8;
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
58
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
59
+ vfp_reg_offset(1, a->vn),
60
+ vfp_reg_offset(1, a->vm),
61
+ opr_sz, opr_sz, 0, fn_gvec);
62
+ return true;
63
+}
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
69
bool is_long = false, q = extract32(insn, 6, 1);
70
bool ptr_is_env = false;
71
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
74
- bool u = extract32(insn, 4, 1);
75
- if (!dc_isar_feature(aa32_dp, s)) {
76
- return 1;
77
- }
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
82
int is_s = extract32(insn, 23, 1);
83
if (!dc_isar_feature(aa32_fhm, s)) {
84
--
85
2.20.1
86
87
diff view generated by jsdifflib
Deleted patch
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
2
to decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 3 +++
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 13 +-----------
11
3 files changed, 39 insertions(+), 12 deletions(-)
12
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
18
vn=%vn_dp vd=%vd_dp size=0
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
21
+
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
29
tcg_temp_free_ptr(fpst);
30
return true;
31
}
32
+
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
34
+{
35
+ gen_helper_gvec_3 *fn_gvec;
36
+ int opr_sz;
37
+ TCGv_ptr fpst;
38
+
39
+ if (!dc_isar_feature(aa32_dp, s)) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vd | a->vn) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
58
+ opr_sz = (1 + a->q) * 8;
59
+ fpst = get_fpstatus_ptr(1);
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->rm),
63
+ opr_sz, opr_sz, a->index, fn_gvec);
64
+ tcg_temp_free_ptr(fpst);
65
+ return true;
66
+}
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/translate.c
70
+++ b/target/arm/translate.c
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
72
bool is_long = false, q = extract32(insn, 6, 1);
73
bool ptr_is_env = false;
74
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
77
- int u = extract32(insn, 4, 1);
78
-
79
- if (!dc_isar_feature(aa32_dp, s)) {
80
- return 1;
81
- }
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
83
- /* rm is just Vm, and index is M. */
84
- data = extract32(insn, 5, 1); /* index */
85
- rm = extract32(insn, 0, 4);
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
89
int is_s = extract32(insn, 20, 1);
90
int vm20 = extract32(insn, 0, 3);
91
--
92
2.20.1
93
94
diff view generated by jsdifflib