1
Nothing much exciting here, but it's 37 patches worth...
1
Hi; here's the latest arm pullreq...
2
2
3
thanks
4
-- PMM
3
-- PMM
5
4
6
The following changes since commit e64a62df378a746c0b257105959613c9f8122e59:
5
The following changes since commit 03a3a62fbd0aa5227e978eef3c67d3978aec9e5f:
7
6
8
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-040320-1' into staging (2020-03-05 12:13:51 +0000)
7
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2023-09-07 10:29:06 -0400)
9
8
10
are available in the Git repository at:
9
are available in the Git repository at:
11
10
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200305
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230908
13
12
14
for you to fetch changes up to 597d61a3b1f94c53a3aaa77671697c0c5f797dbf:
13
for you to fetch changes up to c8f2eb5d414b788420b938f2ffdde891aa6c3ae8:
15
14
16
target/arm: Clean address for DC ZVA (2020-03-05 16:09:21 +0000)
15
arm/kvm: Enable support for KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE (2023-09-08 16:41:36 +0100)
17
16
18
----------------------------------------------------------------
17
----------------------------------------------------------------
19
* versal: Implement ADMA
18
target-arm queue:
20
* Implement (trivially) ARMv8.2-TTCNP
19
* New CPU type: cortex-a710
21
* hw/arm/smmu-common: a fix to smmu_find_smmu_pcibus
20
* Implement new architectural features:
22
* Remove unnecessary endianness-handling on some boards
21
- FEAT_PACQARMA3
23
* Avoid minor memory leaks from timer_new in some devices
22
- FEAT_EPAC
24
* Honour more of the HCR_EL2 trap bits
23
- FEAT_Pauth2
25
* Complain rather than ignoring bad command line options for cubieboard
24
- FEAT_FPAC
26
* Honour TBI for DC ZVA and exception return
25
- FEAT_FPACCOMBINE
26
- FEAT_TIDCP1
27
* Xilinx Versal: Model the CFU/CFI
28
* Implement RMR_ELx registers
29
* Implement handling of HCR_EL2.TIDCP trap bit
30
* arm/kvm: Enable support for KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE
31
* hw/intc/arm_gicv3_its: Avoid maybe-uninitialized error in get_vte()
32
* target/arm: Do not use gen_mte_checkN in trans_STGP
33
* arm64: Restore trapless ptimer access
27
34
28
----------------------------------------------------------------
35
----------------------------------------------------------------
29
Edgar E. Iglesias (2):
36
Aaron Lindsay (6):
30
hw/arm: versal: Add support for the LPD ADMAs
37
target/arm: Add ID_AA64ISAR2_EL1
31
hw/arm: versal: Generate xlnx-versal-virt zdma FDT nodes
38
target/arm: Add feature detection for FEAT_Pauth2 and extensions
39
target/arm: Implement FEAT_EPAC
40
target/arm: Implement FEAT_Pauth2
41
target/arm: Inform helpers whether a PAC instruction is 'combined'
42
target/arm: Implement FEAT_FPAC and FEAT_FPACCOMBINE
32
43
33
Eric Auger (1):
44
Colton Lewis (1):
34
hw/arm/smmu-common: a fix to smmu_find_smmu_pcibus
45
arm64: Restore trapless ptimer access
35
46
36
Niek Linnenbank (4):
47
Francisco Iglesias (8):
37
hw/arm/cubieboard: use ARM Cortex-A8 as the default CPU in machine definition
48
hw/misc: Introduce the Xilinx CFI interface
38
hw/arm/cubieboard: restrict allowed CPU type to ARM Cortex-A8
49
hw/misc: Introduce a model of Xilinx Versal's CFU_APB
39
hw/arm/cubieboard: restrict allowed RAM size to 512MiB and 1GiB
50
hw/misc/xlnx-versal-cfu: Introduce a model of Xilinx Versal CFU_FDRO
40
hw/arm/cubieboard: report error when using unsupported -bios argument
51
hw/misc/xlnx-versal-cfu: Introduce a model of Xilinx Versal's CFU_SFR
52
hw/misc: Introduce a model of Xilinx Versal's CFRAME_REG
53
hw/misc: Introduce a model of Xilinx Versal's CFRAME_BCAST_REG
54
hw/arm/xlnx-versal: Connect the CFU_APB, CFU_FDRO and CFU_SFR
55
hw/arm/versal: Connect the CFRAME_REG and CFRAME_BCAST_REG
41
56
42
Pan Nengyuan (4):
57
Philippe Mathieu-Daudé (1):
43
hw/arm/pxa2xx: move timer_new from init() into realize() to avoid memleaks
58
hw/intc/arm_gicv3_its: Avoid maybe-uninitialized error in get_vte()
44
hw/arm/spitz: move timer_new from init() into realize() to avoid memleaks
45
hw/arm/strongarm: move timer_new from init() into realize() to avoid memleaks
46
hw/timer/cadence_ttc: move timer_new from init() into realize() to avoid memleaks
47
59
48
Peter Maydell (1):
60
Richard Henderson (9):
49
target/arm: Implement (trivially) ARMv8.2-TTCNP
61
tests/tcg/aarch64: Adjust pauth tests for FEAT_FPAC
62
target/arm: Don't change pauth features when changing algorithm
63
target/arm: Implement FEAT_PACQARMA3
64
target/arm: Do not use gen_mte_checkN in trans_STGP
65
target/arm: Implement RMR_ELx
66
target/arm: Implement cortex-a710
67
target/arm: Implement HCR_EL2.TIDCP
68
target/arm: Implement FEAT_TIDCP1
69
target/arm: Enable SCTLR_EL1.TIDCP for user-only
50
70
51
Philippe Mathieu-Daudé (6):
71
Shameer Kolothum (1):
52
hw/arm/smmu-common: Simplify smmu_find_smmu_pcibus() logic
72
arm/kvm: Enable support for KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE
53
hw/arm/gumstix: Simplify since the machines are little-endian only
54
hw/arm/mainstone: Simplify since the machines are little-endian only
55
hw/arm/omap_sx1: Simplify since the machines are little-endian only
56
hw/arm/z2: Simplify since the machines are little-endian only
57
hw/arm/musicpal: Simplify since the machines are little-endian only
58
73
59
Richard Henderson (19):
74
MAINTAINERS | 10 +
60
target/arm: Improve masking of HCR/HCR2 RES0 bits
75
docs/system/arm/cpu-features.rst | 21 +-
61
target/arm: Add HCR_EL2 bit definitions from ARMv8.6
76
docs/system/arm/emulation.rst | 8 +
62
target/arm: Disable has_el2 and has_el3 for user-only
77
docs/system/arm/virt.rst | 1 +
63
target/arm: Remove EL2 and EL3 setup from user-only
78
include/hw/arm/xlnx-versal.h | 85 +++
64
target/arm: Improve masking in arm_hcr_el2_eff
79
include/hw/misc/xlnx-cfi-if.h | 59 +++
65
target/arm: Honor the HCR_EL2.{TVM,TRVM} bits
80
include/hw/misc/xlnx-versal-cframe-reg.h | 303 +++++++++++
66
target/arm: Honor the HCR_EL2.TSW bit
81
include/hw/misc/xlnx-versal-cfu.h | 258 ++++++++++
67
target/arm: Honor the HCR_EL2.TACR bit
82
include/sysemu/kvm_int.h | 1 +
68
target/arm: Honor the HCR_EL2.TPCP bit
83
target/arm/cpu.h | 54 +-
69
target/arm: Honor the HCR_EL2.TPU bit
84
target/arm/helper.h | 2 +
70
target/arm: Honor the HCR_EL2.TTLB bit
85
target/arm/syndrome.h | 7 +
71
tests/tcg/aarch64: Add newline in pauth-1 printf
86
target/arm/tcg/helper-a64.h | 4 +
72
target/arm: Replicate TBI/TBID bits for single range regimes
87
tests/tcg/aarch64/pauth.h | 23 +
73
target/arm: Optimize cpu_mmu_index
88
accel/kvm/kvm-all.c | 1 +
74
target/arm: Introduce core_to_aa64_mmu_idx
89
hw/arm/virt.c | 1 +
75
target/arm: Apply TBI to ESR_ELx in helper_exception_return
90
hw/arm/xlnx-versal.c | 155 +++++-
76
target/arm: Move helper_dc_zva to helper-a64.c
91
hw/intc/arm_gicv3_its.c | 15 +-
77
target/arm: Use DEF_HELPER_FLAGS for helper_dc_zva
92
hw/misc/xlnx-cfi-if.c | 34 ++
78
target/arm: Clean address for DC ZVA
93
hw/misc/xlnx-versal-cframe-reg.c | 858 +++++++++++++++++++++++++++++++
94
hw/misc/xlnx-versal-cfu.c | 563 ++++++++++++++++++++
95
target/arm/arm-qmp-cmds.c | 2 +-
96
target/arm/cpu.c | 4 +
97
target/arm/cpu64.c | 86 +++-
98
target/arm/helper.c | 68 ++-
99
target/arm/hvf/hvf.c | 1 +
100
target/arm/kvm.c | 61 +++
101
target/arm/kvm64.c | 3 +
102
target/arm/tcg/cpu64.c | 215 ++++++++
103
target/arm/tcg/op_helper.c | 33 ++
104
target/arm/tcg/pauth_helper.c | 180 +++++--
105
target/arm/tcg/translate-a64.c | 74 +--
106
target/arm/tcg/translate.c | 33 ++
107
tests/qtest/arm-cpu-features.c | 12 +-
108
tests/tcg/aarch64/pauth-2.c | 54 +-
109
tests/tcg/aarch64/pauth-4.c | 18 +-
110
tests/tcg/aarch64/pauth-5.c | 10 +
111
hw/misc/meson.build | 3 +
112
qemu-options.hx | 15 +
113
tests/tcg/aarch64/Makefile.target | 6 +-
114
40 files changed, 3184 insertions(+), 157 deletions(-)
115
create mode 100644 include/hw/misc/xlnx-cfi-if.h
116
create mode 100644 include/hw/misc/xlnx-versal-cframe-reg.h
117
create mode 100644 include/hw/misc/xlnx-versal-cfu.h
118
create mode 100644 tests/tcg/aarch64/pauth.h
119
create mode 100644 hw/misc/xlnx-cfi-if.c
120
create mode 100644 hw/misc/xlnx-versal-cframe-reg.c
121
create mode 100644 hw/misc/xlnx-versal-cfu.c
79
122
80
include/hw/arm/xlnx-versal.h | 6 +
81
target/arm/cpu.h | 30 ++--
82
target/arm/helper-a64.h | 1 +
83
target/arm/helper.h | 1 -
84
target/arm/internals.h | 6 +
85
hw/arm/cubieboard.c | 29 +++-
86
hw/arm/gumstix.c | 16 +-
87
hw/arm/mainstone.c | 8 +-
88
hw/arm/musicpal.c | 10 --
89
hw/arm/omap_sx1.c | 11 +-
90
hw/arm/pxa2xx.c | 17 +-
91
hw/arm/smmu-common.c | 20 +--
92
hw/arm/spitz.c | 8 +-
93
hw/arm/strongarm.c | 18 ++-
94
hw/arm/xlnx-versal-virt.c | 28 ++++
95
hw/arm/xlnx-versal.c | 24 +++
96
hw/arm/z2.c | 8 +-
97
hw/timer/cadence_ttc.c | 18 ++-
98
target/arm/cpu.c | 13 +-
99
target/arm/cpu64.c | 2 +
100
target/arm/helper-a64.c | 114 ++++++++++++-
101
target/arm/helper.c | 373 ++++++++++++++++++++++++++++++-------------
102
target/arm/op_helper.c | 93 -----------
103
target/arm/translate-a64.c | 4 +-
104
tests/tcg/aarch64/pauth-1.c | 2 +-
105
25 files changed, 551 insertions(+), 309 deletions(-)
106
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Replicate the single TBI bit from TCR_EL2 and TCR_EL3 so that
3
With FEAT_FPAC, AUT* instructions that fail authentication
4
we can unconditionally use pointer bit 55 to index into our
4
do not produce an error value but instead fault.
5
composite TBI1:TBI0 field.
5
6
For pauth-2, install a signal handler and verify it gets called.
7
8
For pauth-4 and pauth-5, we are explicitly testing the error value,
9
so there's nothing to test with FEAT_FPAC, so exit early.
10
Adjust the makefile to use -cpu neoverse-v1, which has FEAT_EPAC
11
but not FEAT_FPAC.
6
12
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-id: 20230829232335.965414-2-richard.henderson@linaro.org
10
Message-id: 20200302175829.2183-2-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
17
---
13
target/arm/helper.c | 6 ++++--
18
tests/tcg/aarch64/pauth.h | 23 +++++++++++++
14
1 file changed, 4 insertions(+), 2 deletions(-)
19
tests/tcg/aarch64/pauth-2.c | 54 ++++++++++++++++++++++++++-----
15
20
tests/tcg/aarch64/pauth-4.c | 18 ++++++++---
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
tests/tcg/aarch64/pauth-5.c | 10 ++++++
17
index XXXXXXX..XXXXXXX 100644
22
tests/tcg/aarch64/Makefile.target | 6 +++-
18
--- a/target/arm/helper.c
23
5 files changed, 98 insertions(+), 13 deletions(-)
19
+++ b/target/arm/helper.c
24
create mode 100644 tests/tcg/aarch64/pauth.h
20
@@ -XXX,XX +XXX,XX @@ static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
25
21
} else if (mmu_idx == ARMMMUIdx_Stage2) {
26
diff --git a/tests/tcg/aarch64/pauth.h b/tests/tcg/aarch64/pauth.h
22
return 0; /* VTCR_EL2 */
27
new file mode 100644
23
} else {
28
index XXXXXXX..XXXXXXX
24
- return extract32(tcr, 20, 1);
29
--- /dev/null
25
+ /* Replicate the single TBI bit so we always have 2 bits. */
30
+++ b/tests/tcg/aarch64/pauth.h
26
+ return extract32(tcr, 20, 1) * 3;
31
@@ -XXX,XX +XXX,XX @@
32
+/*
33
+ * Helper for pauth test case
34
+ *
35
+ * Copyright (c) 2023 Linaro Ltd
36
+ * SPDX-License-Identifier: GPL-2.0-or-later
37
+ */
38
+
39
+#include <assert.h>
40
+#include <sys/auxv.h>
41
+
42
+static int get_pac_feature(void)
43
+{
44
+ unsigned long isar1, isar2;
45
+
46
+ assert(getauxval(AT_HWCAP) & HWCAP_CPUID);
47
+
48
+ asm("mrs %0, id_aa64isar1_el1" : "=r"(isar1));
49
+ asm("mrs %0, S3_0_C0_C6_2" : "=r"(isar2)); /* id_aa64isar2_el1 */
50
+
51
+ return ((isar1 >> 4) & 0xf) /* APA */
52
+ | ((isar1 >> 8) & 0xf) /* API */
53
+ | ((isar2 >> 12) & 0xf); /* APA3 */
54
+}
55
diff --git a/tests/tcg/aarch64/pauth-2.c b/tests/tcg/aarch64/pauth-2.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/tests/tcg/aarch64/pauth-2.c
58
+++ b/tests/tcg/aarch64/pauth-2.c
59
@@ -XXX,XX +XXX,XX @@
60
#include <stdint.h>
61
+#include <signal.h>
62
+#include <stdlib.h>
63
#include <assert.h>
64
+#include "pauth.h"
65
+
66
+
67
+static void sigill(int sig, siginfo_t *info, void *vuc)
68
+{
69
+ ucontext_t *uc = vuc;
70
+ uint64_t test;
71
+
72
+ /* There is only one insn below that is allowed to fault. */
73
+ asm volatile("adr %0, auth2_insn" : "=r"(test));
74
+ assert(test == uc->uc_mcontext.pc);
75
+ exit(0);
76
+}
77
+
78
+static int pac_feature;
79
80
void do_test(uint64_t value)
81
{
82
@@ -XXX,XX +XXX,XX @@ void do_test(uint64_t value)
83
* An invalid salt usually fails authorization, but again there
84
* is a chance of choosing another salt that works.
85
* Iterate until we find another salt which does fail.
86
+ *
87
+ * With FEAT_FPAC, this will SIGILL instead of producing a result.
88
*/
89
for (salt2 = salt1 + 1; ; salt2++) {
90
- asm volatile("autda %0, %2" : "=r"(decode) : "0"(encode), "r"(salt2));
91
+ asm volatile("auth2_insn: autda %0, %2"
92
+ : "=r"(decode) : "0"(encode), "r"(salt2));
93
if (decode != value) {
94
break;
95
}
96
}
97
98
+ assert(pac_feature < 4); /* No FEAT_FPAC */
99
+
100
/* The VA bits, bit 55, and the TBI bits, should be unchanged. */
101
assert(((decode ^ value) & 0xff80ffffffffffffull) == 0);
102
103
/*
104
- * Bits [54:53] are an error indicator based on the key used;
105
- * the DA key above is keynumber 0, so error == 0b01. Otherwise
106
- * bit 55 of the original is sign-extended into the rest of the auth.
107
+ * Without FEAT_Pauth2, bits [54:53] are an error indicator based on
108
+ * the key used; the DA key above is keynumber 0, so error == 0b01.
109
+ * Otherwise, bit 55 of the original is sign-extended into the rest
110
+ * of the auth.
111
*/
112
- if ((value >> 55) & 1) {
113
- assert(((decode >> 48) & 0xff) == 0b10111111);
114
- } else {
115
- assert(((decode >> 48) & 0xff) == 0b00100000);
116
+ if (pac_feature < 3) {
117
+ if ((value >> 55) & 1) {
118
+ assert(((decode >> 48) & 0xff) == 0b10111111);
119
+ } else {
120
+ assert(((decode >> 48) & 0xff) == 0b00100000);
121
+ }
27
}
122
}
28
}
123
}
29
124
30
@@ -XXX,XX +XXX,XX @@ static int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx)
125
int main()
31
} else if (mmu_idx == ARMMMUIdx_Stage2) {
126
{
32
return 0; /* VTCR_EL2 */
127
+ static const struct sigaction sa = {
33
} else {
128
+ .sa_sigaction = sigill,
34
- return extract32(tcr, 29, 1);
129
+ .sa_flags = SA_SIGINFO
35
+ /* Replicate the single TBID bit so we always have 2 bits. */
130
+ };
36
+ return extract32(tcr, 29, 1) * 3;
131
+
132
+ pac_feature = get_pac_feature();
133
+ assert(pac_feature != 0);
134
+
135
+ if (pac_feature >= 4) {
136
+ /* FEAT_FPAC */
137
+ sigaction(SIGILL, &sa, NULL);
138
+ }
139
+
140
do_test(0);
141
do_test(0xda004acedeadbeefull);
142
return 0;
143
diff --git a/tests/tcg/aarch64/pauth-4.c b/tests/tcg/aarch64/pauth-4.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/tests/tcg/aarch64/pauth-4.c
146
+++ b/tests/tcg/aarch64/pauth-4.c
147
@@ -XXX,XX +XXX,XX @@
148
#include <assert.h>
149
#include <stdio.h>
150
#include <stdlib.h>
151
+#include "pauth.h"
152
153
#define TESTS 1000
154
155
int main()
156
{
157
+ char base[TESTS];
158
int i, count = 0;
159
float perc;
160
- void *base = malloc(TESTS);
161
+ int pac_feature = get_pac_feature();
162
+
163
+ /*
164
+ * Exit if no PAuth or FEAT_FPAC, which will SIGILL on AUTIA failure
165
+ * rather than return an error for us to check below.
166
+ */
167
+ if (pac_feature == 0 || pac_feature >= 4) {
168
+ return 0;
169
+ }
170
171
for (i = 0; i < TESTS; i++) {
172
uintptr_t in, x, y;
173
@@ -XXX,XX +XXX,XX @@ int main()
174
in = i + (uintptr_t) base;
175
176
asm("mov %0, %[in]\n\t"
177
- "pacia %0, sp\n\t" /* sigill if pauth not supported */
178
+ "pacia %0, sp\n\t"
179
"eor %0, %0, #4\n\t" /* corrupt single bit */
180
"mov %1, %0\n\t"
181
"autia %1, sp\n\t" /* validate corrupted pointer */
182
@@ -XXX,XX +XXX,XX @@ int main()
183
if (x != y) {
184
count++;
185
}
186
-
37
}
187
}
188
+
189
perc = (float) count / (float) TESTS;
190
- printf("Checks Passed: %0.2f%%", perc * 100.0);
191
+ printf("Checks Passed: %0.2f%%\n", perc * 100.0);
192
assert(perc > 0.95);
193
return 0;
38
}
194
}
39
195
diff --git a/tests/tcg/aarch64/pauth-5.c b/tests/tcg/aarch64/pauth-5.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/tests/tcg/aarch64/pauth-5.c
198
+++ b/tests/tcg/aarch64/pauth-5.c
199
@@ -XXX,XX +XXX,XX @@
200
#include <assert.h>
201
+#include "pauth.h"
202
203
static int x;
204
205
@@ -XXX,XX +XXX,XX @@ int main()
206
{
207
int *p0 = &x, *p1, *p2, *p3;
208
unsigned long salt = 0;
209
+ int pac_feature = get_pac_feature();
210
+
211
+ /*
212
+ * Exit if no PAuth or FEAT_FPAC, which will SIGILL on AUTDA failure
213
+ * rather than return an error for us to check below.
214
+ */
215
+ if (pac_feature == 0 || pac_feature >= 4) {
216
+ return 0;
217
+ }
218
219
/*
220
* With TBI enabled and a 48-bit VA, there are 7 bits of auth, and so
221
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
222
index XXXXXXX..XXXXXXX 100644
223
--- a/tests/tcg/aarch64/Makefile.target
224
+++ b/tests/tcg/aarch64/Makefile.target
225
@@ -XXX,XX +XXX,XX @@ endif
226
ifneq ($(CROSS_CC_HAS_ARMV8_3),)
227
AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5
228
pauth-%: CFLAGS += -march=armv8.3-a
229
-run-pauth-%: QEMU_OPTS += -cpu max
230
+run-pauth-1: QEMU_OPTS += -cpu max
231
+run-pauth-2: QEMU_OPTS += -cpu max
232
+# Choose a cpu with FEAT_Pauth but without FEAT_FPAC for pauth-[45].
233
+run-pauth-4: QEMU_OPTS += -cpu neoverse-v1
234
+run-pauth-5: QEMU_OPTS += -cpu neoverse-v1
235
endif
236
237
# BTI Tests
40
--
238
--
41
2.20.1
239
2.34.1
42
43
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
2
2
3
We now cache the core mmu_idx in env->hflags. Rather than recompute
3
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
from scratch, extract the field. All of the uses of cpu_mmu_index
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
within target/arm are within helpers, and env->hflags is always stable
5
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
6
within a translation block from whence helpers are called.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230829232335.965414-3-richard.henderson@linaro.org
10
Message-id: 20200302175829.2183-3-richard.henderson@linaro.org
9
[PMM: drop the HVF part of the patch and just comment that
10
we need to do something when the register appears in that API]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
14
---
13
target/arm/cpu.h | 23 +++++++++++++----------
15
target/arm/cpu.h | 1 +
14
target/arm/helper.c | 5 -----
16
target/arm/helper.c | 4 ++--
15
2 files changed, 13 insertions(+), 15 deletions(-)
17
target/arm/hvf/hvf.c | 1 +
18
target/arm/kvm64.c | 2 ++
19
4 files changed, 6 insertions(+), 2 deletions(-)
16
20
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
23
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
25
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
22
26
uint32_t dbgdevid1;
23
#define MMU_USER_IDX 0
27
uint64_t id_aa64isar0;
24
28
uint64_t id_aa64isar1;
25
-/**
29
+ uint64_t id_aa64isar2;
26
- * cpu_mmu_index:
30
uint64_t id_aa64pfr0;
27
- * @env: The cpu environment
31
uint64_t id_aa64pfr1;
28
- * @ifetch: True for code access, false for data access.
32
uint64_t id_aa64mmfr0;
29
- *
30
- * Return the core mmu index for the current translation regime.
31
- * This function is used by generic TCG code paths.
32
- */
33
-int cpu_mmu_index(CPUARMState *env, bool ifetch);
34
-
35
/* Indexes used when registering address spaces with cpu_address_space_init */
36
typedef enum ARMASIdx {
37
ARMASIdx_NS = 0,
38
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, BTYPE, 10, 2) /* Not cached. */
39
FIELD(TBFLAG_A64, TBID, 12, 2)
40
FIELD(TBFLAG_A64, UNPRIV, 14, 1)
41
42
+/**
43
+ * cpu_mmu_index:
44
+ * @env: The cpu environment
45
+ * @ifetch: True for code access, false for data access.
46
+ *
47
+ * Return the core mmu index for the current translation regime.
48
+ * This function is used by generic TCG code paths.
49
+ */
50
+static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
51
+{
52
+ return FIELD_EX32(env->hflags, TBFLAG_ANY, MMUIDX);
53
+}
54
+
55
static inline bool bswap_code(bool sctlr_b)
56
{
57
#ifdef CONFIG_USER_ONLY
58
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
diff --git a/target/arm/helper.c b/target/arm/helper.c
59
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/helper.c
35
--- a/target/arm/helper.c
61
+++ b/target/arm/helper.c
36
+++ b/target/arm/helper.c
62
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env)
37
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
63
return arm_mmu_idx_el(env, arm_current_el(env));
38
.access = PL1_R, .type = ARM_CP_CONST,
64
}
39
.accessfn = access_aa64_tid3,
65
40
.resetvalue = cpu->isar.id_aa64isar1 },
66
-int cpu_mmu_index(CPUARMState *env, bool ifetch)
41
- { .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
67
-{
42
+ { .name = "ID_AA64ISAR2_EL1", .state = ARM_CP_STATE_AA64,
68
- return arm_to_core_mmu_idx(arm_mmu_idx(env));
43
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
69
-}
44
.access = PL1_R, .type = ARM_CP_CONST,
70
-
45
.accessfn = access_aa64_tid3,
71
#ifndef CONFIG_USER_ONLY
46
- .resetvalue = 0 },
72
ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
47
+ .resetvalue = cpu->isar.id_aa64isar2 },
73
{
48
{ .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
49
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,
50
.access = PL1_R, .type = ARM_CP_CONST,
51
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/hvf/hvf.c
54
+++ b/target/arm/hvf/hvf.c
55
@@ -XXX,XX +XXX,XX @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
56
{ HV_SYS_REG_ID_AA64DFR1_EL1, &host_isar.id_aa64dfr1 },
57
{ HV_SYS_REG_ID_AA64ISAR0_EL1, &host_isar.id_aa64isar0 },
58
{ HV_SYS_REG_ID_AA64ISAR1_EL1, &host_isar.id_aa64isar1 },
59
+ /* Add ID_AA64ISAR2_EL1 here when HVF supports it */
60
{ HV_SYS_REG_ID_AA64MMFR0_EL1, &host_isar.id_aa64mmfr0 },
61
{ HV_SYS_REG_ID_AA64MMFR1_EL1, &host_isar.id_aa64mmfr1 },
62
{ HV_SYS_REG_ID_AA64MMFR2_EL1, &host_isar.id_aa64mmfr2 },
63
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/kvm64.c
66
+++ b/target/arm/kvm64.c
67
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
68
ARM64_SYS_REG(3, 0, 0, 6, 0));
69
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
70
ARM64_SYS_REG(3, 0, 0, 6, 1));
71
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar2,
72
+ ARM64_SYS_REG(3, 0, 0, 6, 2));
73
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0,
74
ARM64_SYS_REG(3, 0, 0, 7, 0));
75
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
74
--
76
--
75
2.20.1
77
2.34.1
76
78
77
79
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
2
2
3
This bit traps EL1 access to the auxiliary control registers.
3
Rename isar_feature_aa64_pauth_arch to isar_feature_aa64_pauth_qarma5
4
to distinguish the other architectural algorithm qarma3.
5
6
Add ARMPauthFeature and isar_feature_pauth_feature to cover the
7
other pauth conditions.
4
8
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200229012811.24129-9-richard.henderson@linaro.org
12
Message-id: 20230829232335.965414-4-richard.henderson@linaro.org
13
Message-Id: <20230609172324.982888-3-aaron@os.amperecomputing.com>
14
[rth: Add ARMPauthFeature and eliminate most other predicates]
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
17
---
10
target/arm/helper.c | 18 ++++++++++++++----
18
target/arm/cpu.h | 47 +++++++++++++++++++++++++++++------
11
1 file changed, 14 insertions(+), 4 deletions(-)
19
target/arm/tcg/pauth_helper.c | 2 +-
20
2 files changed, 40 insertions(+), 9 deletions(-)
12
21
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
24
--- a/target/arm/cpu.h
16
+++ b/target/arm/helper.c
25
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tsw(CPUARMState *env, const ARMCPRegInfo *ri,
26
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
18
return CP_ACCESS_OK;
27
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
19
}
28
}
20
29
21
+/* Check for traps from EL1 due to HCR_EL2.TACR. */
30
+/*
22
+static CPAccessResult access_tacr(CPUARMState *env, const ARMCPRegInfo *ri,
31
+ * These are the values from APA/API/APA3.
23
+ bool isread)
32
+ * In general these must be compared '>=', per the normal Arm ARM
33
+ * treatment of fields in ID registers.
34
+ */
35
+typedef enum {
36
+ PauthFeat_None = 0,
37
+ PauthFeat_1 = 1,
38
+ PauthFeat_EPAC = 2,
39
+ PauthFeat_2 = 3,
40
+ PauthFeat_FPAC = 4,
41
+ PauthFeat_FPACCOMBINED = 5,
42
+} ARMPauthFeature;
43
+
44
+static inline ARMPauthFeature
45
+isar_feature_pauth_feature(const ARMISARegisters *id)
24
+{
46
+{
25
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TACR)) {
47
+ /*
26
+ return CP_ACCESS_TRAP_EL2;
48
+ * Architecturally, only one of {APA,API,APA3} may be active (non-zero)
27
+ }
49
+ * and the other two must be zero. Thus we may avoid conditionals.
28
+ return CP_ACCESS_OK;
50
+ */
51
+ return (FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) |
52
+ FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, API) |
53
+ FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3));
29
+}
54
+}
30
+
55
+
31
static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
56
static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
32
{
57
{
33
ARMCPU *cpu = env_archcpu(env);
58
/*
34
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo ats1cp_reginfo[] = {
59
* Return true if any form of pauth is enabled, as this
35
static const ARMCPRegInfo actlr2_hactlr2_reginfo[] = {
60
* predicate controls migration of the 128-bit keys.
36
{ .name = "ACTLR2", .state = ARM_CP_STATE_AA32,
61
*/
37
.cp = 15, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 3,
62
- return (id->id_aa64isar1 &
38
- .access = PL1_RW, .type = ARM_CP_CONST,
63
- (FIELD_DP64(0, ID_AA64ISAR1, APA, 0xf) |
39
- .resetvalue = 0 },
64
- FIELD_DP64(0, ID_AA64ISAR1, API, 0xf) |
40
+ .access = PL1_RW, .accessfn = access_tacr,
65
- FIELD_DP64(0, ID_AA64ISAR1, GPA, 0xf) |
41
+ .type = ARM_CP_CONST, .resetvalue = 0 },
66
- FIELD_DP64(0, ID_AA64ISAR1, GPI, 0xf))) != 0;
42
{ .name = "HACTLR2", .state = ARM_CP_STATE_AA32,
67
+ return isar_feature_pauth_feature(id) != PauthFeat_None;
43
.cp = 15, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 3,
68
}
44
.access = PL2_RW, .type = ARM_CP_CONST,
69
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
70
-static inline bool isar_feature_aa64_pauth_arch(const ARMISARegisters *id)
46
ARMCPRegInfo auxcr_reginfo[] = {
71
+static inline bool isar_feature_aa64_pauth_qarma5(const ARMISARegisters *id)
47
{ .name = "ACTLR_EL1", .state = ARM_CP_STATE_BOTH,
72
{
48
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 1,
73
/*
49
- .access = PL1_RW, .type = ARM_CP_CONST,
74
- * Return true if pauth is enabled with the architected QARMA algorithm.
50
- .resetvalue = cpu->reset_auxcr },
75
- * QEMU will always set APA+GPA to the same value.
51
+ .access = PL1_RW, .accessfn = access_tacr,
76
+ * Return true if pauth is enabled with the architected QARMA5 algorithm.
52
+ .type = ARM_CP_CONST, .resetvalue = cpu->reset_auxcr },
77
+ * QEMU will always enable or disable both APA and GPA.
53
{ .name = "ACTLR_EL2", .state = ARM_CP_STATE_BOTH,
78
*/
54
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 1,
79
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0;
55
.access = PL2_RW, .type = ARM_CP_CONST,
80
}
81
82
+static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id)
83
+{
84
+ /*
85
+ * Return true if pauth is enabled with the architected QARMA3 algorithm.
86
+ * QEMU will always enable or disable both APA3 and GPA3.
87
+ */
88
+ return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3) != 0;
89
+}
90
+
91
static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
92
{
93
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2;
94
diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/tcg/pauth_helper.c
97
+++ b/target/arm/tcg/pauth_helper.c
98
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_computepac_impdef(uint64_t data, uint64_t modifier,
99
static uint64_t pauth_computepac(CPUARMState *env, uint64_t data,
100
uint64_t modifier, ARMPACKey key)
101
{
102
- if (cpu_isar_feature(aa64_pauth_arch, env_archcpu(env))) {
103
+ if (cpu_isar_feature(aa64_pauth_qarma5, env_archcpu(env))) {
104
return pauth_computepac_architected(data, modifier, key);
105
} else {
106
return pauth_computepac_impdef(data, modifier, key);
56
--
107
--
57
2.20.1
108
2.34.1
58
59
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This bit traps EL1 access to tlb maintenance insns.
3
We have cpu properties to adjust the pauth algorithm for the
4
purpose of speed of emulation. Retain the set of pauth features
5
supported by the cpu even as the algorithm changes.
6
7
This already affects the neoverse-v1 cpu, which has FEAT_EPAC.
4
8
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200229012811.24129-12-richard.henderson@linaro.org
11
Message-id: 20230829232335.965414-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
target/arm/helper.c | 85 +++++++++++++++++++++++++++++----------------
14
target/arm/cpu64.c | 70 +++++++++++++++++++++++++++---------------
11
1 file changed, 55 insertions(+), 30 deletions(-)
15
target/arm/tcg/cpu64.c | 2 ++
16
2 files changed, 47 insertions(+), 25 deletions(-)
12
17
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
20
--- a/target/arm/cpu64.c
16
+++ b/target/arm/helper.c
21
+++ b/target/arm/cpu64.c
17
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tacr(CPUARMState *env, const ARMCPRegInfo *ri,
22
@@ -XXX,XX +XXX,XX @@ void aarch64_add_sme_properties(Object *obj)
18
return CP_ACCESS_OK;
23
24
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
25
{
26
- int arch_val = 0, impdef_val = 0;
27
- uint64_t t;
28
+ ARMPauthFeature features = cpu_isar_feature(pauth_feature, cpu);
29
+ uint64_t isar1;
30
31
- /* Exit early if PAuth is enabled, and fall through to disable it */
32
- if ((kvm_enabled() || hvf_enabled()) && cpu->prop_pauth) {
33
- if (!cpu_isar_feature(aa64_pauth, cpu)) {
34
- error_setg(errp, "'pauth' feature not supported by %s on this host",
35
- kvm_enabled() ? "KVM" : "hvf");
36
+ /*
37
+ * These properties enable or disable Pauth as a whole, or change
38
+ * the pauth algorithm, but do not change the set of features that
39
+ * are present. We have saved a copy of those features above and
40
+ * will now place it into the field that chooses the algorithm.
41
+ *
42
+ * Begin by disabling all fields.
43
+ */
44
+ isar1 = cpu->isar.id_aa64isar1;
45
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, 0);
46
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 0);
47
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, 0);
48
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 0);
49
+
50
+ if (kvm_enabled() || hvf_enabled()) {
51
+ /*
52
+ * Exit early if PAuth is enabled and fall through to disable it.
53
+ * The algorithm selection properties are not present.
54
+ */
55
+ if (cpu->prop_pauth) {
56
+ if (features == 0) {
57
+ error_setg(errp, "'pauth' feature not supported by "
58
+ "%s on this host", current_accel_name());
59
+ }
60
+ return;
61
+ }
62
+ } else {
63
+ /* Pauth properties are only present when the model supports it. */
64
+ if (features == 0) {
65
+ assert(!cpu->prop_pauth);
66
+ return;
67
}
68
69
- return;
70
- }
71
-
72
- /* TODO: Handle HaveEnhancedPAC, HaveEnhancedPAC2, HaveFPAC. */
73
- if (cpu->prop_pauth) {
74
- if (cpu->prop_pauth_impdef) {
75
- impdef_val = 1;
76
- } else {
77
- arch_val = 1;
78
+ if (cpu->prop_pauth) {
79
+ if (cpu->prop_pauth_impdef) {
80
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, features);
81
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 1);
82
+ } else {
83
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, features);
84
+ isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 1);
85
+ }
86
+ } else if (cpu->prop_pauth_impdef) {
87
+ error_setg(errp, "cannot enable pauth-impdef without pauth");
88
+ error_append_hint(errp, "Add pauth=on to the CPU property list.\n");
89
}
90
- } else if (cpu->prop_pauth_impdef) {
91
- error_setg(errp, "cannot enable pauth-impdef without pauth");
92
- error_append_hint(errp, "Add pauth=on to the CPU property list.\n");
93
}
94
95
- t = cpu->isar.id_aa64isar1;
96
- t = FIELD_DP64(t, ID_AA64ISAR1, APA, arch_val);
97
- t = FIELD_DP64(t, ID_AA64ISAR1, GPA, arch_val);
98
- t = FIELD_DP64(t, ID_AA64ISAR1, API, impdef_val);
99
- t = FIELD_DP64(t, ID_AA64ISAR1, GPI, impdef_val);
100
- cpu->isar.id_aa64isar1 = t;
101
+ cpu->isar.id_aa64isar1 = isar1;
19
}
102
}
20
103
21
+/* Check for traps from EL1 due to HCR_EL2.TTLB. */
104
static Property arm_cpu_pauth_property =
22
+static CPAccessResult access_ttlb(CPUARMState *env, const ARMCPRegInfo *ri,
105
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
23
+ bool isread)
106
index XXXXXXX..XXXXXXX 100644
24
+{
107
--- a/target/arm/tcg/cpu64.c
25
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TTLB)) {
108
+++ b/target/arm/tcg/cpu64.c
26
+ return CP_ACCESS_TRAP_EL2;
109
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
27
+ }
110
28
+ return CP_ACCESS_OK;
111
t = cpu->isar.id_aa64isar1;
29
+}
112
t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
30
+
113
+ t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_1);
31
static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
114
+ t = FIELD_DP64(t, ID_AA64ISAR1, API, 1);
32
{
115
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); /* FEAT_JSCVT */
33
ARMCPU *cpu = env_archcpu(env);
116
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); /* FEAT_FCMA */
34
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
117
t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* FEAT_LRCPC2 */
35
.type = ARM_CP_NO_RAW, .access = PL1_R, .readfn = isr_read },
36
/* 32 bit ITLB invalidates */
37
{ .name = "ITLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 0,
38
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
39
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
40
+ .writefn = tlbiall_write },
41
{ .name = "ITLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
42
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
43
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
44
+ .writefn = tlbimva_write },
45
{ .name = "ITLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 2,
46
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
47
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
48
+ .writefn = tlbiasid_write },
49
/* 32 bit DTLB invalidates */
50
{ .name = "DTLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 0,
51
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
52
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
53
+ .writefn = tlbiall_write },
54
{ .name = "DTLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
55
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
56
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
57
+ .writefn = tlbimva_write },
58
{ .name = "DTLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 2,
59
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
60
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
61
+ .writefn = tlbiasid_write },
62
/* 32 bit TLB invalidates */
63
{ .name = "TLBIALL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
64
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_write },
65
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
66
+ .writefn = tlbiall_write },
67
{ .name = "TLBIMVA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
68
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
69
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
70
+ .writefn = tlbimva_write },
71
{ .name = "TLBIASID", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
72
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiasid_write },
73
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
74
+ .writefn = tlbiasid_write },
75
{ .name = "TLBIMVAA", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
76
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write },
77
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
78
+ .writefn = tlbimvaa_write },
79
REGINFO_SENTINEL
80
};
81
82
static const ARMCPRegInfo v7mp_cp_reginfo[] = {
83
/* 32 bit TLB invalidates, Inner Shareable */
84
{ .name = "TLBIALLIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
85
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbiall_is_write },
86
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
87
+ .writefn = tlbiall_is_write },
88
{ .name = "TLBIMVAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
89
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write },
90
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
91
+ .writefn = tlbimva_is_write },
92
{ .name = "TLBIASIDIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
93
- .type = ARM_CP_NO_RAW, .access = PL1_W,
94
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
95
.writefn = tlbiasid_is_write },
96
{ .name = "TLBIMVAAIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
97
- .type = ARM_CP_NO_RAW, .access = PL1_W,
98
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
99
.writefn = tlbimvaa_is_write },
100
REGINFO_SENTINEL
101
};
102
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
103
/* TLBI operations */
104
{ .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
105
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
106
- .access = PL1_W, .type = ARM_CP_NO_RAW,
107
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
108
.writefn = tlbi_aa64_vmalle1is_write },
109
{ .name = "TLBI_VAE1IS", .state = ARM_CP_STATE_AA64,
110
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 1,
111
- .access = PL1_W, .type = ARM_CP_NO_RAW,
112
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
113
.writefn = tlbi_aa64_vae1is_write },
114
{ .name = "TLBI_ASIDE1IS", .state = ARM_CP_STATE_AA64,
115
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 2,
116
- .access = PL1_W, .type = ARM_CP_NO_RAW,
117
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
118
.writefn = tlbi_aa64_vmalle1is_write },
119
{ .name = "TLBI_VAAE1IS", .state = ARM_CP_STATE_AA64,
120
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 3,
121
- .access = PL1_W, .type = ARM_CP_NO_RAW,
122
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
123
.writefn = tlbi_aa64_vae1is_write },
124
{ .name = "TLBI_VALE1IS", .state = ARM_CP_STATE_AA64,
125
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
126
- .access = PL1_W, .type = ARM_CP_NO_RAW,
127
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
128
.writefn = tlbi_aa64_vae1is_write },
129
{ .name = "TLBI_VAALE1IS", .state = ARM_CP_STATE_AA64,
130
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
131
- .access = PL1_W, .type = ARM_CP_NO_RAW,
132
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
133
.writefn = tlbi_aa64_vae1is_write },
134
{ .name = "TLBI_VMALLE1", .state = ARM_CP_STATE_AA64,
135
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 0,
136
- .access = PL1_W, .type = ARM_CP_NO_RAW,
137
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
138
.writefn = tlbi_aa64_vmalle1_write },
139
{ .name = "TLBI_VAE1", .state = ARM_CP_STATE_AA64,
140
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 1,
141
- .access = PL1_W, .type = ARM_CP_NO_RAW,
142
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
143
.writefn = tlbi_aa64_vae1_write },
144
{ .name = "TLBI_ASIDE1", .state = ARM_CP_STATE_AA64,
145
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 2,
146
- .access = PL1_W, .type = ARM_CP_NO_RAW,
147
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
148
.writefn = tlbi_aa64_vmalle1_write },
149
{ .name = "TLBI_VAAE1", .state = ARM_CP_STATE_AA64,
150
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 3,
151
- .access = PL1_W, .type = ARM_CP_NO_RAW,
152
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
153
.writefn = tlbi_aa64_vae1_write },
154
{ .name = "TLBI_VALE1", .state = ARM_CP_STATE_AA64,
155
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
156
- .access = PL1_W, .type = ARM_CP_NO_RAW,
157
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
158
.writefn = tlbi_aa64_vae1_write },
159
{ .name = "TLBI_VAALE1", .state = ARM_CP_STATE_AA64,
160
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
161
- .access = PL1_W, .type = ARM_CP_NO_RAW,
162
+ .access = PL1_W, .accessfn = access_ttlb, .type = ARM_CP_NO_RAW,
163
.writefn = tlbi_aa64_vae1_write },
164
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
165
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
166
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
167
#endif
168
/* TLB invalidate last level of translation table walk */
169
{ .name = "TLBIMVALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 5,
170
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_is_write },
171
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
172
+ .writefn = tlbimva_is_write },
173
{ .name = "TLBIMVAALIS", .cp = 15, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 7,
174
- .type = ARM_CP_NO_RAW, .access = PL1_W,
175
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
176
.writefn = tlbimvaa_is_write },
177
{ .name = "TLBIMVAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 5,
178
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimva_write },
179
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
180
+ .writefn = tlbimva_write },
181
{ .name = "TLBIMVAAL", .cp = 15, .opc1 = 0, .crn = 8, .crm = 7, .opc2 = 7,
182
- .type = ARM_CP_NO_RAW, .access = PL1_W, .writefn = tlbimvaa_write },
183
+ .type = ARM_CP_NO_RAW, .access = PL1_W, .accessfn = access_ttlb,
184
+ .writefn = tlbimvaa_write },
185
{ .name = "TLBIMVALH", .cp = 15, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
186
.type = ARM_CP_NO_RAW, .access = PL2_W,
187
.writefn = tlbimva_hyp_write },
188
--
118
--
189
2.20.1
119
2.34.1
190
191
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 bits trap EL1 access to set/way cache maintenance insns.
3
Implement the QARMA3 cryptographic algorithm for PAC calculation.
4
Implement a cpu feature to select the algorithm and document it.
4
5
5
Buglink: https://bugs.launchpad.net/bugs/1863685
6
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200229012811.24129-8-richard.henderson@linaro.org
10
Message-id: 20230829232335.965414-6-richard.henderson@linaro.org
11
Message-Id: <20230609172324.982888-4-aaron@os.amperecomputing.com>
12
[rth: Merge cpu feature addition from another patch.]
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
15
---
11
target/arm/helper.c | 22 ++++++++++++++++------
16
docs/system/arm/cpu-features.rst | 21 ++++++++-----
12
1 file changed, 16 insertions(+), 6 deletions(-)
17
docs/system/arm/emulation.rst | 3 ++
18
target/arm/cpu.h | 1 +
19
target/arm/arm-qmp-cmds.c | 2 +-
20
target/arm/cpu64.c | 24 ++++++++++++--
21
target/arm/tcg/pauth_helper.c | 54 ++++++++++++++++++++++++++------
22
tests/qtest/arm-cpu-features.c | 12 ++++++-
23
7 files changed, 94 insertions(+), 23 deletions(-)
13
24
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
27
--- a/docs/system/arm/cpu-features.rst
17
+++ b/target/arm/helper.c
28
+++ b/docs/system/arm/cpu-features.rst
18
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tvm_trvm(CPUARMState *env, const ARMCPRegInfo *ri,
29
@@ -XXX,XX +XXX,XX @@ TCG VCPU Features
19
return CP_ACCESS_OK;
30
TCG VCPU features are CPU features that are specific to TCG.
20
}
31
Below is the list of TCG VCPU features and their descriptions.
21
32
22
+/* Check for traps from EL1 due to HCR_EL2.TSW. */
33
-``pauth-impdef``
23
+static CPAccessResult access_tsw(CPUARMState *env, const ARMCPRegInfo *ri,
34
- When ``FEAT_Pauth`` is enabled, either the *impdef* (Implementation
24
+ bool isread)
35
- Defined) algorithm is enabled or the *architected* QARMA algorithm
36
- is enabled. By default the impdef algorithm is disabled, and QARMA
37
- is enabled.
38
+``pauth``
39
+ Enable or disable ``FEAT_Pauth`` entirely.
40
41
- The architected QARMA algorithm has good cryptographic properties,
42
- but can be quite slow to emulate. The impdef algorithm used by QEMU
43
- is non-cryptographic but significantly faster.
44
+``pauth-impdef``
45
+ When ``pauth`` is enabled, select the QEMU implementation defined algorithm.
46
+
47
+``pauth-qarma3``
48
+ When ``pauth`` is enabled, select the architected QARMA3 algorithm.
49
+
50
+Without either ``pauth-impdef`` or ``pauth-qarma3`` enabled,
51
+the architected QARMA5 algorithm is used. The architected QARMA5
52
+and QARMA3 algorithms have good cryptographic properties, but can
53
+be quite slow to emulate. The impdef algorithm used by QEMU is
54
+non-cryptographic but significantly faster.
55
56
SVE CPU Properties
57
==================
58
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
59
index XXXXXXX..XXXXXXX 100644
60
--- a/docs/system/arm/emulation.rst
61
+++ b/docs/system/arm/emulation.rst
62
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
63
- FEAT_MTE (Memory Tagging Extension)
64
- FEAT_MTE2 (Memory Tagging Extension)
65
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
66
+- FEAT_PACIMP (Pointer authentication - IMPLEMENTATION DEFINED algorithm)
67
+- FEAT_PACQARMA3 (Pointer authentication - QARMA3 algorithm)
68
+- FEAT_PACQARMA5 (Pointer authentication - QARMA5 algorithm)
69
- FEAT_PAN (Privileged access never)
70
- FEAT_PAN2 (AT S1E1R and AT S1E1W instruction variants affected by PSTATE.PAN)
71
- FEAT_PAN3 (Support for SCTLR_ELx.EPAN)
72
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/cpu.h
75
+++ b/target/arm/cpu.h
76
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
77
*/
78
bool prop_pauth;
79
bool prop_pauth_impdef;
80
+ bool prop_pauth_qarma3;
81
bool prop_lpa2;
82
83
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
84
diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/arm-qmp-cmds.c
87
+++ b/target/arm/arm-qmp-cmds.c
88
@@ -XXX,XX +XXX,XX @@ static const char *cpu_model_advertised_features[] = {
89
"sve640", "sve768", "sve896", "sve1024", "sve1152", "sve1280",
90
"sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048",
91
"kvm-no-adjvtime", "kvm-steal-time",
92
- "pauth", "pauth-impdef",
93
+ "pauth", "pauth-impdef", "pauth-qarma3",
94
NULL
95
};
96
97
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/arm/cpu64.c
100
+++ b/target/arm/cpu64.c
101
@@ -XXX,XX +XXX,XX @@ void aarch64_add_sme_properties(Object *obj)
102
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
103
{
104
ARMPauthFeature features = cpu_isar_feature(pauth_feature, cpu);
105
- uint64_t isar1;
106
+ uint64_t isar1, isar2;
107
108
/*
109
* These properties enable or disable Pauth as a whole, or change
110
@@ -XXX,XX +XXX,XX @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
111
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, 0);
112
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 0);
113
114
+ isar2 = cpu->isar.id_aa64isar2;
115
+ isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, 0);
116
+ isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 0);
117
+
118
if (kvm_enabled() || hvf_enabled()) {
119
/*
120
* Exit early if PAuth is enabled and fall through to disable it.
121
@@ -XXX,XX +XXX,XX @@ void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
122
}
123
124
if (cpu->prop_pauth) {
125
+ if (cpu->prop_pauth_impdef && cpu->prop_pauth_qarma3) {
126
+ error_setg(errp,
127
+ "cannot enable both pauth-impdef and pauth-qarma3");
128
+ return;
129
+ }
130
+
131
if (cpu->prop_pauth_impdef) {
132
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, API, features);
133
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPI, 1);
134
+ } else if (cpu->prop_pauth_qarma3) {
135
+ isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, APA3, features);
136
+ isar2 = FIELD_DP64(isar2, ID_AA64ISAR2, GPA3, 1);
137
} else {
138
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, APA, features);
139
isar1 = FIELD_DP64(isar1, ID_AA64ISAR1, GPA, 1);
140
}
141
- } else if (cpu->prop_pauth_impdef) {
142
- error_setg(errp, "cannot enable pauth-impdef without pauth");
143
+ } else if (cpu->prop_pauth_impdef || cpu->prop_pauth_qarma3) {
144
+ error_setg(errp, "cannot enable pauth-impdef or "
145
+ "pauth-qarma3 without pauth");
146
error_append_hint(errp, "Add pauth=on to the CPU property list.\n");
147
}
148
}
149
150
cpu->isar.id_aa64isar1 = isar1;
151
+ cpu->isar.id_aa64isar2 = isar2;
152
}
153
154
static Property arm_cpu_pauth_property =
155
DEFINE_PROP_BOOL("pauth", ARMCPU, prop_pauth, true);
156
static Property arm_cpu_pauth_impdef_property =
157
DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
158
+static Property arm_cpu_pauth_qarma3_property =
159
+ DEFINE_PROP_BOOL("pauth-qarma3", ARMCPU, prop_pauth_qarma3, false);
160
161
void aarch64_add_pauth_properties(Object *obj)
162
{
163
@@ -XXX,XX +XXX,XX @@ void aarch64_add_pauth_properties(Object *obj)
164
cpu->prop_pauth = cpu_isar_feature(aa64_pauth, cpu);
165
} else {
166
qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_impdef_property);
167
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_qarma3_property);
168
}
169
}
170
171
diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c
172
index XXXXXXX..XXXXXXX 100644
173
--- a/target/arm/tcg/pauth_helper.c
174
+++ b/target/arm/tcg/pauth_helper.c
175
@@ -XXX,XX +XXX,XX @@ static uint64_t pac_sub(uint64_t i)
176
return o;
177
}
178
179
+static uint64_t pac_sub1(uint64_t i)
25
+{
180
+{
26
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TSW)) {
181
+ static const uint8_t sub1[16] = {
27
+ return CP_ACCESS_TRAP_EL2;
182
+ 0xa, 0xd, 0xe, 0x6, 0xf, 0x7, 0x3, 0x5,
183
+ 0x9, 0x8, 0x0, 0xc, 0xb, 0x1, 0x2, 0x4,
184
+ };
185
+ uint64_t o = 0;
186
+ int b;
187
+
188
+ for (b = 0; b < 64; b += 4) {
189
+ o |= (uint64_t)sub1[(i >> b) & 0xf] << b;
28
+ }
190
+ }
29
+ return CP_ACCESS_OK;
191
+ return o;
30
+}
192
+}
31
+
193
+
32
static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
194
static uint64_t pac_inv_sub(uint64_t i)
33
{
195
{
34
ARMCPU *cpu = env_archcpu(env);
196
static const uint8_t inv_sub[16] = {
35
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
197
@@ -XXX,XX +XXX,XX @@ static uint64_t tweak_inv_shuffle(uint64_t i)
36
.access = PL1_W, .type = ARM_CP_NOP },
198
}
37
{ .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
199
38
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
200
static uint64_t pauth_computepac_architected(uint64_t data, uint64_t modifier,
39
- .access = PL1_W, .type = ARM_CP_NOP },
201
- ARMPACKey key)
40
+ .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
202
+ ARMPACKey key, bool isqarma3)
41
{ .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
203
{
42
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
204
static const uint64_t RC[5] = {
43
.access = PL0_W, .type = ARM_CP_NOP,
205
0x0000000000000000ull,
44
.accessfn = aa64_cacheop_access },
206
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_computepac_architected(uint64_t data, uint64_t modifier,
45
{ .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
207
0x452821E638D01377ull,
46
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
208
};
47
- .access = PL1_W, .type = ARM_CP_NOP },
209
const uint64_t alpha = 0xC0AC29B7C97C50DDull;
48
+ .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
210
+ int iterations = isqarma3 ? 2 : 4;
49
{ .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
211
/*
50
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
212
* Note that in the ARM pseudocode, key0 contains bits <127:64>
51
.access = PL0_W, .type = ARM_CP_NOP,
213
* and key1 contains bits <63:0> of the 128-bit key.
52
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
214
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_computepac_architected(uint64_t data, uint64_t modifier,
53
.accessfn = aa64_cacheop_access },
215
runningmod = modifier;
54
{ .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
216
workingval = data ^ key0;
55
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
217
56
- .access = PL1_W, .type = ARM_CP_NOP },
218
- for (i = 0; i <= 4; ++i) {
57
+ .access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
219
+ for (i = 0; i <= iterations; ++i) {
58
/* TLBI operations */
220
roundkey = key1 ^ runningmod;
59
{ .name = "TLBI_VMALLE1IS", .state = ARM_CP_STATE_AA64,
221
workingval ^= roundkey;
60
.opc0 = 1, .opc1 = 0, .crn = 8, .crm = 3, .opc2 = 0,
222
workingval ^= RC[i];
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
223
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_computepac_architected(uint64_t data, uint64_t modifier,
62
{ .name = "DCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
224
workingval = pac_cell_shuffle(workingval);
63
.type = ARM_CP_NOP, .access = PL1_W },
225
workingval = pac_mult(workingval);
64
{ .name = "DCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
226
}
65
- .type = ARM_CP_NOP, .access = PL1_W },
227
- workingval = pac_sub(workingval);
66
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
228
+ if (isqarma3) {
67
{ .name = "DCCMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 1,
229
+ workingval = pac_sub1(workingval);
68
.type = ARM_CP_NOP, .access = PL1_W },
230
+ } else {
69
{ .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
231
+ workingval = pac_sub(workingval);
70
- .type = ARM_CP_NOP, .access = PL1_W },
232
+ }
71
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
233
runningmod = tweak_shuffle(runningmod);
72
{ .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1,
234
}
73
.type = ARM_CP_NOP, .access = PL1_W },
235
roundkey = modk0 ^ runningmod;
74
{ .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1,
236
workingval ^= roundkey;
75
.type = ARM_CP_NOP, .access = PL1_W },
237
workingval = pac_cell_shuffle(workingval);
76
{ .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
238
workingval = pac_mult(workingval);
77
- .type = ARM_CP_NOP, .access = PL1_W },
239
- workingval = pac_sub(workingval);
78
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
240
+ if (isqarma3) {
79
/* MMU Domain access control / MPU write buffer control */
241
+ workingval = pac_sub1(workingval);
80
{ .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
242
+ } else {
81
.access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
243
+ workingval = pac_sub(workingval);
244
+ }
245
workingval = pac_cell_shuffle(workingval);
246
workingval = pac_mult(workingval);
247
workingval ^= key1;
248
workingval = pac_cell_inv_shuffle(workingval);
249
- workingval = pac_inv_sub(workingval);
250
+ if (isqarma3) {
251
+ workingval = pac_sub1(workingval);
252
+ } else {
253
+ workingval = pac_inv_sub(workingval);
254
+ }
255
workingval = pac_mult(workingval);
256
workingval = pac_cell_inv_shuffle(workingval);
257
workingval ^= key0;
258
workingval ^= runningmod;
259
- for (i = 0; i <= 4; ++i) {
260
- workingval = pac_inv_sub(workingval);
261
- if (i < 4) {
262
+ for (i = 0; i <= iterations; ++i) {
263
+ if (isqarma3) {
264
+ workingval = pac_sub1(workingval);
265
+ } else {
266
+ workingval = pac_inv_sub(workingval);
267
+ }
268
+ if (i < iterations) {
269
workingval = pac_mult(workingval);
270
workingval = pac_cell_inv_shuffle(workingval);
271
}
272
runningmod = tweak_inv_shuffle(runningmod);
273
roundkey = key1 ^ runningmod;
274
- workingval ^= RC[4 - i];
275
+ workingval ^= RC[iterations - i];
276
workingval ^= roundkey;
277
workingval ^= alpha;
278
}
279
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_computepac(CPUARMState *env, uint64_t data,
280
uint64_t modifier, ARMPACKey key)
281
{
282
if (cpu_isar_feature(aa64_pauth_qarma5, env_archcpu(env))) {
283
- return pauth_computepac_architected(data, modifier, key);
284
+ return pauth_computepac_architected(data, modifier, key, false);
285
+ } else if (cpu_isar_feature(aa64_pauth_qarma3, env_archcpu(env))) {
286
+ return pauth_computepac_architected(data, modifier, key, true);
287
} else {
288
return pauth_computepac_impdef(data, modifier, key);
289
}
290
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
291
index XXXXXXX..XXXXXXX 100644
292
--- a/tests/qtest/arm-cpu-features.c
293
+++ b/tests/qtest/arm-cpu-features.c
294
@@ -XXX,XX +XXX,XX @@ static void pauth_tests_default(QTestState *qts, const char *cpu_type)
295
{
296
assert_has_feature_enabled(qts, cpu_type, "pauth");
297
assert_has_feature_disabled(qts, cpu_type, "pauth-impdef");
298
+ assert_has_feature_disabled(qts, cpu_type, "pauth-qarma3");
299
assert_set_feature(qts, cpu_type, "pauth", false);
300
assert_set_feature(qts, cpu_type, "pauth", true);
301
assert_set_feature(qts, cpu_type, "pauth-impdef", true);
302
assert_set_feature(qts, cpu_type, "pauth-impdef", false);
303
- assert_error(qts, cpu_type, "cannot enable pauth-impdef without pauth",
304
+ assert_set_feature(qts, cpu_type, "pauth-qarma3", true);
305
+ assert_set_feature(qts, cpu_type, "pauth-qarma3", false);
306
+ assert_error(qts, cpu_type,
307
+ "cannot enable pauth-impdef or pauth-qarma3 without pauth",
308
"{ 'pauth': false, 'pauth-impdef': true }");
309
+ assert_error(qts, cpu_type,
310
+ "cannot enable pauth-impdef or pauth-qarma3 without pauth",
311
+ "{ 'pauth': false, 'pauth-qarma3': true }");
312
+ assert_error(qts, cpu_type,
313
+ "cannot enable both pauth-impdef and pauth-qarma3",
314
+ "{ 'pauth': true, 'pauth-impdef': true, 'pauth-qarma3': true }");
315
}
316
317
static void test_query_cpu_model_expansion(const void *data)
82
--
318
--
83
2.20.1
319
2.34.1
84
85
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
2
2
3
Make the output just a bit prettier when running by hand.
3
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Cc: Alex Bennée <alex.bennee@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200229012811.24129-13-richard.henderson@linaro.org
7
Message-id: 20230829232335.965414-7-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-Id: <20230609172324.982888-5-aaron@os.amperecomputing.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
tests/tcg/aarch64/pauth-1.c | 2 +-
12
docs/system/arm/emulation.rst | 1 +
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
target/arm/tcg/cpu64.c | 2 +-
14
target/arm/tcg/pauth_helper.c | 16 +++++++++++-----
15
3 files changed, 13 insertions(+), 6 deletions(-)
13
16
14
diff --git a/tests/tcg/aarch64/pauth-1.c b/tests/tcg/aarch64/pauth-1.c
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/tcg/aarch64/pauth-1.c
19
--- a/docs/system/arm/emulation.rst
17
+++ b/tests/tcg/aarch64/pauth-1.c
20
+++ b/docs/system/arm/emulation.rst
18
@@ -XXX,XX +XXX,XX @@ int main()
21
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
22
- FEAT_DotProd (Advanced SIMD dot product instructions)
23
- FEAT_DoubleFault (Double Fault Extension)
24
- FEAT_E0PD (Preventing EL0 access to halves of address maps)
25
+- FEAT_EPAC (Enhanced pointer authentication)
26
- FEAT_ETS (Enhanced Translation Synchronization)
27
- FEAT_EVT (Enhanced Virtualization Traps)
28
- FEAT_FCMA (Floating-point complex number instructions)
29
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/tcg/cpu64.c
32
+++ b/target/arm/tcg/cpu64.c
33
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
34
35
t = cpu->isar.id_aa64isar1;
36
t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
37
- t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_1);
38
+ t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_EPAC);
39
t = FIELD_DP64(t, ID_AA64ISAR1, API, 1);
40
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); /* FEAT_JSCVT */
41
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); /* FEAT_FCMA */
42
diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/tcg/pauth_helper.c
45
+++ b/target/arm/tcg/pauth_helper.c
46
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_computepac(CPUARMState *env, uint64_t data,
47
static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
48
ARMPACKey *key, bool data)
49
{
50
+ ARMCPU *cpu = env_archcpu(env);
51
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
52
ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data, false);
53
+ ARMPauthFeature pauth_feature = cpu_isar_feature(pauth_feature, cpu);
54
uint64_t pac, ext_ptr, ext, test;
55
int bot_bit, top_bit;
56
57
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
58
*/
59
test = sextract64(ptr, bot_bit, top_bit - bot_bit);
60
if (test != 0 && test != -1) {
61
- /*
62
- * Note that our top_bit is one greater than the pseudocode's
63
- * version, hence "- 2" here.
64
- */
65
- pac ^= MAKE_64BIT_MASK(top_bit - 2, 1);
66
+ if (pauth_feature == PauthFeat_EPAC) {
67
+ pac = 0;
68
+ } else {
69
+ /*
70
+ * Note that our top_bit is one greater than the pseudocode's
71
+ * version, hence "- 2" here.
72
+ */
73
+ pac ^= MAKE_64BIT_MASK(top_bit - 2, 1);
74
+ }
19
}
75
}
20
76
21
perc = (float) count / (float) (TESTS * 2);
77
/*
22
- printf("Ptr Check: %0.2f%%", perc * 100.0);
23
+ printf("Ptr Check: %0.2f%%\n", perc * 100.0);
24
assert(perc > 0.95);
25
return 0;
26
}
27
--
78
--
28
2.20.1
79
2.34.1
29
30
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
2
2
3
The Cubieboard machine does not support the -bios argument.
3
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
4
Report an error when -bios is used and exit immediately.
5
6
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
7
Message-id: 20200227220149.6845-5-nieklinnenbank@gmail.com
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20230829232335.965414-8-richard.henderson@linaro.org
8
Message-Id: <20230609172324.982888-6-aaron@os.amperecomputing.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/arm/cubieboard.c | 7 +++++++
12
docs/system/arm/emulation.rst | 1 +
13
1 file changed, 7 insertions(+)
13
target/arm/tcg/cpu64.c | 2 +-
14
target/arm/tcg/pauth_helper.c | 21 +++++++++++++++++----
15
3 files changed, 19 insertions(+), 5 deletions(-)
14
16
15
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/cubieboard.c
19
--- a/docs/system/arm/emulation.rst
18
+++ b/hw/arm/cubieboard.c
20
+++ b/docs/system/arm/emulation.rst
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
20
#include "exec/address-spaces.h"
22
- FEAT_PAN2 (AT S1E1R and AT S1E1W instruction variants affected by PSTATE.PAN)
21
#include "qapi/error.h"
23
- FEAT_PAN3 (Support for SCTLR_ELx.EPAN)
22
#include "cpu.h"
24
- FEAT_PAuth (Pointer authentication)
23
+#include "sysemu/sysemu.h"
25
+- FEAT_PAuth2 (Enhacements to pointer authentication)
24
#include "hw/sysbus.h"
26
- FEAT_PMULL (PMULL, PMULL2 instructions)
25
#include "hw/boards.h"
27
- FEAT_PMUv3p1 (PMU Extensions v3.1)
26
#include "hw/arm/allwinner-a10.h"
28
- FEAT_PMUv3p4 (PMU Extensions v3.4)
27
@@ -XXX,XX +XXX,XX @@ static void cubieboard_init(MachineState *machine)
29
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
28
AwA10State *a10;
30
index XXXXXXX..XXXXXXX 100644
29
Error *err = NULL;
31
--- a/target/arm/tcg/cpu64.c
30
32
+++ b/target/arm/tcg/cpu64.c
31
+ /* BIOS is not supported by this board */
33
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
32
+ if (bios_name) {
34
33
+ error_report("BIOS not supported for this machine");
35
t = cpu->isar.id_aa64isar1;
34
+ exit(1);
36
t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
37
- t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_EPAC);
38
+ t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_2);
39
t = FIELD_DP64(t, ID_AA64ISAR1, API, 1);
40
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); /* FEAT_JSCVT */
41
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); /* FEAT_FCMA */
42
diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/tcg/pauth_helper.c
45
+++ b/target/arm/tcg/pauth_helper.c
46
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
47
*/
48
test = sextract64(ptr, bot_bit, top_bit - bot_bit);
49
if (test != 0 && test != -1) {
50
- if (pauth_feature == PauthFeat_EPAC) {
51
+ if (pauth_feature >= PauthFeat_2) {
52
+ /* No action required */
53
+ } else if (pauth_feature == PauthFeat_EPAC) {
54
pac = 0;
55
} else {
56
/*
57
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
58
* Preserve the determination between upper and lower at bit 55,
59
* and insert pointer authentication code.
60
*/
61
+ if (pauth_feature >= PauthFeat_2) {
62
+ pac ^= ptr;
63
+ }
64
if (param.tbi) {
65
ptr &= ~MAKE_64BIT_MASK(bot_bit, 55 - bot_bit + 1);
66
pac &= MAKE_64BIT_MASK(bot_bit, 54 - bot_bit + 1);
67
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
68
static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
69
ARMPACKey *key, bool data, int keynumber)
70
{
71
+ ARMCPU *cpu = env_archcpu(env);
72
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
73
ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data, false);
74
+ ARMPauthFeature pauth_feature = cpu_isar_feature(pauth_feature, cpu);
75
int bot_bit, top_bit;
76
- uint64_t pac, orig_ptr, test;
77
+ uint64_t pac, orig_ptr, cmp_mask;
78
79
orig_ptr = pauth_original_ptr(ptr, param);
80
pac = pauth_computepac(env, orig_ptr, modifier, *key);
81
bot_bit = 64 - param.tsz;
82
top_bit = 64 - 8 * param.tbi;
83
84
- test = (pac ^ ptr) & ~MAKE_64BIT_MASK(55, 1);
85
- if (unlikely(extract64(test, bot_bit, top_bit - bot_bit))) {
86
+ cmp_mask = MAKE_64BIT_MASK(bot_bit, top_bit - bot_bit);
87
+ cmp_mask &= ~MAKE_64BIT_MASK(55, 1);
88
+
89
+ if (pauth_feature >= PauthFeat_2) {
90
+ return ptr ^ (pac & cmp_mask);
35
+ }
91
+ }
36
+
92
+
37
/* This board has fixed size RAM (512MiB or 1GiB) */
93
+ if ((pac ^ ptr) & cmp_mask) {
38
if (machine->ram_size != 512 * MiB &&
94
int error_code = (keynumber << 1) | (keynumber ^ 1);
39
machine->ram_size != 1 * GiB) {
95
if (param.tbi) {
96
return deposit64(orig_ptr, 53, 2, error_code);
40
--
97
--
41
2.20.1
98
2.34.1
42
43
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
2
2
3
Don't merely start with v8.0, handle v7VE as well. Ensure that writes
3
An instruction is a 'combined' Pointer Authentication instruction
4
from aarch32 mode do not change bits in the other half of the register.
4
if it does something in addition to PAC -- for instance, branching
5
Protect reads of aa64 id registers with ARM_FEATURE_AARCH64.
5
to or loading an address from the authenticated pointer.
6
6
7
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
7
Knowing whether a PAC operation is 'combined' is needed to
8
implement FEAT_FPACCOMBINE.
9
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200229012811.24129-2-richard.henderson@linaro.org
14
Message-id: 20230829232335.965414-9-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-Id: <20230609172324.982888-7-aaron@os.amperecomputing.com>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
18
---
13
target/arm/helper.c | 38 +++++++++++++++++++++++++-------------
19
target/arm/tcg/helper-a64.h | 4 ++
14
1 file changed, 25 insertions(+), 13 deletions(-)
20
target/arm/tcg/pauth_helper.c | 71 +++++++++++++++++++++++++++-------
21
target/arm/tcg/translate-a64.c | 12 +++---
22
3 files changed, 68 insertions(+), 19 deletions(-)
15
23
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
diff --git a/target/arm/tcg/helper-a64.h b/target/arm/tcg/helper-a64.h
17
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
26
--- a/target/arm/tcg/helper-a64.h
19
+++ b/target/arm/helper.c
27
+++ b/target/arm/tcg/helper-a64.h
20
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(pacda, TCG_CALL_NO_WG, i64, env, i64, i64)
21
REGINFO_SENTINEL
29
DEF_HELPER_FLAGS_3(pacdb, TCG_CALL_NO_WG, i64, env, i64, i64)
22
};
30
DEF_HELPER_FLAGS_3(pacga, TCG_CALL_NO_WG, i64, env, i64, i64)
23
31
DEF_HELPER_FLAGS_3(autia, TCG_CALL_NO_WG, i64, env, i64, i64)
24
-static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
32
+DEF_HELPER_FLAGS_3(autia_combined, TCG_CALL_NO_WG, i64, env, i64, i64)
25
+static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
33
DEF_HELPER_FLAGS_3(autib, TCG_CALL_NO_WG, i64, env, i64, i64)
34
+DEF_HELPER_FLAGS_3(autib_combined, TCG_CALL_NO_WG, i64, env, i64, i64)
35
DEF_HELPER_FLAGS_3(autda, TCG_CALL_NO_WG, i64, env, i64, i64)
36
+DEF_HELPER_FLAGS_3(autda_combined, TCG_CALL_NO_WG, i64, env, i64, i64)
37
DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64)
38
+DEF_HELPER_FLAGS_3(autdb_combined, TCG_CALL_NO_WG, i64, env, i64, i64)
39
DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
40
DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
41
42
diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/tcg/pauth_helper.c
45
+++ b/target/arm/tcg/pauth_helper.c
46
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
47
}
48
49
static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
50
- ARMPACKey *key, bool data, int keynumber)
51
+ ARMPACKey *key, bool data, int keynumber,
52
+ uintptr_t ra, bool is_combined)
26
{
53
{
27
ARMCPU *cpu = env_archcpu(env);
54
ARMCPU *cpu = env_archcpu(env);
28
- /* Begin with bits defined in base ARMv8.0. */
55
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
29
- uint64_t valid_mask = MAKE_64BIT_MASK(0, 34);
56
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(pacga)(CPUARMState *env, uint64_t x, uint64_t y)
30
+
57
return pac & 0xffffffff00000000ull;
31
+ if (arm_feature(env, ARM_FEATURE_V8)) {
58
}
32
+ valid_mask |= MAKE_64BIT_MASK(0, 34); /* ARMv8.0 */
59
33
+ } else {
60
-uint64_t HELPER(autia)(CPUARMState *env, uint64_t x, uint64_t y)
34
+ valid_mask |= MAKE_64BIT_MASK(0, 28); /* ARMv7VE */
61
+static uint64_t pauth_autia(CPUARMState *env, uint64_t x, uint64_t y,
35
+ }
62
+ uintptr_t ra, bool is_combined)
36
63
{
37
if (arm_feature(env, ARM_FEATURE_EL3)) {
64
int el = arm_current_el(env);
38
valid_mask &= ~HCR_HCD;
65
if (!pauth_key_enabled(env, el, SCTLR_EnIA)) {
39
@@ -XXX,XX +XXX,XX @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
66
return x;
40
*/
41
valid_mask &= ~HCR_TSC;
42
}
67
}
43
- if (cpu_isar_feature(aa64_vh, cpu)) {
68
- pauth_check_trap(env, el, GETPC());
44
- valid_mask |= HCR_E2H;
69
- return pauth_auth(env, x, y, &env->keys.apia, false, 0);
45
- }
70
+ pauth_check_trap(env, el, ra);
46
- if (cpu_isar_feature(aa64_lor, cpu)) {
71
+ return pauth_auth(env, x, y, &env->keys.apia, false, 0, ra, is_combined);
47
- valid_mask |= HCR_TLOR;
48
- }
49
- if (cpu_isar_feature(aa64_pauth, cpu)) {
50
- valid_mask |= HCR_API | HCR_APK;
51
+
52
+ if (arm_feature(env, ARM_FEATURE_AARCH64)) {
53
+ if (cpu_isar_feature(aa64_vh, cpu)) {
54
+ valid_mask |= HCR_E2H;
55
+ }
56
+ if (cpu_isar_feature(aa64_lor, cpu)) {
57
+ valid_mask |= HCR_TLOR;
58
+ }
59
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
60
+ valid_mask |= HCR_API | HCR_APK;
61
+ }
62
}
63
64
/* Clear RES0 bits. */
65
@@ -XXX,XX +XXX,XX @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
66
arm_cpu_update_vfiq(cpu);
67
}
72
}
68
73
69
+static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
74
-uint64_t HELPER(autib)(CPUARMState *env, uint64_t x, uint64_t y)
75
+uint64_t HELPER(autia)(CPUARMState *env, uint64_t x, uint64_t y)
70
+{
76
+{
71
+ do_hcr_write(env, value, 0);
77
+ return pauth_autia(env, x, y, GETPC(), false);
72
+}
78
+}
73
+
79
+
74
static void hcr_writehigh(CPUARMState *env, const ARMCPRegInfo *ri,
80
+uint64_t HELPER(autia_combined)(CPUARMState *env, uint64_t x, uint64_t y)
75
uint64_t value)
81
+{
82
+ return pauth_autia(env, x, y, GETPC(), true);
83
+}
84
+
85
+static uint64_t pauth_autib(CPUARMState *env, uint64_t x, uint64_t y,
86
+ uintptr_t ra, bool is_combined)
76
{
87
{
77
/* Handle HCR2 write, i.e. write to high half of HCR_EL2 */
88
int el = arm_current_el(env);
78
value = deposit64(env->cp15.hcr_el2, 32, 32, value);
89
if (!pauth_key_enabled(env, el, SCTLR_EnIB)) {
79
- hcr_write(env, NULL, value);
90
return x;
80
+ do_hcr_write(env, value, MAKE_64BIT_MASK(0, 32));
91
}
92
- pauth_check_trap(env, el, GETPC());
93
- return pauth_auth(env, x, y, &env->keys.apib, false, 1);
94
+ pauth_check_trap(env, el, ra);
95
+ return pauth_auth(env, x, y, &env->keys.apib, false, 1, ra, is_combined);
81
}
96
}
82
97
83
static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
98
-uint64_t HELPER(autda)(CPUARMState *env, uint64_t x, uint64_t y)
84
@@ -XXX,XX +XXX,XX @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
99
+uint64_t HELPER(autib)(CPUARMState *env, uint64_t x, uint64_t y)
100
+{
101
+ return pauth_autib(env, x, y, GETPC(), false);
102
+}
103
+
104
+uint64_t HELPER(autib_combined)(CPUARMState *env, uint64_t x, uint64_t y)
105
+{
106
+ return pauth_autib(env, x, y, GETPC(), true);
107
+}
108
+
109
+static uint64_t pauth_autda(CPUARMState *env, uint64_t x, uint64_t y,
110
+ uintptr_t ra, bool is_combined)
85
{
111
{
86
/* Handle HCR write, i.e. write to low half of HCR_EL2 */
112
int el = arm_current_el(env);
87
value = deposit64(env->cp15.hcr_el2, 0, 32, value);
113
if (!pauth_key_enabled(env, el, SCTLR_EnDA)) {
88
- hcr_write(env, NULL, value);
114
return x;
89
+ do_hcr_write(env, value, MAKE_64BIT_MASK(32, 32));
115
}
116
- pauth_check_trap(env, el, GETPC());
117
- return pauth_auth(env, x, y, &env->keys.apda, true, 0);
118
+ pauth_check_trap(env, el, ra);
119
+ return pauth_auth(env, x, y, &env->keys.apda, true, 0, ra, is_combined);
90
}
120
}
91
121
92
/*
122
-uint64_t HELPER(autdb)(CPUARMState *env, uint64_t x, uint64_t y)
123
+uint64_t HELPER(autda)(CPUARMState *env, uint64_t x, uint64_t y)
124
+{
125
+ return pauth_autda(env, x, y, GETPC(), false);
126
+}
127
+
128
+uint64_t HELPER(autda_combined)(CPUARMState *env, uint64_t x, uint64_t y)
129
+{
130
+ return pauth_autda(env, x, y, GETPC(), true);
131
+}
132
+
133
+static uint64_t pauth_autdb(CPUARMState *env, uint64_t x, uint64_t y,
134
+ uintptr_t ra, bool is_combined)
135
{
136
int el = arm_current_el(env);
137
if (!pauth_key_enabled(env, el, SCTLR_EnDB)) {
138
return x;
139
}
140
- pauth_check_trap(env, el, GETPC());
141
- return pauth_auth(env, x, y, &env->keys.apdb, true, 1);
142
+ pauth_check_trap(env, el, ra);
143
+ return pauth_auth(env, x, y, &env->keys.apdb, true, 1, ra, is_combined);
144
+}
145
+
146
+uint64_t HELPER(autdb)(CPUARMState *env, uint64_t x, uint64_t y)
147
+{
148
+ return pauth_autdb(env, x, y, GETPC(), false);
149
+}
150
+
151
+uint64_t HELPER(autdb_combined)(CPUARMState *env, uint64_t x, uint64_t y)
152
+{
153
+ return pauth_autdb(env, x, y, GETPC(), true);
154
}
155
156
uint64_t HELPER(xpaci)(CPUARMState *env, uint64_t a)
157
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/tcg/translate-a64.c
160
+++ b/target/arm/tcg/translate-a64.c
161
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 auth_branch_target(DisasContext *s, TCGv_i64 dst,
162
163
truedst = tcg_temp_new_i64();
164
if (use_key_a) {
165
- gen_helper_autia(truedst, cpu_env, dst, modifier);
166
+ gen_helper_autia_combined(truedst, cpu_env, dst, modifier);
167
} else {
168
- gen_helper_autib(truedst, cpu_env, dst, modifier);
169
+ gen_helper_autib_combined(truedst, cpu_env, dst, modifier);
170
}
171
return truedst;
172
}
173
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRA(DisasContext *s, arg_LDRA *a)
174
175
if (s->pauth_active) {
176
if (!a->m) {
177
- gen_helper_autda(dirty_addr, cpu_env, dirty_addr,
178
- tcg_constant_i64(0));
179
+ gen_helper_autda_combined(dirty_addr, cpu_env, dirty_addr,
180
+ tcg_constant_i64(0));
181
} else {
182
- gen_helper_autdb(dirty_addr, cpu_env, dirty_addr,
183
- tcg_constant_i64(0));
184
+ gen_helper_autdb_combined(dirty_addr, cpu_env, dirty_addr,
185
+ tcg_constant_i64(0));
186
}
187
}
188
93
--
189
--
94
2.20.1
190
2.34.1
95
191
96
192
diff view generated by jsdifflib
1
From: Pan Nengyuan <pannengyuan@huawei.com>
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
2
2
3
There are some memleaks when we call 'device_list_properties'. This patch move timer_new from init into realize to fix it.
3
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
4
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reported-by: Euler Robot <euler.robot@huawei.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
6
Message-id: 20230829232335.965414-10-richard.henderson@linaro.org
7
Message-id: 20200227025055.14341-4-pannengyuan@huawei.com
7
Message-Id: <20230609172324.982888-8-aaron@os.amperecomputing.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
[rth: Simplify fpac comparison, reusing cmp_mask]
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
hw/arm/spitz.c | 8 +++++++-
12
docs/system/arm/emulation.rst | 2 ++
12
1 file changed, 7 insertions(+), 1 deletion(-)
13
target/arm/syndrome.h | 7 +++++++
14
target/arm/tcg/cpu64.c | 2 +-
15
target/arm/tcg/pauth_helper.c | 18 +++++++++++++++++-
16
4 files changed, 27 insertions(+), 2 deletions(-)
13
17
14
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
18
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/spitz.c
20
--- a/docs/system/arm/emulation.rst
17
+++ b/hw/arm/spitz.c
21
+++ b/docs/system/arm/emulation.rst
18
@@ -XXX,XX +XXX,XX @@ static void spitz_keyboard_init(Object *obj)
22
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
19
23
- FEAT_FGT (Fine-Grained Traps)
20
spitz_keyboard_pre_map(s);
24
- FEAT_FHM (Floating-point half-precision multiplication instructions)
21
25
- FEAT_FP16 (Half-precision floating-point data processing)
22
- s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
26
+- FEAT_FPAC (Faulting on AUT* instructions)
23
qdev_init_gpio_in(dev, spitz_keyboard_strobe, SPITZ_KEY_STROBE_NUM);
27
+- FEAT_FPACCOMBINE (Faulting on combined pointer authentication instructions)
24
qdev_init_gpio_out(dev, s->sense, SPITZ_KEY_SENSE_NUM);
28
- FEAT_FRINTTS (Floating-point to integer instructions)
29
- FEAT_FlagM (Flag manipulation instructions v2)
30
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
31
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/syndrome.h
34
+++ b/target/arm/syndrome.h
35
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
36
EC_SYSTEMREGISTERTRAP = 0x18,
37
EC_SVEACCESSTRAP = 0x19,
38
EC_ERETTRAP = 0x1a,
39
+ EC_PACFAIL = 0x1c,
40
EC_SMETRAP = 0x1d,
41
EC_GPC = 0x1e,
42
EC_INSNABORT = 0x20,
43
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_smetrap(SMEExceptionType etype, bool is_16bit)
44
| (is_16bit ? 0 : ARM_EL_IL) | etype;
25
}
45
}
26
46
27
+static void spitz_keyboard_realize(DeviceState *dev, Error **errp)
47
+static inline uint32_t syn_pacfail(bool data, int keynumber)
28
+{
48
+{
29
+ SpitzKeyboardState *s = SPITZ_KEYBOARD(dev);
49
+ int error_code = (data << 1) | keynumber;
30
+ s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
50
+ return (EC_PACFAIL << ARM_EL_EC_SHIFT) | ARM_EL_IL | error_code;
31
+}
51
+}
32
+
52
+
33
/* LCD backlight controller */
53
static inline uint32_t syn_pactrap(void)
34
54
{
35
#define LCDTG_RESCTL    0x00
55
return EC_PACTRAP << ARM_EL_EC_SHIFT;
36
@@ -XXX,XX +XXX,XX @@ static void spitz_keyboard_class_init(ObjectClass *klass, void *data)
56
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
37
DeviceClass *dc = DEVICE_CLASS(klass);
57
index XXXXXXX..XXXXXXX 100644
38
58
--- a/target/arm/tcg/cpu64.c
39
dc->vmsd = &vmstate_spitz_kbd;
59
+++ b/target/arm/tcg/cpu64.c
40
+ dc->realize = spitz_keyboard_realize;
60
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
61
62
t = cpu->isar.id_aa64isar1;
63
t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
64
- t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_2);
65
+ t = FIELD_DP64(t, ID_AA64ISAR1, APA, PauthFeat_FPACCOMBINED);
66
t = FIELD_DP64(t, ID_AA64ISAR1, API, 1);
67
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); /* FEAT_JSCVT */
68
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); /* FEAT_FCMA */
69
diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/tcg/pauth_helper.c
72
+++ b/target/arm/tcg/pauth_helper.c
73
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
74
}
41
}
75
}
42
76
43
static const TypeInfo spitz_keyboard_info = {
77
+static G_NORETURN
78
+void pauth_fail_exception(CPUARMState *env, bool data,
79
+ int keynumber, uintptr_t ra)
80
+{
81
+ raise_exception_ra(env, EXCP_UDEF, syn_pacfail(data, keynumber),
82
+ exception_target_el(env), ra);
83
+}
84
+
85
static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
86
ARMPACKey *key, bool data, int keynumber,
87
uintptr_t ra, bool is_combined)
88
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
89
cmp_mask &= ~MAKE_64BIT_MASK(55, 1);
90
91
if (pauth_feature >= PauthFeat_2) {
92
- return ptr ^ (pac & cmp_mask);
93
+ ARMPauthFeature fault_feature =
94
+ is_combined ? PauthFeat_FPACCOMBINED : PauthFeat_FPAC;
95
+ uint64_t result = ptr ^ (pac & cmp_mask);
96
+
97
+ if (pauth_feature >= fault_feature
98
+ && ((result ^ sextract64(result, 55, 1)) & cmp_mask)) {
99
+ pauth_fail_exception(env, data, keynumber, ra);
100
+ }
101
+ return result;
102
}
103
104
if ((pac ^ ptr) & cmp_mask) {
44
--
105
--
45
2.20.1
106
2.34.1
46
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This bit traps EL1 access to cache maintenance insns that operate
3
Fix when using GCC v11.4 (Ubuntu 11.4.0-1ubuntu1~22.04) with CFLAGS=-Og:
4
to the point of unification. There are no longer any references to
5
plain aa64_cacheop_access, so remove it.
6
4
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
[4/6] Compiling C object libcommon.fa.p/hw_intc_arm_gicv3_its.c.o
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
FAILED: libcommon.fa.p/hw_intc_arm_gicv3_its.c.o
9
Message-id: 20200229012811.24129-11-richard.henderson@linaro.org
7
inlined from ‘lookup_vte’ at hw/intc/arm_gicv3_its.c:453:9,
8
inlined from ‘vmovp_callback’ at hw/intc/arm_gicv3_its.c:1039:14:
9
hw/intc/arm_gicv3_its.c:347:9: error: ‘vte.rdbase’ may be used uninitialized [-Werror=maybe-uninitialized]
10
347 | trace_gicv3_its_vte_read(vpeid, vte->valid, vte->vptsize,
11
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12
348 | vte->vptaddr, vte->rdbase);
13
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
14
hw/intc/arm_gicv3_its.c: In function ‘vmovp_callback’:
15
hw/intc/arm_gicv3_its.c:1036:13: note: ‘vte’ declared here
16
1036 | VTEntry vte;
17
| ^~~
18
19
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
20
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
21
Message-id: 20230831131348.69032-1-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
23
---
12
target/arm/helper.c | 53 +++++++++++++++++++++++++++------------------
24
hw/intc/arm_gicv3_its.c | 15 ++++++---------
13
1 file changed, 32 insertions(+), 21 deletions(-)
25
1 file changed, 6 insertions(+), 9 deletions(-)
14
26
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
27
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
16
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
29
--- a/hw/intc/arm_gicv3_its.c
18
+++ b/target/arm/helper.c
30
+++ b/hw/intc/arm_gicv3_its.c
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo uao_reginfo = {
31
@@ -XXX,XX +XXX,XX @@ static MemTxResult get_vte(GICv3ITSState *s, uint32_t vpeid, VTEntry *vte)
20
.readfn = aa64_uao_read, .writefn = aa64_uao_write
32
if (entry_addr == -1) {
21
};
33
/* No L2 table entry, i.e. no valid VTE, or a memory error */
22
34
vte->valid = false;
23
-static CPAccessResult aa64_cacheop_access(CPUARMState *env,
35
- goto out;
24
- const ARMCPRegInfo *ri,
36
+ trace_gicv3_its_vte_read_fault(vpeid);
25
- bool isread)
37
+ return MEMTX_OK;
26
-{
38
}
27
- /* Cache invalidate/clean: NOP, but EL0 must UNDEF unless
39
vteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res);
28
- * SCTLR_EL1.UCI is set.
40
if (res != MEMTX_OK) {
29
- */
41
- goto out;
30
- if (arm_current_el(env) == 0 && !(arm_sctlr(env, 0) & SCTLR_UCI)) {
42
+ trace_gicv3_its_vte_read_fault(vpeid);
31
- return CP_ACCESS_TRAP;
43
+ return res;
44
}
45
vte->valid = FIELD_EX64(vteval, VTE, VALID);
46
vte->vptsize = FIELD_EX64(vteval, VTE, VPTSIZE);
47
vte->vptaddr = FIELD_EX64(vteval, VTE, VPTADDR);
48
vte->rdbase = FIELD_EX64(vteval, VTE, RDBASE);
49
-out:
50
- if (res != MEMTX_OK) {
51
- trace_gicv3_its_vte_read_fault(vpeid);
52
- } else {
53
- trace_gicv3_its_vte_read(vpeid, vte->valid, vte->vptsize,
54
- vte->vptaddr, vte->rdbase);
32
- }
55
- }
33
- return CP_ACCESS_OK;
56
+ trace_gicv3_its_vte_read(vpeid, vte->valid, vte->vptsize,
34
-}
57
+ vte->vptaddr, vte->rdbase);
35
-
58
return res;
36
static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
37
const ARMCPRegInfo *ri,
38
bool isread)
39
@@ -XXX,XX +XXX,XX @@ static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
40
return CP_ACCESS_OK;
41
}
59
}
42
60
43
+static CPAccessResult aa64_cacheop_pou_access(CPUARMState *env,
44
+ const ARMCPRegInfo *ri,
45
+ bool isread)
46
+{
47
+ /* Cache invalidate/clean to Point of Unification... */
48
+ switch (arm_current_el(env)) {
49
+ case 0:
50
+ /* ... EL0 must UNDEF unless SCTLR_EL1.UCI is set. */
51
+ if (!(arm_sctlr(env, 0) & SCTLR_UCI)) {
52
+ return CP_ACCESS_TRAP;
53
+ }
54
+ /* fall through */
55
+ case 1:
56
+ /* ... EL1 must trap to EL2 if HCR_EL2.TPU is set. */
57
+ if (arm_hcr_el2_eff(env) & HCR_TPU) {
58
+ return CP_ACCESS_TRAP_EL2;
59
+ }
60
+ break;
61
+ }
62
+ return CP_ACCESS_OK;
63
+}
64
+
65
/* See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions
66
* Page D4-1736 (DDI0487A.b)
67
*/
68
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
69
/* Cache ops: all NOPs since we don't emulate caches */
70
{ .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
71
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
72
- .access = PL1_W, .type = ARM_CP_NOP },
73
+ .access = PL1_W, .type = ARM_CP_NOP,
74
+ .accessfn = aa64_cacheop_pou_access },
75
{ .name = "IC_IALLU", .state = ARM_CP_STATE_AA64,
76
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
77
- .access = PL1_W, .type = ARM_CP_NOP },
78
+ .access = PL1_W, .type = ARM_CP_NOP,
79
+ .accessfn = aa64_cacheop_pou_access },
80
{ .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
81
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
82
.access = PL0_W, .type = ARM_CP_NOP,
83
- .accessfn = aa64_cacheop_access },
84
+ .accessfn = aa64_cacheop_pou_access },
85
{ .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
86
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
87
.access = PL1_W, .accessfn = aa64_cacheop_poc_access,
88
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
89
{ .name = "DC_CVAU", .state = ARM_CP_STATE_AA64,
90
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 11, .opc2 = 1,
91
.access = PL0_W, .type = ARM_CP_NOP,
92
- .accessfn = aa64_cacheop_access },
93
+ .accessfn = aa64_cacheop_pou_access },
94
{ .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
95
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
96
.access = PL0_W, .type = ARM_CP_NOP,
97
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
98
.writefn = tlbiipas2_is_write },
99
/* 32 bit cache operations */
100
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
101
- .type = ARM_CP_NOP, .access = PL1_W },
102
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
103
{ .name = "BPIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 6,
104
.type = ARM_CP_NOP, .access = PL1_W },
105
{ .name = "ICIALLU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 0,
106
- .type = ARM_CP_NOP, .access = PL1_W },
107
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
108
{ .name = "ICIMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 1,
109
- .type = ARM_CP_NOP, .access = PL1_W },
110
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
111
{ .name = "BPIALL", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 6,
112
.type = ARM_CP_NOP, .access = PL1_W },
113
{ .name = "BPIMVA", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 7,
114
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
115
{ .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
116
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
117
{ .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1,
118
- .type = ARM_CP_NOP, .access = PL1_W },
119
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
120
{ .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1,
121
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
122
{ .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
123
--
61
--
124
2.20.1
62
2.34.1
125
63
126
64
diff view generated by jsdifflib
1
From: Pan Nengyuan <pannengyuan@huawei.com>
1
From: Francisco Iglesias <francisco.iglesias@amd.com>
2
2
3
There are some memleaks when we call 'device_list_properties'. This patch move timer_new from init into realize to fix it.
3
Introduce the Xilinx Configuration Frame Interface (CFI) for transmitting
4
CFI data packets between the Xilinx Configuration Frame Unit models
5
(CFU_APB, CFU_FDRO and CFU_SFR), the Xilinx CFRAME controller (CFRAME_REG)
6
and the Xilinx CFRAME broadcast controller (CFRAME_BCAST_REG) models (when
7
emulating bitstream programming and readback).
4
8
5
Reported-by: Euler Robot <euler.robot@huawei.com>
9
Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
6
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
10
Reviewed-by: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Acked-by: Edgar E. Iglesias <edgar@zeroasic.com>
8
Message-id: 20200227025055.14341-7-pannengyuan@huawei.com
12
Message-id: 20230831165701.2016397-2-francisco.iglesias@amd.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
hw/timer/cadence_ttc.c | 18 ++++++++++++------
15
MAINTAINERS | 6 ++++
13
1 file changed, 12 insertions(+), 6 deletions(-)
16
include/hw/misc/xlnx-cfi-if.h | 59 +++++++++++++++++++++++++++++++++++
17
hw/misc/xlnx-cfi-if.c | 34 ++++++++++++++++++++
18
hw/misc/meson.build | 1 +
19
4 files changed, 100 insertions(+)
20
create mode 100644 include/hw/misc/xlnx-cfi-if.h
21
create mode 100644 hw/misc/xlnx-cfi-if.c
14
22
15
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
23
diff --git a/MAINTAINERS b/MAINTAINERS
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/timer/cadence_ttc.c
25
--- a/MAINTAINERS
18
+++ b/hw/timer/cadence_ttc.c
26
+++ b/MAINTAINERS
19
@@ -XXX,XX +XXX,XX @@ static void cadence_timer_init(uint32_t freq, CadenceTimerState *s)
27
@@ -XXX,XX +XXX,XX @@ S: Maintained
20
static void cadence_ttc_init(Object *obj)
28
F: hw/ssi/xlnx-versal-ospi.c
21
{
29
F: include/hw/ssi/xlnx-versal-ospi.h
22
CadenceTTCState *s = CADENCE_TTC(obj);
30
23
- int i;
31
+Xilinx Versal CFI
24
-
32
+M: Francisco Iglesias <francisco.iglesias@amd.com>
25
- for (i = 0; i < 3; ++i) {
33
+S: Maintained
26
- cadence_timer_init(133000000, &s->timer[i]);
34
+F: hw/misc/xlnx-cfi-if.c
27
- sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->timer[i].irq);
35
+F: include/hw/misc/xlnx-cfi-if.h
28
- }
36
+
29
37
STM32F100
30
memory_region_init_io(&s->iomem, obj, &cadence_ttc_ops, s,
38
M: Alexandre Iooss <erdnaxe@crans.org>
31
"timer", 0x1000);
39
L: qemu-arm@nongnu.org
32
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
40
diff --git a/include/hw/misc/xlnx-cfi-if.h b/include/hw/misc/xlnx-cfi-if.h
33
}
41
new file mode 100644
34
42
index XXXXXXX..XXXXXXX
35
+static void cadence_ttc_realize(DeviceState *dev, Error **errp)
43
--- /dev/null
44
+++ b/include/hw/misc/xlnx-cfi-if.h
45
@@ -XXX,XX +XXX,XX @@
46
+/*
47
+ * Xilinx CFI interface
48
+ *
49
+ * Copyright (C) 2023, Advanced Micro Devices, Inc.
50
+ *
51
+ * Written by Francisco Iglesias <francisco.iglesias@amd.com>
52
+ *
53
+ * SPDX-License-Identifier: GPL-2.0-or-later
54
+ */
55
+#ifndef XLNX_CFI_IF_H
56
+#define XLNX_CFI_IF_H 1
57
+
58
+#include "qemu/help-texts.h"
59
+#include "hw/hw.h"
60
+#include "qom/object.h"
61
+
62
+#define TYPE_XLNX_CFI_IF "xlnx-cfi-if"
63
+typedef struct XlnxCfiIfClass XlnxCfiIfClass;
64
+DECLARE_CLASS_CHECKERS(XlnxCfiIfClass, XLNX_CFI_IF, TYPE_XLNX_CFI_IF)
65
+
66
+#define XLNX_CFI_IF(obj) \
67
+ INTERFACE_CHECK(XlnxCfiIf, (obj), TYPE_XLNX_CFI_IF)
68
+
69
+typedef enum {
70
+ PACKET_TYPE_CFU = 0x52,
71
+ PACKET_TYPE_CFRAME = 0xA1,
72
+} xlnx_cfi_packet_type;
73
+
74
+typedef enum {
75
+ CFRAME_FAR = 1,
76
+ CFRAME_SFR = 2,
77
+ CFRAME_FDRI = 4,
78
+ CFRAME_CMD = 6,
79
+} xlnx_cfi_reg_addr;
80
+
81
+typedef struct XlnxCfiPacket {
82
+ uint8_t reg_addr;
83
+ uint32_t data[4];
84
+} XlnxCfiPacket;
85
+
86
+typedef struct XlnxCfiIf {
87
+ Object Parent;
88
+} XlnxCfiIf;
89
+
90
+typedef struct XlnxCfiIfClass {
91
+ InterfaceClass parent;
92
+
93
+ void (*cfi_transfer_packet)(XlnxCfiIf *cfi_if, XlnxCfiPacket *pkt);
94
+} XlnxCfiIfClass;
95
+
96
+/**
97
+ * Transfer a XlnxCfiPacket.
98
+ *
99
+ * @cfi_if: the object implementing this interface
100
+ * @XlnxCfiPacket: a pointer to the XlnxCfiPacket to transfer
101
+ */
102
+void xlnx_cfi_transfer_packet(XlnxCfiIf *cfi_if, XlnxCfiPacket *pkt);
103
+
104
+#endif /* XLNX_CFI_IF_H */
105
diff --git a/hw/misc/xlnx-cfi-if.c b/hw/misc/xlnx-cfi-if.c
106
new file mode 100644
107
index XXXXXXX..XXXXXXX
108
--- /dev/null
109
+++ b/hw/misc/xlnx-cfi-if.c
110
@@ -XXX,XX +XXX,XX @@
111
+/*
112
+ * Xilinx CFI interface
113
+ *
114
+ * Copyright (C) 2023, Advanced Micro Devices, Inc.
115
+ *
116
+ * Written by Francisco Iglesias <francisco.iglesias@amd.com>
117
+ *
118
+ * SPDX-License-Identifier: GPL-2.0-or-later
119
+ */
120
+#include "qemu/osdep.h"
121
+#include "hw/misc/xlnx-cfi-if.h"
122
+
123
+void xlnx_cfi_transfer_packet(XlnxCfiIf *cfi_if, XlnxCfiPacket *pkt)
36
+{
124
+{
37
+ CadenceTTCState *s = CADENCE_TTC(dev);
125
+ XlnxCfiIfClass *xcic = XLNX_CFI_IF_GET_CLASS(cfi_if);
38
+ int i;
39
+
126
+
40
+ for (i = 0; i < 3; ++i) {
127
+ if (xcic->cfi_transfer_packet) {
41
+ cadence_timer_init(133000000, &s->timer[i]);
128
+ xcic->cfi_transfer_packet(cfi_if, pkt);
42
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->timer[i].irq);
43
+ }
129
+ }
44
+}
130
+}
45
+
131
+
46
static int cadence_timer_pre_save(void *opaque)
132
+static const TypeInfo xlnx_cfi_if_info = {
47
{
133
+ .name = TYPE_XLNX_CFI_IF,
48
cadence_timer_sync((CadenceTimerState *)opaque);
134
+ .parent = TYPE_INTERFACE,
49
@@ -XXX,XX +XXX,XX @@ static void cadence_ttc_class_init(ObjectClass *klass, void *data)
135
+ .class_size = sizeof(XlnxCfiIfClass),
50
DeviceClass *dc = DEVICE_CLASS(klass);
136
+};
51
137
+
52
dc->vmsd = &vmstate_cadence_ttc;
138
+static void xlnx_cfi_if_register_types(void)
53
+ dc->realize = cadence_ttc_realize;
139
+{
54
}
140
+ type_register_static(&xlnx_cfi_if_info);
55
141
+}
56
static const TypeInfo cadence_ttc_info = {
142
+
143
+type_init(xlnx_cfi_if_register_types)
144
+
145
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
146
index XXXXXXX..XXXXXXX 100644
147
--- a/hw/misc/meson.build
148
+++ b/hw/misc/meson.build
149
@@ -XXX,XX +XXX,XX @@ specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
150
system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
151
'xlnx-versal-xramc.c',
152
'xlnx-versal-pmc-iou-slcr.c',
153
+ 'xlnx-cfi-if.c',
154
))
155
system_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: files('stm32f2xx_syscfg.c'))
156
system_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: files('stm32f4xx_syscfg.c'))
57
--
157
--
58
2.20.1
158
2.34.1
59
60
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Francisco Iglesias <francisco.iglesias@amd.com>
2
2
3
We missed this case within AArch64.ExceptionReturn.
3
Introduce a model of the software programming interface (CFU_APB) of
4
Xilinx Versal's Configuration Frame Unit.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200302175829.2183-5-richard.henderson@linaro.org
8
Message-id: 20230831165701.2016397-3-francisco.iglesias@amd.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/helper-a64.c | 23 ++++++++++++++++++++++-
11
MAINTAINERS | 2 +
11
1 file changed, 22 insertions(+), 1 deletion(-)
12
include/hw/misc/xlnx-versal-cfu.h | 231 ++++++++++++++++++
13
hw/misc/xlnx-versal-cfu.c | 380 ++++++++++++++++++++++++++++++
14
hw/misc/meson.build | 1 +
15
4 files changed, 614 insertions(+)
16
create mode 100644 include/hw/misc/xlnx-versal-cfu.h
17
create mode 100644 hw/misc/xlnx-versal-cfu.c
12
18
13
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
19
diff --git a/MAINTAINERS b/MAINTAINERS
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-a64.c
21
--- a/MAINTAINERS
16
+++ b/target/arm/helper-a64.c
22
+++ b/MAINTAINERS
17
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
23
@@ -XXX,XX +XXX,XX @@ M: Francisco Iglesias <francisco.iglesias@amd.com>
18
"AArch32 EL%d PC 0x%" PRIx32 "\n",
24
S: Maintained
19
cur_el, new_el, env->regs[15]);
25
F: hw/misc/xlnx-cfi-if.c
20
} else {
26
F: include/hw/misc/xlnx-cfi-if.h
21
+ int tbii;
27
+F: hw/misc/xlnx-versal-cfu.c
22
+
28
+F: include/hw/misc/xlnx-versal-cfu.h
23
env->aarch64 = 1;
29
24
spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar);
30
STM32F100
25
pstate_write(env, spsr);
31
M: Alexandre Iooss <erdnaxe@crans.org>
26
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
32
diff --git a/include/hw/misc/xlnx-versal-cfu.h b/include/hw/misc/xlnx-versal-cfu.h
27
env->pstate &= ~PSTATE_SS;
33
new file mode 100644
28
}
34
index XXXXXXX..XXXXXXX
29
aarch64_restore_sp(env, new_el);
35
--- /dev/null
30
- env->pc = new_pc;
36
+++ b/include/hw/misc/xlnx-versal-cfu.h
31
helper_rebuild_hflags_a64(env, new_el);
37
@@ -XXX,XX +XXX,XX @@
32
+
38
+/*
33
+ /*
39
+ * QEMU model of the CFU Configuration Unit.
34
+ * Apply TBI to the exception return address. We had to delay this
40
+ *
35
+ * until after we selected the new EL, so that we could select the
41
+ * Copyright (C) 2023, Advanced Micro Devices, Inc.
36
+ * correct TBI+TBID bits. This is made easier by waiting until after
42
+ *
37
+ * the hflags rebuild, since we can pull the composite TBII field
43
+ * Written by Francisco Iglesias <francisco.iglesias@amd.com>
38
+ * from there.
44
+ *
39
+ */
45
+ * SPDX-License-Identifier: GPL-2.0-or-later
40
+ tbii = FIELD_EX32(env->hflags, TBFLAG_A64, TBII);
46
+ *
41
+ if ((tbii >> extract64(new_pc, 55, 1)) & 1) {
47
+ * References:
42
+ /* TBI is enabled. */
48
+ * [1] Versal ACAP Technical Reference Manual,
43
+ int core_mmu_idx = cpu_mmu_index(env, false);
49
+ * https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
44
+ if (regime_has_2_ranges(core_to_aa64_mmu_idx(core_mmu_idx))) {
50
+ *
45
+ new_pc = sextract64(new_pc, 0, 56);
51
+ * [2] Versal ACAP Register Reference,
46
+ } else {
52
+ * https://www.xilinx.com/htmldocs/registers/am012/am012-versal-register-reference.html
47
+ new_pc = extract64(new_pc, 0, 56);
53
+ */
54
+#ifndef HW_MISC_XLNX_VERSAL_CFU_APB_H
55
+#define HW_MISC_XLNX_VERSAL_CFU_APB_H
56
+
57
+#include "hw/sysbus.h"
58
+#include "hw/register.h"
59
+#include "hw/misc/xlnx-cfi-if.h"
60
+
61
+#define TYPE_XLNX_VERSAL_CFU_APB "xlnx,versal-cfu-apb"
62
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFUAPB, XLNX_VERSAL_CFU_APB)
63
+
64
+REG32(CFU_ISR, 0x0)
65
+ FIELD(CFU_ISR, USR_GTS_EVENT, 9, 1)
66
+ FIELD(CFU_ISR, USR_GSR_EVENT, 8, 1)
67
+ FIELD(CFU_ISR, SLVERR, 7, 1)
68
+ FIELD(CFU_ISR, DECOMP_ERROR, 6, 1)
69
+ FIELD(CFU_ISR, BAD_CFI_PACKET, 5, 1)
70
+ FIELD(CFU_ISR, AXI_ALIGN_ERROR, 4, 1)
71
+ FIELD(CFU_ISR, CFI_ROW_ERROR, 3, 1)
72
+ FIELD(CFU_ISR, CRC32_ERROR, 2, 1)
73
+ FIELD(CFU_ISR, CRC8_ERROR, 1, 1)
74
+ FIELD(CFU_ISR, SEU_ENDOFCALIB, 0, 1)
75
+REG32(CFU_IMR, 0x4)
76
+ FIELD(CFU_IMR, USR_GTS_EVENT, 9, 1)
77
+ FIELD(CFU_IMR, USR_GSR_EVENT, 8, 1)
78
+ FIELD(CFU_IMR, SLVERR, 7, 1)
79
+ FIELD(CFU_IMR, DECOMP_ERROR, 6, 1)
80
+ FIELD(CFU_IMR, BAD_CFI_PACKET, 5, 1)
81
+ FIELD(CFU_IMR, AXI_ALIGN_ERROR, 4, 1)
82
+ FIELD(CFU_IMR, CFI_ROW_ERROR, 3, 1)
83
+ FIELD(CFU_IMR, CRC32_ERROR, 2, 1)
84
+ FIELD(CFU_IMR, CRC8_ERROR, 1, 1)
85
+ FIELD(CFU_IMR, SEU_ENDOFCALIB, 0, 1)
86
+REG32(CFU_IER, 0x8)
87
+ FIELD(CFU_IER, USR_GTS_EVENT, 9, 1)
88
+ FIELD(CFU_IER, USR_GSR_EVENT, 8, 1)
89
+ FIELD(CFU_IER, SLVERR, 7, 1)
90
+ FIELD(CFU_IER, DECOMP_ERROR, 6, 1)
91
+ FIELD(CFU_IER, BAD_CFI_PACKET, 5, 1)
92
+ FIELD(CFU_IER, AXI_ALIGN_ERROR, 4, 1)
93
+ FIELD(CFU_IER, CFI_ROW_ERROR, 3, 1)
94
+ FIELD(CFU_IER, CRC32_ERROR, 2, 1)
95
+ FIELD(CFU_IER, CRC8_ERROR, 1, 1)
96
+ FIELD(CFU_IER, SEU_ENDOFCALIB, 0, 1)
97
+REG32(CFU_IDR, 0xc)
98
+ FIELD(CFU_IDR, USR_GTS_EVENT, 9, 1)
99
+ FIELD(CFU_IDR, USR_GSR_EVENT, 8, 1)
100
+ FIELD(CFU_IDR, SLVERR, 7, 1)
101
+ FIELD(CFU_IDR, DECOMP_ERROR, 6, 1)
102
+ FIELD(CFU_IDR, BAD_CFI_PACKET, 5, 1)
103
+ FIELD(CFU_IDR, AXI_ALIGN_ERROR, 4, 1)
104
+ FIELD(CFU_IDR, CFI_ROW_ERROR, 3, 1)
105
+ FIELD(CFU_IDR, CRC32_ERROR, 2, 1)
106
+ FIELD(CFU_IDR, CRC8_ERROR, 1, 1)
107
+ FIELD(CFU_IDR, SEU_ENDOFCALIB, 0, 1)
108
+REG32(CFU_ITR, 0x10)
109
+ FIELD(CFU_ITR, USR_GTS_EVENT, 9, 1)
110
+ FIELD(CFU_ITR, USR_GSR_EVENT, 8, 1)
111
+ FIELD(CFU_ITR, SLVERR, 7, 1)
112
+ FIELD(CFU_ITR, DECOMP_ERROR, 6, 1)
113
+ FIELD(CFU_ITR, BAD_CFI_PACKET, 5, 1)
114
+ FIELD(CFU_ITR, AXI_ALIGN_ERROR, 4, 1)
115
+ FIELD(CFU_ITR, CFI_ROW_ERROR, 3, 1)
116
+ FIELD(CFU_ITR, CRC32_ERROR, 2, 1)
117
+ FIELD(CFU_ITR, CRC8_ERROR, 1, 1)
118
+ FIELD(CFU_ITR, SEU_ENDOFCALIB, 0, 1)
119
+REG32(CFU_PROTECT, 0x14)
120
+ FIELD(CFU_PROTECT, ACTIVE, 0, 1)
121
+REG32(CFU_FGCR, 0x18)
122
+ FIELD(CFU_FGCR, GCLK_CAL, 14, 1)
123
+ FIELD(CFU_FGCR, SC_HBC_TRIGGER, 13, 1)
124
+ FIELD(CFU_FGCR, GLOW, 12, 1)
125
+ FIELD(CFU_FGCR, GPWRDWN, 11, 1)
126
+ FIELD(CFU_FGCR, GCAP, 10, 1)
127
+ FIELD(CFU_FGCR, GSCWE, 9, 1)
128
+ FIELD(CFU_FGCR, GHIGH_B, 8, 1)
129
+ FIELD(CFU_FGCR, GMC_B, 7, 1)
130
+ FIELD(CFU_FGCR, GWE, 6, 1)
131
+ FIELD(CFU_FGCR, GRESTORE, 5, 1)
132
+ FIELD(CFU_FGCR, GTS_CFG_B, 4, 1)
133
+ FIELD(CFU_FGCR, GLUTMASK, 3, 1)
134
+ FIELD(CFU_FGCR, EN_GLOBS_B, 2, 1)
135
+ FIELD(CFU_FGCR, EOS, 1, 1)
136
+ FIELD(CFU_FGCR, INIT_COMPLETE, 0, 1)
137
+REG32(CFU_CTL, 0x1c)
138
+ FIELD(CFU_CTL, GSR_GSC, 15, 1)
139
+ FIELD(CFU_CTL, SLVERR_EN, 14, 1)
140
+ FIELD(CFU_CTL, CRC32_RESET, 13, 1)
141
+ FIELD(CFU_CTL, AXI_ERROR_EN, 12, 1)
142
+ FIELD(CFU_CTL, FLUSH_AXI, 11, 1)
143
+ FIELD(CFU_CTL, SSI_PER_SLR_PR, 10, 1)
144
+ FIELD(CFU_CTL, GCAP_CLK_EN, 9, 1)
145
+ FIELD(CFU_CTL, STATUS_SYNC_DISABLE, 8, 1)
146
+ FIELD(CFU_CTL, IGNORE_CFI_ERROR, 7, 1)
147
+ FIELD(CFU_CTL, CFRAME_DISABLE, 6, 1)
148
+ FIELD(CFU_CTL, QWORD_CNT_RESET, 5, 1)
149
+ FIELD(CFU_CTL, CRC8_DISABLE, 4, 1)
150
+ FIELD(CFU_CTL, CRC32_CHECK, 3, 1)
151
+ FIELD(CFU_CTL, DECOMPRESS, 2, 1)
152
+ FIELD(CFU_CTL, SEU_GO, 1, 1)
153
+ FIELD(CFU_CTL, CFI_LOCAL_RESET, 0, 1)
154
+REG32(CFU_CRAM_RW, 0x20)
155
+ FIELD(CFU_CRAM_RW, RFIFO_AFULL_DEPTH, 18, 9)
156
+ FIELD(CFU_CRAM_RW, RD_WAVE_CNT_LEFT, 12, 6)
157
+ FIELD(CFU_CRAM_RW, RD_WAVE_CNT, 6, 6)
158
+ FIELD(CFU_CRAM_RW, WR_WAVE_CNT, 0, 6)
159
+REG32(CFU_MASK, 0x28)
160
+REG32(CFU_CRC_EXPECT, 0x2c)
161
+REG32(CFU_CFRAME_LEFT_T0, 0x60)
162
+ FIELD(CFU_CFRAME_LEFT_T0, NUM, 0, 20)
163
+REG32(CFU_CFRAME_LEFT_T1, 0x64)
164
+ FIELD(CFU_CFRAME_LEFT_T1, NUM, 0, 20)
165
+REG32(CFU_CFRAME_LEFT_T2, 0x68)
166
+ FIELD(CFU_CFRAME_LEFT_T2, NUM, 0, 20)
167
+REG32(CFU_ROW_RANGE, 0x6c)
168
+ FIELD(CFU_ROW_RANGE, HALF_FSR, 5, 1)
169
+ FIELD(CFU_ROW_RANGE, NUM, 0, 5)
170
+REG32(CFU_STATUS, 0x100)
171
+ FIELD(CFU_STATUS, SEU_WRITE_ERROR, 30, 1)
172
+ FIELD(CFU_STATUS, FRCNT_ERROR, 29, 1)
173
+ FIELD(CFU_STATUS, RSVD_ERROR, 28, 1)
174
+ FIELD(CFU_STATUS, FDRO_ERROR, 27, 1)
175
+ FIELD(CFU_STATUS, FDRI_ERROR, 26, 1)
176
+ FIELD(CFU_STATUS, FDRI_READ_ERROR, 25, 1)
177
+ FIELD(CFU_STATUS, READ_FDRI_ERROR, 24, 1)
178
+ FIELD(CFU_STATUS, READ_SFR_ERROR, 23, 1)
179
+ FIELD(CFU_STATUS, READ_STREAM_ERROR, 22, 1)
180
+ FIELD(CFU_STATUS, UNKNOWN_STREAM_PKT, 21, 1)
181
+ FIELD(CFU_STATUS, USR_GTS, 20, 1)
182
+ FIELD(CFU_STATUS, USR_GSR, 19, 1)
183
+ FIELD(CFU_STATUS, AXI_BAD_WSTRB, 18, 1)
184
+ FIELD(CFU_STATUS, AXI_BAD_AR_SIZE, 17, 1)
185
+ FIELD(CFU_STATUS, AXI_BAD_AW_SIZE, 16, 1)
186
+ FIELD(CFU_STATUS, AXI_BAD_ARADDR, 15, 1)
187
+ FIELD(CFU_STATUS, AXI_BAD_AWADDR, 14, 1)
188
+ FIELD(CFU_STATUS, SCAN_CLEAR_PASS, 13, 1)
189
+ FIELD(CFU_STATUS, HC_SEC_ERROR, 12, 1)
190
+ FIELD(CFU_STATUS, GHIGH_B_ISHIGH, 11, 1)
191
+ FIELD(CFU_STATUS, GHIGH_B_ISLOW, 10, 1)
192
+ FIELD(CFU_STATUS, GMC_B_ISHIGH, 9, 1)
193
+ FIELD(CFU_STATUS, GMC_B_ISLOW, 8, 1)
194
+ FIELD(CFU_STATUS, GPWRDWN_B_ISHIGH, 7, 1)
195
+ FIELD(CFU_STATUS, CFI_SEU_CRC_ERROR, 6, 1)
196
+ FIELD(CFU_STATUS, CFI_SEU_ECC_ERROR, 5, 1)
197
+ FIELD(CFU_STATUS, CFI_SEU_HEARTBEAT, 4, 1)
198
+ FIELD(CFU_STATUS, SCAN_CLEAR_DONE, 3, 1)
199
+ FIELD(CFU_STATUS, HC_COMPLETE, 2, 1)
200
+ FIELD(CFU_STATUS, CFI_CFRAME_BUSY, 1, 1)
201
+ FIELD(CFU_STATUS, CFU_STREAM_BUSY, 0, 1)
202
+REG32(CFU_INTERNAL_STATUS, 0x104)
203
+ FIELD(CFU_INTERNAL_STATUS, SSI_EOS, 22, 1)
204
+ FIELD(CFU_INTERNAL_STATUS, SSI_GWE, 21, 1)
205
+ FIELD(CFU_INTERNAL_STATUS, RFIFO_EMPTY, 20, 1)
206
+ FIELD(CFU_INTERNAL_STATUS, RFIFO_FULL, 19, 1)
207
+ FIELD(CFU_INTERNAL_STATUS, SEL_SFR, 18, 1)
208
+ FIELD(CFU_INTERNAL_STATUS, STREAM_CFRAME, 17, 1)
209
+ FIELD(CFU_INTERNAL_STATUS, FDRI_PHASE, 16, 1)
210
+ FIELD(CFU_INTERNAL_STATUS, CFI_PIPE_EN, 15, 1)
211
+ FIELD(CFU_INTERNAL_STATUS, AWFIFO_DCNT, 10, 5)
212
+ FIELD(CFU_INTERNAL_STATUS, WFIFO_DCNT, 5, 5)
213
+ FIELD(CFU_INTERNAL_STATUS, REPAIR_BUSY, 4, 1)
214
+ FIELD(CFU_INTERNAL_STATUS, TRIMU_BUSY, 3, 1)
215
+ FIELD(CFU_INTERNAL_STATUS, TRIMB_BUSY, 2, 1)
216
+ FIELD(CFU_INTERNAL_STATUS, HCLEANR_BUSY, 1, 1)
217
+ FIELD(CFU_INTERNAL_STATUS, HCLEAN_BUSY, 0, 1)
218
+REG32(CFU_QWORD_CNT, 0x108)
219
+REG32(CFU_CRC_LIVE, 0x10c)
220
+REG32(CFU_PENDING_READ_CNT, 0x110)
221
+ FIELD(CFU_PENDING_READ_CNT, NUM, 0, 25)
222
+REG32(CFU_FDRI_CNT, 0x114)
223
+REG32(CFU_ECO1, 0x118)
224
+REG32(CFU_ECO2, 0x11c)
225
+
226
+#define R_MAX (R_CFU_ECO2 + 1)
227
+
228
+#define NUM_STREAM 2
229
+#define WFIFO_SZ 4
230
+
231
+struct XlnxVersalCFUAPB {
232
+ SysBusDevice parent_obj;
233
+ MemoryRegion iomem;
234
+ MemoryRegion iomem_stream[NUM_STREAM];
235
+ qemu_irq irq_cfu_imr;
236
+
237
+ /* 128-bit wfifo. */
238
+ uint32_t wfifo[WFIFO_SZ];
239
+
240
+ uint32_t regs[R_MAX];
241
+ RegisterInfo regs_info[R_MAX];
242
+
243
+ uint8_t fdri_row_addr;
244
+
245
+ struct {
246
+ XlnxCfiIf *cframe[15];
247
+ } cfg;
248
+};
249
+
250
+/**
251
+ * This is a helper function for updating a CFI data write fifo, an array of 4
252
+ * uint32_t and 128 bits of data that are allowed to be written through 4
253
+ * sequential 32 bit accesses. After the last index has been written into the
254
+ * write fifo (wfifo), the data is copied to and returned in a secondary fifo
255
+ * provided to the function (wfifo_ret), and the write fifo is cleared
256
+ * (zeroized).
257
+ *
258
+ * @addr: the address used when calculating the wfifo array index to update
259
+ * @value: the value to write into the wfifo array
260
+ * @wfifo: the wfifo to update
261
+ * @wfifo_out: will return the wfifo data when all 128 bits have been written
262
+ *
263
+ * @return: true if all 128 bits have been updated.
264
+ */
265
+bool update_wfifo(hwaddr addr, uint64_t value,
266
+ uint32_t *wfifo, uint32_t *wfifo_ret);
267
+
268
+#endif
269
diff --git a/hw/misc/xlnx-versal-cfu.c b/hw/misc/xlnx-versal-cfu.c
270
new file mode 100644
271
index XXXXXXX..XXXXXXX
272
--- /dev/null
273
+++ b/hw/misc/xlnx-versal-cfu.c
274
@@ -XXX,XX +XXX,XX @@
275
+/*
276
+ * QEMU model of the CFU Configuration Unit.
277
+ *
278
+ * Copyright (C) 2023, Advanced Micro Devices, Inc.
279
+ *
280
+ * Written by Edgar E. Iglesias <edgar.iglesias@gmail.com>,
281
+ * Sai Pavan Boddu <sai.pavan.boddu@amd.com>,
282
+ * Francisco Iglesias <francisco.iglesias@amd.com>
283
+ *
284
+ * SPDX-License-Identifier: GPL-2.0-or-later
285
+ */
286
+
287
+#include "qemu/osdep.h"
288
+#include "hw/sysbus.h"
289
+#include "hw/register.h"
290
+#include "hw/irq.h"
291
+#include "qemu/bitops.h"
292
+#include "qemu/log.h"
293
+#include "qemu/units.h"
294
+#include "migration/vmstate.h"
295
+#include "hw/qdev-properties.h"
296
+#include "hw/qdev-properties-system.h"
297
+#include "hw/misc/xlnx-versal-cfu.h"
298
+
299
+#ifndef XLNX_VERSAL_CFU_APB_ERR_DEBUG
300
+#define XLNX_VERSAL_CFU_APB_ERR_DEBUG 0
301
+#endif
302
+
303
+#define KEYHOLE_STREAM_4K (4 * KiB)
304
+#define KEYHOLE_STREAM_256K (256 * KiB)
305
+#define CFRAME_BROADCAST_ROW 0x1F
306
+
307
+bool update_wfifo(hwaddr addr, uint64_t value,
308
+ uint32_t *wfifo, uint32_t *wfifo_ret)
309
+{
310
+ unsigned int idx = extract32(addr, 2, 2);
311
+
312
+ wfifo[idx] = value;
313
+
314
+ if (idx == 3) {
315
+ memcpy(wfifo_ret, wfifo, WFIFO_SZ * sizeof(uint32_t));
316
+ memset(wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
317
+ return true;
318
+ }
319
+
320
+ return false;
321
+}
322
+
323
+static void cfu_imr_update_irq(XlnxVersalCFUAPB *s)
324
+{
325
+ bool pending = s->regs[R_CFU_ISR] & ~s->regs[R_CFU_IMR];
326
+ qemu_set_irq(s->irq_cfu_imr, pending);
327
+}
328
+
329
+static void cfu_isr_postw(RegisterInfo *reg, uint64_t val64)
330
+{
331
+ XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
332
+ cfu_imr_update_irq(s);
333
+}
334
+
335
+static uint64_t cfu_ier_prew(RegisterInfo *reg, uint64_t val64)
336
+{
337
+ XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
338
+ uint32_t val = val64;
339
+
340
+ s->regs[R_CFU_IMR] &= ~val;
341
+ cfu_imr_update_irq(s);
342
+ return 0;
343
+}
344
+
345
+static uint64_t cfu_idr_prew(RegisterInfo *reg, uint64_t val64)
346
+{
347
+ XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
348
+ uint32_t val = val64;
349
+
350
+ s->regs[R_CFU_IMR] |= val;
351
+ cfu_imr_update_irq(s);
352
+ return 0;
353
+}
354
+
355
+static uint64_t cfu_itr_prew(RegisterInfo *reg, uint64_t val64)
356
+{
357
+ XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
358
+ uint32_t val = val64;
359
+
360
+ s->regs[R_CFU_ISR] |= val;
361
+ cfu_imr_update_irq(s);
362
+ return 0;
363
+}
364
+
365
+static void cfu_fgcr_postw(RegisterInfo *reg, uint64_t val64)
366
+{
367
+ XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(reg->opaque);
368
+ uint32_t val = (uint32_t)val64;
369
+
370
+ /* Do a scan. It always looks good. */
371
+ if (FIELD_EX32(val, CFU_FGCR, SC_HBC_TRIGGER)) {
372
+ ARRAY_FIELD_DP32(s->regs, CFU_STATUS, SCAN_CLEAR_PASS, 1);
373
+ ARRAY_FIELD_DP32(s->regs, CFU_STATUS, SCAN_CLEAR_DONE, 1);
374
+ }
375
+}
376
+
377
+static const RegisterAccessInfo cfu_apb_regs_info[] = {
378
+ { .name = "CFU_ISR", .addr = A_CFU_ISR,
379
+ .rsvd = 0xfffffc00,
380
+ .w1c = 0x3ff,
381
+ .post_write = cfu_isr_postw,
382
+ },{ .name = "CFU_IMR", .addr = A_CFU_IMR,
383
+ .reset = 0x3ff,
384
+ .rsvd = 0xfffffc00,
385
+ .ro = 0x3ff,
386
+ },{ .name = "CFU_IER", .addr = A_CFU_IER,
387
+ .rsvd = 0xfffffc00,
388
+ .pre_write = cfu_ier_prew,
389
+ },{ .name = "CFU_IDR", .addr = A_CFU_IDR,
390
+ .rsvd = 0xfffffc00,
391
+ .pre_write = cfu_idr_prew,
392
+ },{ .name = "CFU_ITR", .addr = A_CFU_ITR,
393
+ .rsvd = 0xfffffc00,
394
+ .pre_write = cfu_itr_prew,
395
+ },{ .name = "CFU_PROTECT", .addr = A_CFU_PROTECT,
396
+ .reset = 0x1,
397
+ },{ .name = "CFU_FGCR", .addr = A_CFU_FGCR,
398
+ .rsvd = 0xffff8000,
399
+ .post_write = cfu_fgcr_postw,
400
+ },{ .name = "CFU_CTL", .addr = A_CFU_CTL,
401
+ .rsvd = 0xffff0000,
402
+ },{ .name = "CFU_CRAM_RW", .addr = A_CFU_CRAM_RW,
403
+ .reset = 0x401f7d9,
404
+ .rsvd = 0xf8000000,
405
+ },{ .name = "CFU_MASK", .addr = A_CFU_MASK,
406
+ },{ .name = "CFU_CRC_EXPECT", .addr = A_CFU_CRC_EXPECT,
407
+ },{ .name = "CFU_CFRAME_LEFT_T0", .addr = A_CFU_CFRAME_LEFT_T0,
408
+ .rsvd = 0xfff00000,
409
+ },{ .name = "CFU_CFRAME_LEFT_T1", .addr = A_CFU_CFRAME_LEFT_T1,
410
+ .rsvd = 0xfff00000,
411
+ },{ .name = "CFU_CFRAME_LEFT_T2", .addr = A_CFU_CFRAME_LEFT_T2,
412
+ .rsvd = 0xfff00000,
413
+ },{ .name = "CFU_ROW_RANGE", .addr = A_CFU_ROW_RANGE,
414
+ .rsvd = 0xffffffc0,
415
+ .ro = 0x3f,
416
+ },{ .name = "CFU_STATUS", .addr = A_CFU_STATUS,
417
+ .rsvd = 0x80000000,
418
+ .ro = 0x7fffffff,
419
+ },{ .name = "CFU_INTERNAL_STATUS", .addr = A_CFU_INTERNAL_STATUS,
420
+ .rsvd = 0xff800000,
421
+ .ro = 0x7fffff,
422
+ },{ .name = "CFU_QWORD_CNT", .addr = A_CFU_QWORD_CNT,
423
+ .ro = 0xffffffff,
424
+ },{ .name = "CFU_CRC_LIVE", .addr = A_CFU_CRC_LIVE,
425
+ .ro = 0xffffffff,
426
+ },{ .name = "CFU_PENDING_READ_CNT", .addr = A_CFU_PENDING_READ_CNT,
427
+ .rsvd = 0xfe000000,
428
+ .ro = 0x1ffffff,
429
+ },{ .name = "CFU_FDRI_CNT", .addr = A_CFU_FDRI_CNT,
430
+ .ro = 0xffffffff,
431
+ },{ .name = "CFU_ECO1", .addr = A_CFU_ECO1,
432
+ },{ .name = "CFU_ECO2", .addr = A_CFU_ECO2,
433
+ }
434
+};
435
+
436
+static void cfu_apb_reset(DeviceState *dev)
437
+{
438
+ XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(dev);
439
+ unsigned int i;
440
+
441
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
442
+ register_reset(&s->regs_info[i]);
443
+ }
444
+ memset(s->wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
445
+
446
+ s->regs[R_CFU_STATUS] |= R_CFU_STATUS_HC_COMPLETE_MASK;
447
+ cfu_imr_update_irq(s);
448
+}
449
+
450
+static const MemoryRegionOps cfu_apb_ops = {
451
+ .read = register_read_memory,
452
+ .write = register_write_memory,
453
+ .endianness = DEVICE_LITTLE_ENDIAN,
454
+ .valid = {
455
+ .min_access_size = 4,
456
+ .max_access_size = 4,
457
+ },
458
+};
459
+
460
+static void cfu_transfer_cfi_packet(XlnxVersalCFUAPB *s, uint8_t row_addr,
461
+ XlnxCfiPacket *pkt)
462
+{
463
+ if (row_addr == CFRAME_BROADCAST_ROW) {
464
+ for (int i = 0; i < ARRAY_SIZE(s->cfg.cframe); i++) {
465
+ if (s->cfg.cframe[i]) {
466
+ xlnx_cfi_transfer_packet(s->cfg.cframe[i], pkt);
48
+ }
467
+ }
49
+ }
468
+ }
50
+ env->pc = new_pc;
469
+ } else {
51
+
470
+ assert(row_addr < ARRAY_SIZE(s->cfg.cframe));
52
qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
471
+
53
"AArch64 EL%d PC 0x%" PRIx64 "\n",
472
+ if (s->cfg.cframe[row_addr]) {
54
cur_el, new_el, env->pc);
473
+ xlnx_cfi_transfer_packet(s->cfg.cframe[row_addr], pkt);
474
+ }
475
+ }
476
+}
477
+
478
+static uint64_t cfu_stream_read(void *opaque, hwaddr addr, unsigned size)
479
+{
480
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
481
+ HWADDR_PRIx "\n", __func__, addr);
482
+ return 0;
483
+}
484
+
485
+static void cfu_stream_write(void *opaque, hwaddr addr, uint64_t value,
486
+ unsigned size)
487
+{
488
+ XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(opaque);
489
+ uint32_t wfifo[WFIFO_SZ];
490
+
491
+ if (update_wfifo(addr, value, s->wfifo, wfifo)) {
492
+ uint8_t packet_type, row_addr, reg_addr;
493
+
494
+ packet_type = extract32(wfifo[0], 24, 8);
495
+ row_addr = extract32(wfifo[0], 16, 5);
496
+ reg_addr = extract32(wfifo[0], 8, 6);
497
+
498
+ /* Compressed bitstreams are not supported yet. */
499
+ if (ARRAY_FIELD_EX32(s->regs, CFU_CTL, DECOMPRESS) == 0) {
500
+ if (s->regs[R_CFU_FDRI_CNT]) {
501
+ XlnxCfiPacket pkt = {
502
+ .reg_addr = CFRAME_FDRI,
503
+ .data[0] = wfifo[0],
504
+ .data[1] = wfifo[1],
505
+ .data[2] = wfifo[2],
506
+ .data[3] = wfifo[3]
507
+ };
508
+
509
+ cfu_transfer_cfi_packet(s, s->fdri_row_addr, &pkt);
510
+
511
+ s->regs[R_CFU_FDRI_CNT]--;
512
+
513
+ } else if (packet_type == PACKET_TYPE_CFU &&
514
+ reg_addr == CFRAME_FDRI) {
515
+
516
+ /* Load R_CFU_FDRI_CNT, must be multiple of 25 */
517
+ s->regs[R_CFU_FDRI_CNT] = wfifo[1];
518
+
519
+ /* Store target row_addr */
520
+ s->fdri_row_addr = row_addr;
521
+
522
+ if (wfifo[1] % 25 != 0) {
523
+ qemu_log_mask(LOG_GUEST_ERROR,
524
+ "CFU FDRI_CNT is not loaded with "
525
+ "a multiple of 25 value\n");
526
+ }
527
+
528
+ } else if (packet_type == PACKET_TYPE_CFRAME) {
529
+ XlnxCfiPacket pkt = {
530
+ .reg_addr = reg_addr,
531
+ .data[0] = wfifo[1],
532
+ .data[1] = wfifo[2],
533
+ .data[2] = wfifo[3],
534
+ };
535
+ cfu_transfer_cfi_packet(s, row_addr, &pkt);
536
+ }
537
+ }
538
+ }
539
+}
540
+
541
+static const MemoryRegionOps cfu_stream_ops = {
542
+ .read = cfu_stream_read,
543
+ .write = cfu_stream_write,
544
+ .endianness = DEVICE_LITTLE_ENDIAN,
545
+ .valid = {
546
+ .min_access_size = 4,
547
+ .max_access_size = 8,
548
+ },
549
+};
550
+
551
+static void cfu_apb_init(Object *obj)
552
+{
553
+ XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(obj);
554
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
555
+ RegisterInfoArray *reg_array;
556
+ unsigned int i;
557
+ char *name;
558
+
559
+ memory_region_init(&s->iomem, obj, TYPE_XLNX_VERSAL_CFU_APB, R_MAX * 4);
560
+ reg_array =
561
+ register_init_block32(DEVICE(obj), cfu_apb_regs_info,
562
+ ARRAY_SIZE(cfu_apb_regs_info),
563
+ s->regs_info, s->regs,
564
+ &cfu_apb_ops,
565
+ XLNX_VERSAL_CFU_APB_ERR_DEBUG,
566
+ R_MAX * 4);
567
+ memory_region_add_subregion(&s->iomem,
568
+ 0x0,
569
+ &reg_array->mem);
570
+ sysbus_init_mmio(sbd, &s->iomem);
571
+ for (i = 0; i < NUM_STREAM; i++) {
572
+ name = g_strdup_printf(TYPE_XLNX_VERSAL_CFU_APB "-stream%d", i);
573
+ memory_region_init_io(&s->iomem_stream[i], obj, &cfu_stream_ops, s,
574
+ name, i == 0 ? KEYHOLE_STREAM_4K :
575
+ KEYHOLE_STREAM_256K);
576
+ sysbus_init_mmio(sbd, &s->iomem_stream[i]);
577
+ g_free(name);
578
+ }
579
+ sysbus_init_irq(sbd, &s->irq_cfu_imr);
580
+}
581
+
582
+static Property cfu_props[] = {
583
+ DEFINE_PROP_LINK("cframe0", XlnxVersalCFUAPB, cfg.cframe[0],
584
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
585
+ DEFINE_PROP_LINK("cframe1", XlnxVersalCFUAPB, cfg.cframe[1],
586
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
587
+ DEFINE_PROP_LINK("cframe2", XlnxVersalCFUAPB, cfg.cframe[2],
588
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
589
+ DEFINE_PROP_LINK("cframe3", XlnxVersalCFUAPB, cfg.cframe[3],
590
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
591
+ DEFINE_PROP_LINK("cframe4", XlnxVersalCFUAPB, cfg.cframe[4],
592
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
593
+ DEFINE_PROP_LINK("cframe5", XlnxVersalCFUAPB, cfg.cframe[5],
594
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
595
+ DEFINE_PROP_LINK("cframe6", XlnxVersalCFUAPB, cfg.cframe[6],
596
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
597
+ DEFINE_PROP_LINK("cframe7", XlnxVersalCFUAPB, cfg.cframe[7],
598
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
599
+ DEFINE_PROP_LINK("cframe8", XlnxVersalCFUAPB, cfg.cframe[8],
600
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
601
+ DEFINE_PROP_LINK("cframe9", XlnxVersalCFUAPB, cfg.cframe[9],
602
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
603
+ DEFINE_PROP_LINK("cframe10", XlnxVersalCFUAPB, cfg.cframe[10],
604
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
605
+ DEFINE_PROP_LINK("cframe11", XlnxVersalCFUAPB, cfg.cframe[11],
606
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
607
+ DEFINE_PROP_LINK("cframe12", XlnxVersalCFUAPB, cfg.cframe[12],
608
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
609
+ DEFINE_PROP_LINK("cframe13", XlnxVersalCFUAPB, cfg.cframe[13],
610
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
611
+ DEFINE_PROP_LINK("cframe14", XlnxVersalCFUAPB, cfg.cframe[14],
612
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
613
+ DEFINE_PROP_END_OF_LIST(),
614
+};
615
+
616
+static const VMStateDescription vmstate_cfu_apb = {
617
+ .name = TYPE_XLNX_VERSAL_CFU_APB,
618
+ .version_id = 1,
619
+ .minimum_version_id = 1,
620
+ .fields = (VMStateField[]) {
621
+ VMSTATE_UINT32_ARRAY(wfifo, XlnxVersalCFUAPB, 4),
622
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalCFUAPB, R_MAX),
623
+ VMSTATE_UINT8(fdri_row_addr, XlnxVersalCFUAPB),
624
+ VMSTATE_END_OF_LIST(),
625
+ }
626
+};
627
+
628
+static void cfu_apb_class_init(ObjectClass *klass, void *data)
629
+{
630
+ DeviceClass *dc = DEVICE_CLASS(klass);
631
+
632
+ dc->reset = cfu_apb_reset;
633
+ dc->vmsd = &vmstate_cfu_apb;
634
+ device_class_set_props(dc, cfu_props);
635
+}
636
+
637
+static const TypeInfo cfu_apb_info = {
638
+ .name = TYPE_XLNX_VERSAL_CFU_APB,
639
+ .parent = TYPE_SYS_BUS_DEVICE,
640
+ .instance_size = sizeof(XlnxVersalCFUAPB),
641
+ .class_init = cfu_apb_class_init,
642
+ .instance_init = cfu_apb_init,
643
+ .interfaces = (InterfaceInfo[]) {
644
+ { TYPE_XLNX_CFI_IF },
645
+ { }
646
+ }
647
+};
648
+
649
+static void cfu_apb_register_types(void)
650
+{
651
+ type_register_static(&cfu_apb_info);
652
+}
653
+
654
+type_init(cfu_apb_register_types)
655
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
656
index XXXXXXX..XXXXXXX 100644
657
--- a/hw/misc/meson.build
658
+++ b/hw/misc/meson.build
659
@@ -XXX,XX +XXX,XX @@ specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
660
system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
661
'xlnx-versal-xramc.c',
662
'xlnx-versal-pmc-iou-slcr.c',
663
+ 'xlnx-versal-cfu.c',
664
'xlnx-cfi-if.c',
665
))
666
system_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: files('stm32f2xx_syscfg.c'))
55
--
667
--
56
2.20.1
668
2.34.1
57
58
diff view generated by jsdifflib
1
From: Pan Nengyuan <pannengyuan@huawei.com>
1
From: Francisco Iglesias <francisco.iglesias@amd.com>
2
2
3
There are some memleaks when we call 'device_list_properties'. This patch move timer_new from init into realize to fix it.
3
Introduce a model of Xilinx Versal's Configuration Frame Unit's data out
4
port (CFU_FDRO).
4
5
5
Reported-by: Euler Robot <euler.robot@huawei.com>
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
6
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
7
Message-id: 20200227025055.14341-5-pannengyuan@huawei.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230831165701.2016397-4-francisco.iglesias@amd.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/arm/strongarm.c | 18 ++++++++++++------
11
include/hw/misc/xlnx-versal-cfu.h | 12 ++++
12
1 file changed, 12 insertions(+), 6 deletions(-)
12
hw/misc/xlnx-versal-cfu.c | 96 +++++++++++++++++++++++++++++++
13
2 files changed, 108 insertions(+)
13
14
14
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
15
diff --git a/include/hw/misc/xlnx-versal-cfu.h b/include/hw/misc/xlnx-versal-cfu.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/strongarm.c
17
--- a/include/hw/misc/xlnx-versal-cfu.h
17
+++ b/hw/arm/strongarm.c
18
+++ b/include/hw/misc/xlnx-versal-cfu.h
18
@@ -XXX,XX +XXX,XX @@ static void strongarm_rtc_init(Object *obj)
19
@@ -XXX,XX +XXX,XX @@
19
s->last_rcnr = (uint32_t) mktimegm(&tm);
20
#include "hw/sysbus.h"
20
s->last_hz = qemu_clock_get_ms(rtc_clock);
21
#include "hw/register.h"
21
22
#include "hw/misc/xlnx-cfi-if.h"
22
- s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
23
+#include "qemu/fifo32.h"
23
- s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
24
24
-
25
#define TYPE_XLNX_VERSAL_CFU_APB "xlnx,versal-cfu-apb"
25
sysbus_init_irq(dev, &s->rtc_irq);
26
OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFUAPB, XLNX_VERSAL_CFU_APB)
26
sysbus_init_irq(dev, &s->rtc_hz_irq);
27
27
28
+#define TYPE_XLNX_VERSAL_CFU_FDRO "xlnx,versal-cfu-fdro"
28
@@ -XXX,XX +XXX,XX @@ static void strongarm_rtc_init(Object *obj)
29
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFUFDRO, XLNX_VERSAL_CFU_FDRO)
29
sysbus_init_mmio(dev, &s->iomem);
30
+
31
REG32(CFU_ISR, 0x0)
32
FIELD(CFU_ISR, USR_GTS_EVENT, 9, 1)
33
FIELD(CFU_ISR, USR_GSR_EVENT, 8, 1)
34
@@ -XXX,XX +XXX,XX @@ struct XlnxVersalCFUAPB {
35
} cfg;
36
};
37
38
+
39
+struct XlnxVersalCFUFDRO {
40
+ SysBusDevice parent_obj;
41
+ MemoryRegion iomem_fdro;
42
+
43
+ Fifo32 fdro_data;
44
+};
45
+
46
/**
47
* This is a helper function for updating a CFI data write fifo, an array of 4
48
* uint32_t and 128 bits of data that are allowed to be written through 4
49
diff --git a/hw/misc/xlnx-versal-cfu.c b/hw/misc/xlnx-versal-cfu.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/misc/xlnx-versal-cfu.c
52
+++ b/hw/misc/xlnx-versal-cfu.c
53
@@ -XXX,XX +XXX,XX @@ static void cfu_stream_write(void *opaque, hwaddr addr, uint64_t value,
54
}
30
}
55
}
31
56
32
+static void strongarm_rtc_realize(DeviceState *dev, Error **errp)
57
+static uint64_t cfu_fdro_read(void *opaque, hwaddr addr, unsigned size)
33
+{
58
+{
34
+ StrongARMRTCState *s = STRONGARM_RTC(dev);
59
+ XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(opaque);
35
+ s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
60
+ uint64_t ret = 0;
36
+ s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
61
+
62
+ if (!fifo32_is_empty(&s->fdro_data)) {
63
+ ret = fifo32_pop(&s->fdro_data);
64
+ }
65
+
66
+ return ret;
37
+}
67
+}
38
+
68
+
39
static int strongarm_rtc_pre_save(void *opaque)
69
+static void cfu_fdro_write(void *opaque, hwaddr addr, uint64_t value,
70
+ unsigned size)
71
+{
72
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported write from addr=%"
73
+ HWADDR_PRIx "\n", __func__, addr);
74
+}
75
+
76
static const MemoryRegionOps cfu_stream_ops = {
77
.read = cfu_stream_read,
78
.write = cfu_stream_write,
79
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps cfu_stream_ops = {
80
},
81
};
82
83
+static const MemoryRegionOps cfu_fdro_ops = {
84
+ .read = cfu_fdro_read,
85
+ .write = cfu_fdro_write,
86
+ .endianness = DEVICE_LITTLE_ENDIAN,
87
+ .valid = {
88
+ .min_access_size = 4,
89
+ .max_access_size = 4,
90
+ },
91
+};
92
+
93
static void cfu_apb_init(Object *obj)
40
{
94
{
41
StrongARMRTCState *s = opaque;
95
XlnxVersalCFUAPB *s = XLNX_VERSAL_CFU_APB(obj);
42
@@ -XXX,XX +XXX,XX @@ static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, void *data)
96
@@ -XXX,XX +XXX,XX @@ static void cfu_apb_init(Object *obj)
43
97
sysbus_init_irq(sbd, &s->irq_cfu_imr);
44
dc->desc = "StrongARM RTC Controller";
45
dc->vmsd = &vmstate_strongarm_rtc_regs;
46
+ dc->realize = strongarm_rtc_realize;
47
}
98
}
48
99
49
static const TypeInfo strongarm_rtc_sysbus_info = {
100
+static void cfu_fdro_init(Object *obj)
50
@@ -XXX,XX +XXX,XX @@ static void strongarm_uart_init(Object *obj)
101
+{
51
"uart", 0x10000);
102
+ XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(obj);
52
sysbus_init_mmio(dev, &s->iomem);
103
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
53
sysbus_init_irq(dev, &s->irq);
104
+
54
-
105
+ memory_region_init_io(&s->iomem_fdro, obj, &cfu_fdro_ops, s,
55
- s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_rx_to, s);
106
+ TYPE_XLNX_VERSAL_CFU_FDRO, KEYHOLE_STREAM_4K);
56
- s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
107
+ sysbus_init_mmio(sbd, &s->iomem_fdro);
108
+ fifo32_create(&s->fdro_data, 8 * KiB / sizeof(uint32_t));
109
+}
110
+
111
+static void cfu_fdro_reset_enter(Object *obj, ResetType type)
112
+{
113
+ XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(obj);
114
+
115
+ fifo32_reset(&s->fdro_data);
116
+}
117
+
118
+static void cfu_fdro_cfi_transfer_packet(XlnxCfiIf *cfi_if, XlnxCfiPacket *pkt)
119
+{
120
+ XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(cfi_if);
121
+
122
+ if (fifo32_num_free(&s->fdro_data) >= ARRAY_SIZE(pkt->data)) {
123
+ for (int i = 0; i < ARRAY_SIZE(pkt->data); i++) {
124
+ fifo32_push(&s->fdro_data, pkt->data[i]);
125
+ }
126
+ } else {
127
+ /* It is a programming error to fill the fifo. */
128
+ qemu_log_mask(LOG_GUEST_ERROR,
129
+ "CFU_FDRO: CFI data dropped due to full read fifo\n");
130
+ }
131
+}
132
+
133
static Property cfu_props[] = {
134
DEFINE_PROP_LINK("cframe0", XlnxVersalCFUAPB, cfg.cframe[0],
135
TYPE_XLNX_CFI_IF, XlnxCfiIf *),
136
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_cfu_apb = {
137
}
138
};
139
140
+static const VMStateDescription vmstate_cfu_fdro = {
141
+ .name = TYPE_XLNX_VERSAL_CFU_FDRO,
142
+ .version_id = 1,
143
+ .minimum_version_id = 1,
144
+ .fields = (VMStateField[]) {
145
+ VMSTATE_FIFO32(fdro_data, XlnxVersalCFUFDRO),
146
+ VMSTATE_END_OF_LIST(),
147
+ }
148
+};
149
+
150
static void cfu_apb_class_init(ObjectClass *klass, void *data)
151
{
152
DeviceClass *dc = DEVICE_CLASS(klass);
153
@@ -XXX,XX +XXX,XX @@ static void cfu_apb_class_init(ObjectClass *klass, void *data)
154
device_class_set_props(dc, cfu_props);
57
}
155
}
58
156
59
static void strongarm_uart_realize(DeviceState *dev, Error **errp)
157
+static void cfu_fdro_class_init(ObjectClass *klass, void *data)
158
+{
159
+ DeviceClass *dc = DEVICE_CLASS(klass);
160
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
161
+ XlnxCfiIfClass *xcic = XLNX_CFI_IF_CLASS(klass);
162
+
163
+ dc->vmsd = &vmstate_cfu_fdro;
164
+ xcic->cfi_transfer_packet = cfu_fdro_cfi_transfer_packet;
165
+ rc->phases.enter = cfu_fdro_reset_enter;
166
+}
167
+
168
static const TypeInfo cfu_apb_info = {
169
.name = TYPE_XLNX_VERSAL_CFU_APB,
170
.parent = TYPE_SYS_BUS_DEVICE,
171
@@ -XXX,XX +XXX,XX @@ static const TypeInfo cfu_apb_info = {
172
}
173
};
174
175
+static const TypeInfo cfu_fdro_info = {
176
+ .name = TYPE_XLNX_VERSAL_CFU_FDRO,
177
+ .parent = TYPE_SYS_BUS_DEVICE,
178
+ .instance_size = sizeof(XlnxVersalCFUFDRO),
179
+ .class_init = cfu_fdro_class_init,
180
+ .instance_init = cfu_fdro_init,
181
+ .interfaces = (InterfaceInfo[]) {
182
+ { TYPE_XLNX_CFI_IF },
183
+ { }
184
+ }
185
+};
186
+
187
static void cfu_apb_register_types(void)
60
{
188
{
61
StrongARMUARTState *s = STRONGARM_UART(dev);
189
type_register_static(&cfu_apb_info);
62
190
+ type_register_static(&cfu_fdro_info);
63
+ s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
191
}
64
+ strongarm_uart_rx_to,
192
65
+ s);
193
type_init(cfu_apb_register_types)
66
+ s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
67
qemu_chr_fe_set_handlers(&s->chr,
68
strongarm_uart_can_receive,
69
strongarm_uart_receive,
70
--
194
--
71
2.20.1
195
2.34.1
72
73
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Francisco Iglesias <francisco.iglesias@amd.com>
2
2
3
Generate xlnx-versal-virt zdma FDT nodes.
3
Introduce a model of Xilinx Versal's Configuration Frame Unit's Single
4
Frame Read port (CFU_SFR).
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
6
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
8
Message-id: 20230831165701.2016397-5-francisco.iglesias@amd.com
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/arm/xlnx-versal-virt.c | 28 ++++++++++++++++++++++++++++
11
include/hw/misc/xlnx-versal-cfu.h | 15 ++++++
12
1 file changed, 28 insertions(+)
12
hw/misc/xlnx-versal-cfu.c | 87 +++++++++++++++++++++++++++++++
13
2 files changed, 102 insertions(+)
13
14
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
15
diff --git a/include/hw/misc/xlnx-versal-cfu.h b/include/hw/misc/xlnx-versal-cfu.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
17
--- a/include/hw/misc/xlnx-versal-cfu.h
17
+++ b/hw/arm/xlnx-versal-virt.c
18
+++ b/include/hw/misc/xlnx-versal-cfu.h
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_gem_nodes(VersalVirt *s)
19
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFUAPB, XLNX_VERSAL_CFU_APB)
20
#define TYPE_XLNX_VERSAL_CFU_FDRO "xlnx,versal-cfu-fdro"
21
OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFUFDRO, XLNX_VERSAL_CFU_FDRO)
22
23
+#define TYPE_XLNX_VERSAL_CFU_SFR "xlnx,versal-cfu-sfr"
24
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFUSFR, XLNX_VERSAL_CFU_SFR)
25
+
26
REG32(CFU_ISR, 0x0)
27
FIELD(CFU_ISR, USR_GTS_EVENT, 9, 1)
28
FIELD(CFU_ISR, USR_GSR_EVENT, 8, 1)
29
@@ -XXX,XX +XXX,XX @@ struct XlnxVersalCFUFDRO {
30
Fifo32 fdro_data;
31
};
32
33
+struct XlnxVersalCFUSFR {
34
+ SysBusDevice parent_obj;
35
+ MemoryRegion iomem_sfr;
36
+
37
+ /* 128-bit wfifo. */
38
+ uint32_t wfifo[WFIFO_SZ];
39
+
40
+ struct {
41
+ XlnxVersalCFUAPB *cfu;
42
+ } cfg;
43
+};
44
+
45
/**
46
* This is a helper function for updating a CFI data write fifo, an array of 4
47
* uint32_t and 128 bits of data that are allowed to be written through 4
48
diff --git a/hw/misc/xlnx-versal-cfu.c b/hw/misc/xlnx-versal-cfu.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/misc/xlnx-versal-cfu.c
51
+++ b/hw/misc/xlnx-versal-cfu.c
52
@@ -XXX,XX +XXX,XX @@ static void cfu_stream_write(void *opaque, hwaddr addr, uint64_t value,
19
}
53
}
20
}
54
}
21
55
22
+static void fdt_add_zdma_nodes(VersalVirt *s)
56
+static uint64_t cfu_sfr_read(void *opaque, hwaddr addr, unsigned size)
23
+{
57
+{
24
+ const char clocknames[] = "clk_main\0clk_apb";
58
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
25
+ const char compat[] = "xlnx,zynqmp-dma-1.0";
59
+ HWADDR_PRIx "\n", __func__, addr);
26
+ int i;
60
+ return 0;
61
+}
27
+
62
+
28
+ for (i = XLNX_VERSAL_NR_ADMAS - 1; i >= 0; i--) {
63
+static void cfu_sfr_write(void *opaque, hwaddr addr, uint64_t value,
29
+ uint64_t addr = MM_ADMA_CH0 + MM_ADMA_CH0_SIZE * i;
64
+ unsigned size)
30
+ char *name = g_strdup_printf("/dma@%" PRIx64, addr);
65
+{
66
+ XlnxVersalCFUSFR *s = XLNX_VERSAL_CFU_SFR(opaque);
67
+ uint32_t wfifo[WFIFO_SZ];
31
+
68
+
32
+ qemu_fdt_add_subnode(s->fdt, name);
69
+ if (update_wfifo(addr, value, s->wfifo, wfifo)) {
70
+ uint8_t row_addr = extract32(wfifo[0], 23, 5);
71
+ uint32_t frame_addr = extract32(wfifo[0], 0, 23);
72
+ XlnxCfiPacket pkt = { .reg_addr = CFRAME_SFR,
73
+ .data[0] = frame_addr };
33
+
74
+
34
+ qemu_fdt_setprop_cell(s->fdt, name, "xlnx,bus-width", 64);
75
+ if (s->cfg.cfu) {
35
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
76
+ cfu_transfer_cfi_packet(s->cfg.cfu, row_addr, &pkt);
36
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
77
+ }
37
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
38
+ clocknames, sizeof(clocknames));
39
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
40
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_ADMA_IRQ_0 + i,
41
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
42
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
43
+ 2, addr, 2, 0x1000);
44
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
45
+ g_free(name);
46
+ }
78
+ }
47
+}
79
+}
48
+
80
+
49
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
81
static uint64_t cfu_fdro_read(void *opaque, hwaddr addr, unsigned size)
50
{
82
{
51
Error *err = NULL;
83
XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(opaque);
52
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
84
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps cfu_stream_ops = {
53
fdt_add_uart_nodes(s);
85
},
54
fdt_add_gic_nodes(s);
86
};
55
fdt_add_timer_nodes(s);
87
56
+ fdt_add_zdma_nodes(s);
88
+static const MemoryRegionOps cfu_sfr_ops = {
57
fdt_add_cpu_nodes(s, psci_conduit);
89
+ .read = cfu_sfr_read,
58
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
90
+ .write = cfu_sfr_write,
59
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
91
+ .endianness = DEVICE_LITTLE_ENDIAN,
92
+ .valid = {
93
+ .min_access_size = 4,
94
+ .max_access_size = 4,
95
+ },
96
+};
97
+
98
static const MemoryRegionOps cfu_fdro_ops = {
99
.read = cfu_fdro_read,
100
.write = cfu_fdro_write,
101
@@ -XXX,XX +XXX,XX @@ static void cfu_apb_init(Object *obj)
102
sysbus_init_irq(sbd, &s->irq_cfu_imr);
103
}
104
105
+static void cfu_sfr_init(Object *obj)
106
+{
107
+ XlnxVersalCFUSFR *s = XLNX_VERSAL_CFU_SFR(obj);
108
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
109
+
110
+ memory_region_init_io(&s->iomem_sfr, obj, &cfu_sfr_ops, s,
111
+ TYPE_XLNX_VERSAL_CFU_SFR, KEYHOLE_STREAM_4K);
112
+ sysbus_init_mmio(sbd, &s->iomem_sfr);
113
+}
114
+
115
+static void cfu_sfr_reset_enter(Object *obj, ResetType type)
116
+{
117
+ XlnxVersalCFUSFR *s = XLNX_VERSAL_CFU_SFR(obj);
118
+
119
+ memset(s->wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
120
+}
121
+
122
static void cfu_fdro_init(Object *obj)
123
{
124
XlnxVersalCFUFDRO *s = XLNX_VERSAL_CFU_FDRO(obj);
125
@@ -XXX,XX +XXX,XX @@ static Property cfu_props[] = {
126
DEFINE_PROP_END_OF_LIST(),
127
};
128
129
+static Property cfu_sfr_props[] = {
130
+ DEFINE_PROP_LINK("cfu", XlnxVersalCFUSFR, cfg.cfu,
131
+ TYPE_XLNX_VERSAL_CFU_APB, XlnxVersalCFUAPB *),
132
+ DEFINE_PROP_END_OF_LIST(),
133
+};
134
+
135
static const VMStateDescription vmstate_cfu_apb = {
136
.name = TYPE_XLNX_VERSAL_CFU_APB,
137
.version_id = 1,
138
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_cfu_fdro = {
139
}
140
};
141
142
+static const VMStateDescription vmstate_cfu_sfr = {
143
+ .name = TYPE_XLNX_VERSAL_CFU_SFR,
144
+ .version_id = 1,
145
+ .minimum_version_id = 1,
146
+ .fields = (VMStateField[]) {
147
+ VMSTATE_UINT32_ARRAY(wfifo, XlnxVersalCFUSFR, 4),
148
+ VMSTATE_END_OF_LIST(),
149
+ }
150
+};
151
+
152
static void cfu_apb_class_init(ObjectClass *klass, void *data)
153
{
154
DeviceClass *dc = DEVICE_CLASS(klass);
155
@@ -XXX,XX +XXX,XX @@ static void cfu_fdro_class_init(ObjectClass *klass, void *data)
156
rc->phases.enter = cfu_fdro_reset_enter;
157
}
158
159
+static void cfu_sfr_class_init(ObjectClass *klass, void *data)
160
+{
161
+ DeviceClass *dc = DEVICE_CLASS(klass);
162
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
163
+
164
+ device_class_set_props(dc, cfu_sfr_props);
165
+ dc->vmsd = &vmstate_cfu_sfr;
166
+ rc->phases.enter = cfu_sfr_reset_enter;
167
+}
168
+
169
static const TypeInfo cfu_apb_info = {
170
.name = TYPE_XLNX_VERSAL_CFU_APB,
171
.parent = TYPE_SYS_BUS_DEVICE,
172
@@ -XXX,XX +XXX,XX @@ static const TypeInfo cfu_fdro_info = {
173
}
174
};
175
176
+static const TypeInfo cfu_sfr_info = {
177
+ .name = TYPE_XLNX_VERSAL_CFU_SFR,
178
+ .parent = TYPE_SYS_BUS_DEVICE,
179
+ .instance_size = sizeof(XlnxVersalCFUSFR),
180
+ .class_init = cfu_sfr_class_init,
181
+ .instance_init = cfu_sfr_init,
182
+};
183
+
184
static void cfu_apb_register_types(void)
185
{
186
type_register_static(&cfu_apb_info);
187
type_register_static(&cfu_fdro_info);
188
+ type_register_static(&cfu_sfr_info);
189
}
190
191
type_init(cfu_apb_register_types)
60
--
192
--
61
2.20.1
193
2.34.1
62
63
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Francisco Iglesias <francisco.iglesias@amd.com>
2
2
3
This is an aarch64-only function. Move it out of the shared file.
3
Introduce a model of Xilinx Versal's Configuration Frame controller
4
This patch is code movement only.
4
(CFRAME_REG).
5
5
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Message-id: 20230831165701.2016397-6-francisco.iglesias@amd.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20200302175829.2183-6-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/helper-a64.h | 1 +
11
MAINTAINERS | 2 +
13
target/arm/helper.h | 1 -
12
include/hw/misc/xlnx-versal-cframe-reg.h | 286 ++++++++++
14
target/arm/helper-a64.c | 91 ++++++++++++++++++++++++++++++++++++++++
13
hw/misc/xlnx-versal-cframe-reg.c | 697 +++++++++++++++++++++++
15
target/arm/op_helper.c | 93 -----------------------------------------
14
hw/misc/meson.build | 1 +
16
4 files changed, 92 insertions(+), 94 deletions(-)
15
4 files changed, 986 insertions(+)
16
create mode 100644 include/hw/misc/xlnx-versal-cframe-reg.h
17
create mode 100644 hw/misc/xlnx-versal-cframe-reg.c
17
18
18
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
19
diff --git a/MAINTAINERS b/MAINTAINERS
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-a64.h
21
--- a/MAINTAINERS
21
+++ b/target/arm/helper-a64.h
22
+++ b/MAINTAINERS
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
23
@@ -XXX,XX +XXX,XX @@ F: hw/misc/xlnx-cfi-if.c
23
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
24
F: include/hw/misc/xlnx-cfi-if.h
24
25
F: hw/misc/xlnx-versal-cfu.c
25
DEF_HELPER_2(exception_return, void, env, i64)
26
F: include/hw/misc/xlnx-versal-cfu.h
26
+DEF_HELPER_2(dc_zva, void, env, i64)
27
+F: hw/misc/xlnx-versal-cframe-reg.c
27
28
+F: include/hw/misc/xlnx-versal-cframe-reg.h
28
DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
29
29
DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
30
STM32F100
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
31
M: Alexandre Iooss <erdnaxe@crans.org>
31
index XXXXXXX..XXXXXXX 100644
32
diff --git a/include/hw/misc/xlnx-versal-cframe-reg.h b/include/hw/misc/xlnx-versal-cframe-reg.h
32
--- a/target/arm/helper.h
33
new file mode 100644
33
+++ b/target/arm/helper.h
34
index XXXXXXX..XXXXXXX
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
35
--- /dev/null
35
36
+++ b/include/hw/misc/xlnx-versal-cframe-reg.h
36
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
37
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
38
-DEF_HELPER_2(dc_zva, void, env, i64)
39
40
DEF_HELPER_FLAGS_5(gvec_qrdmlah_s16, TCG_CALL_NO_RWG,
41
void, ptr, ptr, ptr, ptr, i32)
42
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper-a64.c
45
+++ b/target/arm/helper-a64.c
46
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
47
*/
38
+/*
48
39
+ * QEMU model of the Configuration Frame Control module
49
#include "qemu/osdep.h"
40
+ *
41
+ * Copyright (C) 2023, Advanced Micro Devices, Inc.
42
+ *
43
+ * Written by Francisco Iglesias <francisco.iglesias@amd.com>
44
+ *
45
+ * SPDX-License-Identifier: GPL-2.0-or-later
46
+ *
47
+ * References:
48
+ * [1] Versal ACAP Technical Reference Manual,
49
+ * https://www.xilinx.com/support/documentation/architecture-manuals/am011-versal-acap-trm.pdf
50
+ *
51
+ * [2] Versal ACAP Register Reference,
52
+ * https://www.xilinx.com/htmldocs/registers/am012/am012-versal-register-reference.html
53
+ */
54
+#ifndef HW_MISC_XLNX_VERSAL_CFRAME_REG_H
55
+#define HW_MISC_XLNX_VERSAL_CFRAME_REG_H
56
+
57
+#include "hw/sysbus.h"
58
+#include "hw/register.h"
59
+#include "hw/misc/xlnx-cfi-if.h"
60
+#include "hw/misc/xlnx-versal-cfu.h"
61
+#include "qemu/fifo32.h"
62
+
63
+#define TYPE_XLNX_VERSAL_CFRAME_REG "xlnx,cframe-reg"
64
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFrameReg, XLNX_VERSAL_CFRAME_REG)
65
+
66
+/*
67
+ * The registers in this module are 128 bits wide but it is ok to write
68
+ * and read them through 4 sequential 32 bit accesses (address[3:2] = 0,
69
+ * 1, 2, 3).
70
+ */
71
+REG32(CRC0, 0x0)
72
+ FIELD(CRC, CRC, 0, 32)
73
+REG32(CRC1, 0x4)
74
+REG32(CRC2, 0x8)
75
+REG32(CRC3, 0xc)
76
+REG32(FAR0, 0x10)
77
+ FIELD(FAR0, SEGMENT, 23, 2)
78
+ FIELD(FAR0, BLOCKTYPE, 20, 3)
79
+ FIELD(FAR0, FRAME_ADDR, 0, 20)
80
+REG32(FAR1, 0x14)
81
+REG32(FAR2, 0x18)
82
+REG32(FAR3, 0x1c)
83
+REG32(FAR_SFR0, 0x20)
84
+ FIELD(FAR_SFR0, BLOCKTYPE, 20, 3)
85
+ FIELD(FAR_SFR0, FRAME_ADDR, 0, 20)
86
+REG32(FAR_SFR1, 0x24)
87
+REG32(FAR_SFR2, 0x28)
88
+REG32(FAR_SFR3, 0x2c)
89
+REG32(FDRI0, 0x40)
90
+REG32(FDRI1, 0x44)
91
+REG32(FDRI2, 0x48)
92
+REG32(FDRI3, 0x4c)
93
+REG32(FRCNT0, 0x50)
94
+ FIELD(FRCNT0, FRCNT, 0, 32)
95
+REG32(FRCNT1, 0x54)
96
+REG32(FRCNT2, 0x58)
97
+REG32(FRCNT3, 0x5c)
98
+REG32(CMD0, 0x60)
99
+ FIELD(CMD0, CMD, 0, 5)
100
+REG32(CMD1, 0x64)
101
+REG32(CMD2, 0x68)
102
+REG32(CMD3, 0x6c)
103
+REG32(CR_MASK0, 0x70)
104
+REG32(CR_MASK1, 0x74)
105
+REG32(CR_MASK2, 0x78)
106
+REG32(CR_MASK3, 0x7c)
107
+REG32(CTL0, 0x80)
108
+ FIELD(CTL, PER_FRAME_CRC, 0, 1)
109
+REG32(CTL1, 0x84)
110
+REG32(CTL2, 0x88)
111
+REG32(CTL3, 0x8c)
112
+REG32(CFRM_ISR0, 0x150)
113
+ FIELD(CFRM_ISR0, READ_BROADCAST_ERROR, 21, 1)
114
+ FIELD(CFRM_ISR0, CMD_MISSING_ERROR, 20, 1)
115
+ FIELD(CFRM_ISR0, RW_ROWOFF_ERROR, 19, 1)
116
+ FIELD(CFRM_ISR0, READ_REG_ADDR_ERROR, 18, 1)
117
+ FIELD(CFRM_ISR0, READ_BLK_TYPE_ERROR, 17, 1)
118
+ FIELD(CFRM_ISR0, READ_FRAME_ADDR_ERROR, 16, 1)
119
+ FIELD(CFRM_ISR0, WRITE_REG_ADDR_ERROR, 15, 1)
120
+ FIELD(CFRM_ISR0, WRITE_BLK_TYPE_ERROR, 13, 1)
121
+ FIELD(CFRM_ISR0, WRITE_FRAME_ADDR_ERROR, 12, 1)
122
+ FIELD(CFRM_ISR0, MFW_OVERRUN_ERROR, 11, 1)
123
+ FIELD(CFRM_ISR0, FAR_FIFO_UNDERFLOW, 10, 1)
124
+ FIELD(CFRM_ISR0, FAR_FIFO_OVERFLOW, 9, 1)
125
+ FIELD(CFRM_ISR0, PER_FRAME_SEQ_ERROR, 8, 1)
126
+ FIELD(CFRM_ISR0, CRC_ERROR, 7, 1)
127
+ FIELD(CFRM_ISR0, WRITE_OVERRUN_ERROR, 6, 1)
128
+ FIELD(CFRM_ISR0, READ_OVERRUN_ERROR, 5, 1)
129
+ FIELD(CFRM_ISR0, CMD_INTERRUPT_ERROR, 4, 1)
130
+ FIELD(CFRM_ISR0, WRITE_INTERRUPT_ERROR, 3, 1)
131
+ FIELD(CFRM_ISR0, READ_INTERRUPT_ERROR, 2, 1)
132
+ FIELD(CFRM_ISR0, SEU_CRC_ERROR, 1, 1)
133
+ FIELD(CFRM_ISR0, SEU_ECC_ERROR, 0, 1)
134
+REG32(CFRM_ISR1, 0x154)
135
+REG32(CFRM_ISR2, 0x158)
136
+REG32(CFRM_ISR3, 0x15c)
137
+REG32(CFRM_IMR0, 0x160)
138
+ FIELD(CFRM_IMR0, READ_BROADCAST_ERROR, 21, 1)
139
+ FIELD(CFRM_IMR0, CMD_MISSING_ERROR, 20, 1)
140
+ FIELD(CFRM_IMR0, RW_ROWOFF_ERROR, 19, 1)
141
+ FIELD(CFRM_IMR0, READ_REG_ADDR_ERROR, 18, 1)
142
+ FIELD(CFRM_IMR0, READ_BLK_TYPE_ERROR, 17, 1)
143
+ FIELD(CFRM_IMR0, READ_FRAME_ADDR_ERROR, 16, 1)
144
+ FIELD(CFRM_IMR0, WRITE_REG_ADDR_ERROR, 15, 1)
145
+ FIELD(CFRM_IMR0, WRITE_BLK_TYPE_ERROR, 13, 1)
146
+ FIELD(CFRM_IMR0, WRITE_FRAME_ADDR_ERROR, 12, 1)
147
+ FIELD(CFRM_IMR0, MFW_OVERRUN_ERROR, 11, 1)
148
+ FIELD(CFRM_IMR0, FAR_FIFO_UNDERFLOW, 10, 1)
149
+ FIELD(CFRM_IMR0, FAR_FIFO_OVERFLOW, 9, 1)
150
+ FIELD(CFRM_IMR0, PER_FRAME_SEQ_ERROR, 8, 1)
151
+ FIELD(CFRM_IMR0, CRC_ERROR, 7, 1)
152
+ FIELD(CFRM_IMR0, WRITE_OVERRUN_ERROR, 6, 1)
153
+ FIELD(CFRM_IMR0, READ_OVERRUN_ERROR, 5, 1)
154
+ FIELD(CFRM_IMR0, CMD_INTERRUPT_ERROR, 4, 1)
155
+ FIELD(CFRM_IMR0, WRITE_INTERRUPT_ERROR, 3, 1)
156
+ FIELD(CFRM_IMR0, READ_INTERRUPT_ERROR, 2, 1)
157
+ FIELD(CFRM_IMR0, SEU_CRC_ERROR, 1, 1)
158
+ FIELD(CFRM_IMR0, SEU_ECC_ERROR, 0, 1)
159
+REG32(CFRM_IMR1, 0x164)
160
+REG32(CFRM_IMR2, 0x168)
161
+REG32(CFRM_IMR3, 0x16c)
162
+REG32(CFRM_IER0, 0x170)
163
+ FIELD(CFRM_IER0, READ_BROADCAST_ERROR, 21, 1)
164
+ FIELD(CFRM_IER0, CMD_MISSING_ERROR, 20, 1)
165
+ FIELD(CFRM_IER0, RW_ROWOFF_ERROR, 19, 1)
166
+ FIELD(CFRM_IER0, READ_REG_ADDR_ERROR, 18, 1)
167
+ FIELD(CFRM_IER0, READ_BLK_TYPE_ERROR, 17, 1)
168
+ FIELD(CFRM_IER0, READ_FRAME_ADDR_ERROR, 16, 1)
169
+ FIELD(CFRM_IER0, WRITE_REG_ADDR_ERROR, 15, 1)
170
+ FIELD(CFRM_IER0, WRITE_BLK_TYPE_ERROR, 13, 1)
171
+ FIELD(CFRM_IER0, WRITE_FRAME_ADDR_ERROR, 12, 1)
172
+ FIELD(CFRM_IER0, MFW_OVERRUN_ERROR, 11, 1)
173
+ FIELD(CFRM_IER0, FAR_FIFO_UNDERFLOW, 10, 1)
174
+ FIELD(CFRM_IER0, FAR_FIFO_OVERFLOW, 9, 1)
175
+ FIELD(CFRM_IER0, PER_FRAME_SEQ_ERROR, 8, 1)
176
+ FIELD(CFRM_IER0, CRC_ERROR, 7, 1)
177
+ FIELD(CFRM_IER0, WRITE_OVERRUN_ERROR, 6, 1)
178
+ FIELD(CFRM_IER0, READ_OVERRUN_ERROR, 5, 1)
179
+ FIELD(CFRM_IER0, CMD_INTERRUPT_ERROR, 4, 1)
180
+ FIELD(CFRM_IER0, WRITE_INTERRUPT_ERROR, 3, 1)
181
+ FIELD(CFRM_IER0, READ_INTERRUPT_ERROR, 2, 1)
182
+ FIELD(CFRM_IER0, SEU_CRC_ERROR, 1, 1)
183
+ FIELD(CFRM_IER0, SEU_ECC_ERROR, 0, 1)
184
+REG32(CFRM_IER1, 0x174)
185
+REG32(CFRM_IER2, 0x178)
186
+REG32(CFRM_IER3, 0x17c)
187
+REG32(CFRM_IDR0, 0x180)
188
+ FIELD(CFRM_IDR0, READ_BROADCAST_ERROR, 21, 1)
189
+ FIELD(CFRM_IDR0, CMD_MISSING_ERROR, 20, 1)
190
+ FIELD(CFRM_IDR0, RW_ROWOFF_ERROR, 19, 1)
191
+ FIELD(CFRM_IDR0, READ_REG_ADDR_ERROR, 18, 1)
192
+ FIELD(CFRM_IDR0, READ_BLK_TYPE_ERROR, 17, 1)
193
+ FIELD(CFRM_IDR0, READ_FRAME_ADDR_ERROR, 16, 1)
194
+ FIELD(CFRM_IDR0, WRITE_REG_ADDR_ERROR, 15, 1)
195
+ FIELD(CFRM_IDR0, WRITE_BLK_TYPE_ERROR, 13, 1)
196
+ FIELD(CFRM_IDR0, WRITE_FRAME_ADDR_ERROR, 12, 1)
197
+ FIELD(CFRM_IDR0, MFW_OVERRUN_ERROR, 11, 1)
198
+ FIELD(CFRM_IDR0, FAR_FIFO_UNDERFLOW, 10, 1)
199
+ FIELD(CFRM_IDR0, FAR_FIFO_OVERFLOW, 9, 1)
200
+ FIELD(CFRM_IDR0, PER_FRAME_SEQ_ERROR, 8, 1)
201
+ FIELD(CFRM_IDR0, CRC_ERROR, 7, 1)
202
+ FIELD(CFRM_IDR0, WRITE_OVERRUN_ERROR, 6, 1)
203
+ FIELD(CFRM_IDR0, READ_OVERRUN_ERROR, 5, 1)
204
+ FIELD(CFRM_IDR0, CMD_INTERRUPT_ERROR, 4, 1)
205
+ FIELD(CFRM_IDR0, WRITE_INTERRUPT_ERROR, 3, 1)
206
+ FIELD(CFRM_IDR0, READ_INTERRUPT_ERROR, 2, 1)
207
+ FIELD(CFRM_IDR0, SEU_CRC_ERROR, 1, 1)
208
+ FIELD(CFRM_IDR0, SEU_ECC_ERROR, 0, 1)
209
+REG32(CFRM_IDR1, 0x184)
210
+REG32(CFRM_IDR2, 0x188)
211
+REG32(CFRM_IDR3, 0x18c)
212
+REG32(CFRM_ITR0, 0x190)
213
+ FIELD(CFRM_ITR0, READ_BROADCAST_ERROR, 21, 1)
214
+ FIELD(CFRM_ITR0, CMD_MISSING_ERROR, 20, 1)
215
+ FIELD(CFRM_ITR0, RW_ROWOFF_ERROR, 19, 1)
216
+ FIELD(CFRM_ITR0, READ_REG_ADDR_ERROR, 18, 1)
217
+ FIELD(CFRM_ITR0, READ_BLK_TYPE_ERROR, 17, 1)
218
+ FIELD(CFRM_ITR0, READ_FRAME_ADDR_ERROR, 16, 1)
219
+ FIELD(CFRM_ITR0, WRITE_REG_ADDR_ERROR, 15, 1)
220
+ FIELD(CFRM_ITR0, WRITE_BLK_TYPE_ERROR, 13, 1)
221
+ FIELD(CFRM_ITR0, WRITE_FRAME_ADDR_ERROR, 12, 1)
222
+ FIELD(CFRM_ITR0, MFW_OVERRUN_ERROR, 11, 1)
223
+ FIELD(CFRM_ITR0, FAR_FIFO_UNDERFLOW, 10, 1)
224
+ FIELD(CFRM_ITR0, FAR_FIFO_OVERFLOW, 9, 1)
225
+ FIELD(CFRM_ITR0, PER_FRAME_SEQ_ERROR, 8, 1)
226
+ FIELD(CFRM_ITR0, CRC_ERROR, 7, 1)
227
+ FIELD(CFRM_ITR0, WRITE_OVERRUN_ERROR, 6, 1)
228
+ FIELD(CFRM_ITR0, READ_OVERRUN_ERROR, 5, 1)
229
+ FIELD(CFRM_ITR0, CMD_INTERRUPT_ERROR, 4, 1)
230
+ FIELD(CFRM_ITR0, WRITE_INTERRUPT_ERROR, 3, 1)
231
+ FIELD(CFRM_ITR0, READ_INTERRUPT_ERROR, 2, 1)
232
+ FIELD(CFRM_ITR0, SEU_CRC_ERROR, 1, 1)
233
+ FIELD(CFRM_ITR0, SEU_ECC_ERROR, 0, 1)
234
+REG32(CFRM_ITR1, 0x194)
235
+REG32(CFRM_ITR2, 0x198)
236
+REG32(CFRM_ITR3, 0x19c)
237
+REG32(SEU_SYNDRM00, 0x1a0)
238
+REG32(SEU_SYNDRM01, 0x1a4)
239
+REG32(SEU_SYNDRM02, 0x1a8)
240
+REG32(SEU_SYNDRM03, 0x1ac)
241
+REG32(SEU_SYNDRM10, 0x1b0)
242
+REG32(SEU_SYNDRM11, 0x1b4)
243
+REG32(SEU_SYNDRM12, 0x1b8)
244
+REG32(SEU_SYNDRM13, 0x1bc)
245
+REG32(SEU_SYNDRM20, 0x1c0)
246
+REG32(SEU_SYNDRM21, 0x1c4)
247
+REG32(SEU_SYNDRM22, 0x1c8)
248
+REG32(SEU_SYNDRM23, 0x1cc)
249
+REG32(SEU_SYNDRM30, 0x1d0)
250
+REG32(SEU_SYNDRM31, 0x1d4)
251
+REG32(SEU_SYNDRM32, 0x1d8)
252
+REG32(SEU_SYNDRM33, 0x1dc)
253
+REG32(SEU_VIRTUAL_SYNDRM0, 0x1e0)
254
+REG32(SEU_VIRTUAL_SYNDRM1, 0x1e4)
255
+REG32(SEU_VIRTUAL_SYNDRM2, 0x1e8)
256
+REG32(SEU_VIRTUAL_SYNDRM3, 0x1ec)
257
+REG32(SEU_CRC0, 0x1f0)
258
+REG32(SEU_CRC1, 0x1f4)
259
+REG32(SEU_CRC2, 0x1f8)
260
+REG32(SEU_CRC3, 0x1fc)
261
+REG32(CFRAME_FAR_BOT0, 0x200)
262
+REG32(CFRAME_FAR_BOT1, 0x204)
263
+REG32(CFRAME_FAR_BOT2, 0x208)
264
+REG32(CFRAME_FAR_BOT3, 0x20c)
265
+REG32(CFRAME_FAR_TOP0, 0x210)
266
+REG32(CFRAME_FAR_TOP1, 0x214)
267
+REG32(CFRAME_FAR_TOP2, 0x218)
268
+REG32(CFRAME_FAR_TOP3, 0x21c)
269
+REG32(LAST_FRAME_BOT0, 0x220)
270
+ FIELD(LAST_FRAME_BOT0, BLOCKTYPE1_LAST_FRAME_LSB, 20, 12)
271
+ FIELD(LAST_FRAME_BOT0, BLOCKTYPE0_LAST_FRAME, 0, 20)
272
+REG32(LAST_FRAME_BOT1, 0x224)
273
+ FIELD(LAST_FRAME_BOT1, BLOCKTYPE3_LAST_FRAME_LSB, 28, 4)
274
+ FIELD(LAST_FRAME_BOT1, BLOCKTYPE2_LAST_FRAME, 8, 20)
275
+ FIELD(LAST_FRAME_BOT1, BLOCKTYPE1_LAST_FRAME_MSB, 0, 8)
276
+REG32(LAST_FRAME_BOT2, 0x228)
277
+ FIELD(LAST_FRAME_BOT2, BLOCKTYPE3_LAST_FRAME_MSB, 0, 16)
278
+REG32(LAST_FRAME_BOT3, 0x22c)
279
+REG32(LAST_FRAME_TOP0, 0x230)
280
+ FIELD(LAST_FRAME_TOP0, BLOCKTYPE5_LAST_FRAME_LSB, 20, 12)
281
+ FIELD(LAST_FRAME_TOP0, BLOCKTYPE4_LAST_FRAME, 0, 20)
282
+REG32(LAST_FRAME_TOP1, 0x234)
283
+ FIELD(LAST_FRAME_TOP1, BLOCKTYPE6_LAST_FRAME, 8, 20)
284
+ FIELD(LAST_FRAME_TOP1, BLOCKTYPE5_LAST_FRAME_MSB, 0, 8)
285
+REG32(LAST_FRAME_TOP2, 0x238)
286
+REG32(LAST_FRAME_TOP3, 0x23c)
287
+
288
+#define CFRAME_REG_R_MAX (R_LAST_FRAME_TOP3 + 1)
289
+
290
+#define FRAME_NUM_QWORDS 25
291
+#define FRAME_NUM_WORDS (FRAME_NUM_QWORDS * 4) /* 25 * 128 bits */
292
+
293
+typedef struct XlnxCFrame {
294
+ uint32_t data[FRAME_NUM_WORDS];
295
+} XlnxCFrame;
296
+
297
+struct XlnxVersalCFrameReg {
298
+ SysBusDevice parent_obj;
299
+ MemoryRegion iomem;
300
+ MemoryRegion iomem_fdri;
301
+ qemu_irq irq_cfrm_imr;
302
+
303
+ /* 128-bit wfifo. */
304
+ uint32_t wfifo[WFIFO_SZ];
305
+
306
+ uint32_t regs[CFRAME_REG_R_MAX];
307
+ RegisterInfo regs_info[CFRAME_REG_R_MAX];
308
+
309
+ bool rowon;
310
+ bool wcfg;
311
+ bool rcfg;
312
+
313
+ GTree *cframes;
314
+ Fifo32 new_f_data;
315
+
316
+ struct {
317
+ XlnxCfiIf *cfu_fdro;
318
+ uint32_t blktype_num_frames[7];
319
+ } cfg;
320
+ bool row_configured;
321
+};
322
+
323
+#endif
324
diff --git a/hw/misc/xlnx-versal-cframe-reg.c b/hw/misc/xlnx-versal-cframe-reg.c
325
new file mode 100644
326
index XXXXXXX..XXXXXXX
327
--- /dev/null
328
+++ b/hw/misc/xlnx-versal-cframe-reg.c
329
@@ -XXX,XX +XXX,XX @@
330
+/*
331
+ * QEMU model of the Configuration Frame Control module
332
+ *
333
+ * Copyright (C) 2023, Advanced Micro Devices, Inc.
334
+ *
335
+ * Written by Francisco Iglesias <francisco.iglesias@amd.com>
336
+ *
337
+ * SPDX-License-Identifier: GPL-2.0-or-later
338
+ */
339
+
340
+#include "qemu/osdep.h"
341
+#include "hw/sysbus.h"
342
+#include "hw/register.h"
343
+#include "hw/registerfields.h"
344
+#include "qemu/bitops.h"
345
+#include "qemu/log.h"
50
+#include "qemu/units.h"
346
+#include "qemu/units.h"
51
#include "cpu.h"
347
+#include "qapi/error.h"
52
#include "exec/gdbstub.h"
348
+#include "hw/qdev-properties.h"
53
#include "exec/helper-proto.h"
349
+#include "migration/vmstate.h"
54
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp)
350
+#include "hw/irq.h"
55
return float16_sqrt(a, s);
351
+#include "hw/misc/xlnx-versal-cframe-reg.h"
56
}
352
+
57
353
+#ifndef XLNX_VERSAL_CFRAME_REG_ERR_DEBUG
58
+void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
354
+#define XLNX_VERSAL_CFRAME_REG_ERR_DEBUG 0
355
+#endif
356
+
357
+#define KEYHOLE_STREAM_4K (4 * KiB)
358
+#define N_WORDS_128BIT 4
359
+
360
+#define MAX_BLOCKTYPE 6
361
+#define MAX_BLOCKTYPE_FRAMES 0xFFFFF
362
+
363
+enum {
364
+ CFRAME_CMD_WCFG = 1,
365
+ CFRAME_CMD_ROWON = 2,
366
+ CFRAME_CMD_ROWOFF = 3,
367
+ CFRAME_CMD_RCFG = 4,
368
+ CFRAME_CMD_DLPARK = 5,
369
+};
370
+
371
+static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
372
+{
373
+ guint ua = GPOINTER_TO_UINT(a);
374
+ guint ub = GPOINTER_TO_UINT(b);
375
+ return (ua > ub) - (ua < ub);
376
+}
377
+
378
+static void cfrm_imr_update_irq(XlnxVersalCFrameReg *s)
379
+{
380
+ bool pending = s->regs[R_CFRM_ISR0] & ~s->regs[R_CFRM_IMR0];
381
+ qemu_set_irq(s->irq_cfrm_imr, pending);
382
+}
383
+
384
+static void cfrm_isr_postw(RegisterInfo *reg, uint64_t val64)
385
+{
386
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
387
+ cfrm_imr_update_irq(s);
388
+}
389
+
390
+static uint64_t cfrm_ier_prew(RegisterInfo *reg, uint64_t val64)
391
+{
392
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
393
+
394
+ s->regs[R_CFRM_IMR0] &= ~s->regs[R_CFRM_IER0];
395
+ s->regs[R_CFRM_IER0] = 0;
396
+ cfrm_imr_update_irq(s);
397
+ return 0;
398
+}
399
+
400
+static uint64_t cfrm_idr_prew(RegisterInfo *reg, uint64_t val64)
401
+{
402
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
403
+
404
+ s->regs[R_CFRM_IMR0] |= s->regs[R_CFRM_IDR0];
405
+ s->regs[R_CFRM_IDR0] = 0;
406
+ cfrm_imr_update_irq(s);
407
+ return 0;
408
+}
409
+
410
+static uint64_t cfrm_itr_prew(RegisterInfo *reg, uint64_t val64)
411
+{
412
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
413
+
414
+ s->regs[R_CFRM_ISR0] |= s->regs[R_CFRM_ITR0];
415
+ s->regs[R_CFRM_ITR0] = 0;
416
+ cfrm_imr_update_irq(s);
417
+ return 0;
418
+}
419
+
420
+static void cframe_incr_far(XlnxVersalCFrameReg *s)
421
+{
422
+ uint32_t faddr = ARRAY_FIELD_EX32(s->regs, FAR0, FRAME_ADDR);
423
+ uint32_t blktype = ARRAY_FIELD_EX32(s->regs, FAR0, BLOCKTYPE);
424
+
425
+ assert(blktype <= MAX_BLOCKTYPE);
426
+
427
+ faddr++;
428
+ if (faddr > s->cfg.blktype_num_frames[blktype]) {
429
+ /* Restart from 0 and increment block type */
430
+ faddr = 0;
431
+ blktype++;
432
+
433
+ assert(blktype <= MAX_BLOCKTYPE);
434
+
435
+ ARRAY_FIELD_DP32(s->regs, FAR0, BLOCKTYPE, blktype);
436
+ }
437
+
438
+ ARRAY_FIELD_DP32(s->regs, FAR0, FRAME_ADDR, faddr);
439
+}
440
+
441
+static void cfrm_fdri_post_write(RegisterInfo *reg, uint64_t val)
442
+{
443
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
444
+
445
+ if (s->row_configured && s->rowon && s->wcfg) {
446
+
447
+ if (fifo32_num_free(&s->new_f_data) >= N_WORDS_128BIT) {
448
+ fifo32_push(&s->new_f_data, s->regs[R_FDRI0]);
449
+ fifo32_push(&s->new_f_data, s->regs[R_FDRI1]);
450
+ fifo32_push(&s->new_f_data, s->regs[R_FDRI2]);
451
+ fifo32_push(&s->new_f_data, s->regs[R_FDRI3]);
452
+ }
453
+
454
+ if (fifo32_is_full(&s->new_f_data)) {
455
+ uint32_t addr = extract32(s->regs[R_FAR0], 0, 23);
456
+ XlnxCFrame *f = g_new(XlnxCFrame, 1);
457
+
458
+ for (int i = 0; i < FRAME_NUM_WORDS; i++) {
459
+ f->data[i] = fifo32_pop(&s->new_f_data);
460
+ }
461
+
462
+ g_tree_replace(s->cframes, GUINT_TO_POINTER(addr), f);
463
+
464
+ cframe_incr_far(s);
465
+
466
+ fifo32_reset(&s->new_f_data);
467
+ }
468
+ }
469
+}
470
+
471
+static void cfrm_readout_frames(XlnxVersalCFrameReg *s, uint32_t start_addr,
472
+ uint32_t end_addr)
59
+{
473
+{
60
+ /*
474
+ /*
61
+ * Implement DC ZVA, which zeroes a fixed-length block of memory.
475
+ * NB: when our minimum glib version is at least 2.68 we can improve the
62
+ * Note that we do not implement the (architecturally mandated)
476
+ * performance of the cframe traversal by using g_tree_lookup_node and
63
+ * alignment fault for attempts to use this on Device memory
477
+ * g_tree_node_next (instead of calling g_tree_lookup for finding each
64
+ * (which matches the usual QEMU behaviour of not implementing either
478
+ * cframe).
65
+ * alignment faults or any memory attribute handling).
66
+ */
479
+ */
67
480
+ for (uint32_t addr = start_addr; addr < end_addr; addr++) {
68
+ ARMCPU *cpu = env_archcpu(env);
481
+ XlnxCFrame *f = g_tree_lookup(s->cframes, GUINT_TO_POINTER(addr));
69
+ uint64_t blocklen = 4 << cpu->dcz_blocksize;
482
+
70
+ uint64_t vaddr = vaddr_in & ~(blocklen - 1);
483
+ /* Transmit the data if a frame was found */
71
+
484
+ if (f) {
72
+#ifndef CONFIG_USER_ONLY
485
+ for (int i = 0; i < FRAME_NUM_WORDS; i += 4) {
73
+ {
486
+ XlnxCfiPacket pkt = {};
74
+ /*
487
+
75
+ * Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than
488
+ pkt.data[0] = f->data[i];
76
+ * the block size so we might have to do more than one TLB lookup.
489
+ pkt.data[1] = f->data[i + 1];
77
+ * We know that in fact for any v8 CPU the page size is at least 4K
490
+ pkt.data[2] = f->data[i + 2];
78
+ * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only
491
+ pkt.data[3] = f->data[i + 3];
79
+ * 1K as an artefact of legacy v5 subpage support being present in the
492
+
80
+ * same QEMU executable. So in practice the hostaddr[] array has
493
+ if (s->cfg.cfu_fdro) {
81
+ * two entries, given the current setting of TARGET_PAGE_BITS_MIN.
494
+ xlnx_cfi_transfer_packet(s->cfg.cfu_fdro, &pkt);
82
+ */
83
+ int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE);
84
+ void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)];
85
+ int try, i;
86
+ unsigned mmu_idx = cpu_mmu_index(env, false);
87
+ TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
88
+
89
+ assert(maxidx <= ARRAY_SIZE(hostaddr));
90
+
91
+ for (try = 0; try < 2; try++) {
92
+
93
+ for (i = 0; i < maxidx; i++) {
94
+ hostaddr[i] = tlb_vaddr_to_host(env,
95
+ vaddr + TARGET_PAGE_SIZE * i,
96
+ 1, mmu_idx);
97
+ if (!hostaddr[i]) {
98
+ break;
99
+ }
100
+ }
101
+ if (i == maxidx) {
102
+ /*
103
+ * If it's all in the TLB it's fair game for just writing to;
104
+ * we know we don't need to update dirty status, etc.
105
+ */
106
+ for (i = 0; i < maxidx - 1; i++) {
107
+ memset(hostaddr[i], 0, TARGET_PAGE_SIZE);
108
+ }
109
+ memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE));
110
+ return;
111
+ }
112
+ /*
113
+ * OK, try a store and see if we can populate the tlb. This
114
+ * might cause an exception if the memory isn't writable,
115
+ * in which case we will longjmp out of here. We must for
116
+ * this purpose use the actual register value passed to us
117
+ * so that we get the fault address right.
118
+ */
119
+ helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC());
120
+ /* Now we can populate the other TLB entries, if any */
121
+ for (i = 0; i < maxidx; i++) {
122
+ uint64_t va = vaddr + TARGET_PAGE_SIZE * i;
123
+ if (va != (vaddr_in & TARGET_PAGE_MASK)) {
124
+ helper_ret_stb_mmu(env, va, 0, oi, GETPC());
125
+ }
495
+ }
126
+ }
496
+ }
127
+ }
497
+ }
128
+
498
+ }
499
+}
500
+
501
+static void cfrm_frcnt_post_write(RegisterInfo *reg, uint64_t val)
502
+{
503
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
504
+
505
+ if (s->row_configured && s->rowon && s->rcfg) {
506
+ uint32_t start_addr = extract32(s->regs[R_FAR0], 0, 23);
507
+ uint32_t end_addr = start_addr + s->regs[R_FRCNT0] / FRAME_NUM_QWORDS;
508
+
509
+ cfrm_readout_frames(s, start_addr, end_addr);
510
+ }
511
+}
512
+
513
+static void cfrm_cmd_post_write(RegisterInfo *reg, uint64_t val)
514
+{
515
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
516
+
517
+ if (s->row_configured) {
518
+ uint8_t cmd = ARRAY_FIELD_EX32(s->regs, CMD0, CMD);
519
+
520
+ switch (cmd) {
521
+ case CFRAME_CMD_WCFG:
522
+ s->wcfg = true;
523
+ break;
524
+ case CFRAME_CMD_ROWON:
525
+ s->rowon = true;
526
+ break;
527
+ case CFRAME_CMD_ROWOFF:
528
+ s->rowon = false;
529
+ break;
530
+ case CFRAME_CMD_RCFG:
531
+ s->rcfg = true;
532
+ break;
533
+ case CFRAME_CMD_DLPARK:
534
+ s->wcfg = false;
535
+ s->rcfg = false;
536
+ break;
537
+ default:
538
+ break;
539
+ };
540
+ }
541
+}
542
+
543
+static uint64_t cfrm_last_frame_bot_post_read(RegisterInfo *reg,
544
+ uint64_t val64)
545
+{
546
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
547
+ uint64_t val = 0;
548
+
549
+ switch (reg->access->addr) {
550
+ case A_LAST_FRAME_BOT0:
551
+ val = FIELD_DP32(val, LAST_FRAME_BOT0, BLOCKTYPE1_LAST_FRAME_LSB,
552
+ s->cfg.blktype_num_frames[1]);
553
+ val = FIELD_DP32(val, LAST_FRAME_BOT0, BLOCKTYPE0_LAST_FRAME,
554
+ s->cfg.blktype_num_frames[0]);
555
+ break;
556
+ case A_LAST_FRAME_BOT1:
557
+ val = FIELD_DP32(val, LAST_FRAME_BOT1, BLOCKTYPE3_LAST_FRAME_LSB,
558
+ s->cfg.blktype_num_frames[3]);
559
+ val = FIELD_DP32(val, LAST_FRAME_BOT1, BLOCKTYPE2_LAST_FRAME,
560
+ s->cfg.blktype_num_frames[2]);
561
+ val = FIELD_DP32(val, LAST_FRAME_BOT1, BLOCKTYPE1_LAST_FRAME_MSB,
562
+ (s->cfg.blktype_num_frames[1] >> 12));
563
+ break;
564
+ case A_LAST_FRAME_BOT2:
565
+ val = FIELD_DP32(val, LAST_FRAME_BOT2, BLOCKTYPE3_LAST_FRAME_MSB,
566
+ (s->cfg.blktype_num_frames[3] >> 4));
567
+ break;
568
+ case A_LAST_FRAME_BOT3:
569
+ default:
570
+ break;
571
+ }
572
+
573
+ return val;
574
+}
575
+
576
+static uint64_t cfrm_last_frame_top_post_read(RegisterInfo *reg,
577
+ uint64_t val64)
578
+{
579
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
580
+ uint64_t val = 0;
581
+
582
+ switch (reg->access->addr) {
583
+ case A_LAST_FRAME_TOP0:
584
+ val = FIELD_DP32(val, LAST_FRAME_TOP0, BLOCKTYPE5_LAST_FRAME_LSB,
585
+ s->cfg.blktype_num_frames[5]);
586
+ val = FIELD_DP32(val, LAST_FRAME_TOP0, BLOCKTYPE4_LAST_FRAME,
587
+ s->cfg.blktype_num_frames[4]);
588
+ break;
589
+ case A_LAST_FRAME_TOP1:
590
+ val = FIELD_DP32(val, LAST_FRAME_TOP1, BLOCKTYPE6_LAST_FRAME,
591
+ s->cfg.blktype_num_frames[6]);
592
+ val = FIELD_DP32(val, LAST_FRAME_TOP1, BLOCKTYPE5_LAST_FRAME_MSB,
593
+ (s->cfg.blktype_num_frames[5] >> 12));
594
+ break;
595
+ case A_LAST_FRAME_TOP2:
596
+ case A_LAST_FRAME_BOT3:
597
+ default:
598
+ break;
599
+ }
600
+
601
+ return val;
602
+}
603
+
604
+static void cfrm_far_sfr_post_write(RegisterInfo *reg, uint64_t val)
605
+{
606
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(reg->opaque);
607
+
608
+ if (s->row_configured && s->rowon && s->rcfg) {
609
+ uint32_t start_addr = extract32(s->regs[R_FAR_SFR0], 0, 23);
610
+
611
+ /* Readback 1 frame */
612
+ cfrm_readout_frames(s, start_addr, start_addr + 1);
613
+ }
614
+}
615
+
616
+static const RegisterAccessInfo cframe_reg_regs_info[] = {
617
+ { .name = "CRC0", .addr = A_CRC0,
618
+ .rsvd = 0x00000000,
619
+ },{ .name = "CRC1", .addr = A_CRC0,
620
+ .rsvd = 0xffffffff,
621
+ },{ .name = "CRC2", .addr = A_CRC0,
622
+ .rsvd = 0xffffffff,
623
+ },{ .name = "CRC3", .addr = A_CRC0,
624
+ .rsvd = 0xffffffff,
625
+ },{ .name = "FAR0", .addr = A_FAR0,
626
+ .rsvd = 0xfe000000,
627
+ },{ .name = "FAR1", .addr = A_FAR1,
628
+ .rsvd = 0xffffffff,
629
+ },{ .name = "FAR2", .addr = A_FAR2,
630
+ .rsvd = 0xffffffff,
631
+ },{ .name = "FAR3", .addr = A_FAR3,
632
+ .rsvd = 0xffffffff,
633
+ },{ .name = "FAR_SFR0", .addr = A_FAR_SFR0,
634
+ .rsvd = 0xff800000,
635
+ },{ .name = "FAR_SFR1", .addr = A_FAR_SFR1,
636
+ .rsvd = 0xffffffff,
637
+ },{ .name = "FAR_SFR2", .addr = A_FAR_SFR2,
638
+ .rsvd = 0xffffffff,
639
+ },{ .name = "FAR_SFR3", .addr = A_FAR_SFR3,
640
+ .rsvd = 0xffffffff,
641
+ .post_write = cfrm_far_sfr_post_write,
642
+ },{ .name = "FDRI0", .addr = A_FDRI0,
643
+ },{ .name = "FDRI1", .addr = A_FDRI1,
644
+ },{ .name = "FDRI2", .addr = A_FDRI2,
645
+ },{ .name = "FDRI3", .addr = A_FDRI3,
646
+ .post_write = cfrm_fdri_post_write,
647
+ },{ .name = "FRCNT0", .addr = A_FRCNT0,
648
+ .rsvd = 0x00000000,
649
+ },{ .name = "FRCNT1", .addr = A_FRCNT1,
650
+ .rsvd = 0xffffffff,
651
+ },{ .name = "FRCNT2", .addr = A_FRCNT2,
652
+ .rsvd = 0xffffffff,
653
+ },{ .name = "FRCNT3", .addr = A_FRCNT3,
654
+ .rsvd = 0xffffffff,
655
+ .post_write = cfrm_frcnt_post_write
656
+ },{ .name = "CMD0", .addr = A_CMD0,
657
+ .rsvd = 0xffffffe0,
658
+ },{ .name = "CMD1", .addr = A_CMD1,
659
+ .rsvd = 0xffffffff,
660
+ },{ .name = "CMD2", .addr = A_CMD2,
661
+ .rsvd = 0xffffffff,
662
+ },{ .name = "CMD3", .addr = A_CMD3,
663
+ .rsvd = 0xffffffff,
664
+ .post_write = cfrm_cmd_post_write
665
+ },{ .name = "CR_MASK0", .addr = A_CR_MASK0,
666
+ .rsvd = 0x00000000,
667
+ },{ .name = "CR_MASK1", .addr = A_CR_MASK1,
668
+ .rsvd = 0x00000000,
669
+ },{ .name = "CR_MASK2", .addr = A_CR_MASK2,
670
+ .rsvd = 0x00000000,
671
+ },{ .name = "CR_MASK3", .addr = A_CR_MASK3,
672
+ .rsvd = 0xffffffff,
673
+ },{ .name = "CTL0", .addr = A_CTL0,
674
+ .rsvd = 0xfffffff8,
675
+ },{ .name = "CTL1", .addr = A_CTL1,
676
+ .rsvd = 0xffffffff,
677
+ },{ .name = "CTL2", .addr = A_CTL2,
678
+ .rsvd = 0xffffffff,
679
+ },{ .name = "CTL3", .addr = A_CTL3,
680
+ .rsvd = 0xffffffff,
681
+ },{ .name = "CFRM_ISR0", .addr = A_CFRM_ISR0,
682
+ .rsvd = 0xffc04000,
683
+ .w1c = 0x3bfff,
684
+ },{ .name = "CFRM_ISR1", .addr = A_CFRM_ISR1,
685
+ .rsvd = 0xffffffff,
686
+ },{ .name = "CFRM_ISR2", .addr = A_CFRM_ISR2,
687
+ .rsvd = 0xffffffff,
688
+ },{ .name = "CFRM_ISR3", .addr = A_CFRM_ISR3,
689
+ .rsvd = 0xffffffff,
690
+ .post_write = cfrm_isr_postw,
691
+ },{ .name = "CFRM_IMR0", .addr = A_CFRM_IMR0,
692
+ .rsvd = 0xffc04000,
693
+ .ro = 0xfffff,
694
+ .reset = 0x3bfff,
695
+ },{ .name = "CFRM_IMR1", .addr = A_CFRM_IMR1,
696
+ .rsvd = 0xffffffff,
697
+ },{ .name = "CFRM_IMR2", .addr = A_CFRM_IMR2,
698
+ .rsvd = 0xffffffff,
699
+ },{ .name = "CFRM_IMR3", .addr = A_CFRM_IMR3,
700
+ .rsvd = 0xffffffff,
701
+ },{ .name = "CFRM_IER0", .addr = A_CFRM_IER0,
702
+ .rsvd = 0xffc04000,
703
+ },{ .name = "CFRM_IER1", .addr = A_CFRM_IER1,
704
+ .rsvd = 0xffffffff,
705
+ },{ .name = "CFRM_IER2", .addr = A_CFRM_IER2,
706
+ .rsvd = 0xffffffff,
707
+ },{ .name = "CFRM_IER3", .addr = A_CFRM_IER3,
708
+ .rsvd = 0xffffffff,
709
+ .pre_write = cfrm_ier_prew,
710
+ },{ .name = "CFRM_IDR0", .addr = A_CFRM_IDR0,
711
+ .rsvd = 0xffc04000,
712
+ },{ .name = "CFRM_IDR1", .addr = A_CFRM_IDR1,
713
+ .rsvd = 0xffffffff,
714
+ },{ .name = "CFRM_IDR2", .addr = A_CFRM_IDR2,
715
+ .rsvd = 0xffffffff,
716
+ },{ .name = "CFRM_IDR3", .addr = A_CFRM_IDR3,
717
+ .rsvd = 0xffffffff,
718
+ .pre_write = cfrm_idr_prew,
719
+ },{ .name = "CFRM_ITR0", .addr = A_CFRM_ITR0,
720
+ .rsvd = 0xffc04000,
721
+ },{ .name = "CFRM_ITR1", .addr = A_CFRM_ITR1,
722
+ .rsvd = 0xffffffff,
723
+ },{ .name = "CFRM_ITR2", .addr = A_CFRM_ITR2,
724
+ .rsvd = 0xffffffff,
725
+ },{ .name = "CFRM_ITR3", .addr = A_CFRM_ITR3,
726
+ .rsvd = 0xffffffff,
727
+ .pre_write = cfrm_itr_prew,
728
+ },{ .name = "SEU_SYNDRM00", .addr = A_SEU_SYNDRM00,
729
+ },{ .name = "SEU_SYNDRM01", .addr = A_SEU_SYNDRM01,
730
+ },{ .name = "SEU_SYNDRM02", .addr = A_SEU_SYNDRM02,
731
+ },{ .name = "SEU_SYNDRM03", .addr = A_SEU_SYNDRM03,
732
+ },{ .name = "SEU_SYNDRM10", .addr = A_SEU_SYNDRM10,
733
+ },{ .name = "SEU_SYNDRM11", .addr = A_SEU_SYNDRM11,
734
+ },{ .name = "SEU_SYNDRM12", .addr = A_SEU_SYNDRM12,
735
+ },{ .name = "SEU_SYNDRM13", .addr = A_SEU_SYNDRM13,
736
+ },{ .name = "SEU_SYNDRM20", .addr = A_SEU_SYNDRM20,
737
+ },{ .name = "SEU_SYNDRM21", .addr = A_SEU_SYNDRM21,
738
+ },{ .name = "SEU_SYNDRM22", .addr = A_SEU_SYNDRM22,
739
+ },{ .name = "SEU_SYNDRM23", .addr = A_SEU_SYNDRM23,
740
+ },{ .name = "SEU_SYNDRM30", .addr = A_SEU_SYNDRM30,
741
+ },{ .name = "SEU_SYNDRM31", .addr = A_SEU_SYNDRM31,
742
+ },{ .name = "SEU_SYNDRM32", .addr = A_SEU_SYNDRM32,
743
+ },{ .name = "SEU_SYNDRM33", .addr = A_SEU_SYNDRM33,
744
+ },{ .name = "SEU_VIRTUAL_SYNDRM0", .addr = A_SEU_VIRTUAL_SYNDRM0,
745
+ },{ .name = "SEU_VIRTUAL_SYNDRM1", .addr = A_SEU_VIRTUAL_SYNDRM1,
746
+ },{ .name = "SEU_VIRTUAL_SYNDRM2", .addr = A_SEU_VIRTUAL_SYNDRM2,
747
+ },{ .name = "SEU_VIRTUAL_SYNDRM3", .addr = A_SEU_VIRTUAL_SYNDRM3,
748
+ },{ .name = "SEU_CRC0", .addr = A_SEU_CRC0,
749
+ },{ .name = "SEU_CRC1", .addr = A_SEU_CRC1,
750
+ },{ .name = "SEU_CRC2", .addr = A_SEU_CRC2,
751
+ },{ .name = "SEU_CRC3", .addr = A_SEU_CRC3,
752
+ },{ .name = "CFRAME_FAR_BOT0", .addr = A_CFRAME_FAR_BOT0,
753
+ },{ .name = "CFRAME_FAR_BOT1", .addr = A_CFRAME_FAR_BOT1,
754
+ },{ .name = "CFRAME_FAR_BOT2", .addr = A_CFRAME_FAR_BOT2,
755
+ },{ .name = "CFRAME_FAR_BOT3", .addr = A_CFRAME_FAR_BOT3,
756
+ },{ .name = "CFRAME_FAR_TOP0", .addr = A_CFRAME_FAR_TOP0,
757
+ },{ .name = "CFRAME_FAR_TOP1", .addr = A_CFRAME_FAR_TOP1,
758
+ },{ .name = "CFRAME_FAR_TOP2", .addr = A_CFRAME_FAR_TOP2,
759
+ },{ .name = "CFRAME_FAR_TOP3", .addr = A_CFRAME_FAR_TOP3,
760
+ },{ .name = "LAST_FRAME_BOT0", .addr = A_LAST_FRAME_BOT0,
761
+ .ro = 0xffffffff,
762
+ .post_read = cfrm_last_frame_bot_post_read,
763
+ },{ .name = "LAST_FRAME_BOT1", .addr = A_LAST_FRAME_BOT1,
764
+ .ro = 0xffffffff,
765
+ .post_read = cfrm_last_frame_bot_post_read,
766
+ },{ .name = "LAST_FRAME_BOT2", .addr = A_LAST_FRAME_BOT2,
767
+ .ro = 0xffffffff,
768
+ .post_read = cfrm_last_frame_bot_post_read,
769
+ },{ .name = "LAST_FRAME_BOT3", .addr = A_LAST_FRAME_BOT3,
770
+ .ro = 0xffffffff,
771
+ .post_read = cfrm_last_frame_bot_post_read,
772
+ },{ .name = "LAST_FRAME_TOP0", .addr = A_LAST_FRAME_TOP0,
773
+ .ro = 0xffffffff,
774
+ .post_read = cfrm_last_frame_top_post_read,
775
+ },{ .name = "LAST_FRAME_TOP1", .addr = A_LAST_FRAME_TOP1,
776
+ .ro = 0xffffffff,
777
+ .post_read = cfrm_last_frame_top_post_read,
778
+ },{ .name = "LAST_FRAME_TOP2", .addr = A_LAST_FRAME_TOP2,
779
+ .ro = 0xffffffff,
780
+ .post_read = cfrm_last_frame_top_post_read,
781
+ },{ .name = "LAST_FRAME_TOP3", .addr = A_LAST_FRAME_TOP3,
782
+ .ro = 0xffffffff,
783
+ .post_read = cfrm_last_frame_top_post_read,
784
+ }
785
+};
786
+
787
+static void cframe_reg_cfi_transfer_packet(XlnxCfiIf *cfi_if,
788
+ XlnxCfiPacket *pkt)
789
+{
790
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(cfi_if);
791
+ uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
792
+
793
+ if (!s->row_configured) {
794
+ return;
795
+ }
796
+
797
+ switch (pkt->reg_addr) {
798
+ case CFRAME_FAR:
799
+ s->regs[R_FAR0] = pkt->data[0];
800
+ break;
801
+ case CFRAME_SFR:
802
+ s->regs[R_FAR_SFR0] = pkt->data[0];
803
+ register_write(&s->regs_info[R_FAR_SFR3], 0,
804
+ we, object_get_typename(OBJECT(s)),
805
+ XLNX_VERSAL_CFRAME_REG_ERR_DEBUG);
806
+ break;
807
+ case CFRAME_FDRI:
808
+ s->regs[R_FDRI0] = pkt->data[0];
809
+ s->regs[R_FDRI1] = pkt->data[1];
810
+ s->regs[R_FDRI2] = pkt->data[2];
811
+ register_write(&s->regs_info[R_FDRI3], pkt->data[3],
812
+ we, object_get_typename(OBJECT(s)),
813
+ XLNX_VERSAL_CFRAME_REG_ERR_DEBUG);
814
+ break;
815
+ case CFRAME_CMD:
816
+ ARRAY_FIELD_DP32(s->regs, CMD0, CMD, pkt->data[0]);
817
+
818
+ register_write(&s->regs_info[R_CMD3], 0,
819
+ we, object_get_typename(OBJECT(s)),
820
+ XLNX_VERSAL_CFRAME_REG_ERR_DEBUG);
821
+ break;
822
+ default:
823
+ break;
824
+ }
825
+}
826
+
827
+static uint64_t cframe_reg_fdri_read(void *opaque, hwaddr addr, unsigned size)
828
+{
829
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
830
+ HWADDR_PRIx "\n", __func__, addr);
831
+ return 0;
832
+}
833
+
834
+static void cframe_reg_fdri_write(void *opaque, hwaddr addr, uint64_t value,
835
+ unsigned size)
836
+{
837
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(opaque);
838
+ uint32_t wfifo[WFIFO_SZ];
839
+
840
+ if (update_wfifo(addr, value, s->wfifo, wfifo)) {
841
+ uint64_t we = MAKE_64BIT_MASK(0, 4 * 8);
842
+
843
+ s->regs[R_FDRI0] = wfifo[0];
844
+ s->regs[R_FDRI1] = wfifo[1];
845
+ s->regs[R_FDRI2] = wfifo[2];
846
+ register_write(&s->regs_info[R_FDRI3], wfifo[3],
847
+ we, object_get_typename(OBJECT(s)),
848
+ XLNX_VERSAL_CFRAME_REG_ERR_DEBUG);
849
+ }
850
+}
851
+
852
+static void cframe_reg_reset_enter(Object *obj, ResetType type)
853
+{
854
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(obj);
855
+ unsigned int i;
856
+
857
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
858
+ register_reset(&s->regs_info[i]);
859
+ }
860
+ memset(s->wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
861
+ fifo32_reset(&s->new_f_data);
862
+
863
+ if (g_tree_nnodes(s->cframes)) {
129
+ /*
864
+ /*
130
+ * Slow path (probably attempt to do this to an I/O device or
865
+ * Take a reference so when g_tree_destroy() unrefs it we keep the
131
+ * similar, or clearing of a block of code we have translations
866
+ * GTree and only destroy its contents. NB: when our minimum
132
+ * cached for). Just do a series of byte writes as the architecture
867
+ * glib version is at least 2.70 we could use g_tree_remove_all().
133
+ * demands. It's not worth trying to use a cpu_physical_memory_map(),
134
+ * memset(), unmap() sequence here because:
135
+ * + we'd need to account for the blocksize being larger than a page
136
+ * + the direct-RAM access case is almost always going to be dealt
137
+ * with in the fastpath code above, so there's no speed benefit
138
+ * + we would have to deal with the map returning NULL because the
139
+ * bounce buffer was in use
140
+ */
868
+ */
141
+ for (i = 0; i < blocklen; i++) {
869
+ g_tree_ref(s->cframes);
142
+ helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETPC());
870
+ g_tree_destroy(s->cframes);
871
+ }
872
+}
873
+
874
+static void cframe_reg_reset_hold(Object *obj)
875
+{
876
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(obj);
877
+
878
+ cfrm_imr_update_irq(s);
879
+}
880
+
881
+static const MemoryRegionOps cframe_reg_ops = {
882
+ .read = register_read_memory,
883
+ .write = register_write_memory,
884
+ .endianness = DEVICE_LITTLE_ENDIAN,
885
+ .valid = {
886
+ .min_access_size = 4,
887
+ .max_access_size = 4,
888
+ },
889
+};
890
+
891
+static const MemoryRegionOps cframe_reg_fdri_ops = {
892
+ .read = cframe_reg_fdri_read,
893
+ .write = cframe_reg_fdri_write,
894
+ .endianness = DEVICE_LITTLE_ENDIAN,
895
+ .valid = {
896
+ .min_access_size = 4,
897
+ .max_access_size = 4,
898
+ },
899
+};
900
+
901
+static void cframe_reg_realize(DeviceState *dev, Error **errp)
902
+{
903
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(dev);
904
+
905
+ for (int i = 0; i < ARRAY_SIZE(s->cfg.blktype_num_frames); i++) {
906
+ if (s->cfg.blktype_num_frames[i] > MAX_BLOCKTYPE_FRAMES) {
907
+ error_setg(errp,
908
+ "blktype-frames%d > 0xFFFFF (max frame per block)",
909
+ i);
910
+ return;
143
+ }
911
+ }
144
+ }
912
+ if (s->cfg.blktype_num_frames[i]) {
145
+#else
913
+ s->row_configured = true;
146
+ memset(g2h(vaddr), 0, blocklen);
914
+ }
147
+#endif
915
+ }
148
+}
916
+}
149
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
917
+
918
+static void cframe_reg_init(Object *obj)
919
+{
920
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(obj);
921
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
922
+ RegisterInfoArray *reg_array;
923
+
924
+ memory_region_init(&s->iomem, obj, TYPE_XLNX_VERSAL_CFRAME_REG,
925
+ CFRAME_REG_R_MAX * 4);
926
+ reg_array =
927
+ register_init_block32(DEVICE(obj), cframe_reg_regs_info,
928
+ ARRAY_SIZE(cframe_reg_regs_info),
929
+ s->regs_info, s->regs,
930
+ &cframe_reg_ops,
931
+ XLNX_VERSAL_CFRAME_REG_ERR_DEBUG,
932
+ CFRAME_REG_R_MAX * 4);
933
+ memory_region_add_subregion(&s->iomem,
934
+ 0x0,
935
+ &reg_array->mem);
936
+ sysbus_init_mmio(sbd, &s->iomem);
937
+ memory_region_init_io(&s->iomem_fdri, obj, &cframe_reg_fdri_ops, s,
938
+ TYPE_XLNX_VERSAL_CFRAME_REG "-fdri",
939
+ KEYHOLE_STREAM_4K);
940
+ sysbus_init_mmio(sbd, &s->iomem_fdri);
941
+ sysbus_init_irq(sbd, &s->irq_cfrm_imr);
942
+
943
+ s->cframes = g_tree_new_full((GCompareDataFunc)int_cmp, NULL,
944
+ NULL, (GDestroyNotify)g_free);
945
+ fifo32_create(&s->new_f_data, FRAME_NUM_WORDS);
946
+}
947
+
948
+static const VMStateDescription vmstate_cframe = {
949
+ .name = "cframe",
950
+ .version_id = 1,
951
+ .minimum_version_id = 1,
952
+ .fields = (VMStateField[]) {
953
+ VMSTATE_UINT32_ARRAY(data, XlnxCFrame, FRAME_NUM_WORDS),
954
+ VMSTATE_END_OF_LIST()
955
+ }
956
+};
957
+
958
+static const VMStateDescription vmstate_cframe_reg = {
959
+ .name = TYPE_XLNX_VERSAL_CFRAME_REG,
960
+ .version_id = 1,
961
+ .minimum_version_id = 1,
962
+ .fields = (VMStateField[]) {
963
+ VMSTATE_UINT32_ARRAY(wfifo, XlnxVersalCFrameReg, 4),
964
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalCFrameReg, CFRAME_REG_R_MAX),
965
+ VMSTATE_BOOL(rowon, XlnxVersalCFrameReg),
966
+ VMSTATE_BOOL(wcfg, XlnxVersalCFrameReg),
967
+ VMSTATE_BOOL(rcfg, XlnxVersalCFrameReg),
968
+ VMSTATE_GTREE_DIRECT_KEY_V(cframes, XlnxVersalCFrameReg, 1,
969
+ &vmstate_cframe, XlnxCFrame),
970
+ VMSTATE_FIFO32(new_f_data, XlnxVersalCFrameReg),
971
+ VMSTATE_END_OF_LIST(),
972
+ }
973
+};
974
+
975
+static Property cframe_regs_props[] = {
976
+ DEFINE_PROP_LINK("cfu-fdro", XlnxVersalCFrameReg, cfg.cfu_fdro,
977
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
978
+ DEFINE_PROP_UINT32("blktype0-frames", XlnxVersalCFrameReg,
979
+ cfg.blktype_num_frames[0], 0),
980
+ DEFINE_PROP_UINT32("blktype1-frames", XlnxVersalCFrameReg,
981
+ cfg.blktype_num_frames[1], 0),
982
+ DEFINE_PROP_UINT32("blktype2-frames", XlnxVersalCFrameReg,
983
+ cfg.blktype_num_frames[2], 0),
984
+ DEFINE_PROP_UINT32("blktype3-frames", XlnxVersalCFrameReg,
985
+ cfg.blktype_num_frames[3], 0),
986
+ DEFINE_PROP_UINT32("blktype4-frames", XlnxVersalCFrameReg,
987
+ cfg.blktype_num_frames[4], 0),
988
+ DEFINE_PROP_UINT32("blktype5-frames", XlnxVersalCFrameReg,
989
+ cfg.blktype_num_frames[5], 0),
990
+ DEFINE_PROP_UINT32("blktype6-frames", XlnxVersalCFrameReg,
991
+ cfg.blktype_num_frames[6], 0),
992
+ DEFINE_PROP_END_OF_LIST(),
993
+};
994
+
995
+static void cframe_reg_class_init(ObjectClass *klass, void *data)
996
+{
997
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
998
+ DeviceClass *dc = DEVICE_CLASS(klass);
999
+ XlnxCfiIfClass *xcic = XLNX_CFI_IF_CLASS(klass);
1000
+
1001
+ dc->vmsd = &vmstate_cframe_reg;
1002
+ dc->realize = cframe_reg_realize;
1003
+ rc->phases.enter = cframe_reg_reset_enter;
1004
+ rc->phases.hold = cframe_reg_reset_hold;
1005
+ device_class_set_props(dc, cframe_regs_props);
1006
+ xcic->cfi_transfer_packet = cframe_reg_cfi_transfer_packet;
1007
+}
1008
+
1009
+static const TypeInfo cframe_reg_info = {
1010
+ .name = TYPE_XLNX_VERSAL_CFRAME_REG,
1011
+ .parent = TYPE_SYS_BUS_DEVICE,
1012
+ .instance_size = sizeof(XlnxVersalCFrameReg),
1013
+ .class_init = cframe_reg_class_init,
1014
+ .instance_init = cframe_reg_init,
1015
+ .interfaces = (InterfaceInfo[]) {
1016
+ { TYPE_XLNX_CFI_IF },
1017
+ { }
1018
+ }
1019
+};
1020
+
1021
+static void cframe_reg_register_types(void)
1022
+{
1023
+ type_register_static(&cframe_reg_info);
1024
+}
1025
+
1026
+type_init(cframe_reg_register_types)
1027
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
150
index XXXXXXX..XXXXXXX 100644
1028
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/op_helper.c
1029
--- a/hw/misc/meson.build
152
+++ b/target/arm/op_helper.c
1030
+++ b/hw/misc/meson.build
153
@@ -XXX,XX +XXX,XX @@
1031
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
154
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
1032
'xlnx-versal-pmc-iou-slcr.c',
155
*/
1033
'xlnx-versal-cfu.c',
156
#include "qemu/osdep.h"
1034
'xlnx-cfi-if.c',
157
-#include "qemu/units.h"
1035
+ 'xlnx-versal-cframe-reg.c',
158
#include "qemu/log.h"
1036
))
159
#include "qemu/main-loop.h"
1037
system_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: files('stm32f2xx_syscfg.c'))
160
#include "cpu.h"
1038
system_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: files('stm32f4xx_syscfg.c'))
161
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i)
162
return ((uint32_t)x >> shift) | (x << (32 - shift));
163
}
164
}
165
-
166
-void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
167
-{
168
- /*
169
- * Implement DC ZVA, which zeroes a fixed-length block of memory.
170
- * Note that we do not implement the (architecturally mandated)
171
- * alignment fault for attempts to use this on Device memory
172
- * (which matches the usual QEMU behaviour of not implementing either
173
- * alignment faults or any memory attribute handling).
174
- */
175
-
176
- ARMCPU *cpu = env_archcpu(env);
177
- uint64_t blocklen = 4 << cpu->dcz_blocksize;
178
- uint64_t vaddr = vaddr_in & ~(blocklen - 1);
179
-
180
-#ifndef CONFIG_USER_ONLY
181
- {
182
- /*
183
- * Slightly awkwardly, QEMU's TARGET_PAGE_SIZE may be less than
184
- * the block size so we might have to do more than one TLB lookup.
185
- * We know that in fact for any v8 CPU the page size is at least 4K
186
- * and the block size must be 2K or less, but TARGET_PAGE_SIZE is only
187
- * 1K as an artefact of legacy v5 subpage support being present in the
188
- * same QEMU executable. So in practice the hostaddr[] array has
189
- * two entries, given the current setting of TARGET_PAGE_BITS_MIN.
190
- */
191
- int maxidx = DIV_ROUND_UP(blocklen, TARGET_PAGE_SIZE);
192
- void *hostaddr[DIV_ROUND_UP(2 * KiB, 1 << TARGET_PAGE_BITS_MIN)];
193
- int try, i;
194
- unsigned mmu_idx = cpu_mmu_index(env, false);
195
- TCGMemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
196
-
197
- assert(maxidx <= ARRAY_SIZE(hostaddr));
198
-
199
- for (try = 0; try < 2; try++) {
200
-
201
- for (i = 0; i < maxidx; i++) {
202
- hostaddr[i] = tlb_vaddr_to_host(env,
203
- vaddr + TARGET_PAGE_SIZE * i,
204
- 1, mmu_idx);
205
- if (!hostaddr[i]) {
206
- break;
207
- }
208
- }
209
- if (i == maxidx) {
210
- /*
211
- * If it's all in the TLB it's fair game for just writing to;
212
- * we know we don't need to update dirty status, etc.
213
- */
214
- for (i = 0; i < maxidx - 1; i++) {
215
- memset(hostaddr[i], 0, TARGET_PAGE_SIZE);
216
- }
217
- memset(hostaddr[i], 0, blocklen - (i * TARGET_PAGE_SIZE));
218
- return;
219
- }
220
- /*
221
- * OK, try a store and see if we can populate the tlb. This
222
- * might cause an exception if the memory isn't writable,
223
- * in which case we will longjmp out of here. We must for
224
- * this purpose use the actual register value passed to us
225
- * so that we get the fault address right.
226
- */
227
- helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC());
228
- /* Now we can populate the other TLB entries, if any */
229
- for (i = 0; i < maxidx; i++) {
230
- uint64_t va = vaddr + TARGET_PAGE_SIZE * i;
231
- if (va != (vaddr_in & TARGET_PAGE_MASK)) {
232
- helper_ret_stb_mmu(env, va, 0, oi, GETPC());
233
- }
234
- }
235
- }
236
-
237
- /*
238
- * Slow path (probably attempt to do this to an I/O device or
239
- * similar, or clearing of a block of code we have translations
240
- * cached for). Just do a series of byte writes as the architecture
241
- * demands. It's not worth trying to use a cpu_physical_memory_map(),
242
- * memset(), unmap() sequence here because:
243
- * + we'd need to account for the blocksize being larger than a page
244
- * + the direct-RAM access case is almost always going to be dealt
245
- * with in the fastpath code above, so there's no speed benefit
246
- * + we would have to deal with the map returning NULL because the
247
- * bounce buffer was in use
248
- */
249
- for (i = 0; i < blocklen; i++) {
250
- helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETPC());
251
- }
252
- }
253
-#else
254
- memset(g2h(vaddr), 0, blocklen);
255
-#endif
256
-}
257
--
1039
--
258
2.20.1
1040
2.34.1
259
260
diff view generated by jsdifflib
1
From: Pan Nengyuan <pannengyuan@huawei.com>
1
From: Francisco Iglesias <francisco.iglesias@amd.com>
2
2
3
There are some memleaks when we call 'device_list_properties'. This patch move timer_new from init into realize to fix it.
3
Introduce a model of Xilinx Versal's Configuration Frame broadcast
4
controller (CFRAME_BCAST_REG).
4
5
5
Reported-by: Euler Robot <euler.robot@huawei.com>
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
6
Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
7
Message-id: 20200227025055.14341-3-pannengyuan@huawei.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230831165701.2016397-7-francisco.iglesias@amd.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/arm/pxa2xx.c | 17 +++++++++++------
11
include/hw/misc/xlnx-versal-cframe-reg.h | 17 +++
12
1 file changed, 11 insertions(+), 6 deletions(-)
12
hw/misc/xlnx-versal-cframe-reg.c | 161 +++++++++++++++++++++++
13
2 files changed, 178 insertions(+)
13
14
14
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
15
diff --git a/include/hw/misc/xlnx-versal-cframe-reg.h b/include/hw/misc/xlnx-versal-cframe-reg.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/pxa2xx.c
17
--- a/include/hw/misc/xlnx-versal-cframe-reg.h
17
+++ b/hw/arm/pxa2xx.c
18
+++ b/include/hw/misc/xlnx-versal-cframe-reg.h
18
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_rtc_init(Object *obj)
19
@@ -XXX,XX +XXX,XX @@
19
s->last_rtcpicr = 0;
20
#define TYPE_XLNX_VERSAL_CFRAME_REG "xlnx,cframe-reg"
20
s->last_hz = s->last_sw = s->last_pi = qemu_clock_get_ms(rtc_clock);
21
OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFrameReg, XLNX_VERSAL_CFRAME_REG)
21
22
22
+ sysbus_init_irq(dev, &s->rtc_irq);
23
+#define TYPE_XLNX_VERSAL_CFRAME_BCAST_REG "xlnx.cframe-bcast-reg"
23
+
24
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCFrameBcastReg,
24
+ memory_region_init_io(&s->iomem, obj, &pxa2xx_rtc_ops, s,
25
+ XLNX_VERSAL_CFRAME_BCAST_REG)
25
+ "pxa2xx-rtc", 0x10000);
26
+
26
+ sysbus_init_mmio(dev, &s->iomem);
27
/*
27
+}
28
* The registers in this module are 128 bits wide but it is ok to write
28
+
29
* and read them through 4 sequential 32 bit accesses (address[3:2] = 0,
29
+static void pxa2xx_rtc_realize(DeviceState *dev, Error **errp)
30
@@ -XXX,XX +XXX,XX @@ struct XlnxVersalCFrameReg {
30
+{
31
bool row_configured;
31
+ PXA2xxRTCState *s = PXA2XX_RTC(dev);
32
};
32
s->rtc_hz = timer_new_ms(rtc_clock, pxa2xx_rtc_hz_tick, s);
33
33
s->rtc_rdal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
34
+struct XlnxVersalCFrameBcastReg {
34
s->rtc_rdal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
35
+ SysBusDevice parent_obj;
35
s->rtc_swal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
36
+ MemoryRegion iomem_reg;
36
s->rtc_swal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
37
+ MemoryRegion iomem_fdri;
37
s->rtc_pi = timer_new_ms(rtc_clock, pxa2xx_rtc_pi_tick, s);
38
+
38
-
39
+ /* 128-bit wfifo. */
39
- sysbus_init_irq(dev, &s->rtc_irq);
40
+ uint32_t wfifo[WFIFO_SZ];
40
-
41
+
41
- memory_region_init_io(&s->iomem, obj, &pxa2xx_rtc_ops, s,
42
+ struct {
42
- "pxa2xx-rtc", 0x10000);
43
+ XlnxCfiIf *cframe[15];
43
- sysbus_init_mmio(dev, &s->iomem);
44
+ } cfg;
45
+};
46
+
47
#endif
48
diff --git a/hw/misc/xlnx-versal-cframe-reg.c b/hw/misc/xlnx-versal-cframe-reg.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/misc/xlnx-versal-cframe-reg.c
51
+++ b/hw/misc/xlnx-versal-cframe-reg.c
52
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps cframe_reg_fdri_ops = {
53
},
54
};
55
56
+static uint64_t cframes_bcast_reg_read(void *opaque, hwaddr addr, unsigned size)
57
+{
58
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
59
+ HWADDR_PRIx "\n", __func__, addr);
60
+ return 0;
61
+}
62
+
63
+static void cframes_bcast_write(XlnxVersalCFrameBcastReg *s, uint8_t reg_addr,
64
+ uint32_t *wfifo)
65
+{
66
+ XlnxCfiPacket pkt = {
67
+ .reg_addr = reg_addr,
68
+ .data[0] = wfifo[0],
69
+ .data[1] = wfifo[1],
70
+ .data[2] = wfifo[2],
71
+ .data[3] = wfifo[3]
72
+ };
73
+
74
+ for (int i = 0; i < ARRAY_SIZE(s->cfg.cframe); i++) {
75
+ if (s->cfg.cframe[i]) {
76
+ xlnx_cfi_transfer_packet(s->cfg.cframe[i], &pkt);
77
+ }
78
+ }
79
+}
80
+
81
+static void cframes_bcast_reg_write(void *opaque, hwaddr addr, uint64_t value,
82
+ unsigned size)
83
+{
84
+ XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(opaque);
85
+ uint32_t wfifo[WFIFO_SZ];
86
+
87
+ if (update_wfifo(addr, value, s->wfifo, wfifo)) {
88
+ uint8_t reg_addr = extract32(addr, 4, 6);
89
+
90
+ cframes_bcast_write(s, reg_addr, wfifo);
91
+ }
92
+}
93
+
94
+static uint64_t cframes_bcast_fdri_read(void *opaque, hwaddr addr,
95
+ unsigned size)
96
+{
97
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unsupported read from addr=%"
98
+ HWADDR_PRIx "\n", __func__, addr);
99
+ return 0;
100
+}
101
+
102
+static void cframes_bcast_fdri_write(void *opaque, hwaddr addr, uint64_t value,
103
+ unsigned size)
104
+{
105
+ XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(opaque);
106
+ uint32_t wfifo[WFIFO_SZ];
107
+
108
+ if (update_wfifo(addr, value, s->wfifo, wfifo)) {
109
+ cframes_bcast_write(s, CFRAME_FDRI, wfifo);
110
+ }
111
+}
112
+
113
+static const MemoryRegionOps cframes_bcast_reg_reg_ops = {
114
+ .read = cframes_bcast_reg_read,
115
+ .write = cframes_bcast_reg_write,
116
+ .endianness = DEVICE_LITTLE_ENDIAN,
117
+ .valid = {
118
+ .min_access_size = 4,
119
+ .max_access_size = 4,
120
+ },
121
+};
122
+
123
+static const MemoryRegionOps cframes_bcast_reg_fdri_ops = {
124
+ .read = cframes_bcast_fdri_read,
125
+ .write = cframes_bcast_fdri_write,
126
+ .endianness = DEVICE_LITTLE_ENDIAN,
127
+ .valid = {
128
+ .min_access_size = 4,
129
+ .max_access_size = 4,
130
+ },
131
+};
132
+
133
static void cframe_reg_realize(DeviceState *dev, Error **errp)
134
{
135
XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(dev);
136
@@ -XXX,XX +XXX,XX @@ static Property cframe_regs_props[] = {
137
DEFINE_PROP_END_OF_LIST(),
138
};
139
140
+static void cframe_bcast_reg_init(Object *obj)
141
+{
142
+ XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(obj);
143
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
144
+
145
+ memory_region_init_io(&s->iomem_reg, obj, &cframes_bcast_reg_reg_ops, s,
146
+ TYPE_XLNX_VERSAL_CFRAME_BCAST_REG, KEYHOLE_STREAM_4K);
147
+ memory_region_init_io(&s->iomem_fdri, obj, &cframes_bcast_reg_fdri_ops, s,
148
+ TYPE_XLNX_VERSAL_CFRAME_BCAST_REG "-fdri",
149
+ KEYHOLE_STREAM_4K);
150
+ sysbus_init_mmio(sbd, &s->iomem_reg);
151
+ sysbus_init_mmio(sbd, &s->iomem_fdri);
152
+}
153
+
154
+static void cframe_bcast_reg_reset_enter(Object *obj, ResetType type)
155
+{
156
+ XlnxVersalCFrameBcastReg *s = XLNX_VERSAL_CFRAME_BCAST_REG(obj);
157
+
158
+ memset(s->wfifo, 0, WFIFO_SZ * sizeof(uint32_t));
159
+}
160
+
161
+static const VMStateDescription vmstate_cframe_bcast_reg = {
162
+ .name = TYPE_XLNX_VERSAL_CFRAME_BCAST_REG,
163
+ .version_id = 1,
164
+ .minimum_version_id = 1,
165
+ .fields = (VMStateField[]) {
166
+ VMSTATE_UINT32_ARRAY(wfifo, XlnxVersalCFrameBcastReg, 4),
167
+ VMSTATE_END_OF_LIST(),
168
+ }
169
+};
170
+
171
+static Property cframe_bcast_regs_props[] = {
172
+ DEFINE_PROP_LINK("cframe0", XlnxVersalCFrameBcastReg, cfg.cframe[0],
173
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
174
+ DEFINE_PROP_LINK("cframe1", XlnxVersalCFrameBcastReg, cfg.cframe[1],
175
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
176
+ DEFINE_PROP_LINK("cframe2", XlnxVersalCFrameBcastReg, cfg.cframe[2],
177
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
178
+ DEFINE_PROP_LINK("cframe3", XlnxVersalCFrameBcastReg, cfg.cframe[3],
179
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
180
+ DEFINE_PROP_LINK("cframe4", XlnxVersalCFrameBcastReg, cfg.cframe[4],
181
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
182
+ DEFINE_PROP_LINK("cframe5", XlnxVersalCFrameBcastReg, cfg.cframe[5],
183
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
184
+ DEFINE_PROP_LINK("cframe6", XlnxVersalCFrameBcastReg, cfg.cframe[6],
185
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
186
+ DEFINE_PROP_LINK("cframe7", XlnxVersalCFrameBcastReg, cfg.cframe[7],
187
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
188
+ DEFINE_PROP_LINK("cframe8", XlnxVersalCFrameBcastReg, cfg.cframe[8],
189
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
190
+ DEFINE_PROP_LINK("cframe9", XlnxVersalCFrameBcastReg, cfg.cframe[9],
191
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
192
+ DEFINE_PROP_LINK("cframe10", XlnxVersalCFrameBcastReg, cfg.cframe[10],
193
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
194
+ DEFINE_PROP_LINK("cframe11", XlnxVersalCFrameBcastReg, cfg.cframe[11],
195
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
196
+ DEFINE_PROP_LINK("cframe12", XlnxVersalCFrameBcastReg, cfg.cframe[12],
197
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
198
+ DEFINE_PROP_LINK("cframe13", XlnxVersalCFrameBcastReg, cfg.cframe[13],
199
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
200
+ DEFINE_PROP_LINK("cframe14", XlnxVersalCFrameBcastReg, cfg.cframe[14],
201
+ TYPE_XLNX_CFI_IF, XlnxCfiIf *),
202
+ DEFINE_PROP_END_OF_LIST(),
203
+};
204
+
205
static void cframe_reg_class_init(ObjectClass *klass, void *data)
206
{
207
ResettableClass *rc = RESETTABLE_CLASS(klass);
208
@@ -XXX,XX +XXX,XX @@ static void cframe_reg_class_init(ObjectClass *klass, void *data)
209
xcic->cfi_transfer_packet = cframe_reg_cfi_transfer_packet;
44
}
210
}
45
211
46
static int pxa2xx_rtc_pre_save(void *opaque)
212
+static void cframe_bcast_reg_class_init(ObjectClass *klass, void *data)
47
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_rtc_sysbus_class_init(ObjectClass *klass, void *data)
213
+{
48
214
+ DeviceClass *dc = DEVICE_CLASS(klass);
49
dc->desc = "PXA2xx RTC Controller";
215
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
50
dc->vmsd = &vmstate_pxa2xx_rtc_regs;
216
+
51
+ dc->realize = pxa2xx_rtc_realize;
217
+ dc->vmsd = &vmstate_cframe_bcast_reg;
218
+ device_class_set_props(dc, cframe_bcast_regs_props);
219
+ rc->phases.enter = cframe_bcast_reg_reset_enter;
220
+}
221
+
222
static const TypeInfo cframe_reg_info = {
223
.name = TYPE_XLNX_VERSAL_CFRAME_REG,
224
.parent = TYPE_SYS_BUS_DEVICE,
225
@@ -XXX,XX +XXX,XX @@ static const TypeInfo cframe_reg_info = {
226
}
227
};
228
229
+static const TypeInfo cframe_bcast_reg_info = {
230
+ .name = TYPE_XLNX_VERSAL_CFRAME_BCAST_REG,
231
+ .parent = TYPE_SYS_BUS_DEVICE,
232
+ .instance_size = sizeof(XlnxVersalCFrameBcastReg),
233
+ .class_init = cframe_bcast_reg_class_init,
234
+ .instance_init = cframe_bcast_reg_init,
235
+};
236
+
237
static void cframe_reg_register_types(void)
238
{
239
type_register_static(&cframe_reg_info);
240
+ type_register_static(&cframe_bcast_reg_info);
52
}
241
}
53
242
54
static const TypeInfo pxa2xx_rtc_sysbus_info = {
243
type_init(cframe_reg_register_types)
55
--
244
--
56
2.20.1
245
2.34.1
57
58
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Francisco Iglesias <francisco.iglesias@amd.com>
2
2
3
Add support for the Versal LPD ADMAs.
3
Connect the Configuration Frame Unit (CFU_APB, CFU_FDRO and CFU_SFR) to
4
the Versal machine.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
6
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Acked-by: Edgar E. Iglesias <edgar@zeroasic.com>
7
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20230831165701.2016397-8-francisco.iglesias@amd.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
include/hw/arm/xlnx-versal.h | 6 ++++++
12
include/hw/arm/xlnx-versal.h | 16 ++++++++++++++
12
hw/arm/xlnx-versal.c | 24 ++++++++++++++++++++++++
13
hw/arm/xlnx-versal.c | 42 ++++++++++++++++++++++++++++++++++++
13
2 files changed, 30 insertions(+)
14
2 files changed, 58 insertions(+)
14
15
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/xlnx-versal.h
18
--- a/include/hw/arm/xlnx-versal.h
18
+++ b/include/hw/arm/xlnx-versal.h
19
+++ b/include/hw/arm/xlnx-versal.h
19
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
20
#define XLNX_VERSAL_NR_ACPUS 2
21
#include "hw/misc/xlnx-versal-crl.h"
21
#define XLNX_VERSAL_NR_UARTS 2
22
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
22
#define XLNX_VERSAL_NR_GEMS 2
23
#include "hw/net/xlnx-versal-canfd.h"
23
+#define XLNX_VERSAL_NR_ADMAS 8
24
+#include "hw/misc/xlnx-versal-cfu.h"
24
#define XLNX_VERSAL_NR_IRQS 192
25
25
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
26
typedef struct Versal {
27
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
27
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
28
struct {
29
XlnxEFuse efuse;
29
SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
30
XlnxVersalEFuseCtrl efuse_ctrl;
30
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
31
XlnxVersalEFuseCache efuse_cache;
31
+ SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
32
+ XlnxVersalCFUAPB cfu_apb;
32
} iou;
33
+ XlnxVersalCFUFDRO cfu_fdro;
33
} lpd;
34
+ XlnxVersalCFUSFR cfu_sfr;
34
35
35
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
36
OrIRQState apb_irq_orgate;
36
#define VERSAL_GEM0_WAKE_IRQ_0 57
37
} pmc;
37
#define VERSAL_GEM1_IRQ_0 58
38
@@ -XXX,XX +XXX,XX @@ struct Versal {
38
#define VERSAL_GEM1_WAKE_IRQ_0 59
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
39
+#define VERSAL_ADMA_IRQ_0 60
40
#define VERSAL_ADMA_IRQ_0 60
40
41
#define VERSAL_XRAM_IRQ_0 79
41
/* Architecturally reserved IRQs suitable for virtualization. */
42
+#define VERSAL_CFU_IRQ_0 120
42
#define VERSAL_RSVD_IRQ_FIRST 111
43
#define VERSAL_PMC_APB_IRQ 121
43
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
44
#define VERSAL_OSPI_IRQ 124
44
#define MM_GEM1 0xff0d0000U
45
#define VERSAL_SD0_IRQ_0 126
45
#define MM_GEM1_SIZE 0x10000
46
@@ -XXX,XX +XXX,XX @@ struct Versal {
46
47
#define MM_PMC_EFUSE_CACHE 0xf1250000
47
+#define MM_ADMA_CH0 0xffa80000U
48
#define MM_PMC_EFUSE_CACHE_SIZE 0x00C00
48
+#define MM_ADMA_CH0_SIZE 0x10000
49
50
+#define MM_PMC_CFU_APB 0xf12b0000
51
+#define MM_PMC_CFU_APB_SIZE 0x10000
52
+#define MM_PMC_CFU_STREAM 0xf12c0000
53
+#define MM_PMC_CFU_STREAM_SIZE 0x1000
54
+#define MM_PMC_CFU_SFR 0xf12c1000
55
+#define MM_PMC_CFU_SFR_SIZE 0x1000
56
+#define MM_PMC_CFU_FDRO 0xf12c2000
57
+#define MM_PMC_CFU_FDRO_SIZE 0x1000
58
+#define MM_PMC_CFU_STREAM_2 0xf1f80000
59
+#define MM_PMC_CFU_STREAM_2_SIZE 0x40000
49
+
60
+
50
#define MM_OCM 0xfffc0000U
61
#define MM_PMC_CRP 0xf1260000U
51
#define MM_OCM_SIZE 0x40000
62
#define MM_PMC_CRP_SIZE 0x10000
52
63
#define MM_PMC_RTC 0xf12a0000
53
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
64
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
54
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/xlnx-versal.c
66
--- a/hw/arm/xlnx-versal.c
56
+++ b/hw/arm/xlnx-versal.c
67
+++ b/hw/arm/xlnx-versal.c
57
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
68
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
58
}
69
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
59
}
70
}
60
71
61
+static void versal_create_admas(Versal *s, qemu_irq *pic)
72
+static void versal_create_cfu(Versal *s, qemu_irq *pic)
62
+{
73
+{
63
+ int i;
74
+ SysBusDevice *sbd;
64
+
75
+
65
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
76
+ /* CFU FDRO */
66
+ char *name = g_strdup_printf("adma%d", i);
77
+ object_initialize_child(OBJECT(s), "cfu-fdro", &s->pmc.cfu_fdro,
67
+ DeviceState *dev;
78
+ TYPE_XLNX_VERSAL_CFU_FDRO);
68
+ MemoryRegion *mr;
79
+ sbd = SYS_BUS_DEVICE(&s->pmc.cfu_fdro);
69
+
80
+
70
+ dev = qdev_create(NULL, "xlnx.zdma");
81
+ sysbus_realize(sbd, &error_fatal);
71
+ s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
82
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_FDRO,
72
+ object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
83
+ sysbus_mmio_get_region(sbd, 0));
73
+ qdev_init_nofail(dev);
74
+
84
+
75
+ mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
85
+ /* CFU APB */
76
+ memory_region_add_subregion(&s->mr_ps,
86
+ object_initialize_child(OBJECT(s), "cfu-apb", &s->pmc.cfu_apb,
77
+ MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
87
+ TYPE_XLNX_VERSAL_CFU_APB);
88
+ sbd = SYS_BUS_DEVICE(&s->pmc.cfu_apb);
78
+
89
+
79
+ sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
90
+ sysbus_realize(sbd, &error_fatal);
80
+ g_free(name);
91
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_APB,
81
+ }
92
+ sysbus_mmio_get_region(sbd, 0));
93
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM,
94
+ sysbus_mmio_get_region(sbd, 1));
95
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_STREAM_2,
96
+ sysbus_mmio_get_region(sbd, 2));
97
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_CFU_IRQ_0]);
98
+
99
+ /* CFU SFR */
100
+ object_initialize_child(OBJECT(s), "cfu-sfr", &s->pmc.cfu_sfr,
101
+ TYPE_XLNX_VERSAL_CFU_SFR);
102
+
103
+ sbd = SYS_BUS_DEVICE(&s->pmc.cfu_sfr);
104
+
105
+ object_property_set_link(OBJECT(&s->pmc.cfu_sfr),
106
+ "cfu", OBJECT(&s->pmc.cfu_apb), &error_abort);
107
+
108
+ sysbus_realize(sbd, &error_fatal);
109
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_SFR,
110
+ sysbus_mmio_get_region(sbd, 0));
82
+}
111
+}
83
+
112
+
84
/* This takes the board allocated linear DDR memory and creates aliases
113
static void versal_create_crl(Versal *s, qemu_irq *pic)
85
* for each split DDR range/aperture on the Versal address map.
114
{
86
*/
115
SysBusDevice *sbd;
87
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
116
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
88
versal_create_apu_gic(s, pic);
117
versal_create_pmc_iou_slcr(s, pic);
89
versal_create_uarts(s, pic);
118
versal_create_ospi(s, pic);
90
versal_create_gems(s, pic);
119
versal_create_crl(s, pic);
91
+ versal_create_admas(s, pic);
120
+ versal_create_cfu(s, pic);
92
versal_map_ddr(s);
121
versal_map_ddr(s);
93
versal_unimp(s);
122
versal_unimp(s);
94
123
95
--
124
--
96
2.20.1
125
2.34.1
97
98
diff view generated by jsdifflib
Deleted patch
1
The ARMv8.2-TTCNP extension allows an implementation to optimize by
2
sharing TLB entries between multiple cores, provided that software
3
declares that it's ready to deal with this by setting a CnP bit in
4
the TTBRn_ELx. It is mandatory from ARMv8.2 onward.
5
1
6
For QEMU's TLB implementation, sharing TLB entries between different
7
cores would not really benefit us and would be a lot of work to
8
implement. So we implement this extension in the "trivial" manner:
9
we allow the guest to set and read back the CnP bit, but don't change
10
our behaviour (this is an architecturally valid implementation
11
choice).
12
13
The only code path which looks at the TTBRn_ELx values for the
14
long-descriptor format where the CnP bit is defined is already doing
15
enough masking to not get confused when the CnP bit at the bottom of
16
the register is set, so we can simply add a comment noting why we're
17
relying on that mask.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20200225193822.18874-1-peter.maydell@linaro.org
22
---
23
target/arm/cpu.c | 1 +
24
target/arm/cpu64.c | 2 ++
25
target/arm/helper.c | 4 ++++
26
3 files changed, 7 insertions(+)
27
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.c
31
+++ b/target/arm/cpu.c
32
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
33
t = cpu->isar.id_mmfr4;
34
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
35
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
36
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
37
cpu->isar.id_mmfr4 = t;
38
}
39
#endif
40
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/cpu64.c
43
+++ b/target/arm/cpu64.c
44
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
45
46
t = cpu->isar.id_aa64mmfr2;
47
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
48
+ t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
49
cpu->isar.id_aa64mmfr2 = t;
50
51
/* Replicate the same data to the 32-bit id registers. */
52
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
53
u = cpu->isar.id_mmfr4;
54
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
55
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
56
+ u = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
57
cpu->isar.id_mmfr4 = u;
58
59
u = cpu->isar.id_aa64dfr0;
60
diff --git a/target/arm/helper.c b/target/arm/helper.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/helper.c
63
+++ b/target/arm/helper.c
64
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
65
66
/* Now we can extract the actual base address from the TTBR */
67
descaddr = extract64(ttbr, 0, 48);
68
+ /*
69
+ * We rely on this masking to clear the RES0 bits at the bottom of the TTBR
70
+ * and also to mask out CnP (bit 0) which could validly be non-zero.
71
+ */
72
descaddr &= ~indexmask;
73
74
/* The address field in the descriptor goes up to bit 39 for ARMv7
75
--
76
2.20.1
77
78
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
Make sure a null SMMUPciBus is returned in case we were
4
not able to identify a pci bus matching the @bus_num.
5
6
This matches the fix done on intel iommu in commit:
7
a2e1cd41ccfe796529abfd1b6aeb1dd4393762a2
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Peter Xu <peterx@redhat.com>
11
Message-Id: <20200226172628.17449-1-eric.auger@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/arm/smmu-common.c | 1 +
17
1 file changed, 1 insertion(+)
18
19
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/smmu-common.c
22
+++ b/hw/arm/smmu-common.c
23
@@ -XXX,XX +XXX,XX @@ SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num)
24
return smmu_pci_bus;
25
}
26
}
27
+ smmu_pci_bus = NULL;
28
}
29
return smmu_pci_bus;
30
}
31
--
32
2.20.1
33
34
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Francisco Iglesias <francisco.iglesias@amd.com>
2
2
3
The Cubieboard contains either 512MiB or 1GiB of onboard RAM [1].
3
Connect the Configuration Frame controller (CFRAME_REG) and the
4
Prevent changing RAM to a different size which could break user programs.
4
Configuration Frame broadcast controller (CFRAME_BCAST_REG) to the
5
Versal machine.
5
6
6
[1] http://linux-sunxi.org/Cubieboard
7
Signed-off-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
8
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Message-id: 20200227220149.6845-4-nieklinnenbank@gmail.com
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20230831165701.2016397-9-francisco.iglesias@amd.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/arm/cubieboard.c | 8 ++++++++
12
include/hw/arm/xlnx-versal.h | 69 +++++++++++++++++++++
15
1 file changed, 8 insertions(+)
13
hw/arm/xlnx-versal.c | 113 ++++++++++++++++++++++++++++++++++-
14
2 files changed, 181 insertions(+), 1 deletion(-)
16
15
17
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/cubieboard.c
18
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/hw/arm/cubieboard.c
19
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@ static void cubieboard_init(MachineState *machine)
20
@@ -XXX,XX +XXX,XX @@
22
AwA10State *a10;
21
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
23
Error *err = NULL;
22
#include "hw/net/xlnx-versal-canfd.h"
24
23
#include "hw/misc/xlnx-versal-cfu.h"
25
+ /* This board has fixed size RAM (512MiB or 1GiB) */
24
+#include "hw/misc/xlnx-versal-cframe-reg.h"
26
+ if (machine->ram_size != 512 * MiB &&
25
27
+ machine->ram_size != 1 * GiB) {
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
+ error_report("This machine can only be used with 512MiB or 1GiB RAM");
27
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
29
+ exit(1);
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
29
#define XLNX_VERSAL_NR_IRQS 192
30
#define XLNX_VERSAL_NR_CANFD 2
31
#define XLNX_VERSAL_CANFD_REF_CLK (24 * 1000 * 1000)
32
+#define XLNX_VERSAL_NR_CFRAME 15
33
34
struct Versal {
35
/*< private >*/
36
@@ -XXX,XX +XXX,XX @@ struct Versal {
37
XlnxVersalCFUAPB cfu_apb;
38
XlnxVersalCFUFDRO cfu_fdro;
39
XlnxVersalCFUSFR cfu_sfr;
40
+ XlnxVersalCFrameReg cframe[XLNX_VERSAL_NR_CFRAME];
41
+ XlnxVersalCFrameBcastReg cframe_bcast;
42
43
OrIRQState apb_irq_orgate;
44
} pmc;
45
@@ -XXX,XX +XXX,XX @@ struct Versal {
46
#define MM_PMC_CFU_STREAM_2 0xf1f80000
47
#define MM_PMC_CFU_STREAM_2_SIZE 0x40000
48
49
+#define MM_PMC_CFRAME0_REG 0xf12d0000
50
+#define MM_PMC_CFRAME0_REG_SIZE 0x1000
51
+#define MM_PMC_CFRAME0_FDRI 0xf12d1000
52
+#define MM_PMC_CFRAME0_FDRI_SIZE 0x1000
53
+#define MM_PMC_CFRAME1_REG 0xf12d2000
54
+#define MM_PMC_CFRAME1_REG_SIZE 0x1000
55
+#define MM_PMC_CFRAME1_FDRI 0xf12d3000
56
+#define MM_PMC_CFRAME1_FDRI_SIZE 0x1000
57
+#define MM_PMC_CFRAME2_REG 0xf12d4000
58
+#define MM_PMC_CFRAME2_REG_SIZE 0x1000
59
+#define MM_PMC_CFRAME2_FDRI 0xf12d5000
60
+#define MM_PMC_CFRAME2_FDRI_SIZE 0x1000
61
+#define MM_PMC_CFRAME3_REG 0xf12d6000
62
+#define MM_PMC_CFRAME3_REG_SIZE 0x1000
63
+#define MM_PMC_CFRAME3_FDRI 0xf12d7000
64
+#define MM_PMC_CFRAME3_FDRI_SIZE 0x1000
65
+#define MM_PMC_CFRAME4_REG 0xf12d8000
66
+#define MM_PMC_CFRAME4_REG_SIZE 0x1000
67
+#define MM_PMC_CFRAME4_FDRI 0xf12d9000
68
+#define MM_PMC_CFRAME4_FDRI_SIZE 0x1000
69
+#define MM_PMC_CFRAME5_REG 0xf12da000
70
+#define MM_PMC_CFRAME5_REG_SIZE 0x1000
71
+#define MM_PMC_CFRAME5_FDRI 0xf12db000
72
+#define MM_PMC_CFRAME5_FDRI_SIZE 0x1000
73
+#define MM_PMC_CFRAME6_REG 0xf12dc000
74
+#define MM_PMC_CFRAME6_REG_SIZE 0x1000
75
+#define MM_PMC_CFRAME6_FDRI 0xf12dd000
76
+#define MM_PMC_CFRAME6_FDRI_SIZE 0x1000
77
+#define MM_PMC_CFRAME7_REG 0xf12de000
78
+#define MM_PMC_CFRAME7_REG_SIZE 0x1000
79
+#define MM_PMC_CFRAME7_FDRI 0xf12df000
80
+#define MM_PMC_CFRAME7_FDRI_SIZE 0x1000
81
+#define MM_PMC_CFRAME8_REG 0xf12e0000
82
+#define MM_PMC_CFRAME8_REG_SIZE 0x1000
83
+#define MM_PMC_CFRAME8_FDRI 0xf12e1000
84
+#define MM_PMC_CFRAME8_FDRI_SIZE 0x1000
85
+#define MM_PMC_CFRAME9_REG 0xf12e2000
86
+#define MM_PMC_CFRAME9_REG_SIZE 0x1000
87
+#define MM_PMC_CFRAME9_FDRI 0xf12e3000
88
+#define MM_PMC_CFRAME9_FDRI_SIZE 0x1000
89
+#define MM_PMC_CFRAME10_REG 0xf12e4000
90
+#define MM_PMC_CFRAME10_REG_SIZE 0x1000
91
+#define MM_PMC_CFRAME10_FDRI 0xf12e5000
92
+#define MM_PMC_CFRAME10_FDRI_SIZE 0x1000
93
+#define MM_PMC_CFRAME11_REG 0xf12e6000
94
+#define MM_PMC_CFRAME11_REG_SIZE 0x1000
95
+#define MM_PMC_CFRAME11_FDRI 0xf12e7000
96
+#define MM_PMC_CFRAME11_FDRI_SIZE 0x1000
97
+#define MM_PMC_CFRAME12_REG 0xf12e8000
98
+#define MM_PMC_CFRAME12_REG_SIZE 0x1000
99
+#define MM_PMC_CFRAME12_FDRI 0xf12e9000
100
+#define MM_PMC_CFRAME12_FDRI_SIZE 0x1000
101
+#define MM_PMC_CFRAME13_REG 0xf12ea000
102
+#define MM_PMC_CFRAME13_REG_SIZE 0x1000
103
+#define MM_PMC_CFRAME13_FDRI 0xf12eb000
104
+#define MM_PMC_CFRAME13_FDRI_SIZE 0x1000
105
+#define MM_PMC_CFRAME14_REG 0xf12ec000
106
+#define MM_PMC_CFRAME14_REG_SIZE 0x1000
107
+#define MM_PMC_CFRAME14_FDRI 0xf12ed000
108
+#define MM_PMC_CFRAME14_FDRI_SIZE 0x1000
109
+#define MM_PMC_CFRAME_BCAST_REG 0xf12ee000
110
+#define MM_PMC_CFRAME_BCAST_REG_SIZE 0x1000
111
+#define MM_PMC_CFRAME_BCAST_FDRI 0xf12ef000
112
+#define MM_PMC_CFRAME_BCAST_FDRI_SIZE 0x1000
113
+
114
#define MM_PMC_CRP 0xf1260000U
115
#define MM_PMC_CRP_SIZE 0x10000
116
#define MM_PMC_RTC 0xf12a0000
117
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/hw/arm/xlnx-versal.c
120
+++ b/hw/arm/xlnx-versal.c
121
@@ -XXX,XX +XXX,XX @@
122
#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
123
#define GEM_REVISION 0x40070106
124
125
-#define VERSAL_NUM_PMC_APB_IRQS 3
126
+#define VERSAL_NUM_PMC_APB_IRQS 18
127
#define NUM_OSPI_IRQ_LINES 3
128
129
static void versal_create_apu_cpus(Versal *s)
130
@@ -XXX,XX +XXX,XX @@ static void versal_create_pmc_apb_irq_orgate(Versal *s, qemu_irq *pic)
131
* - RTC
132
* - BBRAM
133
* - PMC SLCR
134
+ * - CFRAME regs (input 3 - 17 to the orgate)
135
*/
136
object_initialize_child(OBJECT(s), "pmc-apb-irq-orgate",
137
&s->pmc.apb_irq_orgate, TYPE_OR_IRQ);
138
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
139
static void versal_create_cfu(Versal *s, qemu_irq *pic)
140
{
141
SysBusDevice *sbd;
142
+ DeviceState *dev;
143
+ int i;
144
+ const struct {
145
+ uint64_t reg_base;
146
+ uint64_t fdri_base;
147
+ } cframe_addr[] = {
148
+ { MM_PMC_CFRAME0_REG, MM_PMC_CFRAME0_FDRI },
149
+ { MM_PMC_CFRAME1_REG, MM_PMC_CFRAME1_FDRI },
150
+ { MM_PMC_CFRAME2_REG, MM_PMC_CFRAME2_FDRI },
151
+ { MM_PMC_CFRAME3_REG, MM_PMC_CFRAME3_FDRI },
152
+ { MM_PMC_CFRAME4_REG, MM_PMC_CFRAME4_FDRI },
153
+ { MM_PMC_CFRAME5_REG, MM_PMC_CFRAME5_FDRI },
154
+ { MM_PMC_CFRAME6_REG, MM_PMC_CFRAME6_FDRI },
155
+ { MM_PMC_CFRAME7_REG, MM_PMC_CFRAME7_FDRI },
156
+ { MM_PMC_CFRAME8_REG, MM_PMC_CFRAME8_FDRI },
157
+ { MM_PMC_CFRAME9_REG, MM_PMC_CFRAME9_FDRI },
158
+ { MM_PMC_CFRAME10_REG, MM_PMC_CFRAME10_FDRI },
159
+ { MM_PMC_CFRAME11_REG, MM_PMC_CFRAME11_FDRI },
160
+ { MM_PMC_CFRAME12_REG, MM_PMC_CFRAME12_FDRI },
161
+ { MM_PMC_CFRAME13_REG, MM_PMC_CFRAME13_FDRI },
162
+ { MM_PMC_CFRAME14_REG, MM_PMC_CFRAME14_FDRI },
163
+ };
164
+ const struct {
165
+ uint32_t blktype0_frames;
166
+ uint32_t blktype1_frames;
167
+ uint32_t blktype2_frames;
168
+ uint32_t blktype3_frames;
169
+ uint32_t blktype4_frames;
170
+ uint32_t blktype5_frames;
171
+ uint32_t blktype6_frames;
172
+ } cframe_cfg[] = {
173
+ [0] = { 34111, 3528, 12800, 11, 5, 1, 1 },
174
+ [1] = { 38498, 3841, 15361, 13, 7, 3, 1 },
175
+ [2] = { 38498, 3841, 15361, 13, 7, 3, 1 },
176
+ [3] = { 38498, 3841, 15361, 13, 7, 3, 1 },
177
+ };
178
179
/* CFU FDRO */
180
object_initialize_child(OBJECT(s), "cfu-fdro", &s->pmc.cfu_fdro,
181
@@ -XXX,XX +XXX,XX @@ static void versal_create_cfu(Versal *s, qemu_irq *pic)
182
memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_FDRO,
183
sysbus_mmio_get_region(sbd, 0));
184
185
+ /* CFRAME REG */
186
+ for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
187
+ g_autofree char *name = g_strdup_printf("cframe%d", i);
188
+
189
+ object_initialize_child(OBJECT(s), name, &s->pmc.cframe[i],
190
+ TYPE_XLNX_VERSAL_CFRAME_REG);
191
+
192
+ sbd = SYS_BUS_DEVICE(&s->pmc.cframe[i]);
193
+ dev = DEVICE(&s->pmc.cframe[i]);
194
+
195
+ if (i < ARRAY_SIZE(cframe_cfg)) {
196
+ object_property_set_int(OBJECT(dev), "blktype0-frames",
197
+ cframe_cfg[i].blktype0_frames,
198
+ &error_abort);
199
+ object_property_set_int(OBJECT(dev), "blktype1-frames",
200
+ cframe_cfg[i].blktype1_frames,
201
+ &error_abort);
202
+ object_property_set_int(OBJECT(dev), "blktype2-frames",
203
+ cframe_cfg[i].blktype2_frames,
204
+ &error_abort);
205
+ object_property_set_int(OBJECT(dev), "blktype3-frames",
206
+ cframe_cfg[i].blktype3_frames,
207
+ &error_abort);
208
+ object_property_set_int(OBJECT(dev), "blktype4-frames",
209
+ cframe_cfg[i].blktype4_frames,
210
+ &error_abort);
211
+ object_property_set_int(OBJECT(dev), "blktype5-frames",
212
+ cframe_cfg[i].blktype5_frames,
213
+ &error_abort);
214
+ object_property_set_int(OBJECT(dev), "blktype6-frames",
215
+ cframe_cfg[i].blktype6_frames,
216
+ &error_abort);
217
+ }
218
+ object_property_set_link(OBJECT(dev), "cfu-fdro",
219
+ OBJECT(&s->pmc.cfu_fdro), &error_fatal);
220
+
221
+ sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
222
+
223
+ memory_region_add_subregion(&s->mr_ps, cframe_addr[i].reg_base,
224
+ sysbus_mmio_get_region(sbd, 0));
225
+ memory_region_add_subregion(&s->mr_ps, cframe_addr[i].fdri_base,
226
+ sysbus_mmio_get_region(sbd, 1));
227
+ sysbus_connect_irq(sbd, 0,
228
+ qdev_get_gpio_in(DEVICE(&s->pmc.apb_irq_orgate),
229
+ 3 + i));
30
+ }
230
+ }
31
+
231
+
32
/* Only allow Cortex-A8 for this board */
232
+ /* CFRAME BCAST */
33
if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a8")) != 0) {
233
+ object_initialize_child(OBJECT(s), "cframe_bcast", &s->pmc.cframe_bcast,
34
error_report("This board can only be used with cortex-a8 CPU");
234
+ TYPE_XLNX_VERSAL_CFRAME_BCAST_REG);
35
@@ -XXX,XX +XXX,XX @@ static void cubieboard_machine_init(MachineClass *mc)
235
+
36
{
236
+ sbd = SYS_BUS_DEVICE(&s->pmc.cframe_bcast);
37
mc->desc = "cubietech cubieboard (Cortex-A8)";
237
+ dev = DEVICE(&s->pmc.cframe_bcast);
38
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a8");
238
+
39
+ mc->default_ram_size = 1 * GiB;
239
+ for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
40
mc->init = cubieboard_init;
240
+ g_autofree char *propname = g_strdup_printf("cframe%d", i);
41
mc->block_default_type = IF_IDE;
241
+ object_property_set_link(OBJECT(dev), propname,
42
mc->units_per_default_bus = 1;
242
+ OBJECT(&s->pmc.cframe[i]), &error_fatal);
243
+ }
244
+
245
+ sysbus_realize(sbd, &error_fatal);
246
+
247
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_REG,
248
+ sysbus_mmio_get_region(sbd, 0));
249
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_CFRAME_BCAST_FDRI,
250
+ sysbus_mmio_get_region(sbd, 1));
251
+
252
/* CFU APB */
253
object_initialize_child(OBJECT(s), "cfu-apb", &s->pmc.cfu_apb,
254
TYPE_XLNX_VERSAL_CFU_APB);
255
sbd = SYS_BUS_DEVICE(&s->pmc.cfu_apb);
256
+ dev = DEVICE(&s->pmc.cfu_apb);
257
+
258
+ for (i = 0; i < ARRAY_SIZE(s->pmc.cframe); i++) {
259
+ g_autofree char *propname = g_strdup_printf("cframe%d", i);
260
+ object_property_set_link(OBJECT(dev), propname,
261
+ OBJECT(&s->pmc.cframe[i]), &error_fatal);
262
+ }
263
264
sysbus_realize(sbd, &error_fatal);
265
memory_region_add_subregion(&s->mr_ps, MM_PMC_CFU_APB,
43
--
266
--
44
2.20.1
267
2.34.1
45
46
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In arm_cpu_reset, we configure many system registers so that user-only
3
STGP writes to tag memory, it does not check it.
4
behaves as it should with a minimum of ifdefs. However, we do not set
4
This happened to work because we wrote tag memory first
5
all of the system registers as required for a cpu with EL2 and EL3.
5
so that the check always succeeded.
6
7
Disabling EL2 and EL3 mean that we will not look at those registers,
8
which means that we don't have to worry about configuring them.
9
6
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20200229012811.24129-4-richard.henderson@linaro.org
8
Message-id: 20230901203103.136408-1-richard.henderson@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
target/arm/cpu.c | 6 ++++--
12
target/arm/tcg/translate-a64.c | 41 +++++++++++++---------------------
16
1 file changed, 4 insertions(+), 2 deletions(-)
13
1 file changed, 15 insertions(+), 26 deletions(-)
17
14
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
17
--- a/target/arm/tcg/translate-a64.c
21
+++ b/target/arm/cpu.c
18
+++ b/target/arm/tcg/translate-a64.c
22
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_reset_hivecs_property =
19
@@ -XXX,XX +XXX,XX @@ static bool trans_STGP(DisasContext *s, arg_ldstpair *a)
23
static Property arm_cpu_rvbar_property =
20
tcg_gen_addi_i64(dirty_addr, dirty_addr, offset);
24
DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0);
25
26
+#ifndef CONFIG_USER_ONLY
27
static Property arm_cpu_has_el2_property =
28
DEFINE_PROP_BOOL("has_el2", ARMCPU, has_el2, true);
29
30
static Property arm_cpu_has_el3_property =
31
DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true);
32
+#endif
33
34
static Property arm_cpu_cfgend_property =
35
DEFINE_PROP_BOOL("cfgend", ARMCPU, cfgend, false);
36
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
37
qdev_property_add_static(DEVICE(obj), &arm_cpu_rvbar_property);
38
}
21
}
39
22
40
+#ifndef CONFIG_USER_ONLY
23
- if (!s->ata) {
41
if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
24
- /*
42
/* Add the has_el3 state CPU property only if EL3 is allowed. This will
25
- * TODO: We could rely on the stores below, at least for
43
* prevent "has_el3" from existing on CPUs which cannot support EL3.
26
- * system mode, if we arrange to add MO_ALIGN_16.
44
*/
27
- */
45
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el3_property);
28
- gen_helper_stg_stub(cpu_env, dirty_addr);
46
29
- } else if (tb_cflags(s->base.tb) & CF_PARALLEL) {
47
-#ifndef CONFIG_USER_ONLY
30
- gen_helper_stg_parallel(cpu_env, dirty_addr, dirty_addr);
48
object_property_add_link(obj, "secure-memory",
31
- } else {
49
TYPE_MEMORY_REGION,
32
- gen_helper_stg(cpu_env, dirty_addr, dirty_addr);
50
(Object **)&cpu->secure_memory,
33
- }
51
qdev_prop_allow_set_link_before_realize,
34
-
52
OBJ_PROP_LINK_STRONG,
35
- mop = finalize_memop(s, MO_64);
53
&error_abort);
36
- clean_addr = gen_mte_checkN(s, dirty_addr, true, false, 2 << MO_64, mop);
54
-#endif
37
-
38
+ clean_addr = clean_data_tbi(s, dirty_addr);
39
tcg_rt = cpu_reg(s, a->rt);
40
tcg_rt2 = cpu_reg(s, a->rt2);
41
42
/*
43
- * STGP is defined as two 8-byte memory operations and one tag operation.
44
- * We implement it as one single 16-byte memory operation for convenience.
45
- * Rebuild mop as for STP.
46
- * TODO: The atomicity with LSE2 is stronger than required.
47
- * Need a form of MO_ATOM_WITHIN16_PAIR that never requires
48
- * 16-byte atomicity.
49
+ * STGP is defined as two 8-byte memory operations, aligned to TAG_GRANULE,
50
+ * and one tag operation. We implement it as one single aligned 16-byte
51
+ * memory operation for convenience. Note that the alignment ensures
52
+ * MO_ATOM_IFALIGN_PAIR produces 8-byte atomicity for the memory store.
53
*/
54
- mop = MO_128;
55
- if (s->align_mem) {
56
- mop |= MO_ALIGN_8;
57
- }
58
- mop = finalize_memop_pair(s, mop);
59
+ mop = finalize_memop_atom(s, MO_128 | MO_ALIGN, MO_ATOM_IFALIGN_PAIR);
60
61
tmp = tcg_temp_new_i128();
62
if (s->be_data == MO_LE) {
63
@@ -XXX,XX +XXX,XX @@ static bool trans_STGP(DisasContext *s, arg_ldstpair *a)
55
}
64
}
56
65
tcg_gen_qemu_st_i128(tmp, clean_addr, get_mem_index(s), mop);
57
if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
66
58
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el2_property);
67
+ /* Perform the tag store, if tag access enabled. */
59
}
68
+ if (s->ata) {
60
+#endif
69
+ if (tb_cflags(s->base.tb) & CF_PARALLEL) {
61
70
+ gen_helper_stg_parallel(cpu_env, dirty_addr, dirty_addr);
62
if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
71
+ } else {
63
cpu->has_pmu = true;
72
+ gen_helper_stg(cpu_env, dirty_addr, dirty_addr);
73
+ }
74
+ }
75
+
76
op_addr_ldstpair_post(s, a, dirty_addr, offset);
77
return true;
78
}
64
--
79
--
65
2.20.1
80
2.34.1
66
67
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Colton Lewis <coltonlewis@google.com>
2
2
3
This bit traps EL1 access to cache maintenance insns that operate
3
Due to recent KVM changes, QEMU is setting a ptimer offset resulting
4
to the point of coherency or persistence.
4
in unintended trap and emulate access and a consequent performance
5
hit. Filter out the PTIMER_CNT register to restore trapless ptimer
6
access.
5
7
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Quoting Andrew Jones:
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
8
Message-id: 20200229012811.24129-10-richard.henderson@linaro.org
10
Simply reading the CNT register and writing back the same value is
11
enough to set an offset, since the timer will have certainly moved
12
past whatever value was read by the time it's written. QEMU
13
frequently saves and restores all registers in the get-reg-list array,
14
unless they've been explicitly filtered out (with Linux commit
15
680232a94c12, KVM_REG_ARM_PTIMER_CNT is now in the array). So, to
16
restore trapless ptimer accesses, we need a QEMU patch to filter out
17
the register.
18
19
See
20
https://lore.kernel.org/kvmarm/gsntttsonus5.fsf@coltonlewis-kvm.c.googlers.com/T/#m0770023762a821db2a3f0dd0a7dc6aa54e0d0da9
21
for additional context.
22
23
Cc: qemu-stable@nongnu.org
24
Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
25
Signed-off-by: Colton Lewis <coltonlewis@google.com>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Tested-by: Colton Lewis <coltonlewis@google.com>
28
Message-id: 20230831190052.129045-1-coltonlewis@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
30
---
11
target/arm/helper.c | 39 +++++++++++++++++++++++++++++++--------
31
target/arm/kvm64.c | 1 +
12
1 file changed, 31 insertions(+), 8 deletions(-)
32
1 file changed, 1 insertion(+)
13
33
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
15
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
36
--- a/target/arm/kvm64.c
17
+++ b/target/arm/helper.c
37
+++ b/target/arm/kvm64.c
18
@@ -XXX,XX +XXX,XX @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env,
38
@@ -XXX,XX +XXX,XX @@ typedef struct CPRegStateLevel {
19
return CP_ACCESS_OK;
20
}
21
22
+static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
23
+ const ARMCPRegInfo *ri,
24
+ bool isread)
25
+{
26
+ /* Cache invalidate/clean to Point of Coherency or Persistence... */
27
+ switch (arm_current_el(env)) {
28
+ case 0:
29
+ /* ... EL0 must UNDEF unless SCTLR_EL1.UCI is set. */
30
+ if (!(arm_sctlr(env, 0) & SCTLR_UCI)) {
31
+ return CP_ACCESS_TRAP;
32
+ }
33
+ /* fall through */
34
+ case 1:
35
+ /* ... EL1 must trap to EL2 if HCR_EL2.TPCP is set. */
36
+ if (arm_hcr_el2_eff(env) & HCR_TPCP) {
37
+ return CP_ACCESS_TRAP_EL2;
38
+ }
39
+ break;
40
+ }
41
+ return CP_ACCESS_OK;
42
+}
43
+
44
/* See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions
45
* Page D4-1736 (DDI0487A.b)
46
*/
39
*/
47
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
40
static const CPRegStateLevel non_runtime_cpregs[] = {
48
.accessfn = aa64_cacheop_access },
41
{ KVM_REG_ARM_TIMER_CNT, KVM_PUT_FULL_STATE },
49
{ .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
42
+ { KVM_REG_ARM_PTIMER_CNT, KVM_PUT_FULL_STATE },
50
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
51
- .access = PL1_W, .type = ARM_CP_NOP },
52
+ .access = PL1_W, .accessfn = aa64_cacheop_poc_access,
53
+ .type = ARM_CP_NOP },
54
{ .name = "DC_ISW", .state = ARM_CP_STATE_AA64,
55
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
56
.access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
57
{ .name = "DC_CVAC", .state = ARM_CP_STATE_AA64,
58
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 10, .opc2 = 1,
59
.access = PL0_W, .type = ARM_CP_NOP,
60
- .accessfn = aa64_cacheop_access },
61
+ .accessfn = aa64_cacheop_poc_access },
62
{ .name = "DC_CSW", .state = ARM_CP_STATE_AA64,
63
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
64
.access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
65
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
66
{ .name = "DC_CIVAC", .state = ARM_CP_STATE_AA64,
67
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 14, .opc2 = 1,
68
.access = PL0_W, .type = ARM_CP_NOP,
69
- .accessfn = aa64_cacheop_access },
70
+ .accessfn = aa64_cacheop_poc_access },
71
{ .name = "DC_CISW", .state = ARM_CP_STATE_AA64,
72
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
73
.access = PL1_W, .accessfn = access_tsw, .type = ARM_CP_NOP },
74
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
75
{ .name = "BPIMVA", .cp = 15, .opc1 = 0, .crn = 7, .crm = 5, .opc2 = 7,
76
.type = ARM_CP_NOP, .access = PL1_W },
77
{ .name = "DCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
78
- .type = ARM_CP_NOP, .access = PL1_W },
79
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
80
{ .name = "DCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 2,
81
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
82
{ .name = "DCCMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 1,
83
- .type = ARM_CP_NOP, .access = PL1_W },
84
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
85
{ .name = "DCCSW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 10, .opc2 = 2,
86
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
87
{ .name = "DCCMVAU", .cp = 15, .opc1 = 0, .crn = 7, .crm = 11, .opc2 = 1,
88
.type = ARM_CP_NOP, .access = PL1_W },
89
{ .name = "DCCIMVAC", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 1,
90
- .type = ARM_CP_NOP, .access = PL1_W },
91
+ .type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_poc_access },
92
{ .name = "DCCISW", .cp = 15, .opc1 = 0, .crn = 7, .crm = 14, .opc2 = 2,
93
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = access_tsw },
94
/* MMU Domain access control / MPU write buffer control */
95
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpop_reg[] = {
96
{ .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
97
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
98
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
99
- .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
100
+ .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
101
REGINFO_SENTINEL
102
};
43
};
103
44
104
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dcpodp_reg[] = {
45
int kvm_arm_cpreg_level(uint64_t regidx)
105
{ .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
106
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
107
.access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
108
- .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
109
+ .accessfn = aa64_cacheop_poc_access, .writefn = dccvap_writefn },
110
REGINFO_SENTINEL
111
};
112
#endif /*CONFIG_USER_ONLY*/
113
--
46
--
114
2.20.1
47
2.34.1
115
116
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Update the {TGE,E2H} == '11' masking to ARMv8.6.
3
Provide a stub implementation, as a write is a "request".
4
If EL2 is configured for aarch32, disable all of
5
the bits that are RES0 in aarch32 mode.
6
4
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200229012811.24129-6-richard.henderson@linaro.org
6
Message-id: 20230831232441.66020-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/helper.c | 31 +++++++++++++++++++++++++++----
10
target/arm/helper.c | 64 +++++++++++++++++++++++++++++----------------
13
1 file changed, 27 insertions(+), 4 deletions(-)
11
1 file changed, 41 insertions(+), 23 deletions(-)
14
12
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ uint64_t arm_hcr_el2_eff(CPUARMState *env)
17
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
20
* Since the v8.4 language applies to the entire register, and
18
};
21
* appears to be backward compatible, use that.
19
modify_arm_cp_regs(v8_idregs, v8_user_idregs);
22
*/
20
#endif
23
- ret = 0;
21
- /* RVBAR_EL1 is only implemented if EL1 is the highest EL */
24
- } else if (ret & HCR_TGE) {
25
- /* These bits are up-to-date as of ARMv8.4. */
26
+ return 0;
27
+ }
28
+
29
+ /*
30
+ * For a cpu that supports both aarch64 and aarch32, we can set bits
31
+ * in HCR_EL2 (e.g. via EL3) that are RES0 when we enter EL2 as aa32.
32
+ * Ignore all of the bits in HCR+HCR2 that are not valid for aarch32.
33
+ */
34
+ if (!arm_el_is_aa64(env, 2)) {
35
+ uint64_t aa32_valid;
36
+
37
+ /*
22
+ /*
38
+ * These bits are up-to-date as of ARMv8.6.
23
+ * RVBAR_EL1 and RMR_EL1 only implemented if EL1 is the highest EL.
39
+ * For HCR, it's easiest to list just the 2 bits that are invalid.
24
+ * TODO: For RMR, a write with bit 1 set should do something with
40
+ * For HCR2, list those that are valid.
25
+ * cpu_reset(). In the meantime, "the bit is strictly a request",
26
+ * so we are in spec just ignoring writes.
41
+ */
27
+ */
42
+ aa32_valid = MAKE_64BIT_MASK(0, 32) & ~(HCR_RW | HCR_TDZ);
28
if (!arm_feature(env, ARM_FEATURE_EL3) &&
43
+ aa32_valid |= (HCR_CD | HCR_ID | HCR_TERR | HCR_TEA | HCR_MIOCNCE |
29
!arm_feature(env, ARM_FEATURE_EL2)) {
44
+ HCR_TID4 | HCR_TICAB | HCR_TOCU | HCR_TTLBIS);
30
- ARMCPRegInfo rvbar = {
45
+ ret &= aa32_valid;
31
- .name = "RVBAR_EL1", .state = ARM_CP_STATE_BOTH,
46
+ }
32
- .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
47
+
33
- .access = PL1_R,
48
+ if (ret & HCR_TGE) {
34
- .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
49
+ /* These bits are up-to-date as of ARMv8.6. */
35
+ ARMCPRegInfo el1_reset_regs[] = {
50
if (ret & HCR_E2H) {
36
+ { .name = "RVBAR_EL1", .state = ARM_CP_STATE_BOTH,
51
ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
37
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
52
HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
38
+ .access = PL1_R,
53
HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
39
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar) },
54
- HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE);
40
+ { .name = "RMR_EL1", .state = ARM_CP_STATE_BOTH,
55
+ HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE |
41
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 2,
56
+ HCR_TID4 | HCR_TICAB | HCR_TOCU | HCR_ENSCXT |
42
+ .access = PL1_RW, .type = ARM_CP_CONST,
57
+ HCR_TTLBIS | HCR_TTLBOS | HCR_TID5);
43
+ .resetvalue = arm_feature(env, ARM_FEATURE_AARCH64) }
58
} else {
44
};
59
ret |= HCR_FMO | HCR_IMO | HCR_AMO;
45
- define_one_arm_cp_reg(cpu, &rvbar);
46
+ define_arm_cp_regs(cpu, el1_reset_regs);
60
}
47
}
48
define_arm_cp_regs(cpu, v8_idregs);
49
define_arm_cp_regs(cpu, v8_cp_reginfo);
50
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
51
if (cpu_isar_feature(aa64_sel2, cpu)) {
52
define_arm_cp_regs(cpu, el2_sec_cp_reginfo);
53
}
54
- /* RVBAR_EL2 is only implemented if EL2 is the highest EL */
55
+ /*
56
+ * RVBAR_EL2 and RMR_EL2 only implemented if EL2 is the highest EL.
57
+ * See commentary near RMR_EL1.
58
+ */
59
if (!arm_feature(env, ARM_FEATURE_EL3)) {
60
- ARMCPRegInfo rvbar[] = {
61
- {
62
- .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
63
- .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
64
- .access = PL2_R,
65
- .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
66
- },
67
- { .name = "RVBAR", .type = ARM_CP_ALIAS,
68
- .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
69
- .access = PL2_R,
70
- .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
71
- },
72
+ static const ARMCPRegInfo el2_reset_regs[] = {
73
+ { .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
74
+ .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
75
+ .access = PL2_R,
76
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar) },
77
+ { .name = "RVBAR", .type = ARM_CP_ALIAS,
78
+ .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
79
+ .access = PL2_R,
80
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar) },
81
+ { .name = "RMR_EL2", .state = ARM_CP_STATE_AA64,
82
+ .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 2,
83
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 1 },
84
};
85
- define_arm_cp_regs(cpu, rvbar);
86
+ define_arm_cp_regs(cpu, el2_reset_regs);
87
}
88
}
89
90
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
91
{ .name = "RVBAR_EL3", .state = ARM_CP_STATE_AA64,
92
.opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 1,
93
.access = PL3_R,
94
- .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
95
- },
96
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar), },
97
+ { .name = "RMR_EL3", .state = ARM_CP_STATE_AA64,
98
+ .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 0, .opc2 = 2,
99
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 1 },
100
+ { .name = "RMR", .state = ARM_CP_STATE_AA32,
101
+ .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 2,
102
+ .access = PL3_RW, .type = ARM_CP_CONST,
103
+ .resetvalue = arm_feature(env, ARM_FEATURE_AARCH64) },
104
{ .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64,
105
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0,
106
.access = PL3_RW,
61
--
107
--
62
2.20.1
108
2.34.1
63
64
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
If by context we know that we're in AArch64 mode, we need not
3
The cortex-a710 is a first generation ARMv9.0-A processor.
4
test for M-profile when reconstructing the full ARMMMUIdx.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20230831232441.66020-3-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200302175829.2183-4-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/internals.h | 6 ++++++
10
docs/system/arm/virt.rst | 1 +
13
target/arm/translate-a64.c | 2 +-
11
hw/arm/virt.c | 1 +
14
2 files changed, 7 insertions(+), 1 deletion(-)
12
target/arm/tcg/cpu64.c | 212 +++++++++++++++++++++++++++++++++++++++
13
3 files changed, 214 insertions(+)
15
14
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
17
--- a/docs/system/arm/virt.rst
19
+++ b/target/arm/internals.h
18
+++ b/docs/system/arm/virt.rst
20
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx)
19
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
21
}
20
- ``cortex-a57`` (64-bit)
21
- ``cortex-a72`` (64-bit)
22
- ``cortex-a76`` (64-bit)
23
+- ``cortex-a710`` (64-bit)
24
- ``a64fx`` (64-bit)
25
- ``host`` (with KVM only)
26
- ``neoverse-n1`` (64-bit)
27
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/virt.c
30
+++ b/hw/arm/virt.c
31
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
32
ARM_CPU_TYPE_NAME("cortex-a55"),
33
ARM_CPU_TYPE_NAME("cortex-a72"),
34
ARM_CPU_TYPE_NAME("cortex-a76"),
35
+ ARM_CPU_TYPE_NAME("cortex-a710"),
36
ARM_CPU_TYPE_NAME("a64fx"),
37
ARM_CPU_TYPE_NAME("neoverse-n1"),
38
ARM_CPU_TYPE_NAME("neoverse-v1"),
39
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/tcg/cpu64.c
42
+++ b/target/arm/tcg/cpu64.c
43
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_v1_initfn(Object *obj)
44
aarch64_add_sve_properties(obj);
22
}
45
}
23
46
24
+static inline ARMMMUIdx core_to_aa64_mmu_idx(int mmu_idx)
47
+static const ARMCPRegInfo cortex_a710_cp_reginfo[] = {
48
+ { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
49
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 0,
50
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
51
+ .accessfn = access_actlr_w },
52
+ { .name = "CPUACTLR2_EL1", .state = ARM_CP_STATE_AA64,
53
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 1,
54
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
55
+ .accessfn = access_actlr_w },
56
+ { .name = "CPUACTLR3_EL1", .state = ARM_CP_STATE_AA64,
57
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 2,
58
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
59
+ .accessfn = access_actlr_w },
60
+ { .name = "CPUACTLR4_EL1", .state = ARM_CP_STATE_AA64,
61
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 3,
62
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
63
+ .accessfn = access_actlr_w },
64
+ { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
65
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 4,
66
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
67
+ .accessfn = access_actlr_w },
68
+ { .name = "CPUECTLR2_EL1", .state = ARM_CP_STATE_AA64,
69
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 5,
70
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
71
+ .accessfn = access_actlr_w },
72
+ { .name = "CPUPPMCR_EL3", .state = ARM_CP_STATE_AA64,
73
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 4,
74
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
75
+ { .name = "CPUPWRCTLR_EL1", .state = ARM_CP_STATE_AA64,
76
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
77
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
78
+ .accessfn = access_actlr_w },
79
+ { .name = "ATCR_EL1", .state = ARM_CP_STATE_AA64,
80
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 7, .opc2 = 0,
81
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
82
+ { .name = "CPUACTLR5_EL1", .state = ARM_CP_STATE_AA64,
83
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 8, .opc2 = 0,
84
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
85
+ .accessfn = access_actlr_w },
86
+ { .name = "CPUACTLR6_EL1", .state = ARM_CP_STATE_AA64,
87
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 8, .opc2 = 1,
88
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
89
+ .accessfn = access_actlr_w },
90
+ { .name = "CPUACTLR7_EL1", .state = ARM_CP_STATE_AA64,
91
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 8, .opc2 = 2,
92
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
93
+ .accessfn = access_actlr_w },
94
+ { .name = "ATCR_EL2", .state = ARM_CP_STATE_AA64,
95
+ .opc0 = 3, .opc1 = 4, .crn = 15, .crm = 7, .opc2 = 0,
96
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
97
+ { .name = "AVTCR_EL2", .state = ARM_CP_STATE_AA64,
98
+ .opc0 = 3, .opc1 = 4, .crn = 15, .crm = 7, .opc2 = 1,
99
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
100
+ { .name = "CPUPPMCR_EL3", .state = ARM_CP_STATE_AA64,
101
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 0,
102
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
103
+ { .name = "CPUPPMCR2_EL3", .state = ARM_CP_STATE_AA64,
104
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 1,
105
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
106
+ { .name = "CPUPPMCR4_EL3", .state = ARM_CP_STATE_AA64,
107
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 4,
108
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
109
+ { .name = "CPUPPMCR5_EL3", .state = ARM_CP_STATE_AA64,
110
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 5,
111
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
112
+ { .name = "CPUPPMCR6_EL3", .state = ARM_CP_STATE_AA64,
113
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 6,
114
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
115
+ { .name = "CPUACTLR_EL3", .state = ARM_CP_STATE_AA64,
116
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 4, .opc2 = 0,
117
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
118
+ { .name = "ATCR_EL3", .state = ARM_CP_STATE_AA64,
119
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 7, .opc2 = 0,
120
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
121
+ { .name = "CPUPSELR_EL3", .state = ARM_CP_STATE_AA64,
122
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 0,
123
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
124
+ { .name = "CPUPCR_EL3", .state = ARM_CP_STATE_AA64,
125
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 1,
126
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
127
+ { .name = "CPUPOR_EL3", .state = ARM_CP_STATE_AA64,
128
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 2,
129
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
130
+ { .name = "CPUPMR_EL3", .state = ARM_CP_STATE_AA64,
131
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 3,
132
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
133
+ { .name = "CPUPOR2_EL3", .state = ARM_CP_STATE_AA64,
134
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 4,
135
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
136
+ { .name = "CPUPMR2_EL3", .state = ARM_CP_STATE_AA64,
137
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 5,
138
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
139
+ { .name = "CPUPFR_EL3", .state = ARM_CP_STATE_AA64,
140
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 6,
141
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
142
+
143
+ /*
144
+ * Stub RAMINDEX, as we don't actually implement caches, BTB,
145
+ * or anything else with cpu internal memory.
146
+ * "Read" zeros into the IDATA* and DDATA* output registers.
147
+ */
148
+ { .name = "RAMINDEX_EL3", .state = ARM_CP_STATE_AA64,
149
+ .opc0 = 1, .opc1 = 6, .crn = 15, .crm = 0, .opc2 = 0,
150
+ .access = PL3_W, .type = ARM_CP_CONST, .resetvalue = 0 },
151
+ { .name = "IDATA0_EL3", .state = ARM_CP_STATE_AA64,
152
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 0, .opc2 = 0,
153
+ .access = PL3_R, .type = ARM_CP_CONST, .resetvalue = 0 },
154
+ { .name = "IDATA1_EL3", .state = ARM_CP_STATE_AA64,
155
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 0, .opc2 = 1,
156
+ .access = PL3_R, .type = ARM_CP_CONST, .resetvalue = 0 },
157
+ { .name = "IDATA2_EL3", .state = ARM_CP_STATE_AA64,
158
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 0, .opc2 = 2,
159
+ .access = PL3_R, .type = ARM_CP_CONST, .resetvalue = 0 },
160
+ { .name = "DDATA0_EL3", .state = ARM_CP_STATE_AA64,
161
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 1, .opc2 = 0,
162
+ .access = PL3_R, .type = ARM_CP_CONST, .resetvalue = 0 },
163
+ { .name = "DDATA1_EL3", .state = ARM_CP_STATE_AA64,
164
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 1, .opc2 = 1,
165
+ .access = PL3_R, .type = ARM_CP_CONST, .resetvalue = 0 },
166
+ { .name = "DDATA2_EL3", .state = ARM_CP_STATE_AA64,
167
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 1, .opc2 = 2,
168
+ .access = PL3_R, .type = ARM_CP_CONST, .resetvalue = 0 },
169
+};
170
+
171
+static void aarch64_a710_initfn(Object *obj)
25
+{
172
+{
26
+ /* AArch64 is always a-profile. */
173
+ ARMCPU *cpu = ARM_CPU(obj);
27
+ return mmu_idx | ARM_MMU_IDX_A;
174
+
175
+ cpu->dtb_compatible = "arm,cortex-a710";
176
+ set_feature(&cpu->env, ARM_FEATURE_V8);
177
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
178
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
179
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
180
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
181
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
182
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
183
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
184
+
185
+ /* Ordered by Section B.4: AArch64 registers */
186
+ cpu->midr = 0x412FD471; /* r2p1 */
187
+ cpu->revidr = 0;
188
+ cpu->isar.id_pfr0 = 0x21110131;
189
+ cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
190
+ cpu->isar.id_dfr0 = 0x16011099;
191
+ cpu->id_afr0 = 0;
192
+ cpu->isar.id_mmfr0 = 0x10201105;
193
+ cpu->isar.id_mmfr1 = 0x40000000;
194
+ cpu->isar.id_mmfr2 = 0x01260000;
195
+ cpu->isar.id_mmfr3 = 0x02122211;
196
+ cpu->isar.id_isar0 = 0x02101110;
197
+ cpu->isar.id_isar1 = 0x13112111;
198
+ cpu->isar.id_isar2 = 0x21232042;
199
+ cpu->isar.id_isar3 = 0x01112131;
200
+ cpu->isar.id_isar4 = 0x00010142;
201
+ cpu->isar.id_isar5 = 0x11011121; /* with Crypto */
202
+ cpu->isar.id_mmfr4 = 0x21021110;
203
+ cpu->isar.id_isar6 = 0x01111111;
204
+ cpu->isar.mvfr0 = 0x10110222;
205
+ cpu->isar.mvfr1 = 0x13211111;
206
+ cpu->isar.mvfr2 = 0x00000043;
207
+ cpu->isar.id_pfr2 = 0x00000011;
208
+ cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */
209
+ cpu->isar.id_aa64pfr1 = 0x0000000000000221ull;
210
+ cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */
211
+ cpu->isar.id_aa64dfr0 = 0x000011f010305611ull;
212
+ cpu->isar.id_aa64dfr1 = 0;
213
+ cpu->id_aa64afr0 = 0;
214
+ cpu->id_aa64afr1 = 0;
215
+ cpu->isar.id_aa64isar0 = 0x0221111110212120ull; /* with Crypto */
216
+ cpu->isar.id_aa64isar1 = 0x0010111101211032ull;
217
+ cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull;
218
+ cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
219
+ cpu->isar.id_aa64mmfr2 = 0x1221011110101011ull;
220
+ cpu->clidr = 0x0000001482000023ull;
221
+ cpu->gm_blocksize = 4;
222
+ cpu->ctr = 0x000000049444c004ull;
223
+ cpu->dcz_blocksize = 4;
224
+ /* TODO FEAT_MPAM: mpamidr_el1 = 0x0000_0001_0006_003f */
225
+
226
+ /* Section B.5.2: PMCR_EL0 */
227
+ cpu->isar.reset_pmcr_el0 = 0xa000; /* with 20 counters */
228
+
229
+ /* Section B.6.7: ICH_VTR_EL2 */
230
+ cpu->gic_num_lrs = 4;
231
+ cpu->gic_vpribits = 5;
232
+ cpu->gic_vprebits = 5;
233
+ cpu->gic_pribits = 5;
234
+
235
+ /* Section 14: Scalable Vector Extensions support */
236
+ cpu->sve_vq.supported = 1 << 0; /* 128bit */
237
+
238
+ /*
239
+ * The cortex-a710 TRM does not list CCSIDR values. The layout of
240
+ * the caches are in text in Table 7-1, Table 8-1, and Table 9-1.
241
+ *
242
+ * L1: 4-way set associative 64-byte line size, total either 32K or 64K.
243
+ * L2: 8-way set associative 64 byte line size, total either 256K or 512K.
244
+ */
245
+ cpu->ccsidr[0] = make_ccsidr64(4, 64, 64 * KiB); /* L1 dcache */
246
+ cpu->ccsidr[1] = cpu->ccsidr[0]; /* L1 icache */
247
+ cpu->ccsidr[2] = make_ccsidr64(8, 64, 512 * KiB); /* L2 cache */
248
+
249
+ /* FIXME: Not documented -- copied from neoverse-v1 */
250
+ cpu->reset_sctlr = 0x30c50838;
251
+
252
+ define_arm_cp_regs(cpu, cortex_a710_cp_reginfo);
253
+
254
+ aarch64_add_pauth_properties(obj);
255
+ aarch64_add_sve_properties(obj);
28
+}
256
+}
29
+
257
+
30
int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
31
32
/*
258
/*
33
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
259
* -cpu max: a CPU with as many features enabled as our emulation supports.
34
index XXXXXXX..XXXXXXX 100644
260
* The version of '-cpu max' for qemu-system-arm is defined in cpu32.c;
35
--- a/target/arm/translate-a64.c
261
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
36
+++ b/target/arm/translate-a64.c
262
{ .name = "cortex-a55", .initfn = aarch64_a55_initfn },
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
263
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
38
dc->condexec_mask = 0;
264
{ .name = "cortex-a76", .initfn = aarch64_a76_initfn },
39
dc->condexec_cond = 0;
265
+ { .name = "cortex-a710", .initfn = aarch64_a710_initfn },
40
core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
266
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
41
- dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
267
{ .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
42
+ dc->mmu_idx = core_to_aa64_mmu_idx(core_mmu_idx);
268
{ .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
43
dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
44
dc->tbid = FIELD_EX32(tb_flags, TBFLAG_A64, TBID);
45
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
46
--
269
--
47
2.20.1
270
2.34.1
48
49
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 bits trap EL1 access to various virtual memory controls.
3
Perform the check for EL2 enabled in the security space and the
4
TIDCP bit in an out-of-line helper.
4
5
5
Buglink: https://bugs.launchpad.net/bugs/1855072
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20230831232441.66020-4-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200229012811.24129-7-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/helper.c | 82 ++++++++++++++++++++++++++++++---------------
11
target/arm/helper.h | 1 +
12
1 file changed, 55 insertions(+), 27 deletions(-)
12
target/arm/tcg/op_helper.c | 13 +++++++++++++
13
target/arm/tcg/translate-a64.c | 16 ++++++++++++++--
14
target/arm/tcg/translate.c | 27 +++++++++++++++++++++++++++
15
4 files changed, 55 insertions(+), 2 deletions(-)
13
16
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
19
--- a/target/arm/helper.h
17
+++ b/target/arm/helper.c
20
+++ b/target/arm/helper.h
18
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(check_bxj_trap, TCG_CALL_NO_WG, void, env, i32)
19
return CP_ACCESS_OK;
22
23
DEF_HELPER_4(access_check_cp_reg, cptr, env, i32, i32, i32)
24
DEF_HELPER_FLAGS_2(lookup_cp_reg, TCG_CALL_NO_RWG_SE, cptr, env, i32)
25
+DEF_HELPER_FLAGS_2(tidcp_el1, TCG_CALL_NO_WG, void, env, i32)
26
DEF_HELPER_3(set_cp_reg, void, env, cptr, i32)
27
DEF_HELPER_2(get_cp_reg, i32, env, cptr)
28
DEF_HELPER_3(set_cp_reg64, void, env, cptr, i64)
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/tcg/op_helper.c
32
+++ b/target/arm/tcg/op_helper.c
33
@@ -XXX,XX +XXX,XX @@ const void *HELPER(lookup_cp_reg)(CPUARMState *env, uint32_t key)
34
return ri;
20
}
35
}
21
36
22
+/* Check for traps from EL1 due to HCR_EL2.TVM and HCR_EL2.TRVM. */
37
+/*
23
+static CPAccessResult access_tvm_trvm(CPUARMState *env, const ARMCPRegInfo *ri,
38
+ * Test for HCR_EL2.TIDCP at EL1.
24
+ bool isread)
39
+ * Since implementation defined registers are rare, and within QEMU
40
+ * most of them are no-op, do not waste HFLAGS space for this and
41
+ * always use a helper.
42
+ */
43
+void HELPER(tidcp_el1)(CPUARMState *env, uint32_t syndrome)
25
+{
44
+{
26
+ if (arm_current_el(env) == 1) {
45
+ if (arm_hcr_el2_eff(env) & HCR_TIDCP) {
27
+ uint64_t trap = isread ? HCR_TRVM : HCR_TVM;
46
+ raise_exception_ra(env, EXCP_UDEF, syndrome, 2, GETPC());
28
+ if (arm_hcr_el2_eff(env) & trap) {
47
+ }
29
+ return CP_ACCESS_TRAP_EL2;
48
+}
49
+
50
void HELPER(set_cp_reg)(CPUARMState *env, const void *rip, uint32_t value)
51
{
52
const ARMCPRegInfo *ri = rip;
53
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/tcg/translate-a64.c
56
+++ b/target/arm/tcg/translate-a64.c
57
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
58
bool need_exit_tb = false;
59
TCGv_ptr tcg_ri = NULL;
60
TCGv_i64 tcg_rt;
61
+ uint32_t syndrome;
62
+
63
+ if (crn == 11 || crn == 15) {
64
+ /*
65
+ * Check for TIDCP trap, which must take precedence over
66
+ * the UNDEF for "no such register" etc.
67
+ */
68
+ syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
69
+ switch (s->current_el) {
70
+ case 1:
71
+ gen_helper_tidcp_el1(cpu_env, tcg_constant_i32(syndrome));
72
+ break;
30
+ }
73
+ }
31
+ }
74
+ }
32
+ return CP_ACCESS_OK;
75
76
if (!ri) {
77
/* Unknown register; this might be a guest error or a QEMU
78
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
79
/* Emit code to perform further access permissions checks at
80
* runtime; this may result in an exception.
81
*/
82
- uint32_t syndrome;
83
-
84
syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
85
gen_a64_update_pc(s, 0);
86
tcg_ri = tcg_temp_new_ptr();
87
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/tcg/translate.c
90
+++ b/target/arm/tcg/translate.c
91
@@ -XXX,XX +XXX,XX @@ void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
92
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
93
}
94
95
+static bool aa32_cpreg_encoding_in_impdef_space(uint8_t crn, uint8_t crm)
96
+{
97
+ static const uint16_t mask[3] = {
98
+ 0b0000000111100111, /* crn == 9, crm == {c0-c2, c5-c8} */
99
+ 0b0000000100010011, /* crn == 10, crm == {c0, c1, c4, c8} */
100
+ 0b1000000111111111, /* crn == 11, crm == {c0-c8, c15} */
101
+ };
102
+
103
+ if (crn >= 9 && crn <= 11) {
104
+ return (mask[crn - 9] >> crm) & 1;
105
+ }
106
+ return false;
33
+}
107
+}
34
+
108
+
35
static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
109
static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
36
{
110
int opc1, int crn, int crm, int opc2,
37
ARMCPU *cpu = env_archcpu(env);
111
bool isread, int rt, int rt2)
38
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
112
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
39
*/
113
}
40
{ .name = "CONTEXTIDR_EL1", .state = ARM_CP_STATE_BOTH,
114
}
41
.opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
115
42
- .access = PL1_RW, .secure = ARM_CP_SECSTATE_NS,
116
+ if (cpnum == 15 && aa32_cpreg_encoding_in_impdef_space(crn, crm)) {
43
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
117
+ /*
44
+ .secure = ARM_CP_SECSTATE_NS,
118
+ * Check for TIDCP trap, which must take precedence over the UNDEF
45
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[1]),
119
+ * for "no such register" etc. It shares precedence with HSTR,
46
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
120
+ * but raises the same exception, so order doesn't matter.
47
{ .name = "CONTEXTIDR_S", .state = ARM_CP_STATE_AA32,
121
+ */
48
.cp = 15, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 1,
122
+ switch (s->current_el) {
49
- .access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
123
+ case 1:
50
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
124
+ gen_helper_tidcp_el1(cpu_env, tcg_constant_i32(syndrome));
51
+ .secure = ARM_CP_SECSTATE_S,
125
+ break;
52
.fieldoffset = offsetof(CPUARMState, cp15.contextidr_s),
126
+ }
53
.resetvalue = 0, .writefn = contextidr_write, .raw_writefn = raw_write, },
127
+ }
54
REGINFO_SENTINEL
128
+
55
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
129
if (!ri) {
56
/* MMU Domain access control / MPU write buffer control */
130
/*
57
{ .name = "DACR",
131
* Unknown register; this might be a guest error or a QEMU
58
.cp = 15, .opc1 = CP_ANY, .crn = 3, .crm = CP_ANY, .opc2 = CP_ANY,
59
- .access = PL1_RW, .resetvalue = 0,
60
+ .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
61
.writefn = dacr_write, .raw_writefn = raw_write,
62
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
63
offsetoflow32(CPUARMState, cp15.dacr_ns) } },
64
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
65
{ .name = "DMB", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 5,
66
.access = PL0_W, .type = ARM_CP_NOP },
67
{ .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2,
68
- .access = PL1_RW,
69
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
70
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s),
71
offsetof(CPUARMState, cp15.ifar_ns) },
72
.resetvalue = 0, },
73
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
74
*/
75
{ .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH,
76
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 0,
77
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
78
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
79
+ .type = ARM_CP_CONST, .resetvalue = 0 },
80
{ .name = "AFSR1_EL1", .state = ARM_CP_STATE_BOTH,
81
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
82
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
83
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
84
+ .type = ARM_CP_CONST, .resetvalue = 0 },
85
/* MAIR can just read-as-written because we don't implement caches
86
* and so don't need to care about memory attributes.
87
*/
88
{ .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
89
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
90
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
91
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
92
+ .fieldoffset = offsetof(CPUARMState, cp15.mair_el[1]),
93
.resetvalue = 0 },
94
{ .name = "MAIR_EL3", .state = ARM_CP_STATE_AA64,
95
.opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0,
96
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
97
* handled in the field definitions.
98
*/
99
{ .name = "MAIR0", .state = ARM_CP_STATE_AA32,
100
- .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0, .access = PL1_RW,
101
+ .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 0,
102
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
103
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair0_s),
104
offsetof(CPUARMState, cp15.mair0_ns) },
105
.resetfn = arm_cp_reset_ignore },
106
{ .name = "MAIR1", .state = ARM_CP_STATE_AA32,
107
- .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1, .access = PL1_RW,
108
+ .cp = 15, .opc1 = 0, .crn = 10, .crm = 2, .opc2 = 1,
109
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
110
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.mair1_s),
111
offsetof(CPUARMState, cp15.mair1_ns) },
112
.resetfn = arm_cp_reset_ignore },
113
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
114
115
static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
116
{ .name = "DFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 0,
117
- .access = PL1_RW, .type = ARM_CP_ALIAS,
118
+ .access = PL1_RW, .accessfn = access_tvm_trvm, .type = ARM_CP_ALIAS,
119
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dfsr_s),
120
offsetoflow32(CPUARMState, cp15.dfsr_ns) }, },
121
{ .name = "IFSR", .cp = 15, .crn = 5, .crm = 0, .opc1 = 0, .opc2 = 1,
122
- .access = PL1_RW, .resetvalue = 0,
123
+ .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
124
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.ifsr_s),
125
offsetoflow32(CPUARMState, cp15.ifsr_ns) } },
126
{ .name = "DFAR", .cp = 15, .opc1 = 0, .crn = 6, .crm = 0, .opc2 = 0,
127
- .access = PL1_RW, .resetvalue = 0,
128
+ .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
129
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.dfar_s),
130
offsetof(CPUARMState, cp15.dfar_ns) } },
131
{ .name = "FAR_EL1", .state = ARM_CP_STATE_AA64,
132
.opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0,
133
- .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
134
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
135
+ .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]),
136
.resetvalue = 0, },
137
REGINFO_SENTINEL
138
};
139
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
140
static const ARMCPRegInfo vmsa_cp_reginfo[] = {
141
{ .name = "ESR_EL1", .state = ARM_CP_STATE_AA64,
142
.opc0 = 3, .crn = 5, .crm = 2, .opc1 = 0, .opc2 = 0,
143
- .access = PL1_RW,
144
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
145
.fieldoffset = offsetof(CPUARMState, cp15.esr_el[1]), .resetvalue = 0, },
146
{ .name = "TTBR0_EL1", .state = ARM_CP_STATE_BOTH,
147
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
148
- .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
149
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
150
+ .writefn = vmsa_ttbr_write, .resetvalue = 0,
151
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
152
offsetof(CPUARMState, cp15.ttbr0_ns) } },
153
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
154
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
155
- .access = PL1_RW, .writefn = vmsa_ttbr_write, .resetvalue = 0,
156
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
157
+ .writefn = vmsa_ttbr_write, .resetvalue = 0,
158
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
159
offsetof(CPUARMState, cp15.ttbr1_ns) } },
160
{ .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
161
.opc0 = 3, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
162
- .access = PL1_RW, .writefn = vmsa_tcr_el12_write,
163
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
164
+ .writefn = vmsa_tcr_el12_write,
165
.resetfn = vmsa_ttbcr_reset, .raw_writefn = raw_write,
166
.fieldoffset = offsetof(CPUARMState, cp15.tcr_el[1]) },
167
{ .name = "TTBCR", .cp = 15, .crn = 2, .crm = 0, .opc1 = 0, .opc2 = 2,
168
- .access = PL1_RW, .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write,
169
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
170
+ .type = ARM_CP_ALIAS, .writefn = vmsa_ttbcr_write,
171
.raw_writefn = vmsa_ttbcr_raw_write,
172
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tcr_el[3]),
173
offsetoflow32(CPUARMState, cp15.tcr_el[1])} },
174
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
175
*/
176
static const ARMCPRegInfo ttbcr2_reginfo = {
177
.name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3,
178
- .access = PL1_RW, .type = ARM_CP_ALIAS,
179
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
180
+ .type = ARM_CP_ALIAS,
181
.bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]),
182
offsetofhigh32(CPUARMState, cp15.tcr_el[1]) },
183
};
184
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
185
/* NOP AMAIR0/1 */
186
{ .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
187
.opc0 = 3, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 0,
188
- .access = PL1_RW, .type = ARM_CP_CONST,
189
- .resetvalue = 0 },
190
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
191
+ .type = ARM_CP_CONST, .resetvalue = 0 },
192
/* AMAIR1 is mapped to AMAIR_EL1[63:32] */
193
{ .name = "AMAIR1", .cp = 15, .crn = 10, .crm = 3, .opc1 = 0, .opc2 = 1,
194
- .access = PL1_RW, .type = ARM_CP_CONST,
195
- .resetvalue = 0 },
196
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
197
+ .type = ARM_CP_CONST, .resetvalue = 0 },
198
{ .name = "PAR", .cp = 15, .crm = 7, .opc1 = 0,
199
.access = PL1_RW, .type = ARM_CP_64BIT, .resetvalue = 0,
200
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.par_s),
201
offsetof(CPUARMState, cp15.par_ns)} },
202
{ .name = "TTBR0", .cp = 15, .crm = 2, .opc1 = 0,
203
- .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
204
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
205
+ .type = ARM_CP_64BIT | ARM_CP_ALIAS,
206
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
207
offsetof(CPUARMState, cp15.ttbr0_ns) },
208
.writefn = vmsa_ttbr_write, },
209
{ .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
210
- .access = PL1_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
211
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
212
+ .type = ARM_CP_64BIT | ARM_CP_ALIAS,
213
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
214
offsetof(CPUARMState, cp15.ttbr1_ns) },
215
.writefn = vmsa_ttbr_write, },
216
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
217
.type = ARM_CP_NOP, .access = PL1_W },
218
/* MMU Domain access control / MPU write buffer control */
219
{ .name = "DACR", .cp = 15, .opc1 = 0, .crn = 3, .crm = 0, .opc2 = 0,
220
- .access = PL1_RW, .resetvalue = 0,
221
+ .access = PL1_RW, .accessfn = access_tvm_trvm, .resetvalue = 0,
222
.writefn = dacr_write, .raw_writefn = raw_write,
223
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
224
offsetoflow32(CPUARMState, cp15.dacr_ns) } },
225
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
226
ARMCPRegInfo sctlr = {
227
.name = "SCTLR", .state = ARM_CP_STATE_BOTH,
228
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 0,
229
- .access = PL1_RW,
230
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
231
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.sctlr_s),
232
offsetof(CPUARMState, cp15.sctlr_ns) },
233
.writefn = sctlr_write, .resetvalue = cpu->reset_sctlr,
234
--
132
--
235
2.20.1
133
2.34.1
236
237
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20200229012811.24129-3-richard.henderson@linaro.org
4
Message-id: 20230831232441.66020-5-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/cpu.h | 7 +++++++
8
docs/system/arm/emulation.rst | 1 +
9
1 file changed, 7 insertions(+)
9
target/arm/cpu.h | 5 +++++
10
target/arm/helper.h | 1 +
11
target/arm/tcg/cpu64.c | 1 +
12
target/arm/tcg/op_helper.c | 20 ++++++++++++++++++++
13
target/arm/tcg/translate-a64.c | 5 +++++
14
target/arm/tcg/translate.c | 6 ++++++
15
7 files changed, 39 insertions(+)
10
16
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
18
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/system/arm/emulation.rst
20
+++ b/docs/system/arm/emulation.rst
21
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
22
- FEAT_SME_I16I64 (16-bit to 64-bit integer widening outer product instructions)
23
- FEAT_SPECRES (Speculation restriction instructions)
24
- FEAT_SSBS (Speculative Store Bypass Safe)
25
+- FEAT_TIDCP1 (EL0 use of IMPLEMENTATION DEFINED functionality)
26
- FEAT_TLBIOS (TLB invalidate instructions in Outer Shareable domain)
27
- FEAT_TLBIRANGE (TLB invalidate range instructions)
28
- FEAT_TTCNP (Translation table Common not private translations)
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
31
--- a/target/arm/cpu.h
14
+++ b/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
15
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
33
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id)
16
#define HCR_TERR (1ULL << 36)
34
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0;
17
#define HCR_TEA (1ULL << 37)
35
}
18
#define HCR_MIOCNCE (1ULL << 38)
36
19
+/* RES0 bit 39 */
37
+static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id)
20
#define HCR_APK (1ULL << 40)
38
+{
21
#define HCR_API (1ULL << 41)
39
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR1, TIDCP1) != 0;
22
#define HCR_NV (1ULL << 42)
40
+}
23
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
41
+
24
#define HCR_NV2 (1ULL << 45)
42
static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
25
#define HCR_FWB (1ULL << 46)
43
{
26
#define HCR_FIEN (1ULL << 47)
44
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0;
27
+/* RES0 bit 48 */
45
diff --git a/target/arm/helper.h b/target/arm/helper.h
28
#define HCR_TID4 (1ULL << 49)
46
index XXXXXXX..XXXXXXX 100644
29
#define HCR_TICAB (1ULL << 50)
47
--- a/target/arm/helper.h
30
+#define HCR_AMVOFFEN (1ULL << 51)
48
+++ b/target/arm/helper.h
31
#define HCR_TOCU (1ULL << 52)
49
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(check_bxj_trap, TCG_CALL_NO_WG, void, env, i32)
32
+#define HCR_ENSCXT (1ULL << 53)
50
33
#define HCR_TTLBIS (1ULL << 54)
51
DEF_HELPER_4(access_check_cp_reg, cptr, env, i32, i32, i32)
34
#define HCR_TTLBOS (1ULL << 55)
52
DEF_HELPER_FLAGS_2(lookup_cp_reg, TCG_CALL_NO_RWG_SE, cptr, env, i32)
35
#define HCR_ATA (1ULL << 56)
53
+DEF_HELPER_FLAGS_2(tidcp_el0, TCG_CALL_NO_WG, void, env, i32)
36
#define HCR_DCT (1ULL << 57)
54
DEF_HELPER_FLAGS_2(tidcp_el1, TCG_CALL_NO_WG, void, env, i32)
37
+#define HCR_TID5 (1ULL << 58)
55
DEF_HELPER_3(set_cp_reg, void, env, cptr, i32)
38
+#define HCR_TWEDEN (1ULL << 59)
56
DEF_HELPER_2(get_cp_reg, i32, env, cptr)
39
+#define HCR_TWEDEL MAKE_64BIT_MASK(60, 4)
57
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
40
58
index XXXXXXX..XXXXXXX 100644
41
#define SCR_NS (1U << 0)
59
--- a/target/arm/tcg/cpu64.c
42
#define SCR_IRQ (1U << 1)
60
+++ b/target/arm/tcg/cpu64.c
61
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
62
t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
63
t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1); /* FEAT_ETS */
64
t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */
65
+ t = FIELD_DP64(t, ID_AA64MMFR1, TIDCP1, 1); /* FEAT_TIDCP1 */
66
cpu->isar.id_aa64mmfr1 = t;
67
68
t = cpu->isar.id_aa64mmfr2;
69
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/tcg/op_helper.c
72
+++ b/target/arm/tcg/op_helper.c
73
@@ -XXX,XX +XXX,XX @@ void HELPER(tidcp_el1)(CPUARMState *env, uint32_t syndrome)
74
}
75
}
76
77
+/*
78
+ * Similarly, for FEAT_TIDCP1 at EL0.
79
+ * We have already checked for the presence of the feature.
80
+ */
81
+void HELPER(tidcp_el0)(CPUARMState *env, uint32_t syndrome)
82
+{
83
+ /* See arm_sctlr(), but we also need the sctlr el. */
84
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, 0);
85
+ int target_el = mmu_idx == ARMMMUIdx_E20_0 ? 2 : 1;
86
+
87
+ /*
88
+ * The bit is not valid unless the target el is aa64, but since the
89
+ * bit test is simpler perform that first and check validity after.
90
+ */
91
+ if ((env->cp15.sctlr_el[target_el] & SCTLR_TIDCP)
92
+ && arm_el_is_aa64(env, target_el)) {
93
+ raise_exception_ra(env, EXCP_UDEF, syndrome, target_el, GETPC());
94
+ }
95
+}
96
+
97
void HELPER(set_cp_reg)(CPUARMState *env, const void *rip, uint32_t value)
98
{
99
const ARMCPRegInfo *ri = rip;
100
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/tcg/translate-a64.c
103
+++ b/target/arm/tcg/translate-a64.c
104
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, bool isread,
105
*/
106
syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
107
switch (s->current_el) {
108
+ case 0:
109
+ if (dc_isar_feature(aa64_tidcp1, s)) {
110
+ gen_helper_tidcp_el0(cpu_env, tcg_constant_i32(syndrome));
111
+ }
112
+ break;
113
case 1:
114
gen_helper_tidcp_el1(cpu_env, tcg_constant_i32(syndrome));
115
break;
116
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/tcg/translate.c
119
+++ b/target/arm/tcg/translate.c
120
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
121
* but raises the same exception, so order doesn't matter.
122
*/
123
switch (s->current_el) {
124
+ case 0:
125
+ if (arm_dc_feature(s, ARM_FEATURE_AARCH64)
126
+ && dc_isar_feature(aa64_tidcp1, s)) {
127
+ gen_helper_tidcp_el0(cpu_env, tcg_constant_i32(syndrome));
128
+ }
129
+ break;
130
case 1:
131
gen_helper_tidcp_el1(cpu_env, tcg_constant_i32(syndrome));
132
break;
43
--
133
--
44
2.20.1
134
2.34.1
45
46
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We have disabled EL2 and EL3 for user-only, which means that these
3
The linux kernel detects and enables this bit. Once trapped,
4
registers "don't exist" and should not be set.
4
EC_SYSTEMREGISTERTRAP is treated like EC_UNCATEGORIZED, so
5
no changes required within linux-user/aarch64/cpu_loop.c.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200229012811.24129-5-richard.henderson@linaro.org
8
Message-id: 20230831232441.66020-6-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/cpu.c | 6 ------
12
target/arm/cpu.c | 4 ++++
12
1 file changed, 6 deletions(-)
13
1 file changed, 4 insertions(+)
13
14
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
17
--- a/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj)
19
/* Enable all PAC keys. */
20
env->cp15.sctlr_el[1] |= (SCTLR_EnIA | SCTLR_EnIB |
21
SCTLR_EnDA | SCTLR_EnDB);
20
SCTLR_EnDA | SCTLR_EnDB);
22
- /* Enable all PAC instructions */
21
/* Trap on btype=3 for PACIxSP. */
23
- env->cp15.hcr_el2 |= HCR_API;
22
env->cp15.sctlr_el[1] |= SCTLR_BT0;
24
- env->cp15.scr_el3 |= SCR_API;
23
+ /* Trap on implementation defined registers. */
24
+ if (cpu_isar_feature(aa64_tidcp1, cpu)) {
25
+ env->cp15.sctlr_el[1] |= SCTLR_TIDCP;
26
+ }
25
/* and to the FP/Neon instructions */
27
/* and to the FP/Neon instructions */
26
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
28
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
27
/* and to the SVE instructions */
29
CPACR_EL1, FPEN, 3);
28
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
29
- env->cp15.cptr_el[3] |= CPTR_EZ;
30
/* with maximum vector length */
31
env->vfp.zcr_el[1] = cpu_isar_feature(aa64_sve, cpu) ?
32
cpu->sve_max_vq - 1 : 0;
33
- env->vfp.zcr_el[2] = env->vfp.zcr_el[1];
34
- env->vfp.zcr_el[3] = env->vfp.zcr_el[1];
35
/*
36
* Enable TBI0 and TBI1. While the real kernel only enables TBI0,
37
* turning on both here will produce smaller code and otherwise
38
--
30
--
39
2.20.1
31
2.34.1
40
41
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
2
2
3
The smmu_find_smmu_pcibus() function was introduced (in commit
3
Now that we have Eager Page Split support added for ARM in the kernel,
4
cac994ef43b) in a code format that could return an incorrect
4
enable it in Qemu. This adds,
5
pointer, which was then fixed by the previous commit.
5
-eager-split-size to -accel sub-options to set the eager page split chunk size.
6
We could have avoided this by writing the if() statement
6
-enable KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE.
7
differently. Do it now, in case this function is re-used.
8
The code is easier to review (harder to miss bugs).
9
7
10
Acked-by: Eric Auger <eric.auger@redhat.com>
8
The chunk size specifies how many pages to break at a time, using a
11
Reviewed-by: Peter Xu <peterx@redhat.com>
9
single allocation. Bigger the chunk size, more pages need to be
12
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
allocated ahead of time.
11
12
Reviewed-by: Gavin Shan <gshan@redhat.com>
13
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
14
Message-id: 20230905091246.1931-1-shameerali.kolothum.thodi@huawei.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
16
---
15
hw/arm/smmu-common.c | 25 +++++++++++++------------
17
include/sysemu/kvm_int.h | 1 +
16
1 file changed, 13 insertions(+), 12 deletions(-)
18
accel/kvm/kvm-all.c | 1 +
19
target/arm/kvm.c | 61 ++++++++++++++++++++++++++++++++++++++++
20
qemu-options.hx | 15 ++++++++++
21
4 files changed, 78 insertions(+)
17
22
18
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
23
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/smmu-common.c
25
--- a/include/sysemu/kvm_int.h
21
+++ b/hw/arm/smmu-common.c
26
+++ b/include/sysemu/kvm_int.h
22
@@ -XXX,XX +XXX,XX @@ inline int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
27
@@ -XXX,XX +XXX,XX @@ struct KVMState
23
SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num)
28
uint64_t kvm_dirty_ring_bytes; /* Size of the per-vcpu dirty ring */
24
{
29
uint32_t kvm_dirty_ring_size; /* Number of dirty GFNs per ring */
25
SMMUPciBus *smmu_pci_bus = s->smmu_pcibus_by_bus_num[bus_num];
30
bool kvm_dirty_ring_with_bitmap;
26
+ GHashTableIter iter;
31
+ uint64_t kvm_eager_split_size; /* Eager Page Splitting chunk size */
27
32
struct KVMDirtyRingReaper reaper;
28
- if (!smmu_pci_bus) {
33
NotifyVmexitOption notify_vmexit;
29
- GHashTableIter iter;
34
uint32_t notify_window;
30
-
35
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
31
- g_hash_table_iter_init(&iter, s->smmu_pcibus_by_busptr);
36
index XXXXXXX..XXXXXXX 100644
32
- while (g_hash_table_iter_next(&iter, NULL, (void **)&smmu_pci_bus)) {
37
--- a/accel/kvm/kvm-all.c
33
- if (pci_bus_num(smmu_pci_bus->bus) == bus_num) {
38
+++ b/accel/kvm/kvm-all.c
34
- s->smmu_pcibus_by_bus_num[bus_num] = smmu_pci_bus;
39
@@ -XXX,XX +XXX,XX @@ static void kvm_accel_instance_init(Object *obj)
35
- return smmu_pci_bus;
40
/* KVM dirty ring is by default off */
36
- }
41
s->kvm_dirty_ring_size = 0;
37
- }
42
s->kvm_dirty_ring_with_bitmap = false;
38
- smmu_pci_bus = NULL;
43
+ s->kvm_eager_split_size = 0;
39
+ if (smmu_pci_bus) {
44
s->notify_vmexit = NOTIFY_VMEXIT_OPTION_RUN;
40
+ return smmu_pci_bus;
45
s->notify_window = 0;
46
s->xen_version = 0;
47
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/kvm.c
50
+++ b/target/arm/kvm.c
51
@@ -XXX,XX +XXX,XX @@
52
#include "exec/address-spaces.h"
53
#include "hw/boards.h"
54
#include "hw/irq.h"
55
+#include "qapi/visitor.h"
56
#include "qemu/log.h"
57
58
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
59
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
60
}
41
}
61
}
42
- return smmu_pci_bus;
62
63
+ if (s->kvm_eager_split_size) {
64
+ uint32_t sizes;
43
+
65
+
44
+ g_hash_table_iter_init(&iter, s->smmu_pcibus_by_busptr);
66
+ sizes = kvm_vm_check_extension(s, KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES);
45
+ while (g_hash_table_iter_next(&iter, NULL, (void **)&smmu_pci_bus)) {
67
+ if (!sizes) {
46
+ if (pci_bus_num(smmu_pci_bus->bus) == bus_num) {
68
+ s->kvm_eager_split_size = 0;
47
+ s->smmu_pcibus_by_bus_num[bus_num] = smmu_pci_bus;
69
+ warn_report("Eager Page Split support not available");
48
+ return smmu_pci_bus;
70
+ } else if (!(s->kvm_eager_split_size & sizes)) {
71
+ error_report("Eager Page Split requested chunk size not valid");
72
+ ret = -EINVAL;
73
+ } else {
74
+ ret = kvm_vm_enable_cap(s, KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE, 0,
75
+ s->kvm_eager_split_size);
76
+ if (ret < 0) {
77
+ error_report("Enabling of Eager Page Split failed: %s",
78
+ strerror(-ret));
79
+ }
49
+ }
80
+ }
50
+ }
81
+ }
51
+
82
+
52
+ return NULL;
83
kvm_arm_init_debug(s);
84
85
return ret;
86
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void)
87
return true;
53
}
88
}
54
89
55
static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
90
+static void kvm_arch_get_eager_split_size(Object *obj, Visitor *v,
91
+ const char *name, void *opaque,
92
+ Error **errp)
93
+{
94
+ KVMState *s = KVM_STATE(obj);
95
+ uint64_t value = s->kvm_eager_split_size;
96
+
97
+ visit_type_size(v, name, &value, errp);
98
+}
99
+
100
+static void kvm_arch_set_eager_split_size(Object *obj, Visitor *v,
101
+ const char *name, void *opaque,
102
+ Error **errp)
103
+{
104
+ KVMState *s = KVM_STATE(obj);
105
+ uint64_t value;
106
+
107
+ if (s->fd != -1) {
108
+ error_setg(errp, "Unable to set early-split-size after KVM has been initialized");
109
+ return;
110
+ }
111
+
112
+ if (!visit_type_size(v, name, &value, errp)) {
113
+ return;
114
+ }
115
+
116
+ if (value && !is_power_of_2(value)) {
117
+ error_setg(errp, "early-split-size must be a power of two");
118
+ return;
119
+ }
120
+
121
+ s->kvm_eager_split_size = value;
122
+}
123
+
124
void kvm_arch_accel_class_init(ObjectClass *oc)
125
{
126
+ object_class_property_add(oc, "eager-split-size", "size",
127
+ kvm_arch_get_eager_split_size,
128
+ kvm_arch_set_eager_split_size, NULL, NULL);
129
+
130
+ object_class_property_set_description(oc, "eager-split-size",
131
+ "Eager Page Split chunk size for hugepages. (default: 0, disabled)");
132
}
133
diff --git a/qemu-options.hx b/qemu-options.hx
134
index XXXXXXX..XXXXXXX 100644
135
--- a/qemu-options.hx
136
+++ b/qemu-options.hx
137
@@ -XXX,XX +XXX,XX @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
138
" split-wx=on|off (enable TCG split w^x mapping)\n"
139
" tb-size=n (TCG translation block cache size)\n"
140
" dirty-ring-size=n (KVM dirty ring GFN count, default 0)\n"
141
+ " eager-split-size=n (KVM Eager Page Split chunk size, default 0, disabled. ARM only)\n"
142
" notify-vmexit=run|internal-error|disable,notify-window=n (enable notify VM exit and set notify window, x86 only)\n"
143
" thread=single|multi (enable multi-threaded TCG)\n", QEMU_ARCH_ALL)
144
SRST
145
@@ -XXX,XX +XXX,XX @@ SRST
146
is disabled (dirty-ring-size=0). When enabled, KVM will instead
147
record dirty pages in a bitmap.
148
149
+ ``eager-split-size=n``
150
+ KVM implements dirty page logging at the PAGE_SIZE granularity and
151
+ enabling dirty-logging on a huge-page requires breaking it into
152
+ PAGE_SIZE pages in the first place. KVM on ARM does this splitting
153
+ lazily by default. There are performance benefits in doing huge-page
154
+ split eagerly, especially in situations where TLBI costs associated
155
+ with break-before-make sequences are considerable and also if guest
156
+ workloads are read intensive. The size here specifies how many pages
157
+ to break at a time and needs to be a valid block size which is
158
+ 1GB/2MB/4KB, 32MB/16KB and 512MB/64KB for 4KB/16KB/64KB PAGE_SIZE
159
+ respectively. Be wary of specifying a higher size as it will have an
160
+ impact on the memory. By default, this feature is disabled
161
+ (eager-split-size=0).
162
+
163
``notify-vmexit=run|internal-error|disable,notify-window=n``
164
Enables or disables notify VM exit support on x86 host and specify
165
the corresponding notify window to trigger the VM exit if enabled.
56
--
166
--
57
2.20.1
167
2.34.1
58
59
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
As the Connex and Verdex machines only boot in little-endian,
4
we can simplify the code.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/gumstix.c | 16 ++--------------
12
1 file changed, 2 insertions(+), 14 deletions(-)
13
14
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/gumstix.c
17
+++ b/hw/arm/gumstix.c
18
@@ -XXX,XX +XXX,XX @@ static void connex_init(MachineState *machine)
19
{
20
PXA2xxState *cpu;
21
DriveInfo *dinfo;
22
- int be;
23
MemoryRegion *address_space_mem = get_system_memory();
24
25
uint32_t connex_rom = 0x01000000;
26
@@ -XXX,XX +XXX,XX @@ static void connex_init(MachineState *machine)
27
exit(1);
28
}
29
30
-#ifdef TARGET_WORDS_BIGENDIAN
31
- be = 1;
32
-#else
33
- be = 0;
34
-#endif
35
if (!pflash_cfi01_register(0x00000000, "connext.rom", connex_rom,
36
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
37
- sector_len, 2, 0, 0, 0, 0, be)) {
38
+ sector_len, 2, 0, 0, 0, 0, 0)) {
39
error_report("Error registering flash memory");
40
exit(1);
41
}
42
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
43
{
44
PXA2xxState *cpu;
45
DriveInfo *dinfo;
46
- int be;
47
MemoryRegion *address_space_mem = get_system_memory();
48
49
uint32_t verdex_rom = 0x02000000;
50
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
51
exit(1);
52
}
53
54
-#ifdef TARGET_WORDS_BIGENDIAN
55
- be = 1;
56
-#else
57
- be = 0;
58
-#endif
59
if (!pflash_cfi01_register(0x00000000, "verdex.rom", verdex_rom,
60
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
61
- sector_len, 2, 0, 0, 0, 0, be)) {
62
+ sector_len, 2, 0, 0, 0, 0, 0)) {
63
error_report("Error registering flash memory");
64
exit(1);
65
}
66
--
67
2.20.1
68
69
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
We only build the little-endian softmmu configurations. Checking
4
for big endian is pointless, remove the unused code.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/arm/mainstone.c | 8 +-------
11
1 file changed, 1 insertion(+), 7 deletions(-)
12
13
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mainstone.c
16
+++ b/hw/arm/mainstone.c
17
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
18
DeviceState *mst_irq;
19
DriveInfo *dinfo;
20
int i;
21
- int be;
22
MemoryRegion *rom = g_new(MemoryRegion, 1);
23
24
/* Setup CPU & memory */
25
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
26
memory_region_set_readonly(rom, true);
27
memory_region_add_subregion(address_space_mem, 0, rom);
28
29
-#ifdef TARGET_WORDS_BIGENDIAN
30
- be = 1;
31
-#else
32
- be = 0;
33
-#endif
34
/* There are two 32MiB flash devices on the board */
35
for (i = 0; i < 2; i ++) {
36
dinfo = drive_get(IF_PFLASH, 0, i);
37
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
38
i ? "mainstone.flash1" : "mainstone.flash0",
39
MAINSTONE_FLASH,
40
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
41
- sector_len, 4, 0, 0, 0, 0, be)) {
42
+ sector_len, 4, 0, 0, 0, 0, 0)) {
43
error_report("Error registering flash memory");
44
exit(1);
45
}
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
We only build the little-endian softmmu configurations. Checking
4
for big endian is pointless, remove the unused code.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/arm/omap_sx1.c | 11 ++---------
11
1 file changed, 2 insertions(+), 9 deletions(-)
12
13
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/omap_sx1.c
16
+++ b/hw/arm/omap_sx1.c
17
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
18
DriveInfo *dinfo;
19
int fl_idx;
20
uint32_t flash_size = flash0_size;
21
- int be;
22
23
if (machine->ram_size != mc->default_ram_size) {
24
char *sz = size_to_str(mc->default_ram_size);
25
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
26
OMAP_CS2_BASE, &cs[3]);
27
28
fl_idx = 0;
29
-#ifdef TARGET_WORDS_BIGENDIAN
30
- be = 1;
31
-#else
32
- be = 0;
33
-#endif
34
-
35
if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
36
if (!pflash_cfi01_register(OMAP_CS0_BASE,
37
"omap_sx1.flash0-1", flash_size,
38
blk_by_legacy_dinfo(dinfo),
39
- sector_size, 4, 0, 0, 0, 0, be)) {
40
+ sector_size, 4, 0, 0, 0, 0, 0)) {
41
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
42
fl_idx);
43
}
44
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
45
if (!pflash_cfi01_register(OMAP_CS1_BASE,
46
"omap_sx1.flash1-1", flash1_size,
47
blk_by_legacy_dinfo(dinfo),
48
- sector_size, 4, 0, 0, 0, 0, be)) {
49
+ sector_size, 4, 0, 0, 0, 0, 0)) {
50
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
51
fl_idx);
52
}
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
We only build the little-endian softmmu configurations. Checking
4
for big endian is pointless, remove the unused code.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/arm/z2.c | 8 +-------
11
1 file changed, 1 insertion(+), 7 deletions(-)
12
13
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/z2.c
16
+++ b/hw/arm/z2.c
17
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
18
uint32_t sector_len = 0x10000;
19
PXA2xxState *mpu;
20
DriveInfo *dinfo;
21
- int be;
22
void *z2_lcd;
23
I2CBus *bus;
24
DeviceState *wm;
25
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
26
/* Setup CPU & memory */
27
mpu = pxa270_init(address_space_mem, z2_binfo.ram_size, machine->cpu_type);
28
29
-#ifdef TARGET_WORDS_BIGENDIAN
30
- be = 1;
31
-#else
32
- be = 0;
33
-#endif
34
dinfo = drive_get(IF_PFLASH, 0, 0);
35
if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
36
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
37
- sector_len, 4, 0, 0, 0, 0, be)) {
38
+ sector_len, 4, 0, 0, 0, 0, 0)) {
39
error_report("Error registering flash memory");
40
exit(1);
41
}
42
--
43
2.20.1
44
45
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
We only build the little-endian softmmu configurations. Checking
4
for big endian is pointless, remove the unused code.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/arm/musicpal.c | 10 ----------
11
1 file changed, 10 deletions(-)
12
13
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/musicpal.c
16
+++ b/hw/arm/musicpal.c
17
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
18
* 0xFF800000 (if there is 8 MB flash). So remap flash access if the
19
* image is smaller than 32 MB.
20
*/
21
-#ifdef TARGET_WORDS_BIGENDIAN
22
- pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
23
- "musicpal.flash", flash_size,
24
- blk, 0x10000,
25
- MP_FLASH_SIZE_MAX / flash_size,
26
- 2, 0x00BF, 0x236D, 0x0000, 0x0000,
27
- 0x5555, 0x2AAA, 1);
28
-#else
29
pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
30
"musicpal.flash", flash_size,
31
blk, 0x10000,
32
MP_FLASH_SIZE_MAX / flash_size,
33
2, 0x00BF, 0x236D, 0x0000, 0x0000,
34
0x5555, 0x2AAA, 0);
35
-#endif
36
-
37
}
38
sysbus_create_simple(TYPE_MV88W8618_FLASHCFG, MP_FLASHCFG_BASE, NULL);
39
40
--
41
2.20.1
42
43
diff view generated by jsdifflib
Deleted patch
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
2
1
3
The Cubieboard is a singleboard computer with an Allwinner A10 System-on-Chip [1].
4
As documented in the Allwinner A10 User Manual V1.5 [2], the SoC has an ARM
5
Cortex-A8 processor. Currently the Cubieboard machine definition specifies the
6
ARM Cortex-A9 in its description and as the default CPU.
7
8
This patch corrects the Cubieboard machine definition to use the ARM Cortex-A8.
9
10
The only user-visible effect is that our textual description of the
11
machine was wrong, because hw/arm/allwinner-a10.c always creates a
12
Cortex-A8 CPU regardless of the default value in the MachineClass struct.
13
14
[1] http://docs.cubieboard.org/products/start#cubieboard1
15
[2] https://linux-sunxi.org/File:Allwinner_A10_User_manual_V1.5.pdf
16
17
Fixes: 8a863c8120994981a099
18
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
19
Message-id: 20200227220149.6845-2-nieklinnenbank@gmail.com
20
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
[note in commit message that the bug didn't have much visible effect]
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
25
hw/arm/cubieboard.c | 4 ++--
26
1 file changed, 2 insertions(+), 2 deletions(-)
27
28
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/cubieboard.c
31
+++ b/hw/arm/cubieboard.c
32
@@ -XXX,XX +XXX,XX @@ static void cubieboard_init(MachineState *machine)
33
34
static void cubieboard_machine_init(MachineClass *mc)
35
{
36
- mc->desc = "cubietech cubieboard (Cortex-A9)";
37
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
38
+ mc->desc = "cubietech cubieboard (Cortex-A8)";
39
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a8");
40
mc->init = cubieboard_init;
41
mc->block_default_type = IF_IDE;
42
mc->units_per_default_bus = 1;
43
--
44
2.20.1
45
46
diff view generated by jsdifflib
Deleted patch
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
2
1
3
The Cubieboard has an ARM Cortex-A8. Instead of simply ignoring a
4
bogus -cpu option provided by the user, give them an error message so
5
they know their command line is wrong.
6
7
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
8
Message-id: 20200227220149.6845-3-nieklinnenbank@gmail.com
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: tweaked commit message]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/cubieboard.c | 10 +++++++++-
15
1 file changed, 9 insertions(+), 1 deletion(-)
16
17
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/cubieboard.c
20
+++ b/hw/arm/cubieboard.c
21
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info cubieboard_binfo = {
22
23
static void cubieboard_init(MachineState *machine)
24
{
25
- AwA10State *a10 = AW_A10(object_new(TYPE_AW_A10));
26
+ AwA10State *a10;
27
Error *err = NULL;
28
29
+ /* Only allow Cortex-A8 for this board */
30
+ if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a8")) != 0) {
31
+ error_report("This board can only be used with cortex-a8 CPU");
32
+ exit(1);
33
+ }
34
+
35
+ a10 = AW_A10(object_new(TYPE_AW_A10));
36
+
37
object_property_set_int(OBJECT(&a10->emac), 1, "phy-addr", &err);
38
if (err != NULL) {
39
error_reportf_err(err, "Couldn't set phy address: ");
40
--
41
2.20.1
42
43
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The function does not write registers, and only reads them by
4
implication via the exception path.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20200302175829.2183-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/helper-a64.h | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-a64.h
18
+++ b/target/arm/helper-a64.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
20
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
21
22
DEF_HELPER_2(exception_return, void, env, i64)
23
-DEF_HELPER_2(dc_zva, void, env, i64)
24
+DEF_HELPER_FLAGS_2(dc_zva, TCG_CALL_NO_WG, void, env, i64)
25
26
DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
27
DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This data access was forgotten when we added support for cleaning
4
addresses of TBI information.
5
6
Fixes: 3a471103ac1823ba
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200302175829.2183-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
20
return;
21
case ARM_CP_DC_ZVA:
22
/* Writes clear the aligned block of memory which rt points into. */
23
- tcg_rt = cpu_reg(s, rt);
24
+ tcg_rt = clean_data_tbi(s, cpu_reg(s, rt));
25
gen_helper_dc_zva(cpu_env, tcg_rt);
26
return;
27
default:
28
--
29
2.20.1
30
31
diff view generated by jsdifflib