1
The following changes since commit 4cc10cae64c51e17844dc4358481c393d7bf1ed4:
1
Two small bugfixes, plus most of RTH's refactoring of cpregs
2
handling.
2
3
3
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging (2021-05-06 18:56:17 +0100)
4
-- PMM
5
6
The following changes since commit 1fba9dc71a170b3a05b9d3272dd8ecfe7f26e215:
7
8
Merge tag 'pull-request-2022-05-04' of https://gitlab.com/thuth/qemu into staging (2022-05-04 08:07:02 -0700)
4
9
5
are available in the Git repository at:
10
are available in the Git repository at:
6
11
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210510
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220505
8
13
9
for you to fetch changes up to 8f96812baa53005f32aece3e30b140826c20aa19:
14
for you to fetch changes up to 99a50d1a67c602126fc2b3a4812d3000eba9bf34:
10
15
11
hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9 (2021-05-10 13:24:09 +0100)
16
target/arm: read access to performance counters from EL0 (2022-05-05 09:36:22 +0100)
12
17
13
----------------------------------------------------------------
18
----------------------------------------------------------------
14
target-arm queue:
19
target-arm queue:
15
* docs: fix link in sbsa description
20
* Enable read access to performance counters from EL0
16
* linux-user/aarch64: Enable hwcap for RND, BTI, and MTE
21
* Enable SCTLR_EL1.BT0 for aarch64-linux-user
17
* target/arm: Fix tlbbits calculation in tlbi_aa64_vae2is_write()
22
* Refactoring of cpreg handling
18
* target/arm: Split neon and vfp translation to their own
19
compilation units
20
* target/arm: Make WFI a NOP for userspace emulators
21
* hw/sd/omap_mmc: Use device_cold_reset() instead of
22
device_legacy_reset()
23
* include: More fixes for 'extern "C"' block use
24
* hw/arm/imx25_pdk: Fix error message for invalid RAM size
25
* hw/arm/mps2-tz: Implement AN524 memory remapping via machine property
26
* hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9
27
23
28
----------------------------------------------------------------
24
----------------------------------------------------------------
29
Alex Bennée (1):
25
Alex Zuepke (1):
30
docs: fix link in sbsa description
26
target/arm: read access to performance counters from EL0
31
27
32
Guenter Roeck (1):
28
Richard Henderson (22):
33
hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9
29
target/arm: Enable SCTLR_EL1.BT0 for aarch64-linux-user
30
target/arm: Split out cpregs.h
31
target/arm: Reorg CPAccessResult and access_check_cp_reg
32
target/arm: Replace sentinels with ARRAY_SIZE in cpregs.h
33
target/arm: Make some more cpreg data static const
34
target/arm: Reorg ARMCPRegInfo type field bits
35
target/arm: Avoid bare abort() or assert(0)
36
target/arm: Change cpreg access permissions to enum
37
target/arm: Name CPState type
38
target/arm: Name CPSecureState type
39
target/arm: Drop always-true test in define_arm_vh_e2h_redirects_aliases
40
target/arm: Store cpregs key in the hash table directly
41
target/arm: Merge allocation of the cpreg and its name
42
target/arm: Hoist computation of key in add_cpreg_to_hashtable
43
target/arm: Consolidate cpreg updates in add_cpreg_to_hashtable
44
target/arm: Use bool for is64 and ns in add_cpreg_to_hashtable
45
target/arm: Hoist isbanked computation in add_cpreg_to_hashtable
46
target/arm: Perform override check early in add_cpreg_to_hashtable
47
target/arm: Reformat comments in add_cpreg_to_hashtable
48
target/arm: Remove HOST_BIG_ENDIAN ifdef in add_cpreg_to_hashtable
49
target/arm: Add isar predicates for FEAT_Debugv8p2
50
target/arm: Add isar_feature_{aa64,any}_ras
34
51
35
Peter Maydell (22):
52
target/arm/cpregs.h | 453 ++++++++++++++++++++++++++++++++++++++
36
target/arm: Fix tlbbits calculation in tlbi_aa64_vae2is_write()
53
target/arm/cpu.h | 393 +++------------------------------
37
target/arm: Move constant expanders to translate.h
54
hw/arm/pxa2xx.c | 2 +-
38
target/arm: Share unallocated_encoding() and gen_exception_insn()
55
hw/arm/pxa2xx_pic.c | 2 +-
39
target/arm: Make functions used by m-nocp global
56
hw/intc/arm_gicv3_cpuif.c | 6 +-
40
target/arm: Split m-nocp trans functions into their own file
57
hw/intc/arm_gicv3_kvm.c | 3 +-
41
target/arm: Move gen_aa32 functions to translate-a32.h
58
target/arm/cpu.c | 25 +--
42
target/arm: Move vfp_{load, store}_reg{32, 64} to translate-vfp.c.inc
59
target/arm/cpu64.c | 2 +-
43
target/arm: Make functions used by translate-vfp global
60
target/arm/cpu_tcg.c | 5 +-
44
target/arm: Make translate-vfp.c.inc its own compilation unit
61
target/arm/gdbstub.c | 5 +-
45
target/arm: Move vfp_reg_ptr() to translate-neon.c.inc
62
target/arm/helper.c | 358 +++++++++++++-----------------
46
target/arm: Delete unused typedef
63
target/arm/hvf/hvf.c | 2 +-
47
target/arm: Move NeonGenThreeOpEnvFn typedef to translate.h
64
target/arm/kvm-stub.c | 4 +-
48
target/arm: Make functions used by translate-neon global
65
target/arm/kvm.c | 4 +-
49
target/arm: Make translate-neon.c.inc its own compilation unit
66
target/arm/machine.c | 4 +-
50
target/arm: Make WFI a NOP for userspace emulators
67
target/arm/op_helper.c | 57 ++---
51
hw/sd/omap_mmc: Use device_cold_reset() instead of device_legacy_reset()
68
target/arm/translate-a64.c | 14 +-
52
osdep: Make os-win32.h and os-posix.h handle 'extern "C"' themselves
69
target/arm/translate-neon.c | 2 +-
53
include/qemu/bswap.h: Handle being included outside extern "C" block
70
target/arm/translate.c | 13 +-
54
include/disas/dis-asm.h: Handle being included outside 'extern "C"'
71
tests/tcg/aarch64/bti-3.c | 42 ++++
55
hw/misc/mps2-scc: Add "QEMU interface" comment
72
tests/tcg/aarch64/Makefile.target | 6 +-
56
hw/misc/mps2-scc: Support using CFG0 bit 0 for remapping
73
21 files changed, 738 insertions(+), 664 deletions(-)
57
hw/arm/mps2-tz: Implement AN524 memory remapping via machine property
74
create mode 100644 target/arm/cpregs.h
58
75
create mode 100644 tests/tcg/aarch64/bti-3.c
59
Philippe Mathieu-Daudé (1):
60
hw/arm/imx25_pdk: Fix error message for invalid RAM size
61
62
Richard Henderson (1):
63
linux-user/aarch64: Enable hwcap for RND, BTI, and MTE
64
65
docs/system/arm/mps2.rst | 10 +
66
docs/system/arm/sbsa.rst | 2 +-
67
include/disas/dis-asm.h | 12 +-
68
include/hw/misc/mps2-scc.h | 21 ++
69
include/qemu/bswap.h | 26 ++-
70
include/qemu/osdep.h | 8 +-
71
include/sysemu/os-posix.h | 8 +
72
include/sysemu/os-win32.h | 8 +
73
target/arm/translate-a32.h | 144 +++++++++++++
74
target/arm/translate-a64.h | 2 -
75
target/arm/translate.h | 29 +++
76
hw/arm/imx25_pdk.c | 5 +-
77
hw/arm/mps2-tz.c | 108 +++++++++-
78
hw/arm/xilinx_zynq.c | 2 +-
79
hw/misc/mps2-scc.c | 13 +-
80
hw/sd/omap_mmc.c | 2 +-
81
linux-user/elfload.c | 13 ++
82
target/arm/helper.c | 2 +-
83
target/arm/op_helper.c | 12 ++
84
target/arm/translate-a64.c | 15 --
85
target/arm/translate-m-nocp.c | 221 ++++++++++++++++++++
86
.../arm/{translate-neon.c.inc => translate-neon.c} | 19 +-
87
.../arm/{translate-vfp.c.inc => translate-vfp.c} | 230 +++------------------
88
target/arm/translate.c | 200 ++++--------------
89
disas/arm-a64.cc | 2 -
90
disas/nanomips.cpp | 2 -
91
target/arm/meson.build | 15 +-
92
27 files changed, 718 insertions(+), 413 deletions(-)
93
create mode 100644 target/arm/translate-a32.h
94
create mode 100644 target/arm/translate-m-nocp.c
95
rename target/arm/{translate-neon.c.inc => translate-neon.c} (99%)
96
rename target/arm/{translate-vfp.c.inc => translate-vfp.c} (94%)
97
diff view generated by jsdifflib
1
Currently the trans functions for m-nocp.decode all live in
1
From: Richard Henderson <richard.henderson@linaro.org>
2
translate-vfp.inc.c; move them out into their own translation unit,
3
translate-m-nocp.c.
4
2
5
The trans_* functions here are pure code motion with no changes.
3
This controls whether the PACI{A,B}SP instructions trap with BTYPE=3
4
(indirect branch from register other than x16/x17). The linux kernel
5
sets this in bti_enable().
6
6
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/998
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20220427042312.294300-1-richard.henderson@linaro.org
11
[PMM: remove stray change to makefile comment]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210430132740.10391-5-peter.maydell@linaro.org
10
---
13
---
11
target/arm/translate-a32.h | 3 +
14
target/arm/cpu.c | 2 ++
12
target/arm/translate-m-nocp.c | 221 +++++++++++++++++++++++++++++++++
15
tests/tcg/aarch64/bti-3.c | 42 +++++++++++++++++++++++++++++++
13
target/arm/translate.c | 1 -
16
tests/tcg/aarch64/Makefile.target | 6 ++---
14
target/arm/translate-vfp.c.inc | 196 -----------------------------
17
3 files changed, 47 insertions(+), 3 deletions(-)
15
target/arm/meson.build | 3 +-
18
create mode 100644 tests/tcg/aarch64/bti-3.c
16
5 files changed, 226 insertions(+), 198 deletions(-)
17
create mode 100644 target/arm/translate-m-nocp.c
18
19
19
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
20
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a32.h
22
--- a/target/arm/cpu.c
22
+++ b/target/arm/translate-a32.h
23
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
24
#ifndef TARGET_ARM_TRANSLATE_A64_H
25
/* Enable all PAC keys. */
25
#define TARGET_ARM_TRANSLATE_A64_H
26
env->cp15.sctlr_el[1] |= (SCTLR_EnIA | SCTLR_EnIB |
26
27
SCTLR_EnDA | SCTLR_EnDB);
27
+/* Prototypes for autogenerated disassembler functions */
28
+ /* Trap on btype=3 for PACIxSP. */
28
+bool disas_m_nocp(DisasContext *dc, uint32_t insn);
29
+ env->cp15.sctlr_el[1] |= SCTLR_BT0;
29
+
30
/* and to the FP/Neon instructions */
30
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
31
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
31
void arm_gen_condlabel(DisasContext *s);
32
/* and to the SVE instructions */
32
bool vfp_access_check(DisasContext *s);
33
diff --git a/tests/tcg/aarch64/bti-3.c b/tests/tcg/aarch64/bti-3.c
33
diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c
34
new file mode 100644
34
new file mode 100644
35
index XXXXXXX..XXXXXXX
35
index XXXXXXX..XXXXXXX
36
--- /dev/null
36
--- /dev/null
37
+++ b/target/arm/translate-m-nocp.c
37
+++ b/tests/tcg/aarch64/bti-3.c
38
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@
39
+/*
39
+/*
40
+ * ARM translation: M-profile NOCP special-case instructions
40
+ * BTI vs PACIASP
41
+ *
42
+ * Copyright (c) 2020 Linaro, Ltd.
43
+ *
44
+ * This library is free software; you can redistribute it and/or
45
+ * modify it under the terms of the GNU Lesser General Public
46
+ * License as published by the Free Software Foundation; either
47
+ * version 2.1 of the License, or (at your option) any later version.
48
+ *
49
+ * This library is distributed in the hope that it will be useful,
50
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
52
+ * Lesser General Public License for more details.
53
+ *
54
+ * You should have received a copy of the GNU Lesser General Public
55
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
56
+ */
41
+ */
57
+
42
+
58
+#include "qemu/osdep.h"
43
+#include "bti-crt.inc.c"
59
+#include "tcg/tcg-op.h"
60
+#include "translate.h"
61
+#include "translate-a32.h"
62
+
44
+
63
+#include "decode-m-nocp.c.inc"
45
+static void skip2_sigill(int sig, siginfo_t *info, ucontext_t *uc)
64
+
65
+/*
66
+ * Decode VLLDM and VLSTM are nonstandard because:
67
+ * * if there is no FPU then these insns must NOP in
68
+ * Secure state and UNDEF in Nonsecure state
69
+ * * if there is an FPU then these insns do not have
70
+ * the usual behaviour that vfp_access_check() provides of
71
+ * being controlled by CPACR/NSACR enable bits or the
72
+ * lazy-stacking logic.
73
+ */
74
+static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
75
+{
46
+{
76
+ TCGv_i32 fptr;
47
+ uc->uc_mcontext.pc += 8;
77
+
48
+ uc->uc_mcontext.pstate = 1;
78
+ if (!arm_dc_feature(s, ARM_FEATURE_M) ||
79
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
80
+ return false;
81
+ }
82
+
83
+ if (a->op) {
84
+ /*
85
+ * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
86
+ * to take the IMPDEF option to make memory accesses to the stack
87
+ * slots that correspond to the D16-D31 registers (discarding
88
+ * read data and writing UNKNOWN values), so for us the T2
89
+ * encoding behaves identically to the T1 encoding.
90
+ */
91
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
92
+ return false;
93
+ }
94
+ } else {
95
+ /*
96
+ * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
97
+ * This is currently architecturally impossible, but we add the
98
+ * check to stay in line with the pseudocode. Note that we must
99
+ * emit code for the UNDEF so it takes precedence over the NOCP.
100
+ */
101
+ if (dc_isar_feature(aa32_simd_r32, s)) {
102
+ unallocated_encoding(s);
103
+ return true;
104
+ }
105
+ }
106
+
107
+ /*
108
+ * If not secure, UNDEF. We must emit code for this
109
+ * rather than returning false so that this takes
110
+ * precedence over the m-nocp.decode NOCP fallback.
111
+ */
112
+ if (!s->v8m_secure) {
113
+ unallocated_encoding(s);
114
+ return true;
115
+ }
116
+ /* If no fpu, NOP. */
117
+ if (!dc_isar_feature(aa32_vfp, s)) {
118
+ return true;
119
+ }
120
+
121
+ fptr = load_reg(s, a->rn);
122
+ if (a->l) {
123
+ gen_helper_v7m_vlldm(cpu_env, fptr);
124
+ } else {
125
+ gen_helper_v7m_vlstm(cpu_env, fptr);
126
+ }
127
+ tcg_temp_free_i32(fptr);
128
+
129
+ /* End the TB, because we have updated FP control bits */
130
+ s->base.is_jmp = DISAS_UPDATE_EXIT;
131
+ return true;
132
+}
49
+}
133
+
50
+
134
+static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
51
+#define BTYPE_1() \
52
+ asm("mov %0,#1; adr x16, 1f; br x16; 1: hint #25; mov %0,#0" \
53
+ : "=r"(skipped) : : "x16", "x30")
54
+
55
+#define BTYPE_2() \
56
+ asm("mov %0,#1; adr x16, 1f; blr x16; 1: hint #25; mov %0,#0" \
57
+ : "=r"(skipped) : : "x16", "x30")
58
+
59
+#define BTYPE_3() \
60
+ asm("mov %0,#1; adr x15, 1f; br x15; 1: hint #25; mov %0,#0" \
61
+ : "=r"(skipped) : : "x15", "x30")
62
+
63
+#define TEST(WHICH, EXPECT) \
64
+ do { WHICH(); fail += skipped ^ EXPECT; } while (0)
65
+
66
+int main()
135
+{
67
+{
136
+ int btmreg, topreg;
68
+ int fail = 0;
137
+ TCGv_i64 zero;
69
+ int skipped;
138
+ TCGv_i32 aspen, sfpa;
139
+
70
+
140
+ if (!dc_isar_feature(aa32_m_sec_state, s)) {
71
+ /* Signal-like with SA_SIGINFO. */
141
+ /* Before v8.1M, fall through in decode to NOCP check */
72
+ signal_info(SIGILL, skip2_sigill);
142
+ return false;
143
+ }
144
+
73
+
145
+ /* Explicitly UNDEF because this takes precedence over NOCP */
74
+ /* With SCTLR_EL1.BT0 set, PACIASP is not compatible with type=3. */
146
+ if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
75
+ TEST(BTYPE_1, 0);
147
+ unallocated_encoding(s);
76
+ TEST(BTYPE_2, 0);
148
+ return true;
77
+ TEST(BTYPE_3, 1);
149
+ }
150
+
78
+
151
+ if (!dc_isar_feature(aa32_vfp_simd, s)) {
79
+ return fail;
152
+ /* NOP if we have neither FP nor MVE */
153
+ return true;
154
+ }
155
+
156
+ /*
157
+ * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
158
+ * active floating point context so we must NOP (without doing
159
+ * any lazy state preservation or the NOCP check).
160
+ */
161
+ aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
162
+ sfpa = load_cpu_field(v7m.control[M_REG_S]);
163
+ tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
164
+ tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
165
+ tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
166
+ tcg_gen_or_i32(sfpa, sfpa, aspen);
167
+ arm_gen_condlabel(s);
168
+ tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
169
+
170
+ if (s->fp_excp_el != 0) {
171
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
172
+ syn_uncategorized(), s->fp_excp_el);
173
+ return true;
174
+ }
175
+
176
+ topreg = a->vd + a->imm - 1;
177
+ btmreg = a->vd;
178
+
179
+ /* Convert to Sreg numbers if the insn specified in Dregs */
180
+ if (a->size == 3) {
181
+ topreg = topreg * 2 + 1;
182
+ btmreg *= 2;
183
+ }
184
+
185
+ if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
186
+ /* UNPREDICTABLE: we choose to undef */
187
+ unallocated_encoding(s);
188
+ return true;
189
+ }
190
+
191
+ /* Silently ignore requests to clear D16-D31 if they don't exist */
192
+ if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
193
+ topreg = 31;
194
+ }
195
+
196
+ if (!vfp_access_check(s)) {
197
+ return true;
198
+ }
199
+
200
+ /* Zero the Sregs from btmreg to topreg inclusive. */
201
+ zero = tcg_const_i64(0);
202
+ if (btmreg & 1) {
203
+ write_neon_element64(zero, btmreg >> 1, 1, MO_32);
204
+ btmreg++;
205
+ }
206
+ for (; btmreg + 1 <= topreg; btmreg += 2) {
207
+ write_neon_element64(zero, btmreg >> 1, 0, MO_64);
208
+ }
209
+ if (btmreg == topreg) {
210
+ write_neon_element64(zero, btmreg >> 1, 0, MO_32);
211
+ btmreg++;
212
+ }
213
+ assert(btmreg == topreg + 1);
214
+ /* TODO: when MVE is implemented, zero VPR here */
215
+ return true;
216
+}
80
+}
217
+
81
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
218
+static bool trans_NOCP(DisasContext *s, arg_nocp *a)
219
+{
220
+ /*
221
+ * Handle M-profile early check for disabled coprocessor:
222
+ * all we need to do here is emit the NOCP exception if
223
+ * the coprocessor is disabled. Otherwise we return false
224
+ * and the real VFP/etc decode will handle the insn.
225
+ */
226
+ assert(arm_dc_feature(s, ARM_FEATURE_M));
227
+
228
+ if (a->cp == 11) {
229
+ a->cp = 10;
230
+ }
231
+ if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
232
+ (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
233
+ /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
234
+ a->cp = 10;
235
+ }
236
+
237
+ if (a->cp != 10) {
238
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
239
+ syn_uncategorized(), default_exception_el(s));
240
+ return true;
241
+ }
242
+
243
+ if (s->fp_excp_el != 0) {
244
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
245
+ syn_uncategorized(), s->fp_excp_el);
246
+ return true;
247
+ }
248
+
249
+ return false;
250
+}
251
+
252
+static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
253
+{
254
+ /* This range needs a coprocessor check for v8.1M and later only */
255
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
256
+ return false;
257
+ }
258
+ return trans_NOCP(s, a);
259
+}
260
diff --git a/target/arm/translate.c b/target/arm/translate.c
261
index XXXXXXX..XXXXXXX 100644
82
index XXXXXXX..XXXXXXX 100644
262
--- a/target/arm/translate.c
83
--- a/tests/tcg/aarch64/Makefile.target
263
+++ b/target/arm/translate.c
84
+++ b/tests/tcg/aarch64/Makefile.target
264
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
85
@@ -XXX,XX +XXX,XX @@ endif
265
#define ARM_CP_RW_BIT (1 << 20)
86
# BTI Tests
266
87
# bti-1 tests the elf notes, so we require special compiler support.
267
/* Include the VFP and Neon decoders */
88
ifneq ($(CROSS_CC_HAS_ARMV8_BTI),)
268
-#include "decode-m-nocp.c.inc"
89
-AARCH64_TESTS += bti-1
269
#include "translate-vfp.c.inc"
90
-bti-1: CFLAGS += -mbranch-protection=standard
270
#include "translate-neon.c.inc"
91
-bti-1: LDFLAGS += -nostdlib
271
92
+AARCH64_TESTS += bti-1 bti-3
272
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
93
+bti-1 bti-3: CFLAGS += -mbranch-protection=standard
273
index XXXXXXX..XXXXXXX 100644
94
+bti-1 bti-3: LDFLAGS += -nostdlib
274
--- a/target/arm/translate-vfp.c.inc
95
endif
275
+++ b/target/arm/translate-vfp.c.inc
96
# bti-2 tests PROT_BTI, so no special compiler support required.
276
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
97
AARCH64_TESTS += bti-2
277
return true;
278
}
279
280
-/*
281
- * Decode VLLDM and VLSTM are nonstandard because:
282
- * * if there is no FPU then these insns must NOP in
283
- * Secure state and UNDEF in Nonsecure state
284
- * * if there is an FPU then these insns do not have
285
- * the usual behaviour that vfp_access_check() provides of
286
- * being controlled by CPACR/NSACR enable bits or the
287
- * lazy-stacking logic.
288
- */
289
-static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
290
-{
291
- TCGv_i32 fptr;
292
-
293
- if (!arm_dc_feature(s, ARM_FEATURE_M) ||
294
- !arm_dc_feature(s, ARM_FEATURE_V8)) {
295
- return false;
296
- }
297
-
298
- if (a->op) {
299
- /*
300
- * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
301
- * to take the IMPDEF option to make memory accesses to the stack
302
- * slots that correspond to the D16-D31 registers (discarding
303
- * read data and writing UNKNOWN values), so for us the T2
304
- * encoding behaves identically to the T1 encoding.
305
- */
306
- if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
307
- return false;
308
- }
309
- } else {
310
- /*
311
- * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
312
- * This is currently architecturally impossible, but we add the
313
- * check to stay in line with the pseudocode. Note that we must
314
- * emit code for the UNDEF so it takes precedence over the NOCP.
315
- */
316
- if (dc_isar_feature(aa32_simd_r32, s)) {
317
- unallocated_encoding(s);
318
- return true;
319
- }
320
- }
321
-
322
- /*
323
- * If not secure, UNDEF. We must emit code for this
324
- * rather than returning false so that this takes
325
- * precedence over the m-nocp.decode NOCP fallback.
326
- */
327
- if (!s->v8m_secure) {
328
- unallocated_encoding(s);
329
- return true;
330
- }
331
- /* If no fpu, NOP. */
332
- if (!dc_isar_feature(aa32_vfp, s)) {
333
- return true;
334
- }
335
-
336
- fptr = load_reg(s, a->rn);
337
- if (a->l) {
338
- gen_helper_v7m_vlldm(cpu_env, fptr);
339
- } else {
340
- gen_helper_v7m_vlstm(cpu_env, fptr);
341
- }
342
- tcg_temp_free_i32(fptr);
343
-
344
- /* End the TB, because we have updated FP control bits */
345
- s->base.is_jmp = DISAS_UPDATE_EXIT;
346
- return true;
347
-}
348
-
349
-static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
350
-{
351
- int btmreg, topreg;
352
- TCGv_i64 zero;
353
- TCGv_i32 aspen, sfpa;
354
-
355
- if (!dc_isar_feature(aa32_m_sec_state, s)) {
356
- /* Before v8.1M, fall through in decode to NOCP check */
357
- return false;
358
- }
359
-
360
- /* Explicitly UNDEF because this takes precedence over NOCP */
361
- if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
362
- unallocated_encoding(s);
363
- return true;
364
- }
365
-
366
- if (!dc_isar_feature(aa32_vfp_simd, s)) {
367
- /* NOP if we have neither FP nor MVE */
368
- return true;
369
- }
370
-
371
- /*
372
- * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
373
- * active floating point context so we must NOP (without doing
374
- * any lazy state preservation or the NOCP check).
375
- */
376
- aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
377
- sfpa = load_cpu_field(v7m.control[M_REG_S]);
378
- tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
379
- tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
380
- tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
381
- tcg_gen_or_i32(sfpa, sfpa, aspen);
382
- arm_gen_condlabel(s);
383
- tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
384
-
385
- if (s->fp_excp_el != 0) {
386
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
387
- syn_uncategorized(), s->fp_excp_el);
388
- return true;
389
- }
390
-
391
- topreg = a->vd + a->imm - 1;
392
- btmreg = a->vd;
393
-
394
- /* Convert to Sreg numbers if the insn specified in Dregs */
395
- if (a->size == 3) {
396
- topreg = topreg * 2 + 1;
397
- btmreg *= 2;
398
- }
399
-
400
- if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
401
- /* UNPREDICTABLE: we choose to undef */
402
- unallocated_encoding(s);
403
- return true;
404
- }
405
-
406
- /* Silently ignore requests to clear D16-D31 if they don't exist */
407
- if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
408
- topreg = 31;
409
- }
410
-
411
- if (!vfp_access_check(s)) {
412
- return true;
413
- }
414
-
415
- /* Zero the Sregs from btmreg to topreg inclusive. */
416
- zero = tcg_const_i64(0);
417
- if (btmreg & 1) {
418
- write_neon_element64(zero, btmreg >> 1, 1, MO_32);
419
- btmreg++;
420
- }
421
- for (; btmreg + 1 <= topreg; btmreg += 2) {
422
- write_neon_element64(zero, btmreg >> 1, 0, MO_64);
423
- }
424
- if (btmreg == topreg) {
425
- write_neon_element64(zero, btmreg >> 1, 0, MO_32);
426
- btmreg++;
427
- }
428
- assert(btmreg == topreg + 1);
429
- /* TODO: when MVE is implemented, zero VPR here */
430
- return true;
431
-}
432
-
433
-static bool trans_NOCP(DisasContext *s, arg_nocp *a)
434
-{
435
- /*
436
- * Handle M-profile early check for disabled coprocessor:
437
- * all we need to do here is emit the NOCP exception if
438
- * the coprocessor is disabled. Otherwise we return false
439
- * and the real VFP/etc decode will handle the insn.
440
- */
441
- assert(arm_dc_feature(s, ARM_FEATURE_M));
442
-
443
- if (a->cp == 11) {
444
- a->cp = 10;
445
- }
446
- if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
447
- (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
448
- /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
449
- a->cp = 10;
450
- }
451
-
452
- if (a->cp != 10) {
453
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
454
- syn_uncategorized(), default_exception_el(s));
455
- return true;
456
- }
457
-
458
- if (s->fp_excp_el != 0) {
459
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
460
- syn_uncategorized(), s->fp_excp_el);
461
- return true;
462
- }
463
-
464
- return false;
465
-}
466
-
467
-static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
468
-{
469
- /* This range needs a coprocessor check for v8.1M and later only */
470
- if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
471
- return false;
472
- }
473
- return trans_NOCP(s, a);
474
-}
475
-
476
static bool trans_VINS(DisasContext *s, arg_VINS *a)
477
{
478
TCGv_i32 rd, rm;
479
diff --git a/target/arm/meson.build b/target/arm/meson.build
480
index XXXXXXX..XXXXXXX 100644
481
--- a/target/arm/meson.build
482
+++ b/target/arm/meson.build
483
@@ -XXX,XX +XXX,XX @@ gen = [
484
decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
485
decodetree.process('vfp.decode', extra_args: '--static-decode=disas_vfp'),
486
decodetree.process('vfp-uncond.decode', extra_args: '--static-decode=disas_vfp_uncond'),
487
- decodetree.process('m-nocp.decode', extra_args: '--static-decode=disas_m_nocp'),
488
+ decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
489
decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
490
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
491
decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'),
492
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
493
'op_helper.c',
494
'tlb_helper.c',
495
'translate.c',
496
+ 'translate-m-nocp.c',
497
'vec_helper.c',
498
'vfp_helper.c',
499
'cpu_tcg.c',
500
--
98
--
501
2.20.1
99
2.25.1
502
503
diff view generated by jsdifflib
1
Make the remaining functions which are needed by translate-vfp.c.inc
1
From: Richard Henderson <richard.henderson@linaro.org>
2
global.
3
2
3
Move ARMCPRegInfo and all related declarations to a new
4
internal header, out of the public cpu.h.
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220501055028.646596-2-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-8-peter.maydell@linaro.org
8
---
11
---
9
target/arm/translate-a32.h | 18 ++++++++++++++++++
12
target/arm/cpregs.h | 413 +++++++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 25 ++++++++-----------------
13
target/arm/cpu.h | 368 ---------------------------------
11
2 files changed, 26 insertions(+), 17 deletions(-)
14
hw/arm/pxa2xx.c | 1 +
15
hw/arm/pxa2xx_pic.c | 1 +
16
hw/intc/arm_gicv3_cpuif.c | 1 +
17
hw/intc/arm_gicv3_kvm.c | 2 +
18
target/arm/cpu.c | 1 +
19
target/arm/cpu64.c | 1 +
20
target/arm/cpu_tcg.c | 1 +
21
target/arm/gdbstub.c | 3 +-
22
target/arm/helper.c | 1 +
23
target/arm/op_helper.c | 1 +
24
target/arm/translate-a64.c | 4 +-
25
target/arm/translate.c | 3 +-
26
14 files changed, 427 insertions(+), 374 deletions(-)
27
create mode 100644 target/arm/cpregs.h
12
28
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
29
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
14
index XXXXXXX..XXXXXXX 100644
30
new file mode 100644
15
--- a/target/arm/translate-a32.h
31
index XXXXXXX..XXXXXXX
16
+++ b/target/arm/translate-a32.h
32
--- /dev/null
17
@@ -XXX,XX +XXX,XX @@ void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop);
33
+++ b/target/arm/cpregs.h
18
void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop);
34
@@ -XXX,XX +XXX,XX @@
19
void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop);
35
+/*
20
void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop);
36
+ * QEMU ARM CP Register access and descriptions
21
+TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs);
37
+ *
22
+void gen_set_cpsr(TCGv_i32 var, uint32_t mask);
38
+ * Copyright (c) 2022 Linaro Ltd
23
+void gen_set_condexec(DisasContext *s);
39
+ *
24
+void gen_set_pc_im(DisasContext *s, target_ulong val);
40
+ * This program is free software; you can redistribute it and/or
25
+void gen_lookup_tb(DisasContext *s);
41
+ * modify it under the terms of the GNU General Public License
26
+long vfp_reg_offset(bool dp, unsigned reg);
42
+ * as published by the Free Software Foundation; either version 2
27
+long neon_full_reg_offset(unsigned reg);
43
+ * of the License, or (at your option) any later version.
28
44
+ *
29
static inline TCGv_i32 load_cpu_offset(int offset)
45
+ * This program is distributed in the hope that it will be useful,
46
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
47
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48
+ * GNU General Public License for more details.
49
+ *
50
+ * You should have received a copy of the GNU General Public License
51
+ * along with this program; if not, see
52
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
53
+ */
54
+
55
+#ifndef TARGET_ARM_CPREGS_H
56
+#define TARGET_ARM_CPREGS_H
57
+
58
+/*
59
+ * ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
60
+ * special-behaviour cp reg and bits [11..8] indicate what behaviour
61
+ * it has. Otherwise it is a simple cp reg, where CONST indicates that
62
+ * TCG can assume the value to be constant (ie load at translate time)
63
+ * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
64
+ * indicates that the TB should not be ended after a write to this register
65
+ * (the default is that the TB ends after cp writes). OVERRIDE permits
66
+ * a register definition to override a previous definition for the
67
+ * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
68
+ * old must have the OVERRIDE bit set.
69
+ * ALIAS indicates that this register is an alias view of some underlying
70
+ * state which is also visible via another register, and that the other
71
+ * register is handling migration and reset; registers marked ALIAS will not be
72
+ * migrated but may have their state set by syncing of register state from KVM.
73
+ * NO_RAW indicates that this register has no underlying state and does not
74
+ * support raw access for state saving/loading; it will not be used for either
75
+ * migration or KVM state synchronization. (Typically this is for "registers"
76
+ * which are actually used as instructions for cache maintenance and so on.)
77
+ * IO indicates that this register does I/O and therefore its accesses
78
+ * need to be marked with gen_io_start() and also end the TB. In particular,
79
+ * registers which implement clocks or timers require this.
80
+ * RAISES_EXC is for when the read or write hook might raise an exception;
81
+ * the generated code will synchronize the CPU state before calling the hook
82
+ * so that it is safe for the hook to call raise_exception().
83
+ * NEWEL is for writes to registers that might change the exception
84
+ * level - typically on older ARM chips. For those cases we need to
85
+ * re-read the new el when recomputing the translation flags.
86
+ */
87
+#define ARM_CP_SPECIAL 0x0001
88
+#define ARM_CP_CONST 0x0002
89
+#define ARM_CP_64BIT 0x0004
90
+#define ARM_CP_SUPPRESS_TB_END 0x0008
91
+#define ARM_CP_OVERRIDE 0x0010
92
+#define ARM_CP_ALIAS 0x0020
93
+#define ARM_CP_IO 0x0040
94
+#define ARM_CP_NO_RAW 0x0080
95
+#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
96
+#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
97
+#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
98
+#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
99
+#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
100
+#define ARM_CP_DC_GVA (ARM_CP_SPECIAL | 0x0600)
101
+#define ARM_CP_DC_GZVA (ARM_CP_SPECIAL | 0x0700)
102
+#define ARM_LAST_SPECIAL ARM_CP_DC_GZVA
103
+#define ARM_CP_FPU 0x1000
104
+#define ARM_CP_SVE 0x2000
105
+#define ARM_CP_NO_GDB 0x4000
106
+#define ARM_CP_RAISES_EXC 0x8000
107
+#define ARM_CP_NEWEL 0x10000
108
+/* Used only as a terminator for ARMCPRegInfo lists */
109
+#define ARM_CP_SENTINEL 0xfffff
110
+/* Mask of only the flag bits in a type field */
111
+#define ARM_CP_FLAG_MASK 0x1f0ff
112
+
113
+/*
114
+ * Valid values for ARMCPRegInfo state field, indicating which of
115
+ * the AArch32 and AArch64 execution states this register is visible in.
116
+ * If the reginfo doesn't explicitly specify then it is AArch32 only.
117
+ * If the reginfo is declared to be visible in both states then a second
118
+ * reginfo is synthesised for the AArch32 view of the AArch64 register,
119
+ * such that the AArch32 view is the lower 32 bits of the AArch64 one.
120
+ * Note that we rely on the values of these enums as we iterate through
121
+ * the various states in some places.
122
+ */
123
+enum {
124
+ ARM_CP_STATE_AA32 = 0,
125
+ ARM_CP_STATE_AA64 = 1,
126
+ ARM_CP_STATE_BOTH = 2,
127
+};
128
+
129
+/*
130
+ * ARM CP register secure state flags. These flags identify security state
131
+ * attributes for a given CP register entry.
132
+ * The existence of both or neither secure and non-secure flags indicates that
133
+ * the register has both a secure and non-secure hash entry. A single one of
134
+ * these flags causes the register to only be hashed for the specified
135
+ * security state.
136
+ * Although definitions may have any combination of the S/NS bits, each
137
+ * registered entry will only have one to identify whether the entry is secure
138
+ * or non-secure.
139
+ */
140
+enum {
141
+ ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
142
+ ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
143
+};
144
+
145
+/*
146
+ * Return true if cptype is a valid type field. This is used to try to
147
+ * catch errors where the sentinel has been accidentally left off the end
148
+ * of a list of registers.
149
+ */
150
+static inline bool cptype_valid(int cptype)
151
+{
152
+ return ((cptype & ~ARM_CP_FLAG_MASK) == 0)
153
+ || ((cptype & ARM_CP_SPECIAL) &&
154
+ ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL));
155
+}
156
+
157
+/*
158
+ * Access rights:
159
+ * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM
160
+ * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and
161
+ * PL2 (hyp). The other level which has Read and Write bits is Secure PL1
162
+ * (ie any of the privileged modes in Secure state, or Monitor mode).
163
+ * If a register is accessible in one privilege level it's always accessible
164
+ * in higher privilege levels too. Since "Secure PL1" also follows this rule
165
+ * (ie anything visible in PL2 is visible in S-PL1, some things are only
166
+ * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the
167
+ * terminology a little and call this PL3.
168
+ * In AArch64 things are somewhat simpler as the PLx bits line up exactly
169
+ * with the ELx exception levels.
170
+ *
171
+ * If access permissions for a register are more complex than can be
172
+ * described with these bits, then use a laxer set of restrictions, and
173
+ * do the more restrictive/complex check inside a helper function.
174
+ */
175
+#define PL3_R 0x80
176
+#define PL3_W 0x40
177
+#define PL2_R (0x20 | PL3_R)
178
+#define PL2_W (0x10 | PL3_W)
179
+#define PL1_R (0x08 | PL2_R)
180
+#define PL1_W (0x04 | PL2_W)
181
+#define PL0_R (0x02 | PL1_R)
182
+#define PL0_W (0x01 | PL1_W)
183
+
184
+/*
185
+ * For user-mode some registers are accessible to EL0 via a kernel
186
+ * trap-and-emulate ABI. In this case we define the read permissions
187
+ * as actually being PL0_R. However some bits of any given register
188
+ * may still be masked.
189
+ */
190
+#ifdef CONFIG_USER_ONLY
191
+#define PL0U_R PL0_R
192
+#else
193
+#define PL0U_R PL1_R
194
+#endif
195
+
196
+#define PL3_RW (PL3_R | PL3_W)
197
+#define PL2_RW (PL2_R | PL2_W)
198
+#define PL1_RW (PL1_R | PL1_W)
199
+#define PL0_RW (PL0_R | PL0_W)
200
+
201
+typedef enum CPAccessResult {
202
+ /* Access is permitted */
203
+ CP_ACCESS_OK = 0,
204
+ /*
205
+ * Access fails due to a configurable trap or enable which would
206
+ * result in a categorized exception syndrome giving information about
207
+ * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
208
+ * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
209
+ * PL1 if in EL0, otherwise to the current EL).
210
+ */
211
+ CP_ACCESS_TRAP = 1,
212
+ /*
213
+ * Access fails and results in an exception syndrome 0x0 ("uncategorized").
214
+ * Note that this is not a catch-all case -- the set of cases which may
215
+ * result in this failure is specifically defined by the architecture.
216
+ */
217
+ CP_ACCESS_TRAP_UNCATEGORIZED = 2,
218
+ /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
219
+ CP_ACCESS_TRAP_EL2 = 3,
220
+ CP_ACCESS_TRAP_EL3 = 4,
221
+ /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
222
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
223
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
224
+} CPAccessResult;
225
+
226
+typedef struct ARMCPRegInfo ARMCPRegInfo;
227
+
228
+/*
229
+ * Access functions for coprocessor registers. These cannot fail and
230
+ * may not raise exceptions.
231
+ */
232
+typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
233
+typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
234
+ uint64_t value);
235
+/* Access permission check functions for coprocessor registers. */
236
+typedef CPAccessResult CPAccessFn(CPUARMState *env,
237
+ const ARMCPRegInfo *opaque,
238
+ bool isread);
239
+/* Hook function for register reset */
240
+typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
241
+
242
+#define CP_ANY 0xff
243
+
244
+/* Definition of an ARM coprocessor register */
245
+struct ARMCPRegInfo {
246
+ /* Name of register (useful mainly for debugging, need not be unique) */
247
+ const char *name;
248
+ /*
249
+ * Location of register: coprocessor number and (crn,crm,opc1,opc2)
250
+ * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
251
+ * 'wildcard' field -- any value of that field in the MRC/MCR insn
252
+ * will be decoded to this register. The register read and write
253
+ * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
254
+ * used by the program, so it is possible to register a wildcard and
255
+ * then behave differently on read/write if necessary.
256
+ * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
257
+ * must both be zero.
258
+ * For AArch64-visible registers, opc0 is also used.
259
+ * Since there are no "coprocessors" in AArch64, cp is purely used as a
260
+ * way to distinguish (for KVM's benefit) guest-visible system registers
261
+ * from demuxed ones provided to preserve the "no side effects on
262
+ * KVM register read/write from QEMU" semantics. cp==0x13 is guest
263
+ * visible (to match KVM's encoding); cp==0 will be converted to
264
+ * cp==0x13 when the ARMCPRegInfo is registered, for convenience.
265
+ */
266
+ uint8_t cp;
267
+ uint8_t crn;
268
+ uint8_t crm;
269
+ uint8_t opc0;
270
+ uint8_t opc1;
271
+ uint8_t opc2;
272
+ /* Execution state in which this register is visible: ARM_CP_STATE_* */
273
+ int state;
274
+ /* Register type: ARM_CP_* bits/values */
275
+ int type;
276
+ /* Access rights: PL*_[RW] */
277
+ int access;
278
+ /* Security state: ARM_CP_SECSTATE_* bits/values */
279
+ int secure;
280
+ /*
281
+ * The opaque pointer passed to define_arm_cp_regs_with_opaque() when
282
+ * this register was defined: can be used to hand data through to the
283
+ * register read/write functions, since they are passed the ARMCPRegInfo*.
284
+ */
285
+ void *opaque;
286
+ /*
287
+ * Value of this register, if it is ARM_CP_CONST. Otherwise, if
288
+ * fieldoffset is non-zero, the reset value of the register.
289
+ */
290
+ uint64_t resetvalue;
291
+ /*
292
+ * Offset of the field in CPUARMState for this register.
293
+ * This is not needed if either:
294
+ * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
295
+ * 2. both readfn and writefn are specified
296
+ */
297
+ ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
298
+
299
+ /*
300
+ * Offsets of the secure and non-secure fields in CPUARMState for the
301
+ * register if it is banked. These fields are only used during the static
302
+ * registration of a register. During hashing the bank associated
303
+ * with a given security state is copied to fieldoffset which is used from
304
+ * there on out.
305
+ *
306
+ * It is expected that register definitions use either fieldoffset or
307
+ * bank_fieldoffsets in the definition but not both. It is also expected
308
+ * that both bank offsets are set when defining a banked register. This
309
+ * use indicates that a register is banked.
310
+ */
311
+ ptrdiff_t bank_fieldoffsets[2];
312
+
313
+ /*
314
+ * Function for making any access checks for this register in addition to
315
+ * those specified by the 'access' permissions bits. If NULL, no extra
316
+ * checks required. The access check is performed at runtime, not at
317
+ * translate time.
318
+ */
319
+ CPAccessFn *accessfn;
320
+ /*
321
+ * Function for handling reads of this register. If NULL, then reads
322
+ * will be done by loading from the offset into CPUARMState specified
323
+ * by fieldoffset.
324
+ */
325
+ CPReadFn *readfn;
326
+ /*
327
+ * Function for handling writes of this register. If NULL, then writes
328
+ * will be done by writing to the offset into CPUARMState specified
329
+ * by fieldoffset.
330
+ */
331
+ CPWriteFn *writefn;
332
+ /*
333
+ * Function for doing a "raw" read; used when we need to copy
334
+ * coprocessor state to the kernel for KVM or out for
335
+ * migration. This only needs to be provided if there is also a
336
+ * readfn and it has side effects (for instance clear-on-read bits).
337
+ */
338
+ CPReadFn *raw_readfn;
339
+ /*
340
+ * Function for doing a "raw" write; used when we need to copy KVM
341
+ * kernel coprocessor state into userspace, or for inbound
342
+ * migration. This only needs to be provided if there is also a
343
+ * writefn and it masks out "unwritable" bits or has write-one-to-clear
344
+ * or similar behaviour.
345
+ */
346
+ CPWriteFn *raw_writefn;
347
+ /*
348
+ * Function for resetting the register. If NULL, then reset will be done
349
+ * by writing resetvalue to the field specified in fieldoffset. If
350
+ * fieldoffset is 0 then no reset will be done.
351
+ */
352
+ CPResetFn *resetfn;
353
+
354
+ /*
355
+ * "Original" writefn and readfn.
356
+ * For ARMv8.1-VHE register aliases, we overwrite the read/write
357
+ * accessor functions of various EL1/EL0 to perform the runtime
358
+ * check for which sysreg should actually be modified, and then
359
+ * forwards the operation. Before overwriting the accessors,
360
+ * the original function is copied here, so that accesses that
361
+ * really do go to the EL1/EL0 version proceed normally.
362
+ * (The corresponding EL2 register is linked via opaque.)
363
+ */
364
+ CPReadFn *orig_readfn;
365
+ CPWriteFn *orig_writefn;
366
+};
367
+
368
+/*
369
+ * Macros which are lvalues for the field in CPUARMState for the
370
+ * ARMCPRegInfo *ri.
371
+ */
372
+#define CPREG_FIELD32(env, ri) \
373
+ (*(uint32_t *)((char *)(env) + (ri)->fieldoffset))
374
+#define CPREG_FIELD64(env, ri) \
375
+ (*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
376
+
377
+#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
378
+
379
+void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
380
+ const ARMCPRegInfo *regs, void *opaque);
381
+void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
382
+ const ARMCPRegInfo *regs, void *opaque);
383
+static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
384
+{
385
+ define_arm_cp_regs_with_opaque(cpu, regs, 0);
386
+}
387
+static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
388
+{
389
+ define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
390
+}
391
+const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
392
+
393
+/*
394
+ * Definition of an ARM co-processor register as viewed from
395
+ * userspace. This is used for presenting sanitised versions of
396
+ * registers to userspace when emulating the Linux AArch64 CPU
397
+ * ID/feature ABI (advertised as HWCAP_CPUID).
398
+ */
399
+typedef struct ARMCPRegUserSpaceInfo {
400
+ /* Name of register */
401
+ const char *name;
402
+
403
+ /* Is the name actually a glob pattern */
404
+ bool is_glob;
405
+
406
+ /* Only some bits are exported to user space */
407
+ uint64_t exported_bits;
408
+
409
+ /* Fixed bits are applied after the mask */
410
+ uint64_t fixed_bits;
411
+} ARMCPRegUserSpaceInfo;
412
+
413
+#define REGUSERINFO_SENTINEL { .name = NULL }
414
+
415
+void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods);
416
+
417
+/* CPWriteFn that can be used to implement writes-ignored behaviour */
418
+void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
419
+ uint64_t value);
420
+/* CPReadFn that can be used for read-as-zero behaviour */
421
+uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
422
+
423
+/*
424
+ * CPResetFn that does nothing, for use if no reset is required even
425
+ * if fieldoffset is non zero.
426
+ */
427
+void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
428
+
429
+/*
430
+ * Return true if this reginfo struct's field in the cpu state struct
431
+ * is 64 bits wide.
432
+ */
433
+static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
434
+{
435
+ return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);
436
+}
437
+
438
+static inline bool cp_access_ok(int current_el,
439
+ const ARMCPRegInfo *ri, int isread)
440
+{
441
+ return (ri->access >> ((current_el * 2) + isread)) & 1;
442
+}
443
+
444
+/* Raw read of a coprocessor register (as needed for migration, etc) */
445
+uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri);
446
+
447
+#endif /* TARGET_ARM_CPREGS_H */
448
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
449
index XXXXXXX..XXXXXXX 100644
450
--- a/target/arm/cpu.h
451
+++ b/target/arm/cpu.h
452
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
453
return kvmid;
454
}
455
456
-/* ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
457
- * special-behaviour cp reg and bits [11..8] indicate what behaviour
458
- * it has. Otherwise it is a simple cp reg, where CONST indicates that
459
- * TCG can assume the value to be constant (ie load at translate time)
460
- * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
461
- * indicates that the TB should not be ended after a write to this register
462
- * (the default is that the TB ends after cp writes). OVERRIDE permits
463
- * a register definition to override a previous definition for the
464
- * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
465
- * old must have the OVERRIDE bit set.
466
- * ALIAS indicates that this register is an alias view of some underlying
467
- * state which is also visible via another register, and that the other
468
- * register is handling migration and reset; registers marked ALIAS will not be
469
- * migrated but may have their state set by syncing of register state from KVM.
470
- * NO_RAW indicates that this register has no underlying state and does not
471
- * support raw access for state saving/loading; it will not be used for either
472
- * migration or KVM state synchronization. (Typically this is for "registers"
473
- * which are actually used as instructions for cache maintenance and so on.)
474
- * IO indicates that this register does I/O and therefore its accesses
475
- * need to be marked with gen_io_start() and also end the TB. In particular,
476
- * registers which implement clocks or timers require this.
477
- * RAISES_EXC is for when the read or write hook might raise an exception;
478
- * the generated code will synchronize the CPU state before calling the hook
479
- * so that it is safe for the hook to call raise_exception().
480
- * NEWEL is for writes to registers that might change the exception
481
- * level - typically on older ARM chips. For those cases we need to
482
- * re-read the new el when recomputing the translation flags.
483
- */
484
-#define ARM_CP_SPECIAL 0x0001
485
-#define ARM_CP_CONST 0x0002
486
-#define ARM_CP_64BIT 0x0004
487
-#define ARM_CP_SUPPRESS_TB_END 0x0008
488
-#define ARM_CP_OVERRIDE 0x0010
489
-#define ARM_CP_ALIAS 0x0020
490
-#define ARM_CP_IO 0x0040
491
-#define ARM_CP_NO_RAW 0x0080
492
-#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
493
-#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
494
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
495
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
496
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
497
-#define ARM_CP_DC_GVA (ARM_CP_SPECIAL | 0x0600)
498
-#define ARM_CP_DC_GZVA (ARM_CP_SPECIAL | 0x0700)
499
-#define ARM_LAST_SPECIAL ARM_CP_DC_GZVA
500
-#define ARM_CP_FPU 0x1000
501
-#define ARM_CP_SVE 0x2000
502
-#define ARM_CP_NO_GDB 0x4000
503
-#define ARM_CP_RAISES_EXC 0x8000
504
-#define ARM_CP_NEWEL 0x10000
505
-/* Used only as a terminator for ARMCPRegInfo lists */
506
-#define ARM_CP_SENTINEL 0xfffff
507
-/* Mask of only the flag bits in a type field */
508
-#define ARM_CP_FLAG_MASK 0x1f0ff
509
-
510
-/* Valid values for ARMCPRegInfo state field, indicating which of
511
- * the AArch32 and AArch64 execution states this register is visible in.
512
- * If the reginfo doesn't explicitly specify then it is AArch32 only.
513
- * If the reginfo is declared to be visible in both states then a second
514
- * reginfo is synthesised for the AArch32 view of the AArch64 register,
515
- * such that the AArch32 view is the lower 32 bits of the AArch64 one.
516
- * Note that we rely on the values of these enums as we iterate through
517
- * the various states in some places.
518
- */
519
-enum {
520
- ARM_CP_STATE_AA32 = 0,
521
- ARM_CP_STATE_AA64 = 1,
522
- ARM_CP_STATE_BOTH = 2,
523
-};
524
-
525
-/* ARM CP register secure state flags. These flags identify security state
526
- * attributes for a given CP register entry.
527
- * The existence of both or neither secure and non-secure flags indicates that
528
- * the register has both a secure and non-secure hash entry. A single one of
529
- * these flags causes the register to only be hashed for the specified
530
- * security state.
531
- * Although definitions may have any combination of the S/NS bits, each
532
- * registered entry will only have one to identify whether the entry is secure
533
- * or non-secure.
534
- */
535
-enum {
536
- ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
537
- ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
538
-};
539
-
540
-/* Return true if cptype is a valid type field. This is used to try to
541
- * catch errors where the sentinel has been accidentally left off the end
542
- * of a list of registers.
543
- */
544
-static inline bool cptype_valid(int cptype)
545
-{
546
- return ((cptype & ~ARM_CP_FLAG_MASK) == 0)
547
- || ((cptype & ARM_CP_SPECIAL) &&
548
- ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL));
549
-}
550
-
551
-/* Access rights:
552
- * We define bits for Read and Write access for what rev C of the v7-AR ARM ARM
553
- * defines as PL0 (user), PL1 (fiq/irq/svc/abt/und/sys, ie privileged), and
554
- * PL2 (hyp). The other level which has Read and Write bits is Secure PL1
555
- * (ie any of the privileged modes in Secure state, or Monitor mode).
556
- * If a register is accessible in one privilege level it's always accessible
557
- * in higher privilege levels too. Since "Secure PL1" also follows this rule
558
- * (ie anything visible in PL2 is visible in S-PL1, some things are only
559
- * visible in S-PL1) but "Secure PL1" is a bit of a mouthful, we bend the
560
- * terminology a little and call this PL3.
561
- * In AArch64 things are somewhat simpler as the PLx bits line up exactly
562
- * with the ELx exception levels.
563
- *
564
- * If access permissions for a register are more complex than can be
565
- * described with these bits, then use a laxer set of restrictions, and
566
- * do the more restrictive/complex check inside a helper function.
567
- */
568
-#define PL3_R 0x80
569
-#define PL3_W 0x40
570
-#define PL2_R (0x20 | PL3_R)
571
-#define PL2_W (0x10 | PL3_W)
572
-#define PL1_R (0x08 | PL2_R)
573
-#define PL1_W (0x04 | PL2_W)
574
-#define PL0_R (0x02 | PL1_R)
575
-#define PL0_W (0x01 | PL1_W)
576
-
577
-/*
578
- * For user-mode some registers are accessible to EL0 via a kernel
579
- * trap-and-emulate ABI. In this case we define the read permissions
580
- * as actually being PL0_R. However some bits of any given register
581
- * may still be masked.
582
- */
583
-#ifdef CONFIG_USER_ONLY
584
-#define PL0U_R PL0_R
585
-#else
586
-#define PL0U_R PL1_R
587
-#endif
588
-
589
-#define PL3_RW (PL3_R | PL3_W)
590
-#define PL2_RW (PL2_R | PL2_W)
591
-#define PL1_RW (PL1_R | PL1_W)
592
-#define PL0_RW (PL0_R | PL0_W)
593
-
594
/* Return the highest implemented Exception Level */
595
static inline int arm_highest_el(CPUARMState *env)
30
{
596
{
31
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg)
597
@@ -XXX,XX +XXX,XX @@ static inline int arm_current_el(CPUARMState *env)
32
return tmp;
598
}
33
}
599
}
34
600
35
+void store_reg(DisasContext *s, int reg, TCGv_i32 var);
601
-typedef struct ARMCPRegInfo ARMCPRegInfo;
36
+
602
-
37
void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
603
-typedef enum CPAccessResult {
38
TCGv_i32 a32, int index, MemOp opc);
604
- /* Access is permitted */
39
void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
605
- CP_ACCESS_OK = 0,
40
@@ -XXX,XX +XXX,XX @@ DO_GEN_ST(32, MO_UL)
606
- /* Access fails due to a configurable trap or enable which would
41
#undef DO_GEN_LD
607
- * result in a categorized exception syndrome giving information about
42
#undef DO_GEN_ST
608
- * the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
43
609
- * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
44
+#if defined(CONFIG_USER_ONLY)
610
- * PL1 if in EL0, otherwise to the current EL).
45
+#define IS_USER(s) 1
611
- */
46
+#else
612
- CP_ACCESS_TRAP = 1,
47
+#define IS_USER(s) (s->user)
613
- /* Access fails and results in an exception syndrome 0x0 ("uncategorized").
48
+#endif
614
- * Note that this is not a catch-all case -- the set of cases which may
49
+
615
- * result in this failure is specifically defined by the architecture.
50
+/* Set NZCV flags from the high 4 bits of var. */
616
- */
51
+#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
617
- CP_ACCESS_TRAP_UNCATEGORIZED = 2,
52
+
618
- /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
619
- CP_ACCESS_TRAP_EL2 = 3,
620
- CP_ACCESS_TRAP_EL3 = 4,
621
- /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
622
- CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
623
- CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
624
-} CPAccessResult;
625
-
626
-/* Access functions for coprocessor registers. These cannot fail and
627
- * may not raise exceptions.
628
- */
629
-typedef uint64_t CPReadFn(CPUARMState *env, const ARMCPRegInfo *opaque);
630
-typedef void CPWriteFn(CPUARMState *env, const ARMCPRegInfo *opaque,
631
- uint64_t value);
632
-/* Access permission check functions for coprocessor registers. */
633
-typedef CPAccessResult CPAccessFn(CPUARMState *env,
634
- const ARMCPRegInfo *opaque,
635
- bool isread);
636
-/* Hook function for register reset */
637
-typedef void CPResetFn(CPUARMState *env, const ARMCPRegInfo *opaque);
638
-
639
-#define CP_ANY 0xff
640
-
641
-/* Definition of an ARM coprocessor register */
642
-struct ARMCPRegInfo {
643
- /* Name of register (useful mainly for debugging, need not be unique) */
644
- const char *name;
645
- /* Location of register: coprocessor number and (crn,crm,opc1,opc2)
646
- * tuple. Any of crm, opc1 and opc2 may be CP_ANY to indicate a
647
- * 'wildcard' field -- any value of that field in the MRC/MCR insn
648
- * will be decoded to this register. The register read and write
649
- * callbacks will be passed an ARMCPRegInfo with the crn/crm/opc1/opc2
650
- * used by the program, so it is possible to register a wildcard and
651
- * then behave differently on read/write if necessary.
652
- * For 64 bit registers, only crm and opc1 are relevant; crn and opc2
653
- * must both be zero.
654
- * For AArch64-visible registers, opc0 is also used.
655
- * Since there are no "coprocessors" in AArch64, cp is purely used as a
656
- * way to distinguish (for KVM's benefit) guest-visible system registers
657
- * from demuxed ones provided to preserve the "no side effects on
658
- * KVM register read/write from QEMU" semantics. cp==0x13 is guest
659
- * visible (to match KVM's encoding); cp==0 will be converted to
660
- * cp==0x13 when the ARMCPRegInfo is registered, for convenience.
661
- */
662
- uint8_t cp;
663
- uint8_t crn;
664
- uint8_t crm;
665
- uint8_t opc0;
666
- uint8_t opc1;
667
- uint8_t opc2;
668
- /* Execution state in which this register is visible: ARM_CP_STATE_* */
669
- int state;
670
- /* Register type: ARM_CP_* bits/values */
671
- int type;
672
- /* Access rights: PL*_[RW] */
673
- int access;
674
- /* Security state: ARM_CP_SECSTATE_* bits/values */
675
- int secure;
676
- /* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
677
- * this register was defined: can be used to hand data through to the
678
- * register read/write functions, since they are passed the ARMCPRegInfo*.
679
- */
680
- void *opaque;
681
- /* Value of this register, if it is ARM_CP_CONST. Otherwise, if
682
- * fieldoffset is non-zero, the reset value of the register.
683
- */
684
- uint64_t resetvalue;
685
- /* Offset of the field in CPUARMState for this register.
686
- *
687
- * This is not needed if either:
688
- * 1. type is ARM_CP_CONST or one of the ARM_CP_SPECIALs
689
- * 2. both readfn and writefn are specified
690
- */
691
- ptrdiff_t fieldoffset; /* offsetof(CPUARMState, field) */
692
-
693
- /* Offsets of the secure and non-secure fields in CPUARMState for the
694
- * register if it is banked. These fields are only used during the static
695
- * registration of a register. During hashing the bank associated
696
- * with a given security state is copied to fieldoffset which is used from
697
- * there on out.
698
- *
699
- * It is expected that register definitions use either fieldoffset or
700
- * bank_fieldoffsets in the definition but not both. It is also expected
701
- * that both bank offsets are set when defining a banked register. This
702
- * use indicates that a register is banked.
703
- */
704
- ptrdiff_t bank_fieldoffsets[2];
705
-
706
- /* Function for making any access checks for this register in addition to
707
- * those specified by the 'access' permissions bits. If NULL, no extra
708
- * checks required. The access check is performed at runtime, not at
709
- * translate time.
710
- */
711
- CPAccessFn *accessfn;
712
- /* Function for handling reads of this register. If NULL, then reads
713
- * will be done by loading from the offset into CPUARMState specified
714
- * by fieldoffset.
715
- */
716
- CPReadFn *readfn;
717
- /* Function for handling writes of this register. If NULL, then writes
718
- * will be done by writing to the offset into CPUARMState specified
719
- * by fieldoffset.
720
- */
721
- CPWriteFn *writefn;
722
- /* Function for doing a "raw" read; used when we need to copy
723
- * coprocessor state to the kernel for KVM or out for
724
- * migration. This only needs to be provided if there is also a
725
- * readfn and it has side effects (for instance clear-on-read bits).
726
- */
727
- CPReadFn *raw_readfn;
728
- /* Function for doing a "raw" write; used when we need to copy KVM
729
- * kernel coprocessor state into userspace, or for inbound
730
- * migration. This only needs to be provided if there is also a
731
- * writefn and it masks out "unwritable" bits or has write-one-to-clear
732
- * or similar behaviour.
733
- */
734
- CPWriteFn *raw_writefn;
735
- /* Function for resetting the register. If NULL, then reset will be done
736
- * by writing resetvalue to the field specified in fieldoffset. If
737
- * fieldoffset is 0 then no reset will be done.
738
- */
739
- CPResetFn *resetfn;
740
-
741
- /*
742
- * "Original" writefn and readfn.
743
- * For ARMv8.1-VHE register aliases, we overwrite the read/write
744
- * accessor functions of various EL1/EL0 to perform the runtime
745
- * check for which sysreg should actually be modified, and then
746
- * forwards the operation. Before overwriting the accessors,
747
- * the original function is copied here, so that accesses that
748
- * really do go to the EL1/EL0 version proceed normally.
749
- * (The corresponding EL2 register is linked via opaque.)
750
- */
751
- CPReadFn *orig_readfn;
752
- CPWriteFn *orig_writefn;
753
-};
754
-
755
-/* Macros which are lvalues for the field in CPUARMState for the
756
- * ARMCPRegInfo *ri.
757
- */
758
-#define CPREG_FIELD32(env, ri) \
759
- (*(uint32_t *)((char *)(env) + (ri)->fieldoffset))
760
-#define CPREG_FIELD64(env, ri) \
761
- (*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
762
-
763
-#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
764
-
765
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
766
- const ARMCPRegInfo *regs, void *opaque);
767
-void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
768
- const ARMCPRegInfo *regs, void *opaque);
769
-static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
770
-{
771
- define_arm_cp_regs_with_opaque(cpu, regs, 0);
772
-}
773
-static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
774
-{
775
- define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
776
-}
777
-const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
778
-
779
-/*
780
- * Definition of an ARM co-processor register as viewed from
781
- * userspace. This is used for presenting sanitised versions of
782
- * registers to userspace when emulating the Linux AArch64 CPU
783
- * ID/feature ABI (advertised as HWCAP_CPUID).
784
- */
785
-typedef struct ARMCPRegUserSpaceInfo {
786
- /* Name of register */
787
- const char *name;
788
-
789
- /* Is the name actually a glob pattern */
790
- bool is_glob;
791
-
792
- /* Only some bits are exported to user space */
793
- uint64_t exported_bits;
794
-
795
- /* Fixed bits are applied after the mask */
796
- uint64_t fixed_bits;
797
-} ARMCPRegUserSpaceInfo;
798
-
799
-#define REGUSERINFO_SENTINEL { .name = NULL }
800
-
801
-void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods);
802
-
803
-/* CPWriteFn that can be used to implement writes-ignored behaviour */
804
-void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
805
- uint64_t value);
806
-/* CPReadFn that can be used for read-as-zero behaviour */
807
-uint64_t arm_cp_read_zero(CPUARMState *env, const ARMCPRegInfo *ri);
808
-
809
-/* CPResetFn that does nothing, for use if no reset is required even
810
- * if fieldoffset is non zero.
811
- */
812
-void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque);
813
-
814
-/* Return true if this reginfo struct's field in the cpu state struct
815
- * is 64 bits wide.
816
- */
817
-static inline bool cpreg_field_is_64bit(const ARMCPRegInfo *ri)
818
-{
819
- return (ri->state == ARM_CP_STATE_AA64) || (ri->type & ARM_CP_64BIT);
820
-}
821
-
822
-static inline bool cp_access_ok(int current_el,
823
- const ARMCPRegInfo *ri, int isread)
824
-{
825
- return (ri->access >> ((current_el * 2) + isread)) & 1;
826
-}
827
-
828
-/* Raw read of a coprocessor register (as needed for migration, etc) */
829
-uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri);
830
-
831
/**
832
* write_list_to_cpustate
833
* @cpu: ARMCPU
834
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
835
index XXXXXXX..XXXXXXX 100644
836
--- a/hw/arm/pxa2xx.c
837
+++ b/hw/arm/pxa2xx.c
838
@@ -XXX,XX +XXX,XX @@
839
#include "qemu/cutils.h"
840
#include "qemu/log.h"
841
#include "qom/object.h"
842
+#include "target/arm/cpregs.h"
843
844
static struct {
845
hwaddr io_base;
846
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
847
index XXXXXXX..XXXXXXX 100644
848
--- a/hw/arm/pxa2xx_pic.c
849
+++ b/hw/arm/pxa2xx_pic.c
850
@@ -XXX,XX +XXX,XX @@
851
#include "hw/sysbus.h"
852
#include "migration/vmstate.h"
853
#include "qom/object.h"
854
+#include "target/arm/cpregs.h"
855
856
#define ICIP    0x00    /* Interrupt Controller IRQ Pending register */
857
#define ICMR    0x04    /* Interrupt Controller Mask register */
858
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
859
index XXXXXXX..XXXXXXX 100644
860
--- a/hw/intc/arm_gicv3_cpuif.c
861
+++ b/hw/intc/arm_gicv3_cpuif.c
862
@@ -XXX,XX +XXX,XX @@
863
#include "gicv3_internal.h"
864
#include "hw/irq.h"
865
#include "cpu.h"
866
+#include "target/arm/cpregs.h"
867
868
/*
869
* Special case return value from hppvi_index(); must be larger than
870
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
871
index XXXXXXX..XXXXXXX 100644
872
--- a/hw/intc/arm_gicv3_kvm.c
873
+++ b/hw/intc/arm_gicv3_kvm.c
874
@@ -XXX,XX +XXX,XX @@
875
#include "vgic_common.h"
876
#include "migration/blocker.h"
877
#include "qom/object.h"
878
+#include "target/arm/cpregs.h"
879
+
880
881
#ifdef DEBUG_GICV3_KVM
882
#define DPRINTF(fmt, ...) \
883
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
884
index XXXXXXX..XXXXXXX 100644
885
--- a/target/arm/cpu.c
886
+++ b/target/arm/cpu.c
887
@@ -XXX,XX +XXX,XX @@
888
#include "kvm_arm.h"
889
#include "disas/capstone.h"
890
#include "fpu/softfloat.h"
891
+#include "cpregs.h"
892
893
static void arm_cpu_set_pc(CPUState *cs, vaddr value)
894
{
895
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
896
index XXXXXXX..XXXXXXX 100644
897
--- a/target/arm/cpu64.c
898
+++ b/target/arm/cpu64.c
899
@@ -XXX,XX +XXX,XX @@
900
#include "hvf_arm.h"
901
#include "qapi/visitor.h"
902
#include "hw/qdev-properties.h"
903
+#include "cpregs.h"
904
905
906
#ifndef CONFIG_USER_ONLY
907
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
908
index XXXXXXX..XXXXXXX 100644
909
--- a/target/arm/cpu_tcg.c
910
+++ b/target/arm/cpu_tcg.c
911
@@ -XXX,XX +XXX,XX @@
912
#if !defined(CONFIG_USER_ONLY)
913
#include "hw/boards.h"
53
#endif
914
#endif
915
+#include "cpregs.h"
916
917
/* CPU models. These are not needed for the AArch64 linux-user build. */
918
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
919
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
920
index XXXXXXX..XXXXXXX 100644
921
--- a/target/arm/gdbstub.c
922
+++ b/target/arm/gdbstub.c
923
@@ -XXX,XX +XXX,XX @@
924
*/
925
#include "qemu/osdep.h"
926
#include "cpu.h"
927
-#include "internals.h"
928
#include "exec/gdbstub.h"
929
+#include "internals.h"
930
+#include "cpregs.h"
931
932
typedef struct RegisterSysregXmlParam {
933
CPUState *cs;
934
diff --git a/target/arm/helper.c b/target/arm/helper.c
935
index XXXXXXX..XXXXXXX 100644
936
--- a/target/arm/helper.c
937
+++ b/target/arm/helper.c
938
@@ -XXX,XX +XXX,XX @@
939
#include "exec/cpu_ldst.h"
940
#include "semihosting/common-semi.h"
941
#endif
942
+#include "cpregs.h"
943
944
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
945
#define PMCR_NUM_COUNTERS 4 /* QEMU IMPDEF choice */
946
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
947
index XXXXXXX..XXXXXXX 100644
948
--- a/target/arm/op_helper.c
949
+++ b/target/arm/op_helper.c
950
@@ -XXX,XX +XXX,XX @@
951
#include "internals.h"
952
#include "exec/exec-all.h"
953
#include "exec/cpu_ldst.h"
954
+#include "cpregs.h"
955
956
#define SIGNBIT (uint32_t)0x80000000
957
#define SIGNBIT64 ((uint64_t)1 << 63)
958
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
959
index XXXXXXX..XXXXXXX 100644
960
--- a/target/arm/translate-a64.c
961
+++ b/target/arm/translate-a64.c
962
@@ -XXX,XX +XXX,XX @@
963
#include "translate.h"
964
#include "internals.h"
965
#include "qemu/host-utils.h"
966
-
967
#include "semihosting/semihost.h"
968
#include "exec/gen-icount.h"
969
-
970
#include "exec/helper-proto.h"
971
#include "exec/helper-gen.h"
972
#include "exec/log.h"
973
-
974
+#include "cpregs.h"
975
#include "translate-a64.h"
976
#include "qemu/atomic128.h"
977
54
diff --git a/target/arm/translate.c b/target/arm/translate.c
978
diff --git a/target/arm/translate.c b/target/arm/translate.c
55
index XXXXXXX..XXXXXXX 100644
979
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/translate.c
980
--- a/target/arm/translate.c
57
+++ b/target/arm/translate.c
981
+++ b/target/arm/translate.c
58
@@ -XXX,XX +XXX,XX @@
982
@@ -XXX,XX +XXX,XX @@
59
#include "translate.h"
983
#include "qemu/bitops.h"
60
#include "translate-a32.h"
984
#include "arm_ldst.h"
61
985
#include "semihosting/semihost.h"
62
-#if defined(CONFIG_USER_ONLY)
986
-
63
-#define IS_USER(s) 1
987
#include "exec/helper-proto.h"
64
-#else
988
#include "exec/helper-gen.h"
65
-#define IS_USER(s) (s->user)
989
-
66
-#endif
990
#include "exec/log.h"
67
-
991
+#include "cpregs.h"
68
/* These are TCG temporaries used only by the legacy iwMMXt decoder */
992
69
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
993
70
/* These are TCG globals which alias CPUARMState fields */
994
#define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
71
@@ -XXX,XX +XXX,XX @@ void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
72
* This is used for load/store for which use of PC implies (literal),
73
* or ADD that implies ADR.
74
*/
75
-static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
76
+TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
77
{
78
TCGv_i32 tmp = tcg_temp_new_i32();
79
80
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
81
82
/* Set a CPU register. The source must be a temporary and will be
83
marked as dead. */
84
-static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
85
+void store_reg(DisasContext *s, int reg, TCGv_i32 var)
86
{
87
if (reg == 15) {
88
/* In Thumb mode, we must ignore bit 0.
89
@@ -XXX,XX +XXX,XX @@ static void store_sp_checked(DisasContext *s, TCGv_i32 var)
90
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
91
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
92
93
-
94
-static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
95
+void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
96
{
97
TCGv_i32 tmp_mask = tcg_const_i32(mask);
98
gen_helper_cpsr_write(cpu_env, var, tmp_mask);
99
tcg_temp_free_i32(tmp_mask);
100
}
101
-/* Set NZCV flags from the high 4 bits of var. */
102
-#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
103
104
static void gen_exception_internal(int excp)
105
{
106
@@ -XXX,XX +XXX,XX @@ void arm_gen_test_cc(int cc, TCGLabel *label)
107
arm_free_cc(&cmp);
108
}
109
110
-static inline void gen_set_condexec(DisasContext *s)
111
+void gen_set_condexec(DisasContext *s)
112
{
113
if (s->condexec_mask) {
114
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
115
@@ -XXX,XX +XXX,XX @@ static inline void gen_set_condexec(DisasContext *s)
116
}
117
}
118
119
-static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
120
+void gen_set_pc_im(DisasContext *s, target_ulong val)
121
{
122
tcg_gen_movi_i32(cpu_R[15], val);
123
}
124
@@ -XXX,XX +XXX,XX @@ static void gen_exception_el(DisasContext *s, int excp, uint32_t syn,
125
}
126
127
/* Force a TB lookup after an instruction that changes the CPU state. */
128
-static inline void gen_lookup_tb(DisasContext *s)
129
+void gen_lookup_tb(DisasContext *s)
130
{
131
tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
132
s->base.is_jmp = DISAS_EXIT;
133
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
134
/*
135
* Return the offset of a "full" NEON Dreg.
136
*/
137
-static long neon_full_reg_offset(unsigned reg)
138
+long neon_full_reg_offset(unsigned reg)
139
{
140
return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
141
}
142
@@ -XXX,XX +XXX,XX @@ static long neon_element_offset(int reg, int element, MemOp memop)
143
}
144
145
/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
146
-static long vfp_reg_offset(bool dp, unsigned reg)
147
+long vfp_reg_offset(bool dp, unsigned reg)
148
{
149
if (dp) {
150
return neon_element_offset(reg, 0, MO_64);
151
--
995
--
152
2.20.1
996
2.25.1
153
997
154
998
diff view generated by jsdifflib
1
The WFI insn is not system-mode only, though it doesn't usually make
1
From: Richard Henderson <richard.henderson@linaro.org>
2
a huge amount of sense for userspace code to execute it. Currently
3
if you try it in qemu-arm then the helper function will raise an
4
EXCP_HLT exception, which is not covered by the switch in cpu_loop()
5
and results in an abort:
6
2
7
qemu: unhandled CPU exception 0x10001 - aborting
3
Rearrange the values of the enumerators of CPAccessResult
8
R00=00000001 R01=408003e4 R02=408003ec R03=000102ec
4
so that we may directly extract the target el. For the two
9
R04=00010a28 R05=00010158 R06=00087460 R07=00010158
5
special cases in access_check_cp_reg, use CPAccessResult.
10
R08=00000000 R09=00000000 R10=00085b7c R11=408002a4
11
R12=408002b8 R13=408002a0 R14=0001057c R15=000102f8
12
PSR=60000010 -ZC- A usr32
13
qemu:handle_cpu_signal received signal outside vCPU context @ pc=0x7fcbfa4f0a12
14
6
15
Make the WFI helper function return immediately in the usermode
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
emulator. This turns WFI into a NOP, which is OK because:
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
* architecturally "WFI is a NOP" is a permitted implementation
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
* aarch64 Linux kernels use the SCTLR_EL1.nTWI bit to trap
10
Message-id: 20220501055028.646596-3-richard.henderson@linaro.org
19
userspace WFI and NOP it (though aarch32 kernels currently
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
just let WFI do whatever it would do)
12
---
13
target/arm/cpregs.h | 26 ++++++++++++--------
14
target/arm/op_helper.c | 56 +++++++++++++++++++++---------------------
15
2 files changed, 44 insertions(+), 38 deletions(-)
21
16
22
We could in theory make the translate.c code special case user-mode
17
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
23
emulation and NOP the insn entirely rather than making the helper
18
index XXXXXXX..XXXXXXX 100644
24
do nothing, but because no real world code will be trying to
19
--- a/target/arm/cpregs.h
25
execute WFI we don't care about efficiency and the helper provides
20
+++ b/target/arm/cpregs.h
26
a single place where we can make the change rather than having
21
@@ -XXX,XX +XXX,XX @@ static inline bool cptype_valid(int cptype)
27
to touch multiple places in translate.c and translate-a64.c.
22
typedef enum CPAccessResult {
28
23
/* Access is permitted */
29
Fixes: https://bugs.launchpad.net/qemu/+bug/1926759
24
CP_ACCESS_OK = 0,
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
+
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
+ /*
32
Message-id: 20210430162212.825-1-peter.maydell@linaro.org
27
+ * Combined with one of the following, the low 2 bits indicate the
33
---
28
+ * target exception level. If 0, the exception is taken to the usual
34
target/arm/op_helper.c | 12 ++++++++++++
29
+ * target EL (EL1 or PL1 if in EL0, otherwise to the current EL).
35
1 file changed, 12 insertions(+)
30
+ */
36
31
+ CP_ACCESS_EL_MASK = 3,
32
+
33
/*
34
* Access fails due to a configurable trap or enable which would
35
* result in a categorized exception syndrome giving information about
36
* the failing instruction (ie syndrome category 0x3, 0x4, 0x5, 0x6,
37
- * 0xc or 0x18). The exception is taken to the usual target EL (EL1 or
38
- * PL1 if in EL0, otherwise to the current EL).
39
+ * 0xc or 0x18).
40
*/
41
- CP_ACCESS_TRAP = 1,
42
+ CP_ACCESS_TRAP = (1 << 2),
43
+ CP_ACCESS_TRAP_EL2 = CP_ACCESS_TRAP | 2,
44
+ CP_ACCESS_TRAP_EL3 = CP_ACCESS_TRAP | 3,
45
+
46
/*
47
* Access fails and results in an exception syndrome 0x0 ("uncategorized").
48
* Note that this is not a catch-all case -- the set of cases which may
49
* result in this failure is specifically defined by the architecture.
50
*/
51
- CP_ACCESS_TRAP_UNCATEGORIZED = 2,
52
- /* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
53
- CP_ACCESS_TRAP_EL2 = 3,
54
- CP_ACCESS_TRAP_EL3 = 4,
55
- /* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
56
- CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
57
- CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
58
+ CP_ACCESS_TRAP_UNCATEGORIZED = (2 << 2),
59
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = CP_ACCESS_TRAP_UNCATEGORIZED | 2,
60
+ CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = CP_ACCESS_TRAP_UNCATEGORIZED | 3,
61
} CPAccessResult;
62
63
typedef struct ARMCPRegInfo ARMCPRegInfo;
37
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
64
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
38
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/op_helper.c
66
--- a/target/arm/op_helper.c
40
+++ b/target/arm/op_helper.c
67
+++ b/target/arm/op_helper.c
41
@@ -XXX,XX +XXX,XX @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
68
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
42
69
uint32_t isread)
43
void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
44
{
70
{
45
+#ifdef CONFIG_USER_ONLY
71
const ARMCPRegInfo *ri = rip;
46
+ /*
72
+ CPAccessResult res = CP_ACCESS_OK;
47
+ * WFI in the user-mode emulator is technically permitted but not
73
int target_el;
48
+ * something any real-world code would do. AArch64 Linux kernels
74
49
+ * trap it via SCTRL_EL1.nTWI and make it an (expensive) NOP;
75
if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
50
+ * AArch32 kernels don't trap it so it will delay a bit.
76
&& extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
51
+ * For QEMU, make it NOP here, because trying to raise EXCP_HLT
77
- raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
52
+ * would trigger an abort.
78
+ res = CP_ACCESS_TRAP;
53
+ */
79
+ goto fail;
54
+ return;
80
}
55
+#else
81
56
CPUState *cs = env_cpu(env);
82
/*
57
int target_el = check_wfx_trap(env, false);
83
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
58
84
mask &= ~((1 << 4) | (1 << 14));
59
@@ -XXX,XX +XXX,XX @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
85
60
cs->exception_index = EXCP_HLT;
86
if (env->cp15.hstr_el2 & mask) {
61
cs->halted = 1;
87
- target_el = 2;
62
cpu_loop_exit(cs);
88
- goto exept;
63
+#endif
89
+ res = CP_ACCESS_TRAP_EL2;
90
+ goto fail;
91
}
92
}
93
94
- if (!ri->accessfn) {
95
+ if (ri->accessfn) {
96
+ res = ri->accessfn(env, ri, isread);
97
+ }
98
+ if (likely(res == CP_ACCESS_OK)) {
99
return;
100
}
101
102
- switch (ri->accessfn(env, ri, isread)) {
103
- case CP_ACCESS_OK:
104
- return;
105
+ fail:
106
+ switch (res & ~CP_ACCESS_EL_MASK) {
107
case CP_ACCESS_TRAP:
108
- target_el = exception_target_el(env);
109
- break;
110
- case CP_ACCESS_TRAP_EL2:
111
- /* Requesting a trap to EL2 when we're in EL3 is
112
- * a bug in the access function.
113
- */
114
- assert(arm_current_el(env) != 3);
115
- target_el = 2;
116
- break;
117
- case CP_ACCESS_TRAP_EL3:
118
- target_el = 3;
119
break;
120
case CP_ACCESS_TRAP_UNCATEGORIZED:
121
- target_el = exception_target_el(env);
122
- syndrome = syn_uncategorized();
123
- break;
124
- case CP_ACCESS_TRAP_UNCATEGORIZED_EL2:
125
- target_el = 2;
126
- syndrome = syn_uncategorized();
127
- break;
128
- case CP_ACCESS_TRAP_UNCATEGORIZED_EL3:
129
- target_el = 3;
130
syndrome = syn_uncategorized();
131
break;
132
default:
133
g_assert_not_reached();
134
}
135
136
-exept:
137
+ target_el = res & CP_ACCESS_EL_MASK;
138
+ switch (target_el) {
139
+ case 0:
140
+ target_el = exception_target_el(env);
141
+ break;
142
+ case 2:
143
+ assert(arm_current_el(env) != 3);
144
+ assert(arm_is_el2_enabled(env));
145
+ break;
146
+ case 3:
147
+ assert(arm_feature(env, ARM_FEATURE_EL3));
148
+ break;
149
+ default:
150
+ /* No "direct" traps to EL1 */
151
+ g_assert_not_reached();
152
+ }
153
+
154
raise_exception(env, EXCP_UDEF, syndrome, target_el);
64
}
155
}
65
156
66
void HELPER(wfe)(CPUARMState *env)
67
--
157
--
68
2.20.1
158
2.25.1
69
159
70
160
diff view generated by jsdifflib
1
We want to split out the .c.inc files which are currently included
1
From: Richard Henderson <richard.henderson@linaro.org>
2
into translate.c so they are separate compilation units. To do this
3
we need to make some functions which are currently file-local to
4
translate.c have global scope; create a translate-a32.h paralleling
5
the existing translate-a64.h as a place for these declarations to
6
live, so that code moved into the new compilation units can call
7
them.
8
2
9
The functions made global here are those required by the
3
Remove a possible source of error by removing REGINFO_SENTINEL
10
m-nocp.decode functions, except that I have converted the whole
4
and using ARRAY_SIZE (convinently hidden inside a macro) to
11
family of {read,write}_neon_element* and also both the load_cpu and
5
find the end of the set of regs being registered or modified.
12
store_cpu functions for consistency, even though m-nocp only wants a
13
few functions from each.
14
6
7
The space saved by not having the extra array element reduces
8
the executable's .data.rel.ro section by about 9k.
9
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20220501055028.646596-4-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210430132740.10391-4-peter.maydell@linaro.org
18
---
15
---
19
target/arm/translate-a32.h | 57 ++++++++++++++++++++++++++++++++++
16
target/arm/cpregs.h | 53 +++++++++---------
20
target/arm/translate.c | 39 +++++------------------
17
hw/arm/pxa2xx.c | 1 -
21
target/arm/translate-vfp.c.inc | 2 +-
18
hw/arm/pxa2xx_pic.c | 1 -
22
3 files changed, 65 insertions(+), 33 deletions(-)
19
hw/intc/arm_gicv3_cpuif.c | 5 --
23
create mode 100644 target/arm/translate-a32.h
20
hw/intc/arm_gicv3_kvm.c | 1 -
21
target/arm/cpu64.c | 1 -
22
target/arm/cpu_tcg.c | 4 --
23
target/arm/helper.c | 111 ++++++++------------------------------
24
8 files changed, 48 insertions(+), 129 deletions(-)
24
25
25
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
26
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
26
new file mode 100644
27
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX
28
--- a/target/arm/cpregs.h
28
--- /dev/null
29
+++ b/target/arm/cpregs.h
29
+++ b/target/arm/translate-a32.h
30
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@
31
+/*
31
#define ARM_CP_NO_GDB 0x4000
32
+ * AArch32 translation, common definitions.
32
#define ARM_CP_RAISES_EXC 0x8000
33
+ *
33
#define ARM_CP_NEWEL 0x10000
34
+ * Copyright (c) 2021 Linaro, Ltd.
34
-/* Used only as a terminator for ARMCPRegInfo lists */
35
+ *
35
-#define ARM_CP_SENTINEL 0xfffff
36
+ * This library is free software; you can redistribute it and/or
36
/* Mask of only the flag bits in a type field */
37
+ * modify it under the terms of the GNU Lesser General Public
37
#define ARM_CP_FLAG_MASK 0x1f0ff
38
+ * License as published by the Free Software Foundation; either
38
39
+ * version 2.1 of the License, or (at your option) any later version.
39
@@ -XXX,XX +XXX,XX @@ enum {
40
+ *
40
ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
41
+ * This library is distributed in the hope that it will be useful,
41
};
42
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
42
43
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
43
-/*
44
+ * Lesser General Public License for more details.
44
- * Return true if cptype is a valid type field. This is used to try to
45
+ *
45
- * catch errors where the sentinel has been accidentally left off the end
46
+ * You should have received a copy of the GNU Lesser General Public
46
- * of a list of registers.
47
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
47
- */
48
+ */
48
-static inline bool cptype_valid(int cptype)
49
+
50
+#ifndef TARGET_ARM_TRANSLATE_A64_H
51
+#define TARGET_ARM_TRANSLATE_A64_H
52
+
53
+void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
54
+void arm_gen_condlabel(DisasContext *s);
55
+bool vfp_access_check(DisasContext *s);
56
+void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop);
57
+void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop);
58
+void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop);
59
+void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop);
60
+
61
+static inline TCGv_i32 load_cpu_offset(int offset)
62
+{
63
+ TCGv_i32 tmp = tcg_temp_new_i32();
64
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
65
+ return tmp;
66
+}
67
+
68
+#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
69
+
70
+static inline void store_cpu_offset(TCGv_i32 var, int offset)
71
+{
72
+ tcg_gen_st_i32(var, cpu_env, offset);
73
+ tcg_temp_free_i32(var);
74
+}
75
+
76
+#define store_cpu_field(var, name) \
77
+ store_cpu_offset(var, offsetof(CPUARMState, name))
78
+
79
+/* Create a new temporary and set it to the value of a CPU register. */
80
+static inline TCGv_i32 load_reg(DisasContext *s, int reg)
81
+{
82
+ TCGv_i32 tmp = tcg_temp_new_i32();
83
+ load_reg_var(s, tmp, reg);
84
+ return tmp;
85
+}
86
+
87
+#endif
88
diff --git a/target/arm/translate.c b/target/arm/translate.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate.c
91
+++ b/target/arm/translate.c
92
@@ -XXX,XX +XXX,XX @@
93
#define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
94
95
#include "translate.h"
96
+#include "translate-a32.h"
97
98
#if defined(CONFIG_USER_ONLY)
99
#define IS_USER(s) 1
100
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
101
}
102
103
/* Generate a label used for skipping this instruction */
104
-static void arm_gen_condlabel(DisasContext *s)
105
+void arm_gen_condlabel(DisasContext *s)
106
{
107
if (!s->condjmp) {
108
s->condlabel = gen_new_label();
109
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
110
}
111
}
112
113
-static inline TCGv_i32 load_cpu_offset(int offset)
114
-{
49
-{
115
- TCGv_i32 tmp = tcg_temp_new_i32();
50
- return ((cptype & ~ARM_CP_FLAG_MASK) == 0)
116
- tcg_gen_ld_i32(tmp, cpu_env, offset);
51
- || ((cptype & ARM_CP_SPECIAL) &&
117
- return tmp;
52
- ((cptype & ~ARM_CP_FLAG_MASK) <= ARM_LAST_SPECIAL));
118
-}
119
-
120
-#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
121
-
122
-static inline void store_cpu_offset(TCGv_i32 var, int offset)
123
-{
124
- tcg_gen_st_i32(var, cpu_env, offset);
125
- tcg_temp_free_i32(var);
126
-}
127
-
128
-#define store_cpu_field(var, name) \
129
- store_cpu_offset(var, offsetof(CPUARMState, name))
130
-
131
/* The architectural value of PC. */
132
static uint32_t read_pc(DisasContext *s)
133
{
134
@@ -XXX,XX +XXX,XX @@ static uint32_t read_pc(DisasContext *s)
135
}
136
137
/* Set a variable to the value of a CPU register. */
138
-static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
139
+void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
140
{
141
if (reg == 15) {
142
tcg_gen_movi_i32(var, read_pc(s));
143
@@ -XXX,XX +XXX,XX @@ static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
144
}
145
}
146
147
-/* Create a new temporary and set it to the value of a CPU register. */
148
-static inline TCGv_i32 load_reg(DisasContext *s, int reg)
149
-{
150
- TCGv_i32 tmp = tcg_temp_new_i32();
151
- load_reg_var(s, tmp, reg);
152
- return tmp;
153
-}
53
-}
154
-
54
-
155
/*
55
/*
156
* Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
56
* Access rights:
157
* This is used for load/store for which use of PC implies (literal),
57
* We define bits for Read and Write access for what rev C of the v7-AR ARM ARM
158
@@ -XXX,XX +XXX,XX @@ static inline void vfp_store_reg32(TCGv_i32 var, int reg)
58
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
159
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
59
#define CPREG_FIELD64(env, ri) \
60
(*(uint64_t *)((char *)(env) + (ri)->fieldoffset))
61
62
-#define REGINFO_SENTINEL { .type = ARM_CP_SENTINEL }
63
+void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu, const ARMCPRegInfo *reg,
64
+ void *opaque);
65
66
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
67
- const ARMCPRegInfo *regs, void *opaque);
68
-void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
69
- const ARMCPRegInfo *regs, void *opaque);
70
-static inline void define_arm_cp_regs(ARMCPU *cpu, const ARMCPRegInfo *regs)
71
-{
72
- define_arm_cp_regs_with_opaque(cpu, regs, 0);
73
-}
74
static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
75
{
76
- define_one_arm_cp_reg_with_opaque(cpu, regs, 0);
77
+ define_one_arm_cp_reg_with_opaque(cpu, regs, NULL);
160
}
78
}
161
79
+
162
-static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
80
+void define_arm_cp_regs_with_opaque_len(ARMCPU *cpu, const ARMCPRegInfo *regs,
163
+void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
81
+ void *opaque, size_t len);
164
{
82
+
165
long off = neon_element_offset(reg, ele, memop);
83
+#define define_arm_cp_regs_with_opaque(CPU, REGS, OPAQUE) \
166
84
+ do { \
167
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
85
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(REGS) == 0); \
86
+ define_arm_cp_regs_with_opaque_len(CPU, REGS, OPAQUE, \
87
+ ARRAY_SIZE(REGS)); \
88
+ } while (0)
89
+
90
+#define define_arm_cp_regs(CPU, REGS) \
91
+ define_arm_cp_regs_with_opaque(CPU, REGS, NULL)
92
+
93
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
94
95
/*
96
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCPRegUserSpaceInfo {
97
uint64_t fixed_bits;
98
} ARMCPRegUserSpaceInfo;
99
100
-#define REGUSERINFO_SENTINEL { .name = NULL }
101
+void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len,
102
+ const ARMCPRegUserSpaceInfo *mods,
103
+ size_t mods_len);
104
105
-void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods);
106
+#define modify_arm_cp_regs(REGS, MODS) \
107
+ do { \
108
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(REGS) == 0); \
109
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(MODS) == 0); \
110
+ modify_arm_cp_regs_with_len(REGS, ARRAY_SIZE(REGS), \
111
+ MODS, ARRAY_SIZE(MODS)); \
112
+ } while (0)
113
114
/* CPWriteFn that can be used to implement writes-ignored behaviour */
115
void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
116
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/arm/pxa2xx.c
119
+++ b/hw/arm/pxa2xx.c
120
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pxa_cp_reginfo[] = {
121
{ .name = "PWRMODE", .cp = 14, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 0,
122
.access = PL1_RW, .type = ARM_CP_IO,
123
.readfn = arm_cp_read_zero, .writefn = pxa2xx_pwrmode_write },
124
- REGINFO_SENTINEL
125
};
126
127
static void pxa2xx_setup_cp14(PXA2xxState *s)
128
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/hw/arm/pxa2xx_pic.c
131
+++ b/hw/arm/pxa2xx_pic.c
132
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pxa_pic_cp_reginfo[] = {
133
REGINFO_FOR_PIC_CP("ICLR2", 8),
134
REGINFO_FOR_PIC_CP("ICFP2", 9),
135
REGINFO_FOR_PIC_CP("ICPR2", 0xa),
136
- REGINFO_SENTINEL
137
};
138
139
static const MemoryRegionOps pxa2xx_pic_ops = {
140
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/hw/intc/arm_gicv3_cpuif.c
143
+++ b/hw/intc/arm_gicv3_cpuif.c
144
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
145
.readfn = icc_igrpen1_el3_read,
146
.writefn = icc_igrpen1_el3_write,
147
},
148
- REGINFO_SENTINEL
149
};
150
151
static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
152
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_hcr_reginfo[] = {
153
.readfn = ich_vmcr_read,
154
.writefn = ich_vmcr_write,
155
},
156
- REGINFO_SENTINEL
157
};
158
159
static const ARMCPRegInfo gicv3_cpuif_ich_apxr1_reginfo[] = {
160
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr1_reginfo[] = {
161
.readfn = ich_ap_read,
162
.writefn = ich_ap_write,
163
},
164
- REGINFO_SENTINEL
165
};
166
167
static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
168
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_ich_apxr23_reginfo[] = {
169
.readfn = ich_ap_read,
170
.writefn = ich_ap_write,
171
},
172
- REGINFO_SENTINEL
173
};
174
175
static void gicv3_cpuif_el_change_hook(ARMCPU *cpu, void *opaque)
176
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
177
.readfn = ich_lr_read,
178
.writefn = ich_lr_write,
179
},
180
- REGINFO_SENTINEL
181
};
182
define_arm_cp_regs(cpu, lr_regset);
183
}
184
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
185
index XXXXXXX..XXXXXXX 100644
186
--- a/hw/intc/arm_gicv3_kvm.c
187
+++ b/hw/intc/arm_gicv3_kvm.c
188
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
189
*/
190
.resetfn = arm_gicv3_icc_reset,
191
},
192
- REGINFO_SENTINEL
193
};
194
195
/**
196
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/target/arm/cpu64.c
199
+++ b/target/arm/cpu64.c
200
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
201
{ .name = "L2MERRSR",
202
.cp = 15, .opc1 = 3, .crm = 15,
203
.access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
204
- REGINFO_SENTINEL
205
};
206
207
static void aarch64_a57_initfn(Object *obj)
208
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
209
index XXXXXXX..XXXXXXX 100644
210
--- a/target/arm/cpu_tcg.c
211
+++ b/target/arm/cpu_tcg.c
212
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
213
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
214
{ .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
215
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
216
- REGINFO_SENTINEL
217
};
218
219
static void cortex_a8_initfn(Object *obj)
220
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
221
.access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
222
{ .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2,
223
.access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
224
- REGINFO_SENTINEL
225
};
226
227
static void cortex_a9_initfn(Object *obj)
228
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
229
#endif
230
{ .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3,
231
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
232
- REGINFO_SENTINEL
233
};
234
235
static void cortex_a7_initfn(Object *obj)
236
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
237
.access = PL1_RW, .type = ARM_CP_CONST },
238
{ .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5,
239
.opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP },
240
- REGINFO_SENTINEL
241
};
242
243
static void cortex_r5_initfn(Object *obj)
244
diff --git a/target/arm/helper.c b/target/arm/helper.c
245
index XXXXXXX..XXXXXXX 100644
246
--- a/target/arm/helper.c
247
+++ b/target/arm/helper.c
248
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
249
.secure = ARM_CP_SECSTATE_S,
250
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_s),
251
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
252
- REGINFO_SENTINEL
253
};
254
255
static const ARMCPRegInfo not_v8_cp_reginfo[] = {
256
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
257
{ .name = "CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
258
.opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
259
.type = ARM_CP_NOP | ARM_CP_OVERRIDE },
260
- REGINFO_SENTINEL
261
};
262
263
static const ARMCPRegInfo not_v6_cp_reginfo[] = {
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v6_cp_reginfo[] = {
265
*/
266
{ .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2,
267
.access = PL1_W, .type = ARM_CP_WFI },
268
- REGINFO_SENTINEL
269
};
270
271
static const ARMCPRegInfo not_v7_cp_reginfo[] = {
272
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
273
.opc1 = 0, .opc2 = 0, .access = PL1_RW, .type = ARM_CP_NOP },
274
{ .name = "NMRR", .cp = 15, .crn = 10, .crm = 2,
275
.opc1 = 0, .opc2 = 1, .access = PL1_RW, .type = ARM_CP_NOP },
276
- REGINFO_SENTINEL
277
};
278
279
static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
280
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
281
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
282
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
283
.resetfn = cpacr_reset, .writefn = cpacr_write, .readfn = cpacr_read },
284
- REGINFO_SENTINEL
285
};
286
287
typedef struct pm_event {
288
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
289
{ .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
290
.type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
291
.writefn = tlbimvaa_write },
292
- REGINFO_SENTINEL
293
};
294
295
static const ARMCPRegInfo v7mp_cp_reginfo[] = {
296
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7mp_cp_reginfo[] = {
297
{ .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
298
.type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
299
.writefn = tlbimvaa_is_write },
300
- REGINFO_SENTINEL
301
};
302
303
static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
304
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
305
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
306
.writefn = pmovsset_write,
307
.raw_writefn = raw_write },
308
- REGINFO_SENTINEL
309
};
310
311
static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
312
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo t2ee_cp_reginfo[] = {
313
{ .name = "TEEHBR", .cp = 14, .crn = 1, .crm = 0, .opc1 = 6, .opc2 = 0,
314
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, teehbr),
315
.accessfn = teehbr_access, .resetvalue = 0 },
316
- REGINFO_SENTINEL
317
};
318
319
static const ARMCPRegInfo v6k_cp_reginfo[] = {
320
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
321
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidrprw_s),
322
offsetoflow32(CPUARMState, cp15.tpidrprw_ns) },
323
.resetvalue = 0 },
324
- REGINFO_SENTINEL
325
};
326
327
#ifndef CONFIG_USER_ONLY
328
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
329
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_SEC].cval),
330
.writefn = gt_sec_cval_write, .raw_writefn = raw_write,
331
},
332
- REGINFO_SENTINEL
333
};
334
335
static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
336
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
337
.access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
338
.readfn = gt_virt_cnt_read,
339
},
340
- REGINFO_SENTINEL
341
};
342
343
#endif
344
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vapa_cp_reginfo[] = {
345
.access = PL1_W, .accessfn = ats_access,
346
.writefn = ats_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
347
#endif
348
- REGINFO_SENTINEL
349
};
350
351
/* Return basic MPU access permission bits. */
352
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
353
.fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]),
354
.writefn = pmsav7_rgnr_write,
355
.resetfn = arm_cp_reset_ignore },
356
- REGINFO_SENTINEL
357
};
358
359
static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
360
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav5_cp_reginfo[] = {
361
{ .name = "946_PRBS7", .cp = 15, .crn = 6, .crm = 7, .opc1 = 0,
362
.opc2 = CP_ANY, .access = PL1_RW, .resetvalue = 0,
363
.fieldoffset = offsetof(CPUARMState, cp15.c6_region[7]) },
364
- REGINFO_SENTINEL
365
};
366
367
static void vmsa_ttbcr_raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
368
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
369
.access = PL1_RW, .accessfn = access_tvm_trvm,
370
.fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
371
.resetvalue = 0, },
372
- REGINFO_SENTINEL
373
};
374
375
static const ARMCPRegInfo vmsa_cp_reginfo[] = {
376
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
377
/* No offsetoflow32 -- pass the entire TCR to writefn/raw_writefn. */
378
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.tcr_el[3]),
379
offsetof(CPUARMState, cp15.tcr_el[1])} },
380
- REGINFO_SENTINEL
381
};
382
383
/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing
384
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
385
{ .name = "C9", .cp = 15, .crn = 9,
386
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
387
.type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
388
- REGINFO_SENTINEL
389
};
390
391
static void xscale_cpar_write(CPUARMState *env, const ARMCPRegInfo *ri,
392
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo xscale_cp_reginfo[] = {
393
{ .name = "XSCALE_UNLOCK_DCACHE",
394
.cp = 15, .opc1 = 0, .crn = 9, .crm = 2, .opc2 = 1,
395
.access = PL1_W, .type = ARM_CP_NOP },
396
- REGINFO_SENTINEL
397
};
398
399
static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
400
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
401
.access = PL1_RW,
402
.type = ARM_CP_CONST | ARM_CP_NO_RAW | ARM_CP_OVERRIDE,
403
.resetvalue = 0 },
404
- REGINFO_SENTINEL
405
};
406
407
static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = {
408
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_dirty_status_cp_reginfo[] = {
409
{ .name = "CDSR", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 6,
410
.access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
411
.resetvalue = 0 },
412
- REGINFO_SENTINEL
413
};
414
415
static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
416
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
417
.access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
418
{ .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0,
419
.access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
420
- REGINFO_SENTINEL
421
};
422
423
static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
424
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
425
{ .name = "TCI_DCACHE", .cp = 15, .crn = 7, .crm = 14, .opc1 = 0, .opc2 = 3,
426
.access = PL0_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
427
.resetvalue = (1 << 30) },
428
- REGINFO_SENTINEL
429
};
430
431
static const ARMCPRegInfo strongarm_cp_reginfo[] = {
432
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo strongarm_cp_reginfo[] = {
433
.crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
434
.access = PL1_RW, .resetvalue = 0,
435
.type = ARM_CP_CONST | ARM_CP_OVERRIDE | ARM_CP_NO_RAW },
436
- REGINFO_SENTINEL
437
};
438
439
static uint64_t midr_read(CPUARMState *env, const ARMCPRegInfo *ri)
440
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
441
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
442
offsetof(CPUARMState, cp15.ttbr1_ns) },
443
.writefn = vmsa_ttbr_write, },
444
- REGINFO_SENTINEL
445
};
446
447
static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
448
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
449
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
450
.writefn = sdcr_write,
451
.fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
452
- REGINFO_SENTINEL
453
};
454
455
/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */
456
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
457
.type = ARM_CP_CONST,
458
.cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
459
.access = PL2_RW, .resetvalue = 0 },
460
- REGINFO_SENTINEL
461
};
462
463
/* Ditto, but for registers which exist in ARMv8 but not v7 */
464
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
465
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
466
.access = PL2_RW,
467
.type = ARM_CP_CONST, .resetvalue = 0 },
468
- REGINFO_SENTINEL
469
};
470
471
static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
472
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
473
.cp = 15, .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
474
.access = PL2_RW,
475
.fieldoffset = offsetof(CPUARMState, cp15.hstr_el2) },
476
- REGINFO_SENTINEL
477
};
478
479
static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
480
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_v8_cp_reginfo[] = {
481
.access = PL2_RW,
482
.fieldoffset = offsetofhigh32(CPUARMState, cp15.hcr_el2),
483
.writefn = hcr_writehigh },
484
- REGINFO_SENTINEL
485
};
486
487
static CPAccessResult sel2_access(CPUARMState *env, const ARMCPRegInfo *ri,
488
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
489
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 6, .opc2 = 2,
490
.access = PL2_RW, .accessfn = sel2_access,
491
.fieldoffset = offsetof(CPUARMState, cp15.vstcr_el2) },
492
- REGINFO_SENTINEL
493
};
494
495
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
496
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
497
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 5,
498
.access = PL3_W, .type = ARM_CP_NO_RAW,
499
.writefn = tlbi_aa64_vae3_write },
500
- REGINFO_SENTINEL
501
};
502
503
#ifndef CONFIG_USER_ONLY
504
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
505
.cp = 14, .opc0 = 2, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
506
.access = PL1_RW, .accessfn = access_tda,
507
.type = ARM_CP_NOP },
508
- REGINFO_SENTINEL
509
};
510
511
static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
512
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
513
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
514
{ .name = "DBGDSAR", .cp = 14, .crm = 2, .opc1 = 0,
515
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
516
- REGINFO_SENTINEL
517
};
518
519
/* Return the exception level to which exceptions should be taken
520
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
521
.fieldoffset = offsetof(CPUARMState, cp15.dbgbcr[i]),
522
.writefn = dbgbcr_write, .raw_writefn = raw_write
523
},
524
- REGINFO_SENTINEL
525
};
526
define_arm_cp_regs(cpu, dbgregs);
527
}
528
@@ -XXX,XX +XXX,XX @@ static void define_debug_regs(ARMCPU *cpu)
529
.fieldoffset = offsetof(CPUARMState, cp15.dbgwcr[i]),
530
.writefn = dbgwcr_write, .raw_writefn = raw_write
531
},
532
- REGINFO_SENTINEL
533
};
534
define_arm_cp_regs(cpu, dbgregs);
535
}
536
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
537
.type = ARM_CP_IO,
538
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
539
.raw_writefn = pmevtyper_rawwrite },
540
- REGINFO_SENTINEL
541
};
542
define_arm_cp_regs(cpu, pmev_regs);
543
g_free(pmevcntr_name);
544
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
545
.cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
546
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
547
.resetvalue = extract64(cpu->pmceid1, 32, 32) },
548
- REGINFO_SENTINEL
549
};
550
define_arm_cp_regs(cpu, v81_pmu_regs);
551
}
552
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
553
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
554
.access = PL1_R, .accessfn = access_lor_ns,
555
.type = ARM_CP_CONST, .resetvalue = 0 },
556
- REGINFO_SENTINEL
557
};
558
559
#ifdef TARGET_AARCH64
560
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pauth_reginfo[] = {
561
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
562
.access = PL1_RW, .accessfn = access_pauth,
563
.fieldoffset = offsetof(CPUARMState, keys.apib.hi) },
564
- REGINFO_SENTINEL
565
};
566
567
static const ARMCPRegInfo tlbirange_reginfo[] = {
568
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
569
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 5,
570
.access = PL3_W, .type = ARM_CP_NO_RAW,
571
.writefn = tlbi_aa64_rvae3_write },
572
- REGINFO_SENTINEL
573
};
574
575
static const ARMCPRegInfo tlbios_reginfo[] = {
576
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
577
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 5,
578
.access = PL3_W, .type = ARM_CP_NO_RAW,
579
.writefn = tlbi_aa64_vae3is_write },
580
- REGINFO_SENTINEL
581
};
582
583
static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
584
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo rndr_reginfo[] = {
585
.type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END | ARM_CP_IO,
586
.opc0 = 3, .opc1 = 3, .crn = 2, .crm = 4, .opc2 = 1,
587
.access = PL0_R, .readfn = rndr_readfn },
588
- REGINFO_SENTINEL
589
};
590
591
#ifndef CONFIG_USER_ONLY
592
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpop_reg[] = {
593
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
594
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
595
.accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
596
- REGINFO_SENTINEL
597
};
598
599
static const ARMCPRegInfo dcpodp_reg[] = {
600
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpodp_reg[] = {
601
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
602
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
603
.accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
604
- REGINFO_SENTINEL
605
};
606
#endif /*CONFIG_USER_ONLY*/
607
608
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
609
{ .name = "DC_CIGDSW", .state = ARM_CP_STATE_AA64,
610
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 6,
611
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
612
- REGINFO_SENTINEL
613
};
614
615
static const ARMCPRegInfo mte_tco_ro_reginfo[] = {
616
{ .name = "TCO", .state = ARM_CP_STATE_AA64,
617
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
618
.type = ARM_CP_CONST, .access = PL0_RW, },
619
- REGINFO_SENTINEL
620
};
621
622
static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
623
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
624
.accessfn = aa64_zva_access,
625
#endif
626
},
627
- REGINFO_SENTINEL
628
};
629
630
#endif
631
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo predinv_reginfo[] = {
632
{ .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
633
.cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
634
.type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
635
- REGINFO_SENTINEL
636
};
637
638
static uint64_t ccsidr2_read(CPUARMState *env, const ARMCPRegInfo *ri)
639
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ccsidr2_reginfo[] = {
640
.access = PL1_R,
641
.accessfn = access_aa64_tid2,
642
.readfn = ccsidr2_read, .type = ARM_CP_NO_RAW },
643
- REGINFO_SENTINEL
644
};
645
646
static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
647
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo jazelle_regs[] = {
648
.cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
649
.accessfn = access_joscr_jmcr,
650
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
651
- REGINFO_SENTINEL
652
};
653
654
static const ARMCPRegInfo vhe_reginfo[] = {
655
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
656
.access = PL2_RW, .accessfn = e2h_access,
657
.writefn = gt_virt_cval_write, .raw_writefn = raw_write },
658
#endif
659
- REGINFO_SENTINEL
660
};
661
662
#ifndef CONFIG_USER_ONLY
663
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1e1_reginfo[] = {
664
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
665
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
666
.writefn = ats_write64 },
667
- REGINFO_SENTINEL
668
};
669
670
static const ARMCPRegInfo ats1cp_reginfo[] = {
671
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1cp_reginfo[] = {
672
.cp = 15, .opc1 = 0, .crn = 7, .crm = 9, .opc2 = 1,
673
.access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
674
.writefn = ats_write },
675
- REGINFO_SENTINEL
676
};
677
#endif
678
679
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
680
.cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
681
.access = PL2_RW, .type = ARM_CP_CONST,
682
.resetvalue = 0 },
683
- REGINFO_SENTINEL
684
};
685
686
void register_cp_regs_for_features(ARMCPU *cpu)
687
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
688
.access = PL1_R, .type = ARM_CP_CONST,
689
.accessfn = access_aa32_tid3,
690
.resetvalue = cpu->isar.id_isar6 },
691
- REGINFO_SENTINEL
692
};
693
define_arm_cp_regs(cpu, v6_idregs);
694
define_arm_cp_regs(cpu, v6_cp_reginfo);
695
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
696
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
697
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
698
.resetvalue = cpu->pmceid1 },
699
- REGINFO_SENTINEL
700
};
701
#ifdef CONFIG_USER_ONLY
702
ARMCPRegUserSpaceInfo v8_user_idregs[] = {
703
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
704
.exported_bits = 0x000000f0ffffffff },
705
{ .name = "ID_AA64ISAR*_EL1_RESERVED",
706
.is_glob = true },
707
- REGUSERINFO_SENTINEL
708
};
709
modify_arm_cp_regs(v8_idregs, v8_user_idregs);
710
#endif
711
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
712
.access = PL2_RW,
713
.resetvalue = vmpidr_def,
714
.fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
715
- REGINFO_SENTINEL
716
};
717
define_arm_cp_regs(cpu, vpidr_regs);
718
define_arm_cp_regs(cpu, el2_cp_reginfo);
719
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
720
.access = PL2_RW, .accessfn = access_el3_aa32ns,
721
.type = ARM_CP_NO_RAW,
722
.writefn = arm_cp_write_ignore, .readfn = mpidr_read },
723
- REGINFO_SENTINEL
724
};
725
define_arm_cp_regs(cpu, vpidr_regs);
726
define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
727
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
728
.raw_writefn = raw_write, .writefn = sctlr_write,
729
.fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]),
730
.resetvalue = cpu->reset_sctlr },
731
- REGINFO_SENTINEL
732
};
733
734
define_arm_cp_regs(cpu, el3_regs);
735
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
736
{ .name = "DUMMY",
737
.cp = 15, .crn = 0, .crm = 7, .opc1 = 0, .opc2 = CP_ANY,
738
.access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
739
- REGINFO_SENTINEL
740
};
741
ARMCPRegInfo id_v8_midr_cp_reginfo[] = {
742
{ .name = "MIDR_EL1", .state = ARM_CP_STATE_BOTH,
743
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
744
.access = PL1_R,
745
.accessfn = access_aa64_tid1,
746
.type = ARM_CP_CONST, .resetvalue = cpu->revidr },
747
- REGINFO_SENTINEL
748
};
749
ARMCPRegInfo id_cp_reginfo[] = {
750
/* These are common to v8 and pre-v8 */
751
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
752
.access = PL1_R,
753
.accessfn = access_aa32_tid1,
754
.type = ARM_CP_CONST, .resetvalue = 0 },
755
- REGINFO_SENTINEL
756
};
757
/* TLBTR is specific to VMSA */
758
ARMCPRegInfo id_tlbtr_reginfo = {
759
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
760
{ .name = "MIDR_EL1",
761
.exported_bits = 0x00000000ffffffff },
762
{ .name = "REVIDR_EL1" },
763
- REGUSERINFO_SENTINEL
764
};
765
modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
766
#endif
767
if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
768
arm_feature(env, ARM_FEATURE_STRONGARM)) {
769
- ARMCPRegInfo *r;
770
+ size_t i;
771
/* Register the blanket "writes ignored" value first to cover the
772
* whole space. Then update the specific ID registers to allow write
773
* access, so that they ignore writes rather than causing them to
774
* UNDEF.
775
*/
776
define_one_arm_cp_reg(cpu, &crn0_wi_reginfo);
777
- for (r = id_pre_v8_midr_cp_reginfo;
778
- r->type != ARM_CP_SENTINEL; r++) {
779
- r->access = PL1_RW;
780
+ for (i = 0; i < ARRAY_SIZE(id_pre_v8_midr_cp_reginfo); ++i) {
781
+ id_pre_v8_midr_cp_reginfo[i].access = PL1_RW;
782
}
783
- for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {
784
- r->access = PL1_RW;
785
+ for (i = 0; i < ARRAY_SIZE(id_cp_reginfo); ++i) {
786
+ id_cp_reginfo[i].access = PL1_RW;
787
}
788
id_mpuir_reginfo.access = PL1_RW;
789
id_tlbtr_reginfo.access = PL1_RW;
790
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
791
{ .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH,
792
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
793
.access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
794
- REGINFO_SENTINEL
795
};
796
#ifdef CONFIG_USER_ONLY
797
ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
798
{ .name = "MPIDR_EL1",
799
.fixed_bits = 0x0000000080000000 },
800
- REGUSERINFO_SENTINEL
801
};
802
modify_arm_cp_regs(mpidr_cp_reginfo, mpidr_user_cp_reginfo);
803
#endif
804
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
805
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 1,
806
.access = PL3_RW, .type = ARM_CP_CONST,
807
.resetvalue = 0 },
808
- REGINFO_SENTINEL
809
};
810
define_arm_cp_regs(cpu, auxcr_reginfo);
811
if (cpu_isar_feature(aa32_ac2, cpu)) {
812
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
813
.type = ARM_CP_CONST,
814
.opc0 = 3, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 0,
815
.access = PL1_R, .resetvalue = cpu->reset_cbar },
816
- REGINFO_SENTINEL
817
};
818
/* We don't implement a r/w 64 bit CBAR currently */
819
assert(arm_feature(env, ARM_FEATURE_CBAR_RO));
820
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
821
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s),
822
offsetof(CPUARMState, cp15.vbar_ns) },
823
.resetvalue = 0 },
824
- REGINFO_SENTINEL
825
};
826
define_arm_cp_regs(cpu, vbar_cp_reginfo);
827
}
828
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
829
r->writefn);
830
}
831
}
832
- /* Bad type field probably means missing sentinel at end of reg list */
833
- assert(cptype_valid(r->type));
834
+
835
for (crm = crmmin; crm <= crmmax; crm++) {
836
for (opc1 = opc1min; opc1 <= opc1max; opc1++) {
837
for (opc2 = opc2min; opc2 <= opc2max; opc2++) {
838
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
168
}
839
}
169
}
840
}
170
841
171
-static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
842
-void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
172
+void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
843
- const ARMCPRegInfo *regs, void *opaque)
844
+/* Define a whole list of registers */
845
+void define_arm_cp_regs_with_opaque_len(ARMCPU *cpu, const ARMCPRegInfo *regs,
846
+ void *opaque, size_t len)
173
{
847
{
174
long off = neon_element_offset(reg, ele, memop);
848
- /* Define a whole list of registers */
175
849
- const ARMCPRegInfo *r;
176
@@ -XXX,XX +XXX,XX @@ static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
850
- for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
851
- define_one_arm_cp_reg_with_opaque(cpu, r, opaque);
852
+ size_t i;
853
+ for (i = 0; i < len; ++i) {
854
+ define_one_arm_cp_reg_with_opaque(cpu, regs + i, opaque);
177
}
855
}
178
}
856
}
179
857
180
-static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
858
@@ -XXX,XX +XXX,XX @@ void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
181
+void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
859
* user-space cannot alter any values and dynamic values pertaining to
860
* execution state are hidden from user space view anyway.
861
*/
862
-void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
863
+void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len,
864
+ const ARMCPRegUserSpaceInfo *mods,
865
+ size_t mods_len)
182
{
866
{
183
long off = neon_element_offset(reg, ele, memop);
867
- const ARMCPRegUserSpaceInfo *m;
184
868
- ARMCPRegInfo *r;
185
@@ -XXX,XX +XXX,XX @@ static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
869
-
186
}
870
- for (m = mods; m->name; m++) {
187
}
871
+ for (size_t mi = 0; mi < mods_len; ++mi) {
188
872
+ const ARMCPRegUserSpaceInfo *m = mods + mi;
189
-static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
873
GPatternSpec *pat = NULL;
190
+void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
874
+
191
{
875
if (m->is_glob) {
192
long off = neon_element_offset(reg, ele, memop);
876
pat = g_pattern_spec_new(m->name);
193
877
}
194
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
878
- for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
195
index XXXXXXX..XXXXXXX 100644
879
+ for (size_t ri = 0; ri < regs_len; ++ri) {
196
--- a/target/arm/translate-vfp.c.inc
880
+ ARMCPRegInfo *r = regs + ri;
197
+++ b/target/arm/translate-vfp.c.inc
881
+
198
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
882
if (pat && g_pattern_match_string(pat, r->name)) {
199
* The most usual kind of VFP access check, for everything except
883
r->type = ARM_CP_CONST;
200
* FMXR/FMRX to the always-available special registers.
884
r->access = PL0U_R;
201
*/
202
-static bool vfp_access_check(DisasContext *s)
203
+bool vfp_access_check(DisasContext *s)
204
{
205
return full_vfp_access_check(s, false);
206
}
207
--
885
--
208
2.20.1
886
2.25.1
209
887
210
888
diff view generated by jsdifflib
1
On some boards, SCC config register CFG0 bit 0 controls whether
1
From: Richard Henderson <richard.henderson@linaro.org>
2
parts of the board memory map are remapped. Support this with:
3
* a device property scc-cfg0 so the board can specify the
4
initial value of the CFG0 register
5
* an outbound GPIO line which tracks bit 0 and which the board
6
can wire up to provide the remapping
7
2
3
These particular data structures are not modified at runtime.
4
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220501055028.646596-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
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: 20210504120912.23094-3-peter.maydell@linaro.org
12
---
10
---
13
include/hw/misc/mps2-scc.h | 9 +++++++++
11
target/arm/helper.c | 16 ++++++++--------
14
hw/misc/mps2-scc.c | 13 ++++++++++---
12
1 file changed, 8 insertions(+), 8 deletions(-)
15
2 files changed, 19 insertions(+), 3 deletions(-)
16
13
17
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/misc/mps2-scc.h
16
--- a/target/arm/helper.c
20
+++ b/include/hw/misc/mps2-scc.h
17
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
22
* + QOM property "scc-cfg4": value of the read-only CFG4 register
19
.resetvalue = cpu->pmceid1 },
23
* + QOM property "scc-aid": value of the read-only SCC_AID register
20
};
24
* + QOM property "scc-id": value of the read-only SCC_ID register
21
#ifdef CONFIG_USER_ONLY
25
+ * + QOM property "scc-cfg0": reset value of the CFG0 register
22
- ARMCPRegUserSpaceInfo v8_user_idregs[] = {
26
* + QOM property array "oscclk": reset values of the OSCCLK registers
23
+ static const ARMCPRegUserSpaceInfo v8_user_idregs[] = {
27
* (which are accessed via the SYS_CFG channel provided by this device)
24
{ .name = "ID_AA64PFR0_EL1",
28
+ * + named GPIO output "remap": this tracks the value of CFG0 register
25
.exported_bits = 0x000f000f00ff0000,
29
+ * bit 0. Boards where this bit controls memory remapping should
26
.fixed_bits = 0x0000000000000011 },
30
+ * connect this GPIO line to a function performing that mapping.
27
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
31
+ * Boards where bit 0 has no special function should leave the GPIO
28
*/
32
+ * output disconnected.
29
if (arm_feature(env, ARM_FEATURE_EL3)) {
33
*/
30
if (arm_feature(env, ARM_FEATURE_AARCH64)) {
34
#ifndef MPS2_SCC_H
31
- ARMCPRegInfo nsacr = {
35
#define MPS2_SCC_H
32
+ static const ARMCPRegInfo nsacr = {
36
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
33
.name = "NSACR", .type = ARM_CP_CONST,
37
uint32_t num_oscclk;
34
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
38
uint32_t *oscclk;
35
.access = PL1_RW, .accessfn = nsacr_access,
39
uint32_t *oscclk_reset;
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
40
+ uint32_t cfg0_reset;
37
};
41
+
38
define_one_arm_cp_reg(cpu, &nsacr);
42
+ qemu_irq remap;
39
} else {
43
};
40
- ARMCPRegInfo nsacr = {
44
41
+ static const ARMCPRegInfo nsacr = {
45
#endif
42
.name = "NSACR",
46
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
43
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
47
index XXXXXXX..XXXXXXX 100644
44
.access = PL3_RW | PL1_R,
48
--- a/hw/misc/mps2-scc.c
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
49
+++ b/hw/misc/mps2-scc.c
46
}
50
@@ -XXX,XX +XXX,XX @@
47
} else {
51
#include "qemu/bitops.h"
48
if (arm_feature(env, ARM_FEATURE_V8)) {
52
#include "trace.h"
49
- ARMCPRegInfo nsacr = {
53
#include "hw/sysbus.h"
50
+ static const ARMCPRegInfo nsacr = {
54
+#include "hw/irq.h"
51
.name = "NSACR", .type = ARM_CP_CONST,
55
#include "migration/vmstate.h"
52
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 2,
56
#include "hw/registerfields.h"
53
.access = PL1_R,
57
#include "hw/misc/mps2-scc.h"
54
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
58
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
55
.access = PL1_R, .type = ARM_CP_CONST,
59
switch (offset) {
56
.resetvalue = cpu->pmsav7_dregion << 8
60
case A_CFG0:
57
};
61
/*
58
- ARMCPRegInfo crn0_wi_reginfo = {
62
- * TODO on some boards bit 0 controls RAM remapping;
59
+ static const ARMCPRegInfo crn0_wi_reginfo = {
63
- * on others bit 1 is CPU_WAIT.
60
.name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
64
+ * On some boards bit 0 controls board-specific remapping;
61
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
65
+ * we always reflect bit 0 in the 'remap' GPIO output line,
62
.type = ARM_CP_NOP | ARM_CP_OVERRIDE
66
+ * and let the board wire it up or not as it chooses.
63
};
67
+ * TODO on some boards bit 1 is CPU_WAIT.
64
#ifdef CONFIG_USER_ONLY
68
*/
65
- ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
69
s->cfg0 = value;
66
+ static const ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
70
+ qemu_set_irq(s->remap, s->cfg0 & 1);
67
{ .name = "MIDR_EL1",
71
break;
68
.exported_bits = 0x00000000ffffffff },
72
case A_CFG1:
69
{ .name = "REVIDR_EL1" },
73
s->cfg1 = value;
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
74
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
71
.access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
75
int i;
72
};
76
73
#ifdef CONFIG_USER_ONLY
77
trace_mps2_scc_reset();
74
- ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
78
- s->cfg0 = 0;
75
+ static const ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
79
+ s->cfg0 = s->cfg0_reset;
76
{ .name = "MPIDR_EL1",
80
s->cfg1 = 0;
77
.fixed_bits = 0x0000000080000000 },
81
s->cfg2 = 0;
78
};
82
s->cfg5 = 0;
79
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
83
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_init(Object *obj)
80
}
84
81
85
memory_region_init_io(&s->iomem, obj, &mps2_scc_ops, s, "mps2-scc", 0x1000);
82
if (arm_feature(env, ARM_FEATURE_VBAR)) {
86
sysbus_init_mmio(sbd, &s->iomem);
83
- ARMCPRegInfo vbar_cp_reginfo[] = {
87
+ qdev_init_gpio_out_named(DEVICE(obj), &s->remap, "remap", 1);
84
+ static const ARMCPRegInfo vbar_cp_reginfo[] = {
88
}
85
{ .name = "VBAR", .state = ARM_CP_STATE_BOTH,
89
86
.opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0,
90
static void mps2_scc_realize(DeviceState *dev, Error **errp)
87
.access = PL1_RW, .writefn = vbar_write,
91
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
92
DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
93
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
94
DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
95
+ /* Reset value for CFG0 register */
96
+ DEFINE_PROP_UINT32("scc-cfg0", MPS2SCC, cfg0_reset, 0),
97
/*
98
* These are the initial settings for the source clocks on the board.
99
* In hardware they can be configured via a config file read by the
100
--
88
--
101
2.20.1
89
2.25.1
102
90
103
91
diff view generated by jsdifflib
1
Switch translate-neon.c.inc from being #included into translate.c
1
From: Richard Henderson <richard.henderson@linaro.org>
2
to being its own compilation unit.
2
3
3
Instead of defining ARM_CP_FLAG_MASK to remove flags,
4
define ARM_CP_SPECIAL_MASK to isolate special cases.
5
Sort the specials to the low bits. Use an enum.
6
7
Split the large comment block so as to document each
8
value separately.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20220501055028.646596-6-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-14-peter.maydell@linaro.org
8
---
14
---
9
target/arm/translate-a32.h | 3 +++
15
target/arm/cpregs.h | 130 +++++++++++++++++++++++--------------
10
.../arm/{translate-neon.c.inc => translate-neon.c} | 12 +++++++-----
16
target/arm/cpu.c | 4 +-
11
target/arm/translate.c | 3 ---
17
target/arm/helper.c | 4 +-
12
target/arm/meson.build | 7 ++++---
18
target/arm/translate-a64.c | 6 +-
13
4 files changed, 14 insertions(+), 11 deletions(-)
19
target/arm/translate.c | 6 +-
14
rename target/arm/{translate-neon.c.inc => translate-neon.c} (99%)
20
5 files changed, 92 insertions(+), 58 deletions(-)
15
21
16
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
22
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a32.h
24
--- a/target/arm/cpregs.h
19
+++ b/target/arm/translate-a32.h
25
+++ b/target/arm/cpregs.h
20
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@
21
bool disas_m_nocp(DisasContext *dc, uint32_t insn);
27
#define TARGET_ARM_CPREGS_H
22
bool disas_vfp(DisasContext *s, uint32_t insn);
28
23
bool disas_vfp_uncond(DisasContext *s, uint32_t insn);
29
/*
24
+bool disas_neon_dp(DisasContext *s, uint32_t insn);
30
- * ARMCPRegInfo type field bits. If the SPECIAL bit is set this is a
25
+bool disas_neon_ls(DisasContext *s, uint32_t insn);
31
- * special-behaviour cp reg and bits [11..8] indicate what behaviour
26
+bool disas_neon_shared(DisasContext *s, uint32_t insn);
32
- * it has. Otherwise it is a simple cp reg, where CONST indicates that
27
33
- * TCG can assume the value to be constant (ie load at translate time)
28
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
34
- * and 64BIT indicates a 64 bit wide coprocessor register. SUPPRESS_TB_END
29
void arm_gen_condlabel(DisasContext *s);
35
- * indicates that the TB should not be ended after a write to this register
30
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c
36
- * (the default is that the TB ends after cp writes). OVERRIDE permits
31
similarity index 99%
37
- * a register definition to override a previous definition for the
32
rename from target/arm/translate-neon.c.inc
38
- * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
33
rename to target/arm/translate-neon.c
39
- * old must have the OVERRIDE bit set.
34
index XXXXXXX..XXXXXXX 100644
40
- * ALIAS indicates that this register is an alias view of some underlying
35
--- a/target/arm/translate-neon.c.inc
41
- * state which is also visible via another register, and that the other
36
+++ b/target/arm/translate-neon.c
42
- * register is handling migration and reset; registers marked ALIAS will not be
37
@@ -XXX,XX +XXX,XX @@
43
- * migrated but may have their state set by syncing of register state from KVM.
38
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
44
- * NO_RAW indicates that this register has no underlying state and does not
45
- * support raw access for state saving/loading; it will not be used for either
46
- * migration or KVM state synchronization. (Typically this is for "registers"
47
- * which are actually used as instructions for cache maintenance and so on.)
48
- * IO indicates that this register does I/O and therefore its accesses
49
- * need to be marked with gen_io_start() and also end the TB. In particular,
50
- * registers which implement clocks or timers require this.
51
- * RAISES_EXC is for when the read or write hook might raise an exception;
52
- * the generated code will synchronize the CPU state before calling the hook
53
- * so that it is safe for the hook to call raise_exception().
54
- * NEWEL is for writes to registers that might change the exception
55
- * level - typically on older ARM chips. For those cases we need to
56
- * re-read the new el when recomputing the translation flags.
57
+ * ARMCPRegInfo type field bits:
39
*/
58
*/
40
59
-#define ARM_CP_SPECIAL 0x0001
41
-/*
60
-#define ARM_CP_CONST 0x0002
42
- * This file is intended to be included from translate.c; it uses
61
-#define ARM_CP_64BIT 0x0004
43
- * some macros and definitions provided by that file.
62
-#define ARM_CP_SUPPRESS_TB_END 0x0008
44
- * It might be possible to convert it to a standalone .c file eventually.
63
-#define ARM_CP_OVERRIDE 0x0010
45
- */
64
-#define ARM_CP_ALIAS 0x0020
46
+#include "qemu/osdep.h"
65
-#define ARM_CP_IO 0x0040
47
+#include "tcg/tcg-op.h"
66
-#define ARM_CP_NO_RAW 0x0080
48
+#include "tcg/tcg-op-gvec.h"
67
-#define ARM_CP_NOP (ARM_CP_SPECIAL | 0x0100)
49
+#include "exec/exec-all.h"
68
-#define ARM_CP_WFI (ARM_CP_SPECIAL | 0x0200)
50
+#include "exec/gen-icount.h"
69
-#define ARM_CP_NZCV (ARM_CP_SPECIAL | 0x0300)
51
+#include "translate.h"
70
-#define ARM_CP_CURRENTEL (ARM_CP_SPECIAL | 0x0400)
52
+#include "translate-a32.h"
71
-#define ARM_CP_DC_ZVA (ARM_CP_SPECIAL | 0x0500)
53
72
-#define ARM_CP_DC_GVA (ARM_CP_SPECIAL | 0x0600)
54
static inline int plus1(DisasContext *s, int x)
73
-#define ARM_CP_DC_GZVA (ARM_CP_SPECIAL | 0x0700)
55
{
74
-#define ARM_LAST_SPECIAL ARM_CP_DC_GZVA
75
-#define ARM_CP_FPU 0x1000
76
-#define ARM_CP_SVE 0x2000
77
-#define ARM_CP_NO_GDB 0x4000
78
-#define ARM_CP_RAISES_EXC 0x8000
79
-#define ARM_CP_NEWEL 0x10000
80
-/* Mask of only the flag bits in a type field */
81
-#define ARM_CP_FLAG_MASK 0x1f0ff
82
+enum {
83
+ /*
84
+ * Register must be handled specially during translation.
85
+ * The method is one of the values below:
86
+ */
87
+ ARM_CP_SPECIAL_MASK = 0x000f,
88
+ /* Special: no change to PE state: writes ignored, reads ignored. */
89
+ ARM_CP_NOP = 0x0001,
90
+ /* Special: sysreg is WFI, for v5 and v6. */
91
+ ARM_CP_WFI = 0x0002,
92
+ /* Special: sysreg is NZCV. */
93
+ ARM_CP_NZCV = 0x0003,
94
+ /* Special: sysreg is CURRENTEL. */
95
+ ARM_CP_CURRENTEL = 0x0004,
96
+ /* Special: sysreg is DC ZVA or similar. */
97
+ ARM_CP_DC_ZVA = 0x0005,
98
+ ARM_CP_DC_GVA = 0x0006,
99
+ ARM_CP_DC_GZVA = 0x0007,
100
+
101
+ /* Flag: reads produce resetvalue; writes ignored. */
102
+ ARM_CP_CONST = 1 << 4,
103
+ /* Flag: For ARM_CP_STATE_AA32, sysreg is 64-bit. */
104
+ ARM_CP_64BIT = 1 << 5,
105
+ /*
106
+ * Flag: TB should not be ended after a write to this register
107
+ * (the default is that the TB ends after cp writes).
108
+ */
109
+ ARM_CP_SUPPRESS_TB_END = 1 << 6,
110
+ /*
111
+ * Flag: Permit a register definition to override a previous definition
112
+ * for the same (cp, is64, crn, crm, opc1, opc2) tuple: either the new
113
+ * or the old must have the ARM_CP_OVERRIDE bit set.
114
+ */
115
+ ARM_CP_OVERRIDE = 1 << 7,
116
+ /*
117
+ * Flag: Register is an alias view of some underlying state which is also
118
+ * visible via another register, and that the other register is handling
119
+ * migration and reset; registers marked ARM_CP_ALIAS will not be migrated
120
+ * but may have their state set by syncing of register state from KVM.
121
+ */
122
+ ARM_CP_ALIAS = 1 << 8,
123
+ /*
124
+ * Flag: Register does I/O and therefore its accesses need to be marked
125
+ * with gen_io_start() and also end the TB. In particular, registers which
126
+ * implement clocks or timers require this.
127
+ */
128
+ ARM_CP_IO = 1 << 9,
129
+ /*
130
+ * Flag: Register has no underlying state and does not support raw access
131
+ * for state saving/loading; it will not be used for either migration or
132
+ * KVM state synchronization. Typically this is for "registers" which are
133
+ * actually used as instructions for cache maintenance and so on.
134
+ */
135
+ ARM_CP_NO_RAW = 1 << 10,
136
+ /*
137
+ * Flag: The read or write hook might raise an exception; the generated
138
+ * code will synchronize the CPU state before calling the hook so that it
139
+ * is safe for the hook to call raise_exception().
140
+ */
141
+ ARM_CP_RAISES_EXC = 1 << 11,
142
+ /*
143
+ * Flag: Writes to the sysreg might change the exception level - typically
144
+ * on older ARM chips. For those cases we need to re-read the new el when
145
+ * recomputing the translation flags.
146
+ */
147
+ ARM_CP_NEWEL = 1 << 12,
148
+ /*
149
+ * Flag: Access check for this sysreg is identical to accessing FPU state
150
+ * from an instruction: use translation fp_access_check().
151
+ */
152
+ ARM_CP_FPU = 1 << 13,
153
+ /*
154
+ * Flag: Access check for this sysreg is identical to accessing SVE state
155
+ * from an instruction: use translation sve_access_check().
156
+ */
157
+ ARM_CP_SVE = 1 << 14,
158
+ /* Flag: Do not expose in gdb sysreg xml. */
159
+ ARM_CP_NO_GDB = 1 << 15,
160
+};
161
162
/*
163
* Valid values for ARMCPRegInfo state field, indicating which of
164
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
165
index XXXXXXX..XXXXXXX 100644
166
--- a/target/arm/cpu.c
167
+++ b/target/arm/cpu.c
168
@@ -XXX,XX +XXX,XX @@ static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
169
ARMCPRegInfo *ri = value;
170
ARMCPU *cpu = opaque;
171
172
- if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS)) {
173
+ if (ri->type & (ARM_CP_SPECIAL_MASK | ARM_CP_ALIAS)) {
174
return;
175
}
176
177
@@ -XXX,XX +XXX,XX @@ static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque)
178
ARMCPU *cpu = opaque;
179
uint64_t oldvalue, newvalue;
180
181
- if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS | ARM_CP_NO_RAW)) {
182
+ if (ri->type & (ARM_CP_SPECIAL_MASK | ARM_CP_ALIAS | ARM_CP_NO_RAW)) {
183
return;
184
}
185
186
diff --git a/target/arm/helper.c b/target/arm/helper.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/target/arm/helper.c
189
+++ b/target/arm/helper.c
190
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
191
* multiple times. Special registers (ie NOP/WFI) are
192
* never migratable and not even raw-accessible.
193
*/
194
- if ((r->type & ARM_CP_SPECIAL)) {
195
+ if (r->type & ARM_CP_SPECIAL_MASK) {
196
r2->type |= ARM_CP_NO_RAW;
197
}
198
if (((r->crm == CP_ANY) && crm != 0) ||
199
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
200
/* Check that the register definition has enough info to handle
201
* reads and writes if they are permitted.
202
*/
203
- if (!(r->type & (ARM_CP_SPECIAL|ARM_CP_CONST))) {
204
+ if (!(r->type & (ARM_CP_SPECIAL_MASK | ARM_CP_CONST))) {
205
if (r->access & PL3_R) {
206
assert((r->fieldoffset ||
207
(r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1])) ||
208
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
209
index XXXXXXX..XXXXXXX 100644
210
--- a/target/arm/translate-a64.c
211
+++ b/target/arm/translate-a64.c
212
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
213
}
214
215
/* Handle special cases first */
216
- switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
217
+ switch (ri->type & ARM_CP_SPECIAL_MASK) {
218
+ case 0:
219
+ break;
220
case ARM_CP_NOP:
221
return;
222
case ARM_CP_NZCV:
223
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
224
}
225
return;
226
default:
227
- break;
228
+ g_assert_not_reached();
229
}
230
if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
231
return;
56
diff --git a/target/arm/translate.c b/target/arm/translate.c
232
diff --git a/target/arm/translate.c b/target/arm/translate.c
57
index XXXXXXX..XXXXXXX 100644
233
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate.c
234
--- a/target/arm/translate.c
59
+++ b/target/arm/translate.c
235
+++ b/target/arm/translate.c
60
@@ -XXX,XX +XXX,XX @@ void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
236
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
61
237
}
62
#define ARM_CP_RW_BIT (1 << 20)
238
63
239
/* Handle special cases first */
64
-/* Include the Neon decoder */
240
- switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
65
-#include "translate-neon.c.inc"
241
+ switch (ri->type & ARM_CP_SPECIAL_MASK) {
66
-
242
+ case 0:
67
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
243
+ break;
68
{
244
case ARM_CP_NOP:
69
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
245
return;
70
diff --git a/target/arm/meson.build b/target/arm/meson.build
246
case ARM_CP_WFI:
71
index XXXXXXX..XXXXXXX 100644
247
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
72
--- a/target/arm/meson.build
248
s->base.is_jmp = DISAS_WFI;
73
+++ b/target/arm/meson.build
249
return;
74
@@ -XXX,XX +XXX,XX @@
250
default:
75
gen = [
251
- break;
76
decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
252
+ g_assert_not_reached();
77
- decodetree.process('neon-shared.decode', extra_args: '--static-decode=disas_neon_shared'),
253
}
78
- decodetree.process('neon-dp.decode', extra_args: '--static-decode=disas_neon_dp'),
254
79
- decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
255
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
80
+ decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
81
+ decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
82
+ decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
83
decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
84
decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
85
decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
86
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
87
'tlb_helper.c',
88
'translate.c',
89
'translate-m-nocp.c',
90
+ 'translate-neon.c',
91
'translate-vfp.c',
92
'vec_helper.c',
93
'vfp_helper.c',
94
--
256
--
95
2.20.1
257
2.25.1
96
97
diff view generated by jsdifflib
1
The unallocated_encoding() function is the same in both
1
From: Richard Henderson <richard.henderson@linaro.org>
2
translate-a64.c and translate.c; make the translate.c function global
3
and drop the translate-a64.c version. To do this we need to also
4
share gen_exception_insn(), which currently exists in two slightly
5
different versions for A32 and A64: merge those into a single
6
function that can work for both.
7
2
8
This will be useful for splitting up translate.c, which will require
3
Standardize on g_assert_not_reached() for "should not happen".
9
unallocated_encoding() to no longer be file-local. It's also
4
Retain abort() when preceeded by fprintf or error_report.
10
hopefully less confusing to have only one version of the function
11
rather than two.
12
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220501055028.646596-7-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210430132740.10391-3-peter.maydell@linaro.org
16
---
10
---
17
target/arm/translate-a64.h | 2 --
11
target/arm/helper.c | 7 +++----
18
target/arm/translate.h | 3 +++
12
target/arm/hvf/hvf.c | 2 +-
19
target/arm/translate-a64.c | 15 ---------------
13
target/arm/kvm-stub.c | 4 ++--
20
target/arm/translate.c | 14 +++++++++-----
14
target/arm/kvm.c | 4 ++--
21
4 files changed, 12 insertions(+), 22 deletions(-)
15
target/arm/machine.c | 4 ++--
16
target/arm/translate-a64.c | 4 ++--
17
target/arm/translate-neon.c | 2 +-
18
target/arm/translate.c | 4 ++--
19
8 files changed, 15 insertions(+), 16 deletions(-)
22
20
23
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-a64.h
23
--- a/target/arm/helper.c
26
+++ b/target/arm/translate-a64.h
24
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
26
break;
27
default:
28
/* broken reginfo with out-of-range opc1 */
29
- assert(false);
30
- break;
31
+ g_assert_not_reached();
32
}
33
/* assert our permissions are not too lax (stricter is fine) */
34
assert((r->access & ~mask) == 0);
35
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
36
break;
37
default:
38
/* Never happens, but compiler isn't smart enough to tell. */
39
- abort();
40
+ g_assert_not_reached();
41
}
42
}
43
*prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
44
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
45
break;
46
default:
47
/* Never happens, but compiler isn't smart enough to tell. */
48
- abort();
49
+ g_assert_not_reached();
50
}
51
}
52
if (domain_prot == 3) {
53
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/hvf/hvf.c
56
+++ b/target/arm/hvf/hvf.c
57
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
58
/* we got kicked, no exit to process */
59
return 0;
60
default:
61
- assert(0);
62
+ g_assert_not_reached();
63
}
64
65
hvf_sync_vtimer(cpu);
66
diff --git a/target/arm/kvm-stub.c b/target/arm/kvm-stub.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/kvm-stub.c
69
+++ b/target/arm/kvm-stub.c
27
@@ -XXX,XX +XXX,XX @@
70
@@ -XXX,XX +XXX,XX @@
28
#ifndef TARGET_ARM_TRANSLATE_A64_H
71
29
#define TARGET_ARM_TRANSLATE_A64_H
72
bool write_kvmstate_to_list(ARMCPU *cpu)
30
73
{
31
-void unallocated_encoding(DisasContext *s);
74
- abort();
32
-
75
+ g_assert_not_reached();
33
#define unsupported_encoding(s, insn) \
76
}
34
do { \
77
35
qemu_log_mask(LOG_UNIMP, \
78
bool write_list_to_kvmstate(ARMCPU *cpu, int level)
36
diff --git a/target/arm/translate.h b/target/arm/translate.h
79
{
80
- abort();
81
+ g_assert_not_reached();
82
}
83
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
37
index XXXXXXX..XXXXXXX 100644
84
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate.h
85
--- a/target/arm/kvm.c
39
+++ b/target/arm/translate.h
86
+++ b/target/arm/kvm.c
40
@@ -XXX,XX +XXX,XX @@ void arm_free_cc(DisasCompare *cmp);
87
@@ -XXX,XX +XXX,XX @@ bool write_kvmstate_to_list(ARMCPU *cpu)
41
void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
88
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
42
void arm_gen_test_cc(int cc, TCGLabel *label);
89
break;
43
MemOp pow2_align(unsigned i);
90
default:
44
+void unallocated_encoding(DisasContext *s);
91
- abort();
45
+void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
92
+ g_assert_not_reached();
46
+ uint32_t syn, uint32_t target_el);
93
}
47
94
if (ret) {
48
/* Return state of Alternate Half-precision flag, caller frees result */
95
ok = false;
49
static inline TCGv_i32 get_ahp_flag(void)
96
@@ -XXX,XX +XXX,XX @@ bool write_list_to_kvmstate(ARMCPU *cpu, int level)
97
r.addr = (uintptr_t)(cpu->cpreg_values + i);
98
break;
99
default:
100
- abort();
101
+ g_assert_not_reached();
102
}
103
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
104
if (ret) {
105
diff --git a/target/arm/machine.c b/target/arm/machine.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/machine.c
108
+++ b/target/arm/machine.c
109
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
110
if (kvm_enabled()) {
111
if (!write_kvmstate_to_list(cpu)) {
112
/* This should never fail */
113
- abort();
114
+ g_assert_not_reached();
115
}
116
117
/*
118
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
119
} else {
120
if (!write_cpustate_to_list(cpu, false)) {
121
/* This should never fail. */
122
- abort();
123
+ g_assert_not_reached();
124
}
125
}
126
50
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
127
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
51
index XXXXXXX..XXXXXXX 100644
128
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate-a64.c
129
--- a/target/arm/translate-a64.c
53
+++ b/target/arm/translate-a64.c
130
+++ b/target/arm/translate-a64.c
54
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, uint64_t pc, int excp)
131
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
55
s->base.is_jmp = DISAS_NORETURN;
132
gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst);
56
}
133
break;
57
134
default:
58
-static void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
135
- abort();
59
- uint32_t syndrome, uint32_t target_el)
136
+ g_assert_not_reached();
60
-{
137
}
61
- gen_a64_set_pc_im(pc);
138
62
- gen_exception(excp, syndrome, target_el);
139
write_fp_sreg(s, rd, tcg_res);
63
- s->base.is_jmp = DISAS_NORETURN;
140
@@ -XXX,XX +XXX,XX @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
64
-}
141
break;
65
-
142
}
66
static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syndrome)
143
default:
67
{
144
- abort();
68
TCGv_i32 tcg_syn;
145
+ g_assert_not_reached();
69
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
70
}
146
}
71
}
147
}
72
148
73
-void unallocated_encoding(DisasContext *s)
149
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
74
-{
150
index XXXXXXX..XXXXXXX 100644
75
- /* Unallocated and reserved encodings are uncategorized */
151
--- a/target/arm/translate-neon.c
76
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
152
+++ b/target/arm/translate-neon.c
77
- default_exception_el(s));
153
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
78
-}
154
}
79
-
155
break;
80
static void init_tmp_a64_array(DisasContext *s)
156
default:
81
{
157
- abort();
82
#ifdef CONFIG_DEBUG_TCG
158
+ g_assert_not_reached();
159
}
160
if ((vd + a->stride * (nregs - 1)) > 31) {
161
/*
83
diff --git a/target/arm/translate.c b/target/arm/translate.c
162
diff --git a/target/arm/translate.c b/target/arm/translate.c
84
index XXXXXXX..XXXXXXX 100644
163
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/translate.c
164
--- a/target/arm/translate.c
86
+++ b/target/arm/translate.c
165
+++ b/target/arm/translate.c
87
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
166
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
88
s->base.is_jmp = DISAS_NORETURN;
167
offset = 4;
89
}
168
break;
90
169
default:
91
-static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
170
- abort();
92
- int syn, uint32_t target_el)
171
+ g_assert_not_reached();
93
+void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
172
}
94
+ uint32_t syn, uint32_t target_el)
173
tcg_gen_addi_i32(addr, addr, offset);
95
{
174
tmp = load_reg(s, 14);
96
- gen_set_condexec(s);
175
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
97
- gen_set_pc_im(s, pc);
176
offset = 0;
98
+ if (s->aarch64) {
177
break;
99
+ gen_a64_set_pc_im(pc);
178
default:
100
+ } else {
179
- abort();
101
+ gen_set_condexec(s);
180
+ g_assert_not_reached();
102
+ gen_set_pc_im(s, pc);
181
}
103
+ }
182
tcg_gen_addi_i32(addr, addr, offset);
104
gen_exception(excp, syn, target_el);
183
gen_helper_set_r13_banked(cpu_env, tcg_constant_i32(mode), addr);
105
s->base.is_jmp = DISAS_NORETURN;
106
}
107
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
108
s->base.is_jmp = DISAS_NORETURN;
109
}
110
111
-static void unallocated_encoding(DisasContext *s)
112
+void unallocated_encoding(DisasContext *s)
113
{
114
/* Unallocated and reserved encodings are uncategorized */
115
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
116
--
184
--
117
2.20.1
185
2.25.1
118
119
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Commit dfc388797cc4 ("hw/arm: xlnx: Set all boards' GEM 'phy-addr'
3
Create a typedef as well, and use it in ARMCPRegInfo.
4
property value to 23") configured the PHY address for xilinx-zynq-a9
4
This won't be perfect for debugging, but it'll nicely
5
to 23. When trying to boot xilinx-zynq-a9 with zynq-zc702.dtb or
5
display the most common cases.
6
zynq-zc706.dtb, this results in the following error message when
7
trying to use the Ethernet interface.
8
6
9
macb e000b000.ethernet eth0: Could not attach PHY (-19)
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
The devicetree files for ZC702 and ZC706 configure PHY address 7. The
9
Message-id: 20220501055028.646596-8-richard.henderson@linaro.org
12
documentation for the ZC702 and ZC706 evaluation boards suggest that the
13
PHY address is 7, not 23. Other boards use PHY address 0, 1, 3, or 7.
14
I was unable to find a documentation or a devicetree file suggesting
15
or using PHY address 23. The Ethernet interface starts working with
16
zynq-zc702.dtb and zynq-zc706.dtb when setting the PHY address to 7,
17
so let's use it.
18
19
Cc: Bin Meng <bin.meng@windriver.com>
20
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
21
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
22
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
23
Message-id: 20210504124140.1100346-1-linux@roeck-us.net
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
11
---
26
hw/arm/xilinx_zynq.c | 2 +-
12
target/arm/cpregs.h | 44 +++++++++++++++++++++++---------------------
27
1 file changed, 1 insertion(+), 1 deletion(-)
13
target/arm/helper.c | 2 +-
14
2 files changed, 24 insertions(+), 22 deletions(-)
28
15
29
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
30
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/xilinx_zynq.c
18
--- a/target/arm/cpregs.h
32
+++ b/hw/arm/xilinx_zynq.c
19
+++ b/target/arm/cpregs.h
33
@@ -XXX,XX +XXX,XX @@ static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
20
@@ -XXX,XX +XXX,XX @@ enum {
34
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
21
* described with these bits, then use a laxer set of restrictions, and
35
qdev_set_nic_properties(dev, nd);
22
* do the more restrictive/complex check inside a helper function.
36
}
23
*/
37
- object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort);
24
-#define PL3_R 0x80
38
+ object_property_set_int(OBJECT(dev), "phy-addr", 7, &error_abort);
25
-#define PL3_W 0x40
39
s = SYS_BUS_DEVICE(dev);
26
-#define PL2_R (0x20 | PL3_R)
40
sysbus_realize_and_unref(s, &error_fatal);
27
-#define PL2_W (0x10 | PL3_W)
41
sysbus_mmio_map(s, 0, base);
28
-#define PL1_R (0x08 | PL2_R)
29
-#define PL1_W (0x04 | PL2_W)
30
-#define PL0_R (0x02 | PL1_R)
31
-#define PL0_W (0x01 | PL1_W)
32
+typedef enum {
33
+ PL3_R = 0x80,
34
+ PL3_W = 0x40,
35
+ PL2_R = 0x20 | PL3_R,
36
+ PL2_W = 0x10 | PL3_W,
37
+ PL1_R = 0x08 | PL2_R,
38
+ PL1_W = 0x04 | PL2_W,
39
+ PL0_R = 0x02 | PL1_R,
40
+ PL0_W = 0x01 | PL1_W,
41
42
-/*
43
- * For user-mode some registers are accessible to EL0 via a kernel
44
- * trap-and-emulate ABI. In this case we define the read permissions
45
- * as actually being PL0_R. However some bits of any given register
46
- * may still be masked.
47
- */
48
+ /*
49
+ * For user-mode some registers are accessible to EL0 via a kernel
50
+ * trap-and-emulate ABI. In this case we define the read permissions
51
+ * as actually being PL0_R. However some bits of any given register
52
+ * may still be masked.
53
+ */
54
#ifdef CONFIG_USER_ONLY
55
-#define PL0U_R PL0_R
56
+ PL0U_R = PL0_R,
57
#else
58
-#define PL0U_R PL1_R
59
+ PL0U_R = PL1_R,
60
#endif
61
62
-#define PL3_RW (PL3_R | PL3_W)
63
-#define PL2_RW (PL2_R | PL2_W)
64
-#define PL1_RW (PL1_R | PL1_W)
65
-#define PL0_RW (PL0_R | PL0_W)
66
+ PL3_RW = PL3_R | PL3_W,
67
+ PL2_RW = PL2_R | PL2_W,
68
+ PL1_RW = PL1_R | PL1_W,
69
+ PL0_RW = PL0_R | PL0_W,
70
+} CPAccessRights;
71
72
typedef enum CPAccessResult {
73
/* Access is permitted */
74
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
75
/* Register type: ARM_CP_* bits/values */
76
int type;
77
/* Access rights: PL*_[RW] */
78
- int access;
79
+ CPAccessRights access;
80
/* Security state: ARM_CP_SECSTATE_* bits/values */
81
int secure;
82
/*
83
diff --git a/target/arm/helper.c b/target/arm/helper.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/helper.c
86
+++ b/target/arm/helper.c
87
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
88
* to encompass the generic architectural permission check.
89
*/
90
if (r->state != ARM_CP_STATE_AA32) {
91
- int mask = 0;
92
+ CPAccessRights mask;
93
switch (r->opc1) {
94
case 0:
95
/* min_EL EL1, but some accessible to EL0 via kernel ABI */
42
--
96
--
43
2.20.1
97
2.25.1
44
45
diff view generated by jsdifflib
1
Make dis-asm.h handle being included outside an 'extern "C"' block;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
this allows us to remove the 'extern "C"' blocks that our two C++
3
files that include it are using.
4
2
3
Give this enum a name and use in ARMCPRegInfo,
4
add_cpreg_to_hashtable and define_one_arm_cp_reg_with_opaque.
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220501055028.646596-9-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
---
11
---
8
include/disas/dis-asm.h | 12 ++++++++++--
12
target/arm/cpregs.h | 6 +++---
9
disas/arm-a64.cc | 2 --
13
target/arm/helper.c | 6 ++++--
10
disas/nanomips.cpp | 2 --
14
2 files changed, 7 insertions(+), 5 deletions(-)
11
3 files changed, 10 insertions(+), 6 deletions(-)
12
15
13
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/include/disas/dis-asm.h
18
--- a/target/arm/cpregs.h
16
+++ b/include/disas/dis-asm.h
19
+++ b/target/arm/cpregs.h
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ enum {
18
#ifndef DISAS_DIS_ASM_H
21
* Note that we rely on the values of these enums as we iterate through
19
#define DISAS_DIS_ASM_H
22
* the various states in some places.
20
23
*/
21
+#include "qemu/bswap.h"
24
-enum {
25
+typedef enum {
26
ARM_CP_STATE_AA32 = 0,
27
ARM_CP_STATE_AA64 = 1,
28
ARM_CP_STATE_BOTH = 2,
29
-};
30
+} CPState;
31
32
/*
33
* ARM CP register secure state flags. These flags identify security state
34
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
35
uint8_t opc1;
36
uint8_t opc2;
37
/* Execution state in which this register is visible: ARM_CP_STATE_* */
38
- int state;
39
+ CPState state;
40
/* Register type: ARM_CP_* bits/values */
41
int type;
42
/* Access rights: PL*_[RW] */
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/helper.c
46
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
48
}
49
50
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
51
- void *opaque, int state, int secstate,
52
+ void *opaque, CPState state, int secstate,
53
int crm, int opc1, int opc2,
54
const char *name)
55
{
56
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
57
* bits; the ARM_CP_64BIT* flag applies only to the AArch32 view of
58
* the register, if any.
59
*/
60
- int crm, opc1, opc2, state;
61
+ int crm, opc1, opc2;
62
int crmmin = (r->crm == CP_ANY) ? 0 : r->crm;
63
int crmmax = (r->crm == CP_ANY) ? 15 : r->crm;
64
int opc1min = (r->opc1 == CP_ANY) ? 0 : r->opc1;
65
int opc1max = (r->opc1 == CP_ANY) ? 7 : r->opc1;
66
int opc2min = (r->opc2 == CP_ANY) ? 0 : r->opc2;
67
int opc2max = (r->opc2 == CP_ANY) ? 7 : r->opc2;
68
+ CPState state;
22
+
69
+
23
+#ifdef __cplusplus
70
/* 64 bit registers have only CRm and Opc1 fields */
24
+extern "C" {
71
assert(!((r->type & ARM_CP_64BIT) && (r->opc2 || r->crn)));
25
+#endif
72
/* op0 only exists in the AArch64 encodings */
26
+
27
typedef void *PTR;
28
typedef uint64_t bfd_vma;
29
typedef int64_t bfd_signed_vma;
30
@@ -XXX,XX +XXX,XX @@ bool cap_disas_plugin(disassemble_info *info, uint64_t pc, size_t size);
31
32
/* from libbfd */
33
34
-#include "qemu/bswap.h"
35
-
36
static inline bfd_vma bfd_getl64(const bfd_byte *addr)
37
{
38
return ldq_le_p(addr);
39
@@ -XXX,XX +XXX,XX @@ static inline bfd_vma bfd_getb16(const bfd_byte *addr)
40
41
typedef bool bfd_boolean;
42
43
+#ifdef __cplusplus
44
+}
45
+#endif
46
+
47
#endif /* DISAS_DIS_ASM_H */
48
diff --git a/disas/arm-a64.cc b/disas/arm-a64.cc
49
index XXXXXXX..XXXXXXX 100644
50
--- a/disas/arm-a64.cc
51
+++ b/disas/arm-a64.cc
52
@@ -XXX,XX +XXX,XX @@
53
*/
54
55
#include "qemu/osdep.h"
56
-extern "C" {
57
#include "disas/dis-asm.h"
58
-}
59
60
#include "vixl/a64/disasm-a64.h"
61
62
diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
63
index XXXXXXX..XXXXXXX 100644
64
--- a/disas/nanomips.cpp
65
+++ b/disas/nanomips.cpp
66
@@ -XXX,XX +XXX,XX @@
67
*/
68
69
#include "qemu/osdep.h"
70
-extern "C" {
71
#include "disas/dis-asm.h"
72
-}
73
74
#include <cstring>
75
#include <stdexcept>
76
--
73
--
77
2.20.1
74
2.25.1
78
75
79
76
diff view generated by jsdifflib
1
Both os-win32.h and os-posix.h include system header files. Instead
1
From: Richard Henderson <richard.henderson@linaro.org>
2
of having osdep.h include them inside its 'extern "C"' block, make
3
these headers handle that themselves, so that we don't include the
4
system headers inside 'extern "C"'.
5
2
6
This doesn't fix any current problems, but it's conceptually the
3
Give this enum a name and use in ARMCPRegInfo and add_cpreg_to_hashtable.
7
right way to handle system headers.
4
Add the enumerator ARM_CP_SECSTATE_BOTH to clarify how 0
5
is handled in define_one_arm_cp_reg_with_opaque.
8
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220501055028.646596-10-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
---
11
---
12
include/qemu/osdep.h | 8 ++++----
12
target/arm/cpregs.h | 7 ++++---
13
include/sysemu/os-posix.h | 8 ++++++++
13
target/arm/helper.c | 7 +++++--
14
include/sysemu/os-win32.h | 8 ++++++++
14
2 files changed, 9 insertions(+), 5 deletions(-)
15
3 files changed, 20 insertions(+), 4 deletions(-)
16
15
17
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
16
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/include/qemu/osdep.h
18
--- a/target/arm/cpregs.h
20
+++ b/include/qemu/osdep.h
19
+++ b/target/arm/cpregs.h
21
@@ -XXX,XX +XXX,XX @@ QEMU_EXTERN_C int daemon(int, int);
20
@@ -XXX,XX +XXX,XX @@ typedef enum {
21
* registered entry will only have one to identify whether the entry is secure
22
* or non-secure.
22
*/
23
*/
23
#include "glib-compat.h"
24
-enum {
24
25
+typedef enum {
25
-#ifdef __cplusplus
26
+ ARM_CP_SECSTATE_BOTH = 0, /* define one cpreg for each secstate */
26
-extern "C" {
27
ARM_CP_SECSTATE_S = (1 << 0), /* bit[0]: Secure state register */
27
-#endif
28
ARM_CP_SECSTATE_NS = (1 << 1), /* bit[1]: Non-secure state register */
28
-
29
-};
29
#ifdef _WIN32
30
+} CPSecureState;
30
#include "sysemu/os-win32.h"
31
#endif
32
@@ -XXX,XX +XXX,XX @@ extern "C" {
33
#include "sysemu/os-posix.h"
34
#endif
35
36
+#ifdef __cplusplus
37
+extern "C" {
38
+#endif
39
+
40
#include "qemu/typedefs.h"
41
31
42
/*
32
/*
43
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
33
* Access rights:
34
@@ -XXX,XX +XXX,XX @@ struct ARMCPRegInfo {
35
/* Access rights: PL*_[RW] */
36
CPAccessRights access;
37
/* Security state: ARM_CP_SECSTATE_* bits/values */
38
- int secure;
39
+ CPSecureState secure;
40
/*
41
* The opaque pointer passed to define_arm_cp_regs_with_opaque() when
42
* this register was defined: can be used to hand data through to the
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
44
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/sysemu/os-posix.h
45
--- a/target/arm/helper.c
46
+++ b/include/sysemu/os-posix.h
46
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@
47
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
48
#include <sys/sysmacros.h>
49
#endif
50
51
+#ifdef __cplusplus
52
+extern "C" {
53
+#endif
54
+
55
void os_set_line_buffering(void);
56
void os_set_proc_name(const char *s);
57
void os_setup_signal_handling(void);
58
@@ -XXX,XX +XXX,XX @@ static inline void qemu_funlockfile(FILE *f)
59
funlockfile(f);
60
}
48
}
61
49
62
+#ifdef __cplusplus
50
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
63
+}
51
- void *opaque, CPState state, int secstate,
64
+#endif
52
+ void *opaque, CPState state,
65
+
53
+ CPSecureState secstate,
66
#endif
54
int crm, int opc1, int opc2,
67
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
55
const char *name)
68
index XXXXXXX..XXXXXXX 100644
56
{
69
--- a/include/sysemu/os-win32.h
57
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
70
+++ b/include/sysemu/os-win32.h
58
r->secure, crm, opc1, opc2,
71
@@ -XXX,XX +XXX,XX @@
59
r->name);
72
#include <windows.h>
60
break;
73
#include <ws2tcpip.h>
61
- default:
74
62
+ case ARM_CP_SECSTATE_BOTH:
75
+#ifdef __cplusplus
63
name = g_strdup_printf("%s_S", r->name);
76
+extern "C" {
64
add_cpreg_to_hashtable(cpu, r, opaque, state,
77
+#endif
65
ARM_CP_SECSTATE_S,
78
+
66
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
79
#if defined(_WIN64)
67
ARM_CP_SECSTATE_NS,
80
/* On w64, setjmp is implemented by _setjmp which needs a second parameter.
68
crm, opc1, opc2, r->name);
81
* If this parameter is NULL, longjump does no stack unwinding.
69
break;
82
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags);
70
+ default:
83
ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
71
+ g_assert_not_reached();
84
struct sockaddr *addr, socklen_t *addrlen);
72
}
85
73
} else {
86
+#ifdef __cplusplus
74
/* AArch64 registers get mapped to non-secure instance
87
+}
88
+#endif
89
+
90
#endif
91
--
75
--
92
2.20.1
76
2.25.1
93
94
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The i.MX25 PDK board has 2 banks for SDRAM, each can
3
The new_key field is always non-zero -- drop the if.
4
address up to 256 MiB. So the total RAM usable for this
5
board is 512M. When we ask for more we get a misleading
6
error message:
7
4
8
$ qemu-system-arm -M imx25-pdk -m 513M
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
qemu-system-arm: Invalid RAM size, should be 128 MiB
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
7
Message-id: 20220501055028.646596-11-richard.henderson@linaro.org
11
Update the error message to better match the reality:
8
[PMM: reinstated dropped PL3_RW mask]
12
13
$ qemu-system-arm -M imx25-pdk -m 513M
14
qemu-system-arm: RAM size more than 512 MiB is not supported
15
16
Fixes: bf350daae02 ("arm/imx25_pdk: drop RAM size fixup")
17
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
20
Message-id: 20210407225608.1882855-1-f4bug@amsat.org
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
10
---
23
hw/arm/imx25_pdk.c | 5 ++---
11
target/arm/helper.c | 23 +++++++++++------------
24
1 file changed, 2 insertions(+), 3 deletions(-)
12
1 file changed, 11 insertions(+), 12 deletions(-)
25
13
26
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/imx25_pdk.c
16
--- a/target/arm/helper.c
29
+++ b/hw/arm/imx25_pdk.c
17
+++ b/target/arm/helper.c
30
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info imx25_pdk_binfo;
18
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
31
19
32
static void imx25_pdk_init(MachineState *machine)
20
for (i = 0; i < ARRAY_SIZE(aliases); i++) {
33
{
21
const struct E2HAlias *a = &aliases[i];
34
- MachineClass *mc = MACHINE_GET_CLASS(machine);
22
- ARMCPRegInfo *src_reg, *dst_reg;
35
IMX25PDK *s = g_new0(IMX25PDK, 1);
23
+ ARMCPRegInfo *src_reg, *dst_reg, *new_reg;
36
unsigned int ram_size;
24
+ uint32_t *new_key;
37
unsigned int alias_offset;
25
+ bool ok;
38
@@ -XXX,XX +XXX,XX @@ static void imx25_pdk_init(MachineState *machine)
26
39
27
if (a->feature && !a->feature(&cpu->isar)) {
40
/* We need to initialize our memory */
28
continue;
41
if (machine->ram_size > (FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE)) {
29
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
42
- char *sz = size_to_str(mc->default_ram_size);
30
g_assert(src_reg->opaque == NULL);
43
- error_report("Invalid RAM size, should be %s", sz);
31
44
+ char *sz = size_to_str(FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE);
32
/* Create alias before redirection so we dup the right data. */
45
+ error_report("RAM size more than %s is not supported", sz);
33
- if (a->new_key) {
46
g_free(sz);
34
- ARMCPRegInfo *new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
47
exit(EXIT_FAILURE);
35
- uint32_t *new_key = g_memdup(&a->new_key, sizeof(uint32_t));
48
}
36
- bool ok;
37
+ new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
38
+ new_key = g_memdup(&a->new_key, sizeof(uint32_t));
39
40
- new_reg->name = a->new_name;
41
- new_reg->type |= ARM_CP_ALIAS;
42
- /* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
43
- new_reg->access &= PL2_RW | PL3_RW;
44
+ new_reg->name = a->new_name;
45
+ new_reg->type |= ARM_CP_ALIAS;
46
+ /* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
47
+ new_reg->access &= PL2_RW | PL3_RW;
48
49
- ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
50
- g_assert(ok);
51
- }
52
+ ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
53
+ g_assert(ok);
54
55
src_reg->opaque = dst_reg;
56
src_reg->orig_readfn = src_reg->readfn ?: raw_read;
49
--
57
--
50
2.20.1
58
2.25.1
51
52
diff view generated by jsdifflib
1
Make the remaining functions needed by the translate-neon code
1
From: Richard Henderson <richard.henderson@linaro.org>
2
global.
3
2
3
Cast the uint32_t key into a gpointer directly, which
4
allows us to avoid allocating storage for each key.
5
6
Use g_hash_table_lookup when we already have a gpointer
7
(e.g. for callbacks like count_cpreg), or when using
8
get_arm_cp_reginfo would require casting away const.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20220501055028.646596-12-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-13-peter.maydell@linaro.org
8
---
14
---
9
target/arm/translate-a32.h | 8 ++++++++
15
target/arm/cpu.c | 4 ++--
10
target/arm/translate.c | 10 ++--------
16
target/arm/gdbstub.c | 2 +-
11
2 files changed, 10 insertions(+), 8 deletions(-)
17
target/arm/helper.c | 41 ++++++++++++++++++-----------------------
18
3 files changed, 21 insertions(+), 26 deletions(-)
12
19
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
20
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a32.h
22
--- a/target/arm/cpu.c
16
+++ b/target/arm/translate-a32.h
23
+++ b/target/arm/cpu.c
17
@@ -XXX,XX +XXX,XX @@ void gen_set_pc_im(DisasContext *s, target_ulong val);
24
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
18
void gen_lookup_tb(DisasContext *s);
25
ARMCPU *cpu = ARM_CPU(obj);
19
long vfp_reg_offset(bool dp, unsigned reg);
26
20
long neon_full_reg_offset(unsigned reg);
27
cpu_set_cpustate_pointers(cpu);
21
+long neon_element_offset(int reg, int element, MemOp memop);
28
- cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
22
+void gen_rev16(TCGv_i32 dest, TCGv_i32 var);
29
- g_free, cpreg_hashtable_data_destroy);
23
30
+ cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
24
static inline TCGv_i32 load_cpu_offset(int offset)
31
+ NULL, cpreg_hashtable_data_destroy);
32
33
QLIST_INIT(&cpu->pre_el_change_hooks);
34
QLIST_INIT(&cpu->el_change_hooks);
35
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/gdbstub.c
38
+++ b/target/arm/gdbstub.c
39
@@ -XXX,XX +XXX,XX @@ static void arm_gen_one_xml_sysreg_tag(GString *s, DynamicGDBXMLInfo *dyn_xml,
40
static void arm_register_sysreg_for_xml(gpointer key, gpointer value,
41
gpointer p)
25
{
42
{
26
@@ -XXX,XX +XXX,XX @@ DO_GEN_ST(32, MO_UL)
43
- uint32_t ri_key = *(uint32_t *)key;
27
/* Set NZCV flags from the high 4 bits of var. */
44
+ uint32_t ri_key = (uintptr_t)key;
28
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
45
ARMCPRegInfo *ri = value;
29
46
RegisterSysregXmlParam *param = (RegisterSysregXmlParam *)p;
30
+/* Swap low and high halfwords. */
47
GString *s = param->s;
31
+static inline void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
+{
33
+ tcg_gen_rotri_i32(dest, var, 16);
34
+}
35
+
36
#endif
37
diff --git a/target/arm/translate.c b/target/arm/translate.c
38
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate.c
50
--- a/target/arm/helper.c
40
+++ b/target/arm/translate.c
51
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
52
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu)
53
static void add_cpreg_to_list(gpointer key, gpointer opaque)
54
{
55
ARMCPU *cpu = opaque;
56
- uint64_t regidx;
57
- const ARMCPRegInfo *ri;
58
-
59
- regidx = *(uint32_t *)key;
60
- ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
61
+ uint32_t regidx = (uintptr_t)key;
62
+ const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
63
64
if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
65
cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
66
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_list(gpointer key, gpointer opaque)
67
static void count_cpreg(gpointer key, gpointer opaque)
68
{
69
ARMCPU *cpu = opaque;
70
- uint64_t regidx;
71
const ARMCPRegInfo *ri;
72
73
- regidx = *(uint32_t *)key;
74
- ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
75
+ ri = g_hash_table_lookup(cpu->cp_regs, key);
76
77
if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
78
cpu->cpreg_array_len++;
79
@@ -XXX,XX +XXX,XX @@ static void count_cpreg(gpointer key, gpointer opaque)
80
81
static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
82
{
83
- uint64_t aidx = cpreg_to_kvm_id(*(uint32_t *)a);
84
- uint64_t bidx = cpreg_to_kvm_id(*(uint32_t *)b);
85
+ uint64_t aidx = cpreg_to_kvm_id((uintptr_t)a);
86
+ uint64_t bidx = cpreg_to_kvm_id((uintptr_t)b);
87
88
if (aidx > bidx) {
89
return 1;
90
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
91
for (i = 0; i < ARRAY_SIZE(aliases); i++) {
92
const struct E2HAlias *a = &aliases[i];
93
ARMCPRegInfo *src_reg, *dst_reg, *new_reg;
94
- uint32_t *new_key;
95
bool ok;
96
97
if (a->feature && !a->feature(&cpu->isar)) {
98
continue;
99
}
100
101
- src_reg = g_hash_table_lookup(cpu->cp_regs, &a->src_key);
102
- dst_reg = g_hash_table_lookup(cpu->cp_regs, &a->dst_key);
103
+ src_reg = g_hash_table_lookup(cpu->cp_regs,
104
+ (gpointer)(uintptr_t)a->src_key);
105
+ dst_reg = g_hash_table_lookup(cpu->cp_regs,
106
+ (gpointer)(uintptr_t)a->dst_key);
107
g_assert(src_reg != NULL);
108
g_assert(dst_reg != NULL);
109
110
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
111
112
/* Create alias before redirection so we dup the right data. */
113
new_reg = g_memdup(src_reg, sizeof(ARMCPRegInfo));
114
- new_key = g_memdup(&a->new_key, sizeof(uint32_t));
115
116
new_reg->name = a->new_name;
117
new_reg->type |= ARM_CP_ALIAS;
118
/* Remove PL1/PL0 access, leaving PL2/PL3 R/W in place. */
119
new_reg->access &= PL2_RW | PL3_RW;
120
121
- ok = g_hash_table_insert(cpu->cp_regs, new_key, new_reg);
122
+ ok = g_hash_table_insert(cpu->cp_regs,
123
+ (gpointer)(uintptr_t)a->new_key, new_reg);
124
g_assert(ok);
125
126
src_reg->opaque = dst_reg;
127
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
128
/* Private utility function for define_one_arm_cp_reg_with_opaque():
129
* add a single reginfo struct to the hash table.
130
*/
131
- uint32_t *key = g_new(uint32_t, 1);
132
+ uint32_t key;
133
ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
134
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
135
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
136
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
137
if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
138
r2->cp = CP_REG_ARM64_SYSREG_CP;
139
}
140
- *key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
141
- r2->opc0, opc1, opc2);
142
+ key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
143
+ r2->opc0, opc1, opc2);
144
} else {
145
- *key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
146
+ key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
147
}
148
if (opaque) {
149
r2->opaque = opaque;
150
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
151
* requested.
152
*/
153
if (!(r->type & ARM_CP_OVERRIDE)) {
154
- ARMCPRegInfo *oldreg;
155
- oldreg = g_hash_table_lookup(cpu->cp_regs, key);
156
+ const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
157
if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
158
fprintf(stderr, "Register redefined: cp=%d %d bit "
159
"crn=%d crm=%d opc1=%d opc2=%d, "
160
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
161
g_assert_not_reached();
162
}
163
}
164
- g_hash_table_insert(cpu->cp_regs, key, r2);
165
+ g_hash_table_insert(cpu->cp_regs, (gpointer)(uintptr_t)key, r2);
42
}
166
}
43
167
44
/* Byteswap each halfword. */
168
45
-static void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
169
@@ -XXX,XX +XXX,XX @@ void modify_arm_cp_regs_with_len(ARMCPRegInfo *regs, size_t regs_len,
46
+void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
170
171
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
47
{
172
{
48
TCGv_i32 tmp = tcg_temp_new_i32();
173
- return g_hash_table_lookup(cpregs, &encoded_cp);
49
TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
174
+ return g_hash_table_lookup(cpregs, (gpointer)(uintptr_t)encoded_cp);
50
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
51
tcg_gen_ext16s_i32(dest, var);
52
}
175
}
53
176
54
-/* Swap low and high halfwords. */
177
void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
55
-static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
56
-{
57
- tcg_gen_rotri_i32(dest, var, 16);
58
-}
59
-
60
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
61
tmp = (t0 ^ t1) & 0x8000;
62
t0 &= ~0x8000;
63
@@ -XXX,XX +XXX,XX @@ long neon_full_reg_offset(unsigned reg)
64
* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
65
* where 0 is the least significant end of the register.
66
*/
67
-static long neon_element_offset(int reg, int element, MemOp memop)
68
+long neon_element_offset(int reg, int element, MemOp memop)
69
{
70
int element_size = 1 << (memop & MO_SIZE);
71
int ofs = element * element_size;
72
--
178
--
73
2.20.1
179
2.25.1
74
75
diff view generated by jsdifflib
1
The function vfp_reg_ptr() is used only in translate-neon.c.inc;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
move it there.
3
2
3
Simplify freeing cp_regs hash table entries by using a single
4
allocation for the entire value.
5
6
This fixes a theoretical bug if we were to ever free the entire
7
hash table, because we've been installing string literal constants
8
into the cpreg structure in define_arm_vh_e2h_redirects_aliases.
9
However, at present we only free entries created for AArch32
10
wildcard cpregs which get overwritten by more specific cpregs,
11
so this bug is never exposed.
12
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20220501055028.646596-13-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-10-peter.maydell@linaro.org
8
---
17
---
9
target/arm/translate.c | 7 -------
18
target/arm/cpu.c | 16 +---------------
10
target/arm/translate-neon.c.inc | 7 +++++++
19
target/arm/helper.c | 10 ++++++++--
11
2 files changed, 7 insertions(+), 7 deletions(-)
20
2 files changed, 9 insertions(+), 17 deletions(-)
12
21
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
22
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
24
--- a/target/arm/cpu.c
16
+++ b/target/arm/translate.c
25
+++ b/target/arm/cpu.c
17
@@ -XXX,XX +XXX,XX @@ void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
26
@@ -XXX,XX +XXX,XX @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz)
18
}
27
return (Aff1 << ARM_AFF1_SHIFT) | Aff0;
19
}
28
}
20
29
21
-static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
30
-static void cpreg_hashtable_data_destroy(gpointer data)
22
-{
31
-{
23
- TCGv_ptr ret = tcg_temp_new_ptr();
32
- /*
24
- tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
33
- * Destroy function for cpu->cp_regs hashtable data entries.
25
- return ret;
34
- * We must free the name string because it was g_strdup()ed in
35
- * add_cpreg_to_hashtable(). It's OK to cast away the 'const'
36
- * from r->name because we know we definitely allocated it.
37
- */
38
- ARMCPRegInfo *r = data;
39
-
40
- g_free((void *)r->name);
41
- g_free(r);
26
-}
42
-}
27
-
43
-
28
#define ARM_CP_RW_BIT (1 << 20)
44
static void arm_cpu_initfn(Object *obj)
29
45
{
30
/* Include the Neon decoder */
46
ARMCPU *cpu = ARM_CPU(obj);
31
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
47
48
cpu_set_cpustate_pointers(cpu);
49
cpu->cp_regs = g_hash_table_new_full(g_direct_hash, g_direct_equal,
50
- NULL, cpreg_hashtable_data_destroy);
51
+ NULL, g_free);
52
53
QLIST_INIT(&cpu->pre_el_change_hooks);
54
QLIST_INIT(&cpu->el_change_hooks);
55
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-neon.c.inc
57
--- a/target/arm/helper.c
34
+++ b/target/arm/translate-neon.c.inc
58
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ static inline int neon_3same_fp_size(DisasContext *s, int x)
59
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
36
#include "decode-neon-ls.c.inc"
60
* add a single reginfo struct to the hash table.
37
#include "decode-neon-shared.c.inc"
61
*/
38
62
uint32_t key;
39
+static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
63
- ARMCPRegInfo *r2 = g_memdup(r, sizeof(ARMCPRegInfo));
40
+{
64
+ ARMCPRegInfo *r2;
41
+ TCGv_ptr ret = tcg_temp_new_ptr();
65
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
42
+ tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
66
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
43
+ return ret;
67
+ size_t name_len;
44
+}
45
+
68
+
46
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
69
+ /* Combine cpreg and name into one allocation. */
47
{
70
+ name_len = strlen(name) + 1;
48
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
71
+ r2 = g_malloc(sizeof(*r2) + name_len);
72
+ *r2 = *r;
73
+ r2->name = memcpy(r2 + 1, name, name_len);
74
75
- r2->name = g_strdup(name);
76
/* Reset the secure state to the specific incoming state. This is
77
* necessary as the register may have been defined with both states.
78
*/
49
--
79
--
50
2.20.1
80
2.25.1
51
52
diff view generated by jsdifflib
1
The AN524 FPGA image supports two memory maps, which differ in where
1
From: Richard Henderson <richard.henderson@linaro.org>
2
the QSPI and BRAM are. In the default map, the BRAM is at
3
0x0000_0000, and the QSPI at 0x2800_0000. In the second map, they
4
are the other way around.
5
2
6
In hardware, the initial mapping can be selected by the user by
3
Move the computation of key to the top of the function.
7
writing either "REMAP: BRAM" (the default) or "REMAP: QSPI" in the
4
Hoist the resolution of cp as well, as an input to the
8
board configuration file. The board config file is acted on by the
5
computation of key.
9
"Motherboard Configuration Controller", which is an entirely separate
10
microcontroller on the dev board but outside the FPGA.
11
6
12
The guest can also dynamically change the mapping via the SCC
7
This will be required by a subsequent patch.
13
CFG_REG0 register.
14
8
15
Implement this functionality for QEMU, using a machine property
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
"remap" with valid values "BRAM" and "QSPI" to allow the user to set
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
the initial mapping, in the same way they can on the FPGA, and
11
Message-id: 20220501055028.646596-14-richard.henderson@linaro.org
18
wiring up the bit from the SCC register to also switch the mapping.
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/helper.c | 49 +++++++++++++++++++++++++--------------------
15
1 file changed, 27 insertions(+), 22 deletions(-)
19
16
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
23
Message-id: 20210504120912.23094-4-peter.maydell@linaro.org
24
---
25
docs/system/arm/mps2.rst | 10 ++++
26
hw/arm/mps2-tz.c | 108 ++++++++++++++++++++++++++++++++++++++-
27
2 files changed, 117 insertions(+), 1 deletion(-)
28
29
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/docs/system/arm/mps2.rst
19
--- a/target/arm/helper.c
32
+++ b/docs/system/arm/mps2.rst
20
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
21
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
34
flash, but only as simple ROM, so attempting to rewrite the flash
22
ARMCPRegInfo *r2;
35
from the guest will fail
23
int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
36
- QEMU does not model the USB controller in MPS3 boards
24
int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
37
+
25
+ int cp = r->cp;
38
+Machine-specific options
26
size_t name_len;
39
+""""""""""""""""""""""""
27
40
+
28
+ switch (state) {
41
+The following machine-specific options are supported:
29
+ case ARM_CP_STATE_AA32:
42
+
30
+ /* We assume it is a cp15 register if the .cp field is left unset. */
43
+remap
31
+ if (cp == 0 && r->state == ARM_CP_STATE_BOTH) {
44
+ Supported for ``mps3-an524`` only.
32
+ cp = 15;
45
+ Set ``BRAM``/``QSPI`` to select the initial memory mapping. The
33
+ }
46
+ default is ``BRAM``.
34
+ key = ENCODE_CP_REG(cp, is64, ns, r->crn, crm, opc1, opc2);
47
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
35
+ break;
48
index XXXXXXX..XXXXXXX 100644
36
+ case ARM_CP_STATE_AA64:
49
--- a/hw/arm/mps2-tz.c
37
+ /*
50
+++ b/hw/arm/mps2-tz.c
38
+ * To allow abbreviation of ARMCPRegInfo definitions, we treat
51
@@ -XXX,XX +XXX,XX @@
39
+ * cp == 0 as equivalent to the value for "standard guest-visible
52
#include "hw/boards.h"
40
+ * sysreg". STATE_BOTH definitions are also always "standard sysreg"
53
#include "exec/address-spaces.h"
41
+ * in their AArch64 view (the .cp value may be non-zero for the
54
#include "sysemu/sysemu.h"
42
+ * benefit of the AArch32 view).
55
+#include "sysemu/reset.h"
43
+ */
56
#include "hw/misc/unimp.h"
44
+ if (cp == 0 || r->state == ARM_CP_STATE_BOTH) {
57
#include "hw/char/cmsdk-apb-uart.h"
45
+ cp = CP_REG_ARM64_SYSREG_CP;
58
#include "hw/timer/cmsdk-apb-timer.h"
46
+ }
59
@@ -XXX,XX +XXX,XX @@
47
+ key = ENCODE_AA64_CP_REG(cp, r->crn, crm, r->opc0, opc1, opc2);
60
#include "hw/core/split-irq.h"
48
+ break;
61
#include "hw/qdev-clock.h"
49
+ default:
62
#include "qom/object.h"
50
+ g_assert_not_reached();
63
+#include "hw/irq.h"
64
65
#define MPS2TZ_NUMIRQ_MAX 96
66
#define MPS2TZ_RAM_MAX 5
67
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
68
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
69
Clock *sysclk;
70
Clock *s32kclk;
71
+
72
+ bool remap;
73
+ qemu_irq remap_irq;
74
};
75
76
#define TYPE_MPS2TZ_MACHINE "mps2tz"
77
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
78
},
79
};
80
81
+/*
82
+ * Note that the addresses and MPC numbering here should match up
83
+ * with those used in remap_memory(), which can swap the BRAM and QSPI.
84
+ */
85
static const RAMInfo an524_raminfo[] = { {
86
.name = "bram",
87
.base = 0x00000000,
88
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
89
90
object_initialize_child(OBJECT(mms), "scc", scc, TYPE_MPS2_SCC);
91
sccdev = DEVICE(scc);
92
+ qdev_prop_set_uint32(sccdev, "scc-cfg0", mms->remap ? 1 : 0);
93
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
94
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
95
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
96
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
97
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
98
}
99
100
+static hwaddr boot_mem_base(MPS2TZMachineState *mms)
101
+{
102
+ /*
103
+ * Return the canonical address of the block which will be mapped
104
+ * at address 0x0 (i.e. where the vector table is).
105
+ * This is usually 0, but if the AN524 alternate memory map is
106
+ * enabled it will be the base address of the QSPI block.
107
+ */
108
+ return mms->remap ? 0x28000000 : 0;
109
+}
110
+
111
+static void remap_memory(MPS2TZMachineState *mms, int map)
112
+{
113
+ /*
114
+ * Remap the memory for the AN524. 'map' is the value of
115
+ * SCC CFG_REG0 bit 0, i.e. 0 for the default map and 1
116
+ * for the "option 1" mapping where QSPI is at address 0.
117
+ *
118
+ * Effectively we need to swap around the "upstream" ends of
119
+ * MPC 0 and MPC 1.
120
+ */
121
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
122
+ int i;
123
+
124
+ if (mmc->fpga_type != FPGA_AN524) {
125
+ return;
126
+ }
51
+ }
127
+
52
+
128
+ memory_region_transaction_begin();
53
/* Combine cpreg and name into one allocation. */
129
+ for (i = 0; i < 2; i++) {
54
name_len = strlen(name) + 1;
130
+ TZMPC *mpc = &mms->mpc[i];
55
r2 = g_malloc(sizeof(*r2) + name_len);
131
+ MemoryRegion *upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
56
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
132
+ hwaddr addr = (i ^ map) ? 0x28000000 : 0;
57
}
133
+
58
134
+ memory_region_set_address(upstream, addr);
59
if (r->state == ARM_CP_STATE_BOTH) {
135
+ }
60
- /* We assume it is a cp15 register if the .cp field is left unset.
136
+ memory_region_transaction_commit();
61
- */
137
+}
62
- if (r2->cp == 0) {
138
+
63
- r2->cp = 15;
139
+static void remap_irq_fn(void *opaque, int n, int level)
64
- }
140
+{
65
-
141
+ MPS2TZMachineState *mms = opaque;
66
#if HOST_BIG_ENDIAN
142
+
67
if (r2->fieldoffset) {
143
+ remap_memory(mms, level);
68
r2->fieldoffset += sizeof(uint32_t);
144
+}
69
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
145
+
70
#endif
146
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
147
const char *name, hwaddr size,
148
const int *irqs)
149
@@ -XXX,XX +XXX,XX @@ static uint32_t boot_ram_size(MPS2TZMachineState *mms)
150
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
151
152
for (p = mmc->raminfo; p->name; p++) {
153
- if (p->base == 0) {
154
+ if (p->base == boot_mem_base(mms)) {
155
return p->size;
156
}
71
}
157
}
72
}
158
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
73
- if (state == ARM_CP_STATE_AA64) {
159
74
- /* To allow abbreviation of ARMCPRegInfo
160
create_non_mpc_ram(mms);
75
- * definitions, we treat cp == 0 as equivalent to
161
76
- * the value for "standard guest-visible sysreg".
162
+ if (mmc->fpga_type == FPGA_AN524) {
77
- * STATE_BOTH definitions are also always "standard
163
+ /*
78
- * sysreg" in their AArch64 view (the .cp value may
164
+ * Connect the line from the SCC so that we can remap when the
79
- * be non-zero for the benefit of the AArch32 view).
165
+ * guest updates that register.
80
- */
166
+ */
81
- if (r->cp == 0 || r->state == ARM_CP_STATE_BOTH) {
167
+ mms->remap_irq = qemu_allocate_irq(remap_irq_fn, mms, 0);
82
- r2->cp = CP_REG_ARM64_SYSREG_CP;
168
+ qdev_connect_gpio_out_named(DEVICE(&mms->scc), "remap", 0,
83
- }
169
+ mms->remap_irq);
84
- key = ENCODE_AA64_CP_REG(r2->cp, r2->crn, crm,
170
+ }
85
- r2->opc0, opc1, opc2);
171
+
86
- } else {
172
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
87
- key = ENCODE_CP_REG(r2->cp, is64, ns, r2->crn, crm, opc1, opc2);
173
boot_ram_size(mms));
88
- }
174
}
89
if (opaque) {
175
@@ -XXX,XX +XXX,XX @@ static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
90
r2->opaque = opaque;
176
*iregion = region;
91
}
177
}
92
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
178
93
/* Make sure reginfo passed to helpers for wildcarded regs
179
+static char *mps2_get_remap(Object *obj, Error **errp)
94
* has the correct crm/opc1/opc2 for this reg, not CP_ANY:
180
+{
95
*/
181
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(obj);
96
+ r2->cp = cp;
182
+ const char *val = mms->remap ? "QSPI" : "BRAM";
97
r2->crm = crm;
183
+ return g_strdup(val);
98
r2->opc1 = opc1;
184
+}
99
r2->opc2 = opc2;
185
+
186
+static void mps2_set_remap(Object *obj, const char *value, Error **errp)
187
+{
188
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(obj);
189
+
190
+ if (!strcmp(value, "BRAM")) {
191
+ mms->remap = false;
192
+ } else if (!strcmp(value, "QSPI")) {
193
+ mms->remap = true;
194
+ } else {
195
+ error_setg(errp, "Invalid remap value");
196
+ error_append_hint(errp, "Valid values are BRAM and QSPI.\n");
197
+ }
198
+}
199
+
200
+static void mps2_machine_reset(MachineState *machine)
201
+{
202
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
203
+
204
+ /*
205
+ * Set the initial memory mapping before triggering the reset of
206
+ * the rest of the system, so that the guest image loader and CPU
207
+ * reset see the correct mapping.
208
+ */
209
+ remap_memory(mms, mms->remap);
210
+ qemu_devices_reset();
211
+}
212
+
213
static void mps2tz_class_init(ObjectClass *oc, void *data)
214
{
215
MachineClass *mc = MACHINE_CLASS(oc);
216
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
217
218
mc->init = mps2tz_common_init;
219
+ mc->reset = mps2_machine_reset;
220
iic->check = mps2_tz_idau_check;
221
}
222
223
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
224
mmc->raminfo = an524_raminfo;
225
mmc->armsse_type = TYPE_SSE200;
226
mps2tz_set_default_ram_info(mmc);
227
+
228
+ object_class_property_add_str(oc, "remap", mps2_get_remap, mps2_set_remap);
229
+ object_class_property_set_description(oc, "remap",
230
+ "Set memory mapping. Valid values "
231
+ "are BRAM (default) and QSPI.");
232
}
233
234
static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
235
--
100
--
236
2.20.1
101
2.25.1
237
238
diff view generated by jsdifflib
1
Make bswap.h handle being included outside an 'extern "C"' block:
1
From: Richard Henderson <richard.henderson@linaro.org>
2
all system headers are included first, then all declarations are
3
put inside an 'extern "C"' block.
4
2
5
This requires a little rearrangement as currently we have an ifdef
3
Put most of the value writeback to the same place,
6
ladder that has some system includes and some local declarations
4
and improve the comment that goes with them.
7
or definitions, and we need to separate those out.
8
5
9
We want to do this because dis-asm.h includes bswap.h, dis-asm.h
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
may need to be included from C++ files, and system headers should
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
not be included within 'extern "C"' blocks.
8
Message-id: 20220501055028.646596-15-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.c | 28 ++++++++++++----------------
12
1 file changed, 12 insertions(+), 16 deletions(-)
12
13
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
---
16
include/qemu/bswap.h | 26 ++++++++++++++++++++++----
17
1 file changed, 22 insertions(+), 4 deletions(-)
18
19
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/include/qemu/bswap.h
16
--- a/target/arm/helper.c
22
+++ b/include/qemu/bswap.h
17
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
24
#ifndef BSWAP_H
19
*r2 = *r;
25
#define BSWAP_H
20
r2->name = memcpy(r2 + 1, name, name_len);
26
21
27
-#include "fpu/softfloat-types.h"
22
- /* Reset the secure state to the specific incoming state. This is
28
-
23
- * necessary as the register may have been defined with both states.
29
#ifdef CONFIG_MACHINE_BSWAP_H
24
+ /*
30
# include <sys/endian.h>
25
+ * Update fields to match the instantiation, overwiting wildcards
31
# include <machine/bswap.h>
26
+ * such as CP_ANY, ARM_CP_STATE_BOTH, or ARM_CP_SECSTATE_BOTH.
32
@@ -XXX,XX +XXX,XX @@
27
*/
33
# include <endian.h>
28
+ r2->cp = cp;
34
#elif defined(CONFIG_BYTESWAP_H)
29
+ r2->crm = crm;
35
# include <byteswap.h>
30
+ r2->opc1 = opc1;
36
+#define BSWAP_FROM_BYTESWAP
31
+ r2->opc2 = opc2;
37
+# else
32
+ r2->state = state;
38
+#define BSWAP_FROM_FALLBACKS
33
r2->secure = secstate;
39
+#endif /* ! CONFIG_MACHINE_BSWAP_H */
34
+ if (opaque) {
40
35
+ r2->opaque = opaque;
41
+#ifdef __cplusplus
36
+ }
42
+extern "C" {
37
43
+#endif
38
if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
39
/* Register is banked (using both entries in array).
40
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
41
#endif
42
}
43
}
44
- if (opaque) {
45
- r2->opaque = opaque;
46
- }
47
- /* reginfo passed to helpers is correct for the actual access,
48
- * and is never ARM_CP_STATE_BOTH:
49
- */
50
- r2->state = state;
51
- /* Make sure reginfo passed to helpers for wildcarded regs
52
- * has the correct crm/opc1/opc2 for this reg, not CP_ANY:
53
- */
54
- r2->cp = cp;
55
- r2->crm = crm;
56
- r2->opc1 = opc1;
57
- r2->opc2 = opc2;
44
+
58
+
45
+#include "fpu/softfloat-types.h"
59
/* By convention, for wildcarded registers only the first
46
+
60
* entry is used for migration; the others are marked as
47
+#ifdef BSWAP_FROM_BYTESWAP
61
* ALIAS so we don't try to transfer the register
48
static inline uint16_t bswap16(uint16_t x)
49
{
50
return bswap_16(x);
51
@@ -XXX,XX +XXX,XX @@ static inline uint64_t bswap64(uint64_t x)
52
{
53
return bswap_64(x);
54
}
55
-# else
56
+#endif
57
+
58
+#ifdef BSWAP_FROM_FALLBACKS
59
static inline uint16_t bswap16(uint16_t x)
60
{
61
return (((x & 0x00ff) << 8) |
62
@@ -XXX,XX +XXX,XX @@ static inline uint64_t bswap64(uint64_t x)
63
((x & 0x00ff000000000000ULL) >> 40) |
64
((x & 0xff00000000000000ULL) >> 56));
65
}
66
-#endif /* ! CONFIG_MACHINE_BSWAP_H */
67
+#endif
68
+
69
+#undef BSWAP_FROM_BYTESWAP
70
+#undef BSWAP_FROM_FALLBACKS
71
72
static inline void bswap16s(uint16_t *s)
73
{
74
@@ -XXX,XX +XXX,XX @@ DO_STN_LDN_P(be)
75
#undef le_bswaps
76
#undef be_bswaps
77
78
+#ifdef __cplusplus
79
+}
80
+#endif
81
+
82
#endif /* BSWAP_H */
83
--
62
--
84
2.20.1
63
2.25.1
85
86
diff view generated by jsdifflib
1
The MPS2 SCC device doesn't have any documentation of its properties;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
add a "QEMU interface" format comment describing them.
3
2
3
Bool is a more appropriate type for these variables.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20220501055028.646596-16-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210504120912.23094-2-peter.maydell@linaro.org
7
---
9
---
8
include/hw/misc/mps2-scc.h | 12 ++++++++++++
10
target/arm/helper.c | 4 ++--
9
1 file changed, 12 insertions(+)
11
1 file changed, 2 insertions(+), 2 deletions(-)
10
12
11
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/include/hw/misc/mps2-scc.h
15
--- a/target/arm/helper.c
14
+++ b/include/hw/misc/mps2-scc.h
16
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
16
* (at your option) any later version.
18
*/
17
*/
19
uint32_t key;
18
20
ARMCPRegInfo *r2;
19
+/*
21
- int is64 = (r->type & ARM_CP_64BIT) ? 1 : 0;
20
+ * This is a model of the Serial Communication Controller (SCC)
22
- int ns = (secstate & ARM_CP_SECSTATE_NS) ? 1 : 0;
21
+ * block found in most MPS FPGA images.
23
+ bool is64 = r->type & ARM_CP_64BIT;
22
+ *
24
+ bool ns = secstate & ARM_CP_SECSTATE_NS;
23
+ * QEMU interface:
25
int cp = r->cp;
24
+ * + sysbus MMIO region 0: the register bank
26
size_t name_len;
25
+ * + QOM property "scc-cfg4": value of the read-only CFG4 register
26
+ * + QOM property "scc-aid": value of the read-only SCC_AID register
27
+ * + QOM property "scc-id": value of the read-only SCC_ID register
28
+ * + QOM property array "oscclk": reset values of the OSCCLK registers
29
+ * (which are accessed via the SYS_CFG channel provided by this device)
30
+ */
31
#ifndef MPS2_SCC_H
32
#define MPS2_SCC_H
33
27
34
--
28
--
35
2.20.1
29
2.25.1
36
37
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
A trailing _ makes all the difference to the rendered link.
3
Computing isbanked only once makes the code
4
a bit easier to read.
4
5
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210428131316.31390-1-alex.bennee@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220501055028.646596-17-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
docs/system/arm/sbsa.rst | 2 +-
11
target/arm/helper.c | 6 ++++--
11
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 4 insertions(+), 2 deletions(-)
12
13
13
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/system/arm/sbsa.rst
16
--- a/target/arm/helper.c
16
+++ b/docs/system/arm/sbsa.rst
17
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ Arm Server Base System Architecture Reference board (``sbsa-ref``)
18
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
18
While the `virt` board is a generic board platform that doesn't match
19
bool is64 = r->type & ARM_CP_64BIT;
19
any real hardware the `sbsa-ref` board intends to look like real
20
bool ns = secstate & ARM_CP_SECSTATE_NS;
20
hardware. The `Server Base System Architecture
21
int cp = r->cp;
21
-<https://developer.arm.com/documentation/den0029/latest>` defines a
22
+ bool isbanked;
22
+<https://developer.arm.com/documentation/den0029/latest>`_ defines a
23
size_t name_len;
23
minimum base line of hardware support and importantly how the firmware
24
24
reports that to any operating system. It is a static system that
25
switch (state) {
25
reports a very minimal DT to the firmware for non-discoverable
26
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
27
r2->opaque = opaque;
28
}
29
30
- if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
31
+ isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
32
+ if (isbanked) {
33
/* Register is banked (using both entries in array).
34
* Overwriting fieldoffset as the array is only used to define
35
* banked registers but later only fieldoffset is used.
36
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
37
}
38
39
if (state == ARM_CP_STATE_AA32) {
40
- if (r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1]) {
41
+ if (isbanked) {
42
/* If the register is banked then we don't need to migrate or
43
* reset the 32-bit instance in certain cases:
44
*
26
--
45
--
27
2.20.1
46
2.25.1
28
29
diff view generated by jsdifflib
1
The omap_mmc_reset() function resets its SD card via
1
From: Richard Henderson <richard.henderson@linaro.org>
2
device_legacy_reset(). We know that the SD card does not have a qbus
3
of its own, so the new device_cold_reset() function (which resets
4
both the device and its child buses) is equivalent here to
5
device_legacy_reset() and we can just switch to the new API.
6
2
3
Perform the override check early, so that it is still done
4
even when we decide to discard an unreachable cpreg.
5
6
Use assert not printf+abort.
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20220501055028.646596-18-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210430222348.8514-1-peter.maydell@linaro.org
10
---
12
---
11
hw/sd/omap_mmc.c | 2 +-
13
target/arm/helper.c | 22 ++++++++--------------
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 8 insertions(+), 14 deletions(-)
13
15
14
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/sd/omap_mmc.c
18
--- a/target/arm/helper.c
17
+++ b/hw/sd/omap_mmc.c
19
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ void omap_mmc_reset(struct omap_mmc_s *host)
20
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
19
* into any bus, and we must reset it manually. When omap_mmc is
21
g_assert_not_reached();
20
* QOMified this must move into the QOM reset function.
22
}
21
*/
23
22
- device_legacy_reset(DEVICE(host->card));
24
+ /* Overriding of an existing definition must be explicitly requested. */
23
+ device_cold_reset(DEVICE(host->card));
25
+ if (!(r->type & ARM_CP_OVERRIDE)) {
26
+ const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
27
+ if (oldreg) {
28
+ assert(oldreg->type & ARM_CP_OVERRIDE);
29
+ }
30
+ }
31
+
32
/* Combine cpreg and name into one allocation. */
33
name_len = strlen(name) + 1;
34
r2 = g_malloc(sizeof(*r2) + name_len);
35
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
36
assert(!raw_accessors_invalid(r2));
37
}
38
39
- /* Overriding of an existing definition must be explicitly
40
- * requested.
41
- */
42
- if (!(r->type & ARM_CP_OVERRIDE)) {
43
- const ARMCPRegInfo *oldreg = get_arm_cp_reginfo(cpu->cp_regs, key);
44
- if (oldreg && !(oldreg->type & ARM_CP_OVERRIDE)) {
45
- fprintf(stderr, "Register redefined: cp=%d %d bit "
46
- "crn=%d crm=%d opc1=%d opc2=%d, "
47
- "was %s, now %s\n", r2->cp, 32 + 32 * is64,
48
- r2->crn, r2->crm, r2->opc1, r2->opc2,
49
- oldreg->name, r2->name);
50
- g_assert_not_reached();
51
- }
52
- }
53
g_hash_table_insert(cpu->cp_regs, (gpointer)(uintptr_t)key, r2);
24
}
54
}
25
55
26
static uint64_t omap_mmc_read(void *opaque, hwaddr offset,
27
--
56
--
28
2.20.1
57
2.25.1
29
30
diff view generated by jsdifflib
1
Move the various gen_aa32* functions and macros out of translate.c
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and into translate-a32.h.
3
2
3
Put the block comments into the current coding style.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20220501055028.646596-19-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-6-peter.maydell@linaro.org
8
---
9
---
9
target/arm/translate-a32.h | 53 ++++++++++++++++++++++++++++++++++++++
10
target/arm/helper.c | 24 +++++++++++++++---------
10
target/arm/translate.c | 51 ++++++++++++------------------------
11
1 file changed, 15 insertions(+), 9 deletions(-)
11
2 files changed, 69 insertions(+), 35 deletions(-)
12
12
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a32.h
15
--- a/target/arm/helper.c
16
+++ b/target/arm/translate-a32.h
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg)
17
@@ -XXX,XX +XXX,XX @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
18
return tmp;
18
return cpu_list;
19
}
19
}
20
20
21
+void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
21
+/*
22
+ TCGv_i32 a32, int index, MemOp opc);
22
+ * Private utility function for define_one_arm_cp_reg_with_opaque():
23
+void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
23
+ * add a single reginfo struct to the hash table.
24
+ TCGv_i32 a32, int index, MemOp opc);
24
+ */
25
+void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
25
static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
26
+ TCGv_i32 a32, int index, MemOp opc);
26
void *opaque, CPState state,
27
+void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
27
CPSecureState secstate,
28
+ TCGv_i32 a32, int index, MemOp opc);
28
int crm, int opc1, int opc2,
29
+void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
29
const char *name)
30
+ int index, MemOp opc);
31
+void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
32
+ int index, MemOp opc);
33
+void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
34
+ int index, MemOp opc);
35
+void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
36
+ int index, MemOp opc);
37
+
38
+#define DO_GEN_LD(SUFF, OPC) \
39
+ static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
40
+ TCGv_i32 a32, int index) \
41
+ { \
42
+ gen_aa32_ld_i32(s, val, a32, index, OPC); \
43
+ }
44
+
45
+#define DO_GEN_ST(SUFF, OPC) \
46
+ static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
47
+ TCGv_i32 a32, int index) \
48
+ { \
49
+ gen_aa32_st_i32(s, val, a32, index, OPC); \
50
+ }
51
+
52
+static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
53
+ TCGv_i32 a32, int index)
54
+{
55
+ gen_aa32_ld_i64(s, val, a32, index, MO_Q);
56
+}
57
+
58
+static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
59
+ TCGv_i32 a32, int index)
60
+{
61
+ gen_aa32_st_i64(s, val, a32, index, MO_Q);
62
+}
63
+
64
+DO_GEN_LD(8u, MO_UB)
65
+DO_GEN_LD(16u, MO_UW)
66
+DO_GEN_LD(32u, MO_UL)
67
+DO_GEN_ST(8, MO_UB)
68
+DO_GEN_ST(16, MO_UW)
69
+DO_GEN_ST(32, MO_UL)
70
+
71
+#undef DO_GEN_LD
72
+#undef DO_GEN_ST
73
+
74
#endif
75
diff --git a/target/arm/translate.c b/target/arm/translate.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/translate.c
78
+++ b/target/arm/translate.c
79
@@ -XXX,XX +XXX,XX @@ static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
80
* Internal routines are used for NEON cases where the endianness
81
* and/or alignment has already been taken into account and manipulated.
82
*/
83
-static void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
84
- TCGv_i32 a32, int index, MemOp opc)
85
+void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
86
+ TCGv_i32 a32, int index, MemOp opc)
87
{
30
{
88
TCGv addr = gen_aa32_addr(s, a32, opc);
31
- /* Private utility function for define_one_arm_cp_reg_with_opaque():
89
tcg_gen_qemu_ld_i32(val, addr, index, opc);
32
- * add a single reginfo struct to the hash table.
90
tcg_temp_free(addr);
33
- */
91
}
34
uint32_t key;
92
35
ARMCPRegInfo *r2;
93
-static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
36
bool is64 = r->type & ARM_CP_64BIT;
94
- TCGv_i32 a32, int index, MemOp opc)
37
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
95
+void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
38
96
+ TCGv_i32 a32, int index, MemOp opc)
39
isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
97
{
40
if (isbanked) {
98
TCGv addr = gen_aa32_addr(s, a32, opc);
41
- /* Register is banked (using both entries in array).
99
tcg_gen_qemu_st_i32(val, addr, index, opc);
42
+ /*
100
tcg_temp_free(addr);
43
+ * Register is banked (using both entries in array).
101
}
44
* Overwriting fieldoffset as the array is only used to define
102
45
* banked registers but later only fieldoffset is used.
103
-static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
46
*/
104
- TCGv_i32 a32, int index, MemOp opc)
47
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
105
+void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
48
106
+ TCGv_i32 a32, int index, MemOp opc)
49
if (state == ARM_CP_STATE_AA32) {
107
{
50
if (isbanked) {
108
TCGv addr = gen_aa32_addr(s, a32, opc);
51
- /* If the register is banked then we don't need to migrate or
109
52
+ /*
110
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
53
+ * If the register is banked then we don't need to migrate or
111
tcg_temp_free(addr);
54
* reset the 32-bit instance in certain cases:
112
}
55
*
113
56
* 1) If the register has both 32-bit and 64-bit instances then we
114
-static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
57
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
115
- TCGv_i32 a32, int index, MemOp opc)
58
r2->type |= ARM_CP_ALIAS;
116
+void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
59
}
117
+ TCGv_i32 a32, int index, MemOp opc)
60
} else if ((secstate != r->secure) && !ns) {
118
{
61
- /* The register is not banked so we only want to allow migration of
119
TCGv addr = gen_aa32_addr(s, a32, opc);
62
- * the non-secure instance.
120
63
+ /*
121
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
64
+ * The register is not banked so we only want to allow migration
122
tcg_temp_free(addr);
65
+ * of the non-secure instance.
123
}
66
*/
124
67
r2->type |= ARM_CP_ALIAS;
125
-static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
68
}
126
- int index, MemOp opc)
69
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
127
+void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
70
}
128
+ int index, MemOp opc)
129
{
130
gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
131
}
132
133
-static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
134
- int index, MemOp opc)
135
+void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
136
+ int index, MemOp opc)
137
{
138
gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
139
}
140
141
-static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
142
- int index, MemOp opc)
143
+void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
144
+ int index, MemOp opc)
145
{
146
gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
147
}
148
149
-static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
150
- int index, MemOp opc)
151
+void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
152
+ int index, MemOp opc)
153
{
154
gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
155
}
156
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
157
gen_aa32_st_i32(s, val, a32, index, OPC); \
158
}
71
}
159
72
160
-static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
73
- /* By convention, for wildcarded registers only the first
161
- TCGv_i32 a32, int index)
74
+ /*
162
-{
75
+ * By convention, for wildcarded registers only the first
163
- gen_aa32_ld_i64(s, val, a32, index, MO_Q);
76
* entry is used for migration; the others are marked as
164
-}
77
* ALIAS so we don't try to transfer the register
165
-
78
* multiple times. Special registers (ie NOP/WFI) are
166
-static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
79
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
167
- TCGv_i32 a32, int index)
80
r2->type |= ARM_CP_ALIAS | ARM_CP_NO_GDB;
168
-{
81
}
169
- gen_aa32_st_i64(s, val, a32, index, MO_Q);
82
170
-}
83
- /* Check that raw accesses are either forbidden or handled. Note that
171
-
84
+ /*
172
-DO_GEN_LD(8u, MO_UB)
85
+ * Check that raw accesses are either forbidden or handled. Note that
173
-DO_GEN_LD(16u, MO_UW)
86
* we can't assert this earlier because the setup of fieldoffset for
174
-DO_GEN_LD(32u, MO_UL)
87
* banked registers has to be done first.
175
-DO_GEN_ST(8, MO_UB)
88
*/
176
-DO_GEN_ST(16, MO_UW)
177
-DO_GEN_ST(32, MO_UL)
178
-
179
static inline void gen_hvc(DisasContext *s, int imm16)
180
{
181
/* The pre HVC helper handles cases when HVC gets trapped
182
--
89
--
183
2.20.1
90
2.25.1
184
185
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These three features are already enabled by TCG, but are missing
3
Since e03b56863d2bc, our host endian indicator is unconditionally
4
their hwcap bits. Update HWCAP2 from linux v5.12.
4
set, which means that we can use a normal C condition.
5
5
6
Cc: qemu-stable@nongnu.org (for 6.0.1)
7
Buglink: https://bugs.launchpad.net/bugs/1926044
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210427214108.88503-1-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220501055028.646596-20-richard.henderson@linaro.org
9
[PMM: quote correct git hash in commit message]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
linux-user/elfload.c | 13 +++++++++++++
12
target/arm/helper.c | 9 +++------
13
1 file changed, 13 insertions(+)
13
1 file changed, 3 insertions(+), 6 deletions(-)
14
14
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
17
--- a/target/arm/helper.c
18
+++ b/linux-user/elfload.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ enum {
19
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
20
ARM_HWCAP2_A64_SVESM4 = 1 << 6,
20
r2->type |= ARM_CP_ALIAS;
21
ARM_HWCAP2_A64_FLAGM2 = 1 << 7,
21
}
22
ARM_HWCAP2_A64_FRINT = 1 << 8,
22
23
+ ARM_HWCAP2_A64_SVEI8MM = 1 << 9,
23
- if (r->state == ARM_CP_STATE_BOTH) {
24
+ ARM_HWCAP2_A64_SVEF32MM = 1 << 10,
24
-#if HOST_BIG_ENDIAN
25
+ ARM_HWCAP2_A64_SVEF64MM = 1 << 11,
25
- if (r2->fieldoffset) {
26
+ ARM_HWCAP2_A64_SVEBF16 = 1 << 12,
26
- r2->fieldoffset += sizeof(uint32_t);
27
+ ARM_HWCAP2_A64_I8MM = 1 << 13,
27
- }
28
+ ARM_HWCAP2_A64_BF16 = 1 << 14,
28
-#endif
29
+ ARM_HWCAP2_A64_DGH = 1 << 15,
29
+ if (HOST_BIG_ENDIAN &&
30
+ ARM_HWCAP2_A64_RNG = 1 << 16,
30
+ r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
31
+ ARM_HWCAP2_A64_BTI = 1 << 17,
31
+ r2->fieldoffset += sizeof(uint32_t);
32
+ ARM_HWCAP2_A64_MTE = 1 << 18,
32
}
33
};
33
}
34
34
35
#define ELF_HWCAP get_elf_hwcap()
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
37
GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
38
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
39
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
40
+ GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
41
+ GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
42
+ GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
43
44
return hwcaps;
45
}
46
--
35
--
47
2.20.1
36
2.25.1
48
49
diff view generated by jsdifflib
1
Some of the constant expanders defined in translate.c are generically
1
From: Richard Henderson <richard.henderson@linaro.org>
2
useful and will be used by the separate C files for VFP and Neon once
3
they are created; move the expander definitions to translate.h.
4
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220501055028.646596-24-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210430132740.10391-2-peter.maydell@linaro.org
9
---
7
---
10
target/arm/translate.h | 24 ++++++++++++++++++++++++
8
target/arm/cpu.h | 15 +++++++++++++++
11
target/arm/translate.c | 24 ------------------------
9
1 file changed, 15 insertions(+)
12
2 files changed, 24 insertions(+), 24 deletions(-)
13
10
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
13
--- a/target/arm/cpu.h
17
+++ b/target/arm/translate.h
14
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
15
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
19
extern TCGv_i64 cpu_exclusive_addr;
16
return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
20
extern TCGv_i64 cpu_exclusive_val;
17
}
21
18
22
+/*
19
+static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id)
23
+ * Constant expanders for the decoders.
24
+ */
25
+
26
+static inline int negate(DisasContext *s, int x)
27
+{
20
+{
28
+ return -x;
21
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8;
29
+}
22
+}
30
+
23
+
31
+static inline int plus_2(DisasContext *s, int x)
24
/*
25
* 64-bit feature tests via id registers.
26
*/
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
28
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
29
}
30
31
+static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
32
+{
32
+{
33
+ return x + 2;
33
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
34
+}
34
+}
35
+
35
+
36
+static inline int times_2(DisasContext *s, int x)
36
static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
37
{
38
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0;
39
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
40
return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
41
}
42
43
+static inline bool isar_feature_any_debugv8p2(const ARMISARegisters *id)
37
+{
44
+{
38
+ return x * 2;
45
+ return isar_feature_aa64_debugv8p2(id) || isar_feature_aa32_debugv8p2(id);
39
+}
46
+}
40
+
47
+
41
+static inline int times_4(DisasContext *s, int x)
48
/*
42
+{
49
* Forward to the above feature tests given an ARMCPU pointer.
43
+ return x * 4;
44
+}
45
+
46
static inline int arm_dc_feature(DisasContext *dc, int feature)
47
{
48
return (dc->features & (1ULL << feature)) != 0;
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 void arm_gen_condlabel(DisasContext *s)
54
}
55
}
56
57
-/*
58
- * Constant expanders for the decoders.
59
- */
60
-
61
-static int negate(DisasContext *s, int x)
62
-{
63
- return -x;
64
-}
65
-
66
-static int plus_2(DisasContext *s, int x)
67
-{
68
- return x + 2;
69
-}
70
-
71
-static int times_2(DisasContext *s, int x)
72
-{
73
- return x * 2;
74
-}
75
-
76
-static int times_4(DisasContext *s, int x)
77
-{
78
- return x * 4;
79
-}
80
-
81
/* Flags for the disas_set_da_iss info argument:
82
* lower bits hold the Rt register number, higher bits are flags.
83
*/
50
*/
84
--
51
--
85
2.20.1
52
2.25.1
86
87
diff view generated by jsdifflib
1
The functions vfp_load_reg32(), vfp_load_reg64(), vfp_store_reg32()
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and vfp_store_reg64() are used only in translate-vfp.c.inc. Move
3
them to that file.
4
2
3
Add the aa64 predicate for detecting RAS support from id registers.
4
We already have the aa32 version from the M-profile work.
5
Add the 'any' predicate for testing both aa64 and aa32.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220501055028.646596-34-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210430132740.10391-7-peter.maydell@linaro.org
9
---
11
---
10
target/arm/translate.c | 20 --------------------
12
target/arm/cpu.h | 10 ++++++++++
11
target/arm/translate-vfp.c.inc | 20 ++++++++++++++++++++
13
1 file changed, 10 insertions(+)
12
2 files changed, 20 insertions(+), 20 deletions(-)
13
14
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
17
--- a/target/arm/cpu.h
17
+++ b/target/arm/translate.c
18
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id)
19
}
20
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL1) >= 2;
20
}
21
}
21
22
22
-static inline void vfp_load_reg64(TCGv_i64 var, int reg)
23
+static inline bool isar_feature_aa64_ras(const ARMISARegisters *id)
23
-{
24
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
25
-}
26
-
27
-static inline void vfp_store_reg64(TCGv_i64 var, int reg)
28
-{
29
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
30
-}
31
-
32
-static inline void vfp_load_reg32(TCGv_i32 var, int reg)
33
-{
34
- tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
35
-}
36
-
37
-static inline void vfp_store_reg32(TCGv_i32 var, int reg)
38
-{
39
- tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
40
-}
41
-
42
void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
43
{
44
long off = neon_element_offset(reg, ele, memop);
45
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate-vfp.c.inc
48
+++ b/target/arm/translate-vfp.c.inc
49
@@ -XXX,XX +XXX,XX @@
50
#include "decode-vfp.c.inc"
51
#include "decode-vfp-uncond.c.inc"
52
53
+static inline void vfp_load_reg64(TCGv_i64 var, int reg)
54
+{
24
+{
55
+ tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
25
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) != 0;
56
+}
26
+}
57
+
27
+
58
+static inline void vfp_store_reg64(TCGv_i64 var, int reg)
28
static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
29
{
30
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
31
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_debugv8p2(const ARMISARegisters *id)
32
return isar_feature_aa64_debugv8p2(id) || isar_feature_aa32_debugv8p2(id);
33
}
34
35
+static inline bool isar_feature_any_ras(const ARMISARegisters *id)
59
+{
36
+{
60
+ tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
37
+ return isar_feature_aa64_ras(id) || isar_feature_aa32_ras(id);
61
+}
62
+
63
+static inline void vfp_load_reg32(TCGv_i32 var, int reg)
64
+{
65
+ tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
66
+}
67
+
68
+static inline void vfp_store_reg32(TCGv_i32 var, int reg)
69
+{
70
+ tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
71
+}
38
+}
72
+
39
+
73
/*
40
/*
74
* The imm8 encodes the sign bit, enough bits to represent an exponent in
41
* Forward to the above feature tests given an ARMCPU pointer.
75
* the range 01....1xx to 10....0xx, and the most significant 4 bits of
42
*/
76
--
43
--
77
2.20.1
44
2.25.1
78
79
diff view generated by jsdifflib
1
In tlbi_aa64_vae2is_write() the calculation
1
From: Alex Zuepke <alex.zuepke@tum.de>
2
bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : ARMMMUIdx_SE2,
3
pageaddr)
4
2
5
has the two arms of the ?: expression reversed. Fix the bug.
3
The ARMv8 manual defines that PMUSERENR_EL0.ER enables read-access
4
to both PMXEVCNTR_EL0 and PMEVCNTR<n>_EL0 registers, however,
5
we only use it for PMXEVCNTR_EL0. Extend to PMEVCNTR<n>_EL0 as well.
6
6
7
Fixes: b6ad6062f1e5
7
Signed-off-by: Alex Zuepke <alex.zuepke@tum.de>
8
Reported-by: Rebecca Cran <rebecca@nuviainc.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220428132717.84190-1-alex.zuepke@tum.de
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
12
Reviewed-by: Rebecca Cran <rebecca@nuviainc.com>
13
Message-id: 20210420123106.10861-1-peter.maydell@linaro.org
14
---
11
---
15
target/arm/helper.c | 2 +-
12
target/arm/helper.c | 4 ++--
16
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 2 insertions(+), 2 deletions(-)
17
14
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
21
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
19
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
23
uint64_t pageaddr = sextract64(value << 12, 0, 56);
20
.crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
24
bool secure = arm_is_secure_below_el3(env);
21
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
25
int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
22
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
26
- int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : ARMMMUIdx_SE2,
23
- .accessfn = pmreg_access },
27
+ int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2,
24
+ .accessfn = pmreg_access_xevcntr },
28
pageaddr);
25
{ .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
29
26
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
30
tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
27
- .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
28
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access_xevcntr,
29
.type = ARM_CP_IO,
30
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
31
.raw_readfn = pmevcntr_rawread,
31
--
32
--
32
2.20.1
33
2.25.1
33
34
diff view generated by jsdifflib
Deleted patch
1
Switch translate-vfp.c.inc from being #included into translate.c
2
to being its own compilation unit.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-9-peter.maydell@linaro.org
8
---
9
target/arm/translate-a32.h | 2 ++
10
target/arm/{translate-vfp.c.inc => translate-vfp.c} | 12 +++++++-----
11
target/arm/translate.c | 3 +--
12
target/arm/meson.build | 5 +++--
13
4 files changed, 13 insertions(+), 9 deletions(-)
14
rename target/arm/{translate-vfp.c.inc => translate-vfp.c} (99%)
15
16
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a32.h
19
+++ b/target/arm/translate-a32.h
20
@@ -XXX,XX +XXX,XX @@
21
22
/* Prototypes for autogenerated disassembler functions */
23
bool disas_m_nocp(DisasContext *dc, uint32_t insn);
24
+bool disas_vfp(DisasContext *s, uint32_t insn);
25
+bool disas_vfp_uncond(DisasContext *s, uint32_t insn);
26
27
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
28
void arm_gen_condlabel(DisasContext *s);
29
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c
30
similarity index 99%
31
rename from target/arm/translate-vfp.c.inc
32
rename to target/arm/translate-vfp.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-vfp.c.inc
35
+++ b/target/arm/translate-vfp.c
36
@@ -XXX,XX +XXX,XX @@
37
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
38
*/
39
40
-/*
41
- * This file is intended to be included from translate.c; it uses
42
- * some macros and definitions provided by that file.
43
- * It might be possible to convert it to a standalone .c file eventually.
44
- */
45
+#include "qemu/osdep.h"
46
+#include "tcg/tcg-op.h"
47
+#include "tcg/tcg-op-gvec.h"
48
+#include "exec/exec-all.h"
49
+#include "exec/gen-icount.h"
50
+#include "translate.h"
51
+#include "translate-a32.h"
52
53
/* Include the generated VFP decoder */
54
#include "decode-vfp.c.inc"
55
diff --git a/target/arm/translate.c b/target/arm/translate.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/translate.c
58
+++ b/target/arm/translate.c
59
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
60
61
#define ARM_CP_RW_BIT (1 << 20)
62
63
-/* Include the VFP and Neon decoders */
64
-#include "translate-vfp.c.inc"
65
+/* Include the Neon decoder */
66
#include "translate-neon.c.inc"
67
68
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
69
diff --git a/target/arm/meson.build b/target/arm/meson.build
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/meson.build
72
+++ b/target/arm/meson.build
73
@@ -XXX,XX +XXX,XX @@ gen = [
74
decodetree.process('neon-shared.decode', extra_args: '--static-decode=disas_neon_shared'),
75
decodetree.process('neon-dp.decode', extra_args: '--static-decode=disas_neon_dp'),
76
decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
77
- decodetree.process('vfp.decode', extra_args: '--static-decode=disas_vfp'),
78
- decodetree.process('vfp-uncond.decode', extra_args: '--static-decode=disas_vfp_uncond'),
79
+ decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
80
+ decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
81
decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
82
decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
83
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
84
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
85
'tlb_helper.c',
86
'translate.c',
87
'translate-m-nocp.c',
88
+ 'translate-vfp.c',
89
'vec_helper.c',
90
'vfp_helper.c',
91
'cpu_tcg.c',
92
--
93
2.20.1
94
95
diff view generated by jsdifflib
Deleted patch
1
The VFPGenFixPointFn typedef is unused; delete it.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210430132740.10391-11-peter.maydell@linaro.org
7
---
8
target/arm/translate.c | 2 --
9
1 file changed, 2 deletions(-)
10
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
16
/* Function prototypes for gen_ functions calling Neon helpers. */
17
typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
18
TCGv_i32, TCGv_i32);
19
-/* Function prototypes for gen_ functions for fix point conversions */
20
-typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
21
22
/* initialize TCG globals. */
23
void arm_translate_init(void)
24
--
25
2.20.1
26
27
diff view generated by jsdifflib
Deleted patch
1
Move the NeonGenThreeOpEnvFn typedef to translate.h together
2
with the other similar typedefs.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210430132740.10391-12-peter.maydell@linaro.org
8
---
9
target/arm/translate.h | 2 ++
10
target/arm/translate.c | 3 ---
11
2 files changed, 2 insertions(+), 3 deletions(-)
12
13
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.h
16
+++ b/target/arm/translate.h
17
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
18
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
19
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
20
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
21
+typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
22
+ TCGv_i32, TCGv_i32);
23
typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
24
typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
25
typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
26
diff --git a/target/arm/translate.c b/target/arm/translate.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate.c
29
+++ b/target/arm/translate.c
30
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
31
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
32
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
33
34
-/* Function prototypes for gen_ functions calling Neon helpers. */
35
-typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
36
- TCGv_i32, TCGv_i32);
37
38
/* initialize TCG globals. */
39
void arm_translate_init(void)
40
--
41
2.20.1
42
43
diff view generated by jsdifflib