1
Hi; here's the latest arm pullreq. This is mostly patches from
1
Hi; here's the latest round of arm patches. I have included also
2
RTH, plus a couple of other more minor things. Switching to
2
my patchset for the RTC devices to avoid keeping time_t and
3
PCREL is the big one, hopefully should improve performance.
3
time_t diffs in 32-bit variables.
4
4
5
thanks
5
thanks
6
-- PMM
6
-- PMM
7
7
8
The following changes since commit 214a8da23651f2472b296b3293e619fd58d9e212:
8
The following changes since commit 156618d9ea67f2f2e31d9dedd97f2dcccbe6808c:
9
9
10
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2022-10-18 11:14:31 -0400)
10
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2023-08-30 09:20:27 -0400)
11
11
12
are available in the Git repository at:
12
are available in the Git repository at:
13
13
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20221020
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230831
15
15
16
for you to fetch changes up to 5db899303799e49209016a93289b8694afa1449e:
16
for you to fetch changes up to e73b8bb8a3e9a162f70e9ffbf922d4fafc96bbfb:
17
17
18
hw/ide/microdrive: Use device_cold_reset() for self-resets (2022-10-20 12:11:53 +0100)
18
hw/arm: Set number of MPU regions correctly for an505, an521, an524 (2023-08-31 11:07:02 +0100)
19
19
20
----------------------------------------------------------------
20
----------------------------------------------------------------
21
target-arm queue:
21
target-arm queue:
22
* Switch to TARGET_TB_PCREL
22
* Some of the preliminary patches for Cortex-A710 support
23
* More pagetable-walk refactoring preparatory to HAFDBS
23
* i.MX7 and i.MX6UL refactoring
24
* update the cortex-a15 MIDR to latest rev
24
* Implement SRC device for i.MX7
25
* hw/char/pl011: fix baud rate calculation
25
* Catch illegal-exception-return from EL3 with bad NSE/NS
26
* hw/ide/microdrive: Use device_cold_reset() for self-resets
26
* Use 64-bit offsets for holding time_t differences in RTC devices
27
* Model correct number of MPU regions for an505, an521, an524 boards
27
28
28
----------------------------------------------------------------
29
----------------------------------------------------------------
29
Alex Bennée (1):
30
Alex Bennée (1):
30
target/arm: update the cortex-a15 MIDR to latest rev
31
target/arm: properly document FEAT_CRC32
31
32
32
Baruch Siach (1):
33
Jean-Christophe Dubois (6):
33
hw/char/pl011: fix baud rate calculation
34
Remove i.MX7 IOMUX GPR device from i.MX6UL
35
Refactor i.MX6UL processor code
36
Add i.MX6UL missing devices.
37
Refactor i.MX7 processor code
38
Add i.MX7 missing TZ devices and memory regions
39
Add i.MX7 SRC device implementation
34
40
35
Peter Maydell (1):
41
Peter Maydell (8):
36
hw/ide/microdrive: Use device_cold_reset() for self-resets
42
target/arm: Catch illegal-exception-return from EL3 with bad NSE/NS
43
hw/rtc/m48t59: Use 64-bit arithmetic in set_alarm()
44
hw/rtc/twl92230: Use int64_t for sec_offset and alm_sec
45
hw/rtc/aspeed_rtc: Use 64-bit offset for holding time_t difference
46
rtc: Use time_t for passing and returning time offsets
47
target/arm: Do all "ARM_FEATURE_X implies Y" checks in post_init
48
hw/arm/armv7m: Add mpu-ns-regions and mpu-s-regions properties
49
hw/arm: Set number of MPU regions correctly for an505, an521, an524
37
50
38
Richard Henderson (21):
51
Richard Henderson (9):
39
target/arm: Enable TARGET_PAGE_ENTRY_EXTRA
52
target/arm: Reduce dcz_blocksize to uint8_t
40
target/arm: Use probe_access_full for MTE
53
target/arm: Allow cpu to configure GM blocksize
41
target/arm: Use probe_access_full for BTI
54
target/arm: Support more GM blocksizes
42
target/arm: Add ARMMMUIdx_Phys_{S,NS}
55
target/arm: When tag memory is not present, set MTE=1
43
target/arm: Move ARMMMUIdx_Stage2 to a real tlb mmu_idx
56
target/arm: Introduce make_ccsidr64
44
target/arm: Restrict tlb flush from vttbr_write to vmid change
57
target/arm: Apply access checks to neoverse-n1 special registers
45
target/arm: Split out S1Translate type
58
target/arm: Apply access checks to neoverse-v1 special registers
46
target/arm: Plumb debug into S1Translate
59
target/arm: Suppress FEAT_TRBE (Trace Buffer Extension)
47
target/arm: Move be test for regime into S1TranslateResult
60
target/arm: Implement FEAT_HPDS2 as a no-op
48
target/arm: Use softmmu tlbs for page table walking
49
target/arm: Split out get_phys_addr_twostage
50
target/arm: Use bool consistently for get_phys_addr subroutines
51
target/arm: Introduce curr_insn_len
52
target/arm: Change gen_goto_tb to work on displacements
53
target/arm: Change gen_*set_pc_im to gen_*update_pc
54
target/arm: Change gen_exception_insn* to work on displacements
55
target/arm: Remove gen_exception_internal_insn pc argument
56
target/arm: Change gen_jmp* to work on displacements
57
target/arm: Introduce gen_pc_plus_diff for aarch64
58
target/arm: Introduce gen_pc_plus_diff for aarch32
59
target/arm: Enable TARGET_TB_PCREL
60
61
61
target/arm/cpu-param.h | 17 +-
62
docs/system/arm/emulation.rst | 2 +
62
target/arm/cpu.h | 47 ++--
63
include/hw/arm/armsse.h | 5 +
63
target/arm/internals.h | 1 +
64
include/hw/arm/armv7m.h | 8 +
64
target/arm/sve_ldst_internal.h | 1 +
65
include/hw/arm/fsl-imx6ul.h | 158 ++++++++++++++++---
65
target/arm/translate-a32.h | 2 +-
66
include/hw/arm/fsl-imx7.h | 338 ++++++++++++++++++++++++++++++-----------
66
target/arm/translate.h | 66 ++++-
67
include/hw/misc/imx7_src.h | 66 ++++++++
67
hw/char/pl011.c | 2 +-
68
include/hw/rtc/aspeed_rtc.h | 2 +-
68
hw/ide/microdrive.c | 8 +-
69
include/sysemu/rtc.h | 4 +-
69
target/arm/cpu.c | 23 +-
70
target/arm/cpregs.h | 2 +
70
target/arm/cpu_tcg.c | 4 +-
71
target/arm/cpu.h | 5 +-
71
target/arm/helper.c | 155 +++++++++---
72
target/arm/internals.h | 6 -
72
target/arm/mte_helper.c | 62 ++---
73
target/arm/tcg/translate.h | 2 +
73
target/arm/ptw.c | 535 +++++++++++++++++++++++++----------------
74
hw/arm/armsse.c | 16 ++
74
target/arm/sve_helper.c | 54 ++---
75
hw/arm/armv7m.c | 21 +++
75
target/arm/tlb_helper.c | 24 +-
76
hw/arm/fsl-imx6ul.c | 174 +++++++++++++--------
76
target/arm/translate-a64.c | 220 ++++++++++-------
77
hw/arm/fsl-imx7.c | 201 +++++++++++++++++++-----
77
target/arm/translate-m-nocp.c | 8 +-
78
hw/arm/mps2-tz.c | 29 ++++
78
target/arm/translate-mve.c | 2 +-
79
hw/misc/imx7_src.c | 276 +++++++++++++++++++++++++++++++++
79
target/arm/translate-vfp.c | 10 +-
80
hw/rtc/aspeed_rtc.c | 5 +-
80
target/arm/translate.c | 284 +++++++++++++---------
81
hw/rtc/m48t59.c | 2 +-
81
20 files changed, 918 insertions(+), 607 deletions(-)
82
hw/rtc/twl92230.c | 4 +-
83
softmmu/rtc.c | 4 +-
84
target/arm/cpu.c | 207 ++++++++++++++-----------
85
target/arm/helper.c | 15 +-
86
target/arm/tcg/cpu32.c | 2 +-
87
target/arm/tcg/cpu64.c | 102 +++++++++----
88
target/arm/tcg/helper-a64.c | 9 ++
89
target/arm/tcg/mte_helper.c | 90 ++++++++---
90
target/arm/tcg/translate-a64.c | 5 +-
91
hw/misc/meson.build | 1 +
92
hw/misc/trace-events | 4 +
93
31 files changed, 1393 insertions(+), 372 deletions(-)
94
create mode 100644 include/hw/misc/imx7_src.h
95
create mode 100644 hw/misc/imx7_src.c
82
96
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
So far, limit the change to S1_ptw_translate, arm_ldl_ptw, and
3
This value is only 4 bits wide.
4
arm_ldq_ptw. Use probe_access_full to find the host address,
5
and if so use a host load. If the probe fails, we've got our
6
fault info already. On the off chance that page tables are not
7
in RAM, continue to use the address_space_ld* functions.
8
4
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20221011031911.2408754-11-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20230811214031.171020-2-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
target/arm/cpu.h | 5 +
11
target/arm/cpu.h | 3 ++-
15
target/arm/ptw.c | 196 +++++++++++++++++++++++++---------------
12
1 file changed, 2 insertions(+), 1 deletion(-)
16
target/arm/tlb_helper.c | 17 +++-
17
3 files changed, 144 insertions(+), 74 deletions(-)
18
13
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
16
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMTBFlags {
18
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
24
target_ulong flags2;
19
bool prop_lpa2;
25
} CPUARMTBFlags;
20
26
21
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
27
+typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
22
- uint32_t dcz_blocksize;
23
+ uint8_t dcz_blocksize;
28
+
24
+
29
typedef struct CPUArchState {
25
uint64_t rvbar_prop; /* Property/input signals. */
30
/* Regs for current mode. */
26
31
uint32_t regs[16];
27
/* Configurable aspects of GIC cpu interface (which is part of the CPU) */
32
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
33
struct CPUBreakpoint *cpu_breakpoint[16];
34
struct CPUWatchpoint *cpu_watchpoint[16];
35
36
+ /* Optional fault info across tlb lookup. */
37
+ ARMMMUFaultInfo *tlb_fi;
38
+
39
/* Fields up to this point are cleared by a CPU reset */
40
struct {} end_reset_fields;
41
42
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/ptw.c
45
+++ b/target/arm/ptw.c
46
@@ -XXX,XX +XXX,XX @@
47
#include "qemu/osdep.h"
48
#include "qemu/log.h"
49
#include "qemu/range.h"
50
+#include "exec/exec-all.h"
51
#include "cpu.h"
52
#include "internals.h"
53
#include "idau.h"
54
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
55
bool out_secure;
56
bool out_be;
57
hwaddr out_phys;
58
+ void *out_host;
59
} S1Translate;
60
61
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
62
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
63
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
64
}
65
66
-static bool ptw_attrs_are_device(uint64_t hcr, ARMCacheAttrs cacheattrs)
67
+static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
68
{
69
/*
70
* For an S1 page table walk, the stage 1 attributes are always
71
@@ -XXX,XX +XXX,XX @@ static bool ptw_attrs_are_device(uint64_t hcr, ARMCacheAttrs cacheattrs)
72
* With HCR_EL2.FWB == 1 this is when descriptor bit [4] is 0, ie
73
* when cacheattrs.attrs bit [2] is 0.
74
*/
75
- assert(cacheattrs.is_s2_format);
76
if (hcr & HCR_FWB) {
77
- return (cacheattrs.attrs & 0x4) == 0;
78
+ return (attrs & 0x4) == 0;
79
} else {
80
- return (cacheattrs.attrs & 0xc) == 0;
81
+ return (attrs & 0xc) == 0;
82
}
83
}
84
85
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
86
hwaddr addr, ARMMMUFaultInfo *fi)
87
{
88
bool is_secure = ptw->in_secure;
89
+ ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
90
ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
91
+ bool s2_phys = false;
92
+ uint8_t pte_attrs;
93
+ bool pte_secure;
94
95
- if (arm_mmu_idx_is_stage1_of_2(ptw->in_mmu_idx) &&
96
- !regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
97
- GetPhysAddrResult s2 = {};
98
- S1Translate s2ptw = {
99
- .in_mmu_idx = s2_mmu_idx,
100
- .in_secure = is_secure,
101
- .in_debug = ptw->in_debug,
102
- };
103
- uint64_t hcr;
104
- int ret;
105
+ if (!arm_mmu_idx_is_stage1_of_2(mmu_idx)
106
+ || regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
107
+ s2_mmu_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
108
+ s2_phys = true;
109
+ }
110
111
- ret = get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
112
- false, &s2, fi);
113
- if (ret) {
114
- assert(fi->type != ARMFault_None);
115
- fi->s2addr = addr;
116
- fi->stage2 = true;
117
- fi->s1ptw = true;
118
- fi->s1ns = !is_secure;
119
- return false;
120
+ if (unlikely(ptw->in_debug)) {
121
+ /*
122
+ * From gdbstub, do not use softmmu so that we don't modify the
123
+ * state of the cpu at all, including softmmu tlb contents.
124
+ */
125
+ if (s2_phys) {
126
+ ptw->out_phys = addr;
127
+ pte_attrs = 0;
128
+ pte_secure = is_secure;
129
+ } else {
130
+ S1Translate s2ptw = {
131
+ .in_mmu_idx = s2_mmu_idx,
132
+ .in_secure = is_secure,
133
+ .in_debug = true,
134
+ };
135
+ GetPhysAddrResult s2 = { };
136
+ if (!get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
137
+ false, &s2, fi)) {
138
+ goto fail;
139
+ }
140
+ ptw->out_phys = s2.f.phys_addr;
141
+ pte_attrs = s2.cacheattrs.attrs;
142
+ pte_secure = s2.f.attrs.secure;
143
}
144
+ ptw->out_host = NULL;
145
+ } else {
146
+ CPUTLBEntryFull *full;
147
+ int flags;
148
149
- hcr = arm_hcr_el2_eff_secstate(env, is_secure);
150
- if ((hcr & HCR_PTW) && ptw_attrs_are_device(hcr, s2.cacheattrs)) {
151
+ env->tlb_fi = fi;
152
+ flags = probe_access_full(env, addr, MMU_DATA_LOAD,
153
+ arm_to_core_mmu_idx(s2_mmu_idx),
154
+ true, &ptw->out_host, &full, 0);
155
+ env->tlb_fi = NULL;
156
+
157
+ if (unlikely(flags & TLB_INVALID_MASK)) {
158
+ goto fail;
159
+ }
160
+ ptw->out_phys = full->phys_addr;
161
+ pte_attrs = full->pte_attrs;
162
+ pte_secure = full->attrs.secure;
163
+ }
164
+
165
+ if (!s2_phys) {
166
+ uint64_t hcr = arm_hcr_el2_eff_secstate(env, is_secure);
167
+
168
+ if ((hcr & HCR_PTW) && S2_attrs_are_device(hcr, pte_attrs)) {
169
/*
170
* PTW set and S1 walk touched S2 Device memory:
171
* generate Permission fault.
172
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
173
fi->s1ns = !is_secure;
174
return false;
175
}
176
-
177
- if (arm_is_secure_below_el3(env)) {
178
- /* Check if page table walk is to secure or non-secure PA space. */
179
- if (is_secure) {
180
- is_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
181
- } else {
182
- is_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
183
- }
184
- } else {
185
- assert(!is_secure);
186
- }
187
-
188
- addr = s2.f.phys_addr;
189
}
190
191
- ptw->out_secure = is_secure;
192
- ptw->out_phys = addr;
193
- ptw->out_be = regime_translation_big_endian(env, ptw->in_mmu_idx);
194
+ /* Check if page table walk is to secure or non-secure PA space. */
195
+ ptw->out_secure = (is_secure
196
+ && !(pte_secure
197
+ ? env->cp15.vstcr_el2 & VSTCR_SW
198
+ : env->cp15.vtcr_el2 & VTCR_NSW));
199
+ ptw->out_be = regime_translation_big_endian(env, mmu_idx);
200
return true;
201
+
202
+ fail:
203
+ assert(fi->type != ARMFault_None);
204
+ fi->s2addr = addr;
205
+ fi->stage2 = true;
206
+ fi->s1ptw = true;
207
+ fi->s1ns = !is_secure;
208
+ return false;
209
}
210
211
/* All loads done in the course of a page table walk go through here. */
212
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
213
ARMMMUFaultInfo *fi)
214
{
215
CPUState *cs = env_cpu(env);
216
- MemTxAttrs attrs = {};
217
- MemTxResult result = MEMTX_OK;
218
- AddressSpace *as;
219
uint32_t data;
220
221
if (!S1_ptw_translate(env, ptw, addr, fi)) {
222
+ /* Failure. */
223
+ assert(fi->s1ptw);
224
return 0;
225
}
226
- addr = ptw->out_phys;
227
- attrs.secure = ptw->out_secure;
228
- as = arm_addressspace(cs, attrs);
229
- if (ptw->out_be) {
230
- data = address_space_ldl_be(as, addr, attrs, &result);
231
+
232
+ if (likely(ptw->out_host)) {
233
+ /* Page tables are in RAM, and we have the host address. */
234
+ if (ptw->out_be) {
235
+ data = ldl_be_p(ptw->out_host);
236
+ } else {
237
+ data = ldl_le_p(ptw->out_host);
238
+ }
239
} else {
240
- data = address_space_ldl_le(as, addr, attrs, &result);
241
+ /* Page tables are in MMIO. */
242
+ MemTxAttrs attrs = { .secure = ptw->out_secure };
243
+ AddressSpace *as = arm_addressspace(cs, attrs);
244
+ MemTxResult result = MEMTX_OK;
245
+
246
+ if (ptw->out_be) {
247
+ data = address_space_ldl_be(as, ptw->out_phys, attrs, &result);
248
+ } else {
249
+ data = address_space_ldl_le(as, ptw->out_phys, attrs, &result);
250
+ }
251
+ if (unlikely(result != MEMTX_OK)) {
252
+ fi->type = ARMFault_SyncExternalOnWalk;
253
+ fi->ea = arm_extabort_type(result);
254
+ return 0;
255
+ }
256
}
257
- if (result == MEMTX_OK) {
258
- return data;
259
- }
260
- fi->type = ARMFault_SyncExternalOnWalk;
261
- fi->ea = arm_extabort_type(result);
262
- return 0;
263
+ return data;
264
}
265
266
static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
267
ARMMMUFaultInfo *fi)
268
{
269
CPUState *cs = env_cpu(env);
270
- MemTxAttrs attrs = {};
271
- MemTxResult result = MEMTX_OK;
272
- AddressSpace *as;
273
uint64_t data;
274
275
if (!S1_ptw_translate(env, ptw, addr, fi)) {
276
+ /* Failure. */
277
+ assert(fi->s1ptw);
278
return 0;
279
}
280
- addr = ptw->out_phys;
281
- attrs.secure = ptw->out_secure;
282
- as = arm_addressspace(cs, attrs);
283
- if (ptw->out_be) {
284
- data = address_space_ldq_be(as, addr, attrs, &result);
285
+
286
+ if (likely(ptw->out_host)) {
287
+ /* Page tables are in RAM, and we have the host address. */
288
+ if (ptw->out_be) {
289
+ data = ldq_be_p(ptw->out_host);
290
+ } else {
291
+ data = ldq_le_p(ptw->out_host);
292
+ }
293
} else {
294
- data = address_space_ldq_le(as, addr, attrs, &result);
295
+ /* Page tables are in MMIO. */
296
+ MemTxAttrs attrs = { .secure = ptw->out_secure };
297
+ AddressSpace *as = arm_addressspace(cs, attrs);
298
+ MemTxResult result = MEMTX_OK;
299
+
300
+ if (ptw->out_be) {
301
+ data = address_space_ldq_be(as, ptw->out_phys, attrs, &result);
302
+ } else {
303
+ data = address_space_ldq_le(as, ptw->out_phys, attrs, &result);
304
+ }
305
+ if (unlikely(result != MEMTX_OK)) {
306
+ fi->type = ARMFault_SyncExternalOnWalk;
307
+ fi->ea = arm_extabort_type(result);
308
+ return 0;
309
+ }
310
}
311
- if (result == MEMTX_OK) {
312
- return data;
313
- }
314
- fi->type = ARMFault_SyncExternalOnWalk;
315
- fi->ea = arm_extabort_type(result);
316
- return 0;
317
+ return data;
318
}
319
320
static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
321
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
322
index XXXXXXX..XXXXXXX 100644
323
--- a/target/arm/tlb_helper.c
324
+++ b/target/arm/tlb_helper.c
325
@@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
326
bool probe, uintptr_t retaddr)
327
{
328
ARMCPU *cpu = ARM_CPU(cs);
329
- ARMMMUFaultInfo fi = {};
330
GetPhysAddrResult res = {};
331
+ ARMMMUFaultInfo local_fi, *fi;
332
int ret;
333
334
+ /*
335
+ * Allow S1_ptw_translate to see any fault generated here.
336
+ * Since this may recurse, read and clear.
337
+ */
338
+ fi = cpu->env.tlb_fi;
339
+ if (fi) {
340
+ cpu->env.tlb_fi = NULL;
341
+ } else {
342
+ fi = memset(&local_fi, 0, sizeof(local_fi));
343
+ }
344
+
345
/*
346
* Walk the page table and (if the mapping exists) add the page
347
* to the TLB. On success, return true. Otherwise, if probing,
348
@@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
349
*/
350
ret = get_phys_addr(&cpu->env, address, access_type,
351
core_to_arm_mmu_idx(&cpu->env, mmu_idx),
352
- &res, &fi);
353
+ &res, fi);
354
if (likely(!ret)) {
355
/*
356
* Map a single [sub]page. Regions smaller than our declared
357
@@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
358
} else {
359
/* now we have a real cpu fault */
360
cpu_restore_state(cs, retaddr, true);
361
- arm_deliver_fault(cpu, address, access_type, mmu_idx, &fi);
362
+ arm_deliver_fault(cpu, address, access_type, mmu_idx, fi);
363
}
364
}
365
#else
366
--
28
--
367
2.25.1
29
2.34.1
30
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The CPUTLBEntryFull structure now stores the original pte attributes, as
3
Previously we hard-coded the blocksize with GMID_EL1_BS.
4
well as the physical address. Therefore, we no longer need a separate
4
But the value we choose for -cpu max does not match the
5
bit in MemTxAttrs, nor do we need to walk the tree of memory regions.
5
value that cortex-a710 uses.
6
7
Mirror the way we handle dcz_blocksize.
6
8
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20221011031911.2408754-3-richard.henderson@linaro.org
11
Message-id: 20230811214031.171020-3-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
target/arm/cpu.h | 1 -
14
target/arm/cpu.h | 2 ++
13
target/arm/sve_ldst_internal.h | 1 +
15
target/arm/internals.h | 6 -----
14
target/arm/mte_helper.c | 62 ++++++++++------------------------
16
target/arm/tcg/translate.h | 2 ++
15
target/arm/sve_helper.c | 54 ++++++++++-------------------
17
target/arm/helper.c | 11 +++++---
16
target/arm/tlb_helper.c | 4 ---
18
target/arm/tcg/cpu64.c | 1 +
17
5 files changed, 36 insertions(+), 86 deletions(-)
19
target/arm/tcg/mte_helper.c | 46 ++++++++++++++++++++++------------
20
target/arm/tcg/translate-a64.c | 5 ++--
21
7 files changed, 45 insertions(+), 28 deletions(-)
18
22
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
25
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs *x)
27
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
24
* generic target bits directly.
28
25
*/
29
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
26
#define arm_tlb_bti_gp(x) (typecheck_memtxattrs(x)->target_tlb_bit0)
30
uint8_t dcz_blocksize;
27
-#define arm_tlb_mte_tagged(x) (typecheck_memtxattrs(x)->target_tlb_bit1)
31
+ /* GM blocksize, in log_2(words), ie low 4 bits of GMID_EL0 */
28
32
+ uint8_t gm_blocksize;
33
34
uint64_t rvbar_prop; /* Property/input signals. */
35
36
diff --git a/target/arm/internals.h b/target/arm/internals.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/internals.h
39
+++ b/target/arm/internals.h
40
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(CPUState *cs);
41
42
#endif /* !CONFIG_USER_ONLY */
43
44
-/*
45
- * The log2 of the words in the tag block, for GMID_EL1.BS.
46
- * The is the maximum, 256 bytes, which manipulates 64-bits of tags.
47
- */
48
-#define GMID_EL1_BS 6
49
-
29
/*
50
/*
30
* AArch64 usage of the PAGE_TARGET_* bits for linux-user.
51
* SVE predicates are 1/8 the size of SVE vectors, and cannot use
31
diff --git a/target/arm/sve_ldst_internal.h b/target/arm/sve_ldst_internal.h
52
* the same simd_desc() encoding due to restrictions on size.
32
index XXXXXXX..XXXXXXX 100644
53
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
33
--- a/target/arm/sve_ldst_internal.h
54
index XXXXXXX..XXXXXXX 100644
34
+++ b/target/arm/sve_ldst_internal.h
55
--- a/target/arm/tcg/translate.h
35
@@ -XXX,XX +XXX,XX @@ typedef struct {
56
+++ b/target/arm/tcg/translate.h
36
void *host;
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
37
int flags;
58
int8_t btype;
38
MemTxAttrs attrs;
59
/* A copy of cpu->dcz_blocksize. */
39
+ bool tagged;
60
uint8_t dcz_blocksize;
40
} SVEHostPage;
61
+ /* A copy of cpu->gm_blocksize. */
41
62
+ uint8_t gm_blocksize;
42
bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
63
/* True if this page is guarded. */
43
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
64
bool guarded_page;
44
index XXXXXXX..XXXXXXX 100644
65
/* Bottom two bits of XScale c15_cpar coprocessor access control reg */
45
--- a/target/arm/mte_helper.c
66
diff --git a/target/arm/helper.c b/target/arm/helper.c
46
+++ b/target/arm/mte_helper.c
67
index XXXXXXX..XXXXXXX 100644
47
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
68
--- a/target/arm/helper.c
48
TARGET_PAGE_BITS - LOG2_TAG_GRANULE - 1);
69
+++ b/target/arm/helper.c
49
return tags + index;
70
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_reginfo[] = {
50
#else
71
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 0, .opc2 = 6,
51
- uintptr_t index;
72
.access = PL1_RW, .accessfn = access_mte,
52
CPUTLBEntryFull *full;
73
.fieldoffset = offsetof(CPUARMState, cp15.gcr_el1) },
53
+ MemTxAttrs attrs;
74
- { .name = "GMID_EL1", .state = ARM_CP_STATE_AA64,
54
int in_page, flags;
75
- .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 4,
55
- ram_addr_t ptr_ra;
76
- .access = PL1_R, .accessfn = access_aa64_tid5,
56
hwaddr ptr_paddr, tag_paddr, xlat;
77
- .type = ARM_CP_CONST, .resetvalue = GMID_EL1_BS },
57
MemoryRegion *mr;
78
{ .name = "TCO", .state = ARM_CP_STATE_AA64,
58
ARMASIdx tag_asi;
79
.opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 7,
59
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
80
.type = ARM_CP_NO_RAW,
60
* valid. Indicate to probe_access_flags no-fault, then assert that
81
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
61
* we received a valid page.
82
* then define only a RAZ/WI version of PSTATE.TCO.
62
*/
83
*/
63
- flags = probe_access_flags(env, ptr, ptr_access, ptr_mmu_idx,
84
if (cpu_isar_feature(aa64_mte, cpu)) {
64
- ra == 0, &host, ra);
85
+ ARMCPRegInfo gmid_reginfo = {
65
+ flags = probe_access_full(env, ptr, ptr_access, ptr_mmu_idx,
86
+ .name = "GMID_EL1", .state = ARM_CP_STATE_AA64,
66
+ ra == 0, &host, &full, ra);
87
+ .opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 4,
67
assert(!(flags & TLB_INVALID_MASK));
88
+ .access = PL1_R, .accessfn = access_aa64_tid5,
68
89
+ .type = ARM_CP_CONST, .resetvalue = cpu->gm_blocksize,
69
- /*
90
+ };
70
- * Find the CPUTLBEntryFull for ptr. This *must* be present in the TLB
91
+ define_one_arm_cp_reg(cpu, &gmid_reginfo);
71
- * because we just found the mapping.
92
define_arm_cp_regs(cpu, mte_reginfo);
72
- * TODO: Perhaps there should be a cputlb helper that returns a
93
define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
73
- * matching tlb entry + iotlb entry.
94
} else if (cpu_isar_feature(aa64_mte_insn_reg, cpu)) {
74
- */
95
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
75
- index = tlb_index(env, ptr_mmu_idx, ptr);
96
index XXXXXXX..XXXXXXX 100644
76
-# ifdef CONFIG_DEBUG_TCG
97
--- a/target/arm/tcg/cpu64.c
77
- {
98
+++ b/target/arm/tcg/cpu64.c
78
- CPUTLBEntry *entry = tlb_entry(env, ptr_mmu_idx, ptr);
99
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
79
- target_ulong comparator = (ptr_access == MMU_DATA_LOAD
100
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
80
- ? entry->addr_read
101
cpu->dcz_blocksize = 7; /* 512 bytes */
81
- : tlb_addr_write(entry));
102
#endif
82
- g_assert(tlb_hit(comparator, ptr));
103
+ cpu->gm_blocksize = 6; /* 256 bytes */
83
- }
104
84
-# endif
105
cpu->sve_vq.supported = MAKE_64BIT_MASK(0, ARM_MAX_VQ);
85
- full = &env_tlb(env)->d[ptr_mmu_idx].fulltlb[index];
106
cpu->sme_vq.supported = SVE_VQ_POW2_MAP;
107
diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/tcg/mte_helper.c
110
+++ b/target/arm/tcg/mte_helper.c
111
@@ -XXX,XX +XXX,XX @@ void HELPER(st2g_stub)(CPUARMState *env, uint64_t ptr)
112
}
113
}
114
115
-#define LDGM_STGM_SIZE (4 << GMID_EL1_BS)
86
-
116
-
87
/* If the virtual page MemAttr != Tagged, access unchecked. */
117
uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
88
- if (!arm_tlb_mte_tagged(&full->attrs)) {
118
{
89
+ if (full->pte_attrs != 0xf0) {
119
int mmu_idx = cpu_mmu_index(env, false);
90
return NULL;
120
uintptr_t ra = GETPC();
121
+ int gm_bs = env_archcpu(env)->gm_blocksize;
122
+ int gm_bs_bytes = 4 << gm_bs;
123
void *tag_mem;
124
125
- ptr = QEMU_ALIGN_DOWN(ptr, LDGM_STGM_SIZE);
126
+ ptr = QEMU_ALIGN_DOWN(ptr, gm_bs_bytes);
127
128
/* Trap if accessing an invalid page. */
129
tag_mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_LOAD,
130
- LDGM_STGM_SIZE, MMU_DATA_LOAD,
131
- LDGM_STGM_SIZE / (2 * TAG_GRANULE), ra);
132
+ gm_bs_bytes, MMU_DATA_LOAD,
133
+ gm_bs_bytes / (2 * TAG_GRANULE), ra);
134
135
/* The tag is squashed to zero if the page does not support tags. */
136
if (!tag_mem) {
137
return 0;
91
}
138
}
92
139
93
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
140
- QEMU_BUILD_BUG_ON(GMID_EL1_BS != 6);
94
return NULL;
141
/*
142
- * We are loading 64-bits worth of tags. The ordering of elements
143
- * within the word corresponds to a 64-bit little-endian operation.
144
+ * The ordering of elements within the word corresponds to
145
+ * a little-endian operation.
146
*/
147
- return ldq_le_p(tag_mem);
148
+ switch (gm_bs) {
149
+ case 6:
150
+ /* 256 bytes -> 16 tags -> 64 result bits */
151
+ return ldq_le_p(tag_mem);
152
+ default:
153
+ /* cpu configured with unsupported gm blocksize. */
154
+ g_assert_not_reached();
155
+ }
156
}
157
158
void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
159
{
160
int mmu_idx = cpu_mmu_index(env, false);
161
uintptr_t ra = GETPC();
162
+ int gm_bs = env_archcpu(env)->gm_blocksize;
163
+ int gm_bs_bytes = 4 << gm_bs;
164
void *tag_mem;
165
166
- ptr = QEMU_ALIGN_DOWN(ptr, LDGM_STGM_SIZE);
167
+ ptr = QEMU_ALIGN_DOWN(ptr, gm_bs_bytes);
168
169
/* Trap if accessing an invalid page. */
170
tag_mem = allocation_tag_mem(env, mmu_idx, ptr, MMU_DATA_STORE,
171
- LDGM_STGM_SIZE, MMU_DATA_LOAD,
172
- LDGM_STGM_SIZE / (2 * TAG_GRANULE), ra);
173
+ gm_bs_bytes, MMU_DATA_LOAD,
174
+ gm_bs_bytes / (2 * TAG_GRANULE), ra);
175
176
/*
177
* Tag store only happens if the page support tags,
178
@@ -XXX,XX +XXX,XX @@ void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
179
return;
95
}
180
}
96
181
97
+ /*
182
- QEMU_BUILD_BUG_ON(GMID_EL1_BS != 6);
98
+ * Remember these values across the second lookup below,
99
+ * which may invalidate this pointer via tlb resize.
100
+ */
101
+ ptr_paddr = full->phys_addr;
102
+ attrs = full->attrs;
103
+ full = NULL;
104
+
105
/*
183
/*
106
* The Normal memory access can extend to the next page. E.g. a single
184
- * We are storing 64-bits worth of tags. The ordering of elements
107
* 8-byte access to the last byte of a page will check only the last
185
- * within the word corresponds to a 64-bit little-endian operation.
108
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
186
+ * The ordering of elements within the word corresponds to
187
+ * a little-endian operation.
109
*/
188
*/
110
in_page = -(ptr | TARGET_PAGE_MASK);
189
- stq_le_p(tag_mem, val);
111
if (unlikely(ptr_size > in_page)) {
190
+ switch (gm_bs) {
112
- void *ignore;
191
+ case 6:
113
- flags |= probe_access_flags(env, ptr + in_page, ptr_access,
192
+ stq_le_p(tag_mem, val);
114
- ptr_mmu_idx, ra == 0, &ignore, ra);
193
+ break;
115
+ flags |= probe_access_full(env, ptr + in_page, ptr_access,
194
+ default:
116
+ ptr_mmu_idx, ra == 0, &host, &full, ra);
195
+ /* cpu configured with unsupported gm blocksize. */
117
assert(!(flags & TLB_INVALID_MASK));
196
+ g_assert_not_reached();
118
}
197
+ }
119
120
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
121
if (unlikely(flags & TLB_WATCHPOINT)) {
122
int wp = ptr_access == MMU_DATA_LOAD ? BP_MEM_READ : BP_MEM_WRITE;
123
assert(ra != 0);
124
- cpu_check_watchpoint(env_cpu(env), ptr, ptr_size,
125
- full->attrs, wp, ra);
126
+ cpu_check_watchpoint(env_cpu(env), ptr, ptr_size, attrs, wp, ra);
127
}
128
129
- /*
130
- * Find the physical address within the normal mem space.
131
- * The memory region lookup must succeed because TLB_MMIO was
132
- * not set in the cputlb lookup above.
133
- */
134
- mr = memory_region_from_host(host, &ptr_ra);
135
- tcg_debug_assert(mr != NULL);
136
- tcg_debug_assert(memory_region_is_ram(mr));
137
- ptr_paddr = ptr_ra;
138
- do {
139
- ptr_paddr += mr->addr;
140
- mr = mr->container;
141
- } while (mr);
142
-
143
/* Convert to the physical address in tag space. */
144
tag_paddr = ptr_paddr >> (LOG2_TAG_GRANULE + 1);
145
146
/* Look up the address in tag space. */
147
- tag_asi = full->attrs.secure ? ARMASIdx_TagS : ARMASIdx_TagNS;
148
+ tag_asi = attrs.secure ? ARMASIdx_TagS : ARMASIdx_TagNS;
149
tag_as = cpu_get_address_space(env_cpu(env), tag_asi);
150
mr = address_space_translate(tag_as, tag_paddr, &xlat, NULL,
151
- tag_access == MMU_DATA_STORE,
152
- full->attrs);
153
+ tag_access == MMU_DATA_STORE, attrs);
154
155
/*
156
* Note that @mr will never be NULL. If there is nothing in the address
157
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/sve_helper.c
160
+++ b/target/arm/sve_helper.c
161
@@ -XXX,XX +XXX,XX @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
162
*/
163
addr = useronly_clean_ptr(addr);
164
165
+#ifdef CONFIG_USER_ONLY
166
flags = probe_access_flags(env, addr, access_type, mmu_idx, nofault,
167
&info->host, retaddr);
168
+ memset(&info->attrs, 0, sizeof(info->attrs));
169
+ /* Require both ANON and MTE; see allocation_tag_mem(). */
170
+ info->tagged = (flags & PAGE_ANON) && (flags & PAGE_MTE);
171
+#else
172
+ CPUTLBEntryFull *full;
173
+ flags = probe_access_full(env, addr, access_type, mmu_idx, nofault,
174
+ &info->host, &full, retaddr);
175
+ info->attrs = full->attrs;
176
+ info->tagged = full->pte_attrs == 0xf0;
177
+#endif
178
info->flags = flags;
179
180
if (flags & TLB_INVALID_MASK) {
181
@@ -XXX,XX +XXX,XX @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
182
183
/* Ensure that info->host[] is relative to addr, not addr + mem_off. */
184
info->host -= mem_off;
185
-
186
-#ifdef CONFIG_USER_ONLY
187
- memset(&info->attrs, 0, sizeof(info->attrs));
188
- /* Require both MAP_ANON and PROT_MTE -- see allocation_tag_mem. */
189
- arm_tlb_mte_tagged(&info->attrs) =
190
- (flags & PAGE_ANON) && (flags & PAGE_MTE);
191
-#else
192
- /*
193
- * Find the iotlbentry for addr and return the transaction attributes.
194
- * This *must* be present in the TLB because we just found the mapping.
195
- */
196
- {
197
- uintptr_t index = tlb_index(env, mmu_idx, addr);
198
-
199
-# ifdef CONFIG_DEBUG_TCG
200
- CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
201
- target_ulong comparator = (access_type == MMU_DATA_LOAD
202
- ? entry->addr_read
203
- : tlb_addr_write(entry));
204
- g_assert(tlb_hit(comparator, addr));
205
-# endif
206
-
207
- CPUTLBEntryFull *full = &env_tlb(env)->d[mmu_idx].fulltlb[index];
208
- info->attrs = full->attrs;
209
- }
210
-#endif
211
-
212
return true;
213
}
198
}
214
199
215
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check(SVEContLdSt *info, CPUARMState *env,
200
void HELPER(stzgm_tags)(CPUARMState *env, uint64_t ptr, uint64_t val)
216
intptr_t mem_off, reg_off, reg_last;
201
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
217
202
index XXXXXXX..XXXXXXX 100644
218
/* Process the page only if MemAttr == Tagged. */
203
--- a/target/arm/tcg/translate-a64.c
219
- if (arm_tlb_mte_tagged(&info->page[0].attrs)) {
204
+++ b/target/arm/tcg/translate-a64.c
220
+ if (info->page[0].tagged) {
205
@@ -XXX,XX +XXX,XX @@ static bool trans_STGM(DisasContext *s, arg_ldst_tag *a)
221
mem_off = info->mem_off_first[0];
206
gen_helper_stgm(cpu_env, addr, tcg_rt);
222
reg_off = info->reg_off_first[0];
207
} else {
223
reg_last = info->reg_off_split;
208
MMUAccessType acc = MMU_DATA_STORE;
224
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check(SVEContLdSt *info, CPUARMState *env,
209
- int size = 4 << GMID_EL1_BS;
225
}
210
+ int size = 4 << s->gm_blocksize;
226
211
227
mem_off = info->mem_off_first[1];
212
clean_addr = clean_data_tbi(s, addr);
228
- if (mem_off >= 0 && arm_tlb_mte_tagged(&info->page[1].attrs)) {
213
tcg_gen_andi_i64(clean_addr, clean_addr, -size);
229
+ if (mem_off >= 0 && info->page[1].tagged) {
214
@@ -XXX,XX +XXX,XX @@ static bool trans_LDGM(DisasContext *s, arg_ldst_tag *a)
230
reg_off = info->reg_off_first[1];
215
gen_helper_ldgm(tcg_rt, cpu_env, addr);
231
reg_last = info->reg_off_last[1];
216
} else {
232
217
MMUAccessType acc = MMU_DATA_LOAD;
233
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
218
- int size = 4 << GMID_EL1_BS;
234
* Disable MTE checking if the Tagged bit is not set. Since TBI must
219
+ int size = 4 << s->gm_blocksize;
235
* be set within MTEDESC for MTE, !mtedesc => !mte_active.
220
236
*/
221
clean_addr = clean_data_tbi(s, addr);
237
- if (!arm_tlb_mte_tagged(&info.page[0].attrs)) {
222
tcg_gen_andi_i64(clean_addr, clean_addr, -size);
238
+ if (!info.page[0].tagged) {
223
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
239
mtedesc = 0;
224
dc->cp_regs = arm_cpu->cp_regs;
240
}
225
dc->features = env->features;
241
226
dc->dcz_blocksize = arm_cpu->dcz_blocksize;
242
@@ -XXX,XX +XXX,XX @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
227
+ dc->gm_blocksize = arm_cpu->gm_blocksize;
243
cpu_check_watchpoint(env_cpu(env), addr, msize,
228
244
info.attrs, BP_MEM_READ, retaddr);
229
#ifdef CONFIG_USER_ONLY
245
}
230
/* In sve_probe_page, we assume TBI is enabled. */
246
- if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
247
+ if (mtedesc && info.tagged) {
248
mte_check(env, mtedesc, addr, retaddr);
249
}
250
if (unlikely(info.flags & TLB_MMIO)) {
251
@@ -XXX,XX +XXX,XX @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
252
msize, info.attrs,
253
BP_MEM_READ, retaddr);
254
}
255
- if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
256
+ if (mtedesc && info.tagged) {
257
mte_check(env, mtedesc, addr, retaddr);
258
}
259
tlb_fn(env, &scratch, reg_off, addr, retaddr);
260
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
261
(env_cpu(env), addr, msize) & BP_MEM_READ)) {
262
goto fault;
263
}
264
- if (mtedesc &&
265
- arm_tlb_mte_tagged(&info.attrs) &&
266
- !mte_probe(env, mtedesc, addr)) {
267
+ if (mtedesc && info.tagged && !mte_probe(env, mtedesc, addr)) {
268
goto fault;
269
}
270
271
@@ -XXX,XX +XXX,XX @@ void sve_st1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
272
info.attrs, BP_MEM_WRITE, retaddr);
273
}
274
275
- if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
276
+ if (mtedesc && info.tagged) {
277
mte_check(env, mtedesc, addr, retaddr);
278
}
279
}
280
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
281
index XXXXXXX..XXXXXXX 100644
282
--- a/target/arm/tlb_helper.c
283
+++ b/target/arm/tlb_helper.c
284
@@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
285
res.f.phys_addr &= TARGET_PAGE_MASK;
286
address &= TARGET_PAGE_MASK;
287
}
288
- /* Notice and record tagged memory. */
289
- if (cpu_isar_feature(aa64_mte, cpu) && res.cacheattrs.attrs == 0xf0) {
290
- arm_tlb_mte_tagged(&res.f.attrs) = true;
291
- }
292
293
res.f.pte_attrs = res.cacheattrs.attrs;
294
res.f.shareability = res.cacheattrs.shareability;
295
--
231
--
296
2.25.1
232
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In preparation for TARGET_TB_PCREL, reduce reliance on absolute values.
3
Support all of the easy GM block sizes.
4
Use direct memory operations, since the pointers are aligned.
4
5
6
While BS=2 (16 bytes, 1 tag) is a legal setting, that requires
7
an atomic store of one nibble. This is not difficult, but there
8
is also no point in supporting it until required.
9
10
Note that cortex-a710 sets GM blocksize to match its cacheline
11
size of 64 bytes. I expect many implementations will also
12
match the cacheline, which makes 16 bytes very unlikely.
13
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20230811214031.171020-4-richard.henderson@linaro.org
7
Message-id: 20221020030641.2066807-3-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
18
---
10
target/arm/translate-a64.c | 40 ++++++++++++++++++++------------------
19
target/arm/cpu.c | 18 +++++++++---
11
target/arm/translate.c | 10 ++++++----
20
target/arm/tcg/mte_helper.c | 56 +++++++++++++++++++++++++++++++------
12
2 files changed, 27 insertions(+), 23 deletions(-)
21
2 files changed, 62 insertions(+), 12 deletions(-)
13
22
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
23
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
25
--- a/target/arm/cpu.c
17
+++ b/target/arm/translate-a64.c
26
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static inline bool use_goto_tb(DisasContext *s, uint64_t dest)
27
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
19
return translator_use_goto_tb(&s->base, dest);
28
ID_PFR1, VIRTUALIZATION, 0);
29
}
30
31
+ if (cpu_isar_feature(aa64_mte, cpu)) {
32
+ /*
33
+ * The architectural range of GM blocksize is 2-6, however qemu
34
+ * doesn't support blocksize of 2 (see HELPER(ldgm)).
35
+ */
36
+ if (tcg_enabled()) {
37
+ assert(cpu->gm_blocksize >= 3 && cpu->gm_blocksize <= 6);
38
+ }
39
+
40
#ifndef CONFIG_USER_ONLY
41
- if (cpu->tag_memory == NULL && cpu_isar_feature(aa64_mte, cpu)) {
42
/*
43
* Disable the MTE feature bits if we do not have tag-memory
44
* provided by the machine.
45
*/
46
- cpu->isar.id_aa64pfr1 =
47
- FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
48
- }
49
+ if (cpu->tag_memory == NULL) {
50
+ cpu->isar.id_aa64pfr1 =
51
+ FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
52
+ }
53
#endif
54
+ }
55
56
if (tcg_enabled()) {
57
/*
58
diff --git a/target/arm/tcg/mte_helper.c b/target/arm/tcg/mte_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/tcg/mte_helper.c
61
+++ b/target/arm/tcg/mte_helper.c
62
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
63
int gm_bs = env_archcpu(env)->gm_blocksize;
64
int gm_bs_bytes = 4 << gm_bs;
65
void *tag_mem;
66
+ uint64_t ret;
67
+ int shift;
68
69
ptr = QEMU_ALIGN_DOWN(ptr, gm_bs_bytes);
70
71
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(ldgm)(CPUARMState *env, uint64_t ptr)
72
73
/*
74
* The ordering of elements within the word corresponds to
75
- * a little-endian operation.
76
+ * a little-endian operation. Computation of shift comes from
77
+ *
78
+ * index = address<LOG2_TAG_GRANULE+3:LOG2_TAG_GRANULE>
79
+ * data<index*4+3:index*4> = tag
80
+ *
81
+ * Because of the alignment of ptr above, BS=6 has shift=0.
82
+ * All memory operations are aligned. Defer support for BS=2,
83
+ * requiring insertion or extraction of a nibble, until we
84
+ * support a cpu that requires it.
85
*/
86
switch (gm_bs) {
87
+ case 3:
88
+ /* 32 bytes -> 2 tags -> 8 result bits */
89
+ ret = *(uint8_t *)tag_mem;
90
+ break;
91
+ case 4:
92
+ /* 64 bytes -> 4 tags -> 16 result bits */
93
+ ret = cpu_to_le16(*(uint16_t *)tag_mem);
94
+ break;
95
+ case 5:
96
+ /* 128 bytes -> 8 tags -> 32 result bits */
97
+ ret = cpu_to_le32(*(uint32_t *)tag_mem);
98
+ break;
99
case 6:
100
/* 256 bytes -> 16 tags -> 64 result bits */
101
- return ldq_le_p(tag_mem);
102
+ return cpu_to_le64(*(uint64_t *)tag_mem);
103
default:
104
- /* cpu configured with unsupported gm blocksize. */
105
+ /*
106
+ * CPU configured with unsupported/invalid gm blocksize.
107
+ * This is detected early in arm_cpu_realizefn.
108
+ */
109
g_assert_not_reached();
110
}
111
+ shift = extract64(ptr, LOG2_TAG_GRANULE, 4) * 4;
112
+ return ret << shift;
20
}
113
}
21
114
22
-static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
115
void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
23
+static void gen_goto_tb(DisasContext *s, int n, int64_t diff)
116
@@ -XXX,XX +XXX,XX @@ void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
24
{
117
int gm_bs = env_archcpu(env)->gm_blocksize;
25
+ uint64_t dest = s->pc_curr + diff;
118
int gm_bs_bytes = 4 << gm_bs;
26
+
119
void *tag_mem;
27
if (use_goto_tb(s, dest)) {
120
+ int shift;
28
tcg_gen_goto_tb(n);
121
29
gen_a64_set_pc_im(dest);
122
ptr = QEMU_ALIGN_DOWN(ptr, gm_bs_bytes);
30
@@ -XXX,XX +XXX,XX @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
123
31
*/
124
@@ -XXX,XX +XXX,XX @@ void HELPER(stgm)(CPUARMState *env, uint64_t ptr, uint64_t val)
32
static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
33
{
34
- uint64_t addr = s->pc_curr + sextract32(insn, 0, 26) * 4;
35
+ int64_t diff = sextract32(insn, 0, 26) * 4;
36
37
if (insn & (1U << 31)) {
38
/* BL Branch with link */
39
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
40
41
/* B Branch / BL Branch with link */
42
reset_btype(s);
43
- gen_goto_tb(s, 0, addr);
44
+ gen_goto_tb(s, 0, diff);
45
}
46
47
/* Compare and branch (immediate)
48
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
49
static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
50
{
51
unsigned int sf, op, rt;
52
- uint64_t addr;
53
+ int64_t diff;
54
TCGLabel *label_match;
55
TCGv_i64 tcg_cmp;
56
57
sf = extract32(insn, 31, 1);
58
op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
59
rt = extract32(insn, 0, 5);
60
- addr = s->pc_curr + sextract32(insn, 5, 19) * 4;
61
+ diff = sextract32(insn, 5, 19) * 4;
62
63
tcg_cmp = read_cpu_reg(s, rt, sf);
64
label_match = gen_new_label();
65
@@ -XXX,XX +XXX,XX @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
66
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
67
tcg_cmp, 0, label_match);
68
69
- gen_goto_tb(s, 0, s->base.pc_next);
70
+ gen_goto_tb(s, 0, 4);
71
gen_set_label(label_match);
72
- gen_goto_tb(s, 1, addr);
73
+ gen_goto_tb(s, 1, diff);
74
}
75
76
/* Test and branch (immediate)
77
@@ -XXX,XX +XXX,XX @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
78
static void disas_test_b_imm(DisasContext *s, uint32_t insn)
79
{
80
unsigned int bit_pos, op, rt;
81
- uint64_t addr;
82
+ int64_t diff;
83
TCGLabel *label_match;
84
TCGv_i64 tcg_cmp;
85
86
bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
87
op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
88
- addr = s->pc_curr + sextract32(insn, 5, 14) * 4;
89
+ diff = sextract32(insn, 5, 14) * 4;
90
rt = extract32(insn, 0, 5);
91
92
tcg_cmp = tcg_temp_new_i64();
93
@@ -XXX,XX +XXX,XX @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
94
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
95
tcg_cmp, 0, label_match);
96
tcg_temp_free_i64(tcg_cmp);
97
- gen_goto_tb(s, 0, s->base.pc_next);
98
+ gen_goto_tb(s, 0, 4);
99
gen_set_label(label_match);
100
- gen_goto_tb(s, 1, addr);
101
+ gen_goto_tb(s, 1, diff);
102
}
103
104
/* Conditional branch (immediate)
105
@@ -XXX,XX +XXX,XX @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
106
static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
107
{
108
unsigned int cond;
109
- uint64_t addr;
110
+ int64_t diff;
111
112
if ((insn & (1 << 4)) || (insn & (1 << 24))) {
113
unallocated_encoding(s);
114
return;
125
return;
115
}
126
}
116
- addr = s->pc_curr + sextract32(insn, 5, 19) * 4;
127
117
+ diff = sextract32(insn, 5, 19) * 4;
128
- /*
118
cond = extract32(insn, 0, 4);
129
- * The ordering of elements within the word corresponds to
119
130
- * a little-endian operation.
120
reset_btype(s);
131
- */
121
@@ -XXX,XX +XXX,XX @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
132
+ /* See LDGM for comments on BS and on shift. */
122
/* genuinely conditional branches */
133
+ shift = extract64(ptr, LOG2_TAG_GRANULE, 4) * 4;
123
TCGLabel *label_match = gen_new_label();
134
+ val >>= shift;
124
arm_gen_test_cc(cond, label_match);
135
switch (gm_bs) {
125
- gen_goto_tb(s, 0, s->base.pc_next);
136
+ case 3:
126
+ gen_goto_tb(s, 0, 4);
137
+ /* 32 bytes -> 2 tags -> 8 result bits */
127
gen_set_label(label_match);
138
+ *(uint8_t *)tag_mem = val;
128
- gen_goto_tb(s, 1, addr);
139
+ break;
129
+ gen_goto_tb(s, 1, diff);
140
+ case 4:
130
} else {
141
+ /* 64 bytes -> 4 tags -> 16 result bits */
131
/* 0xe and 0xf are both "always" conditions */
142
+ *(uint16_t *)tag_mem = cpu_to_le16(val);
132
- gen_goto_tb(s, 0, addr);
143
+ break;
133
+ gen_goto_tb(s, 0, diff);
144
+ case 5:
134
}
145
+ /* 128 bytes -> 8 tags -> 32 result bits */
135
}
146
+ *(uint32_t *)tag_mem = cpu_to_le32(val);
136
147
+ break;
137
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
148
case 6:
138
* any pending interrupts immediately.
149
- stq_le_p(tag_mem, val);
139
*/
150
+ /* 256 bytes -> 16 tags -> 64 result bits */
140
reset_btype(s);
151
+ *(uint64_t *)tag_mem = cpu_to_le64(val);
141
- gen_goto_tb(s, 0, s->base.pc_next);
152
break;
142
+ gen_goto_tb(s, 0, 4);
143
return;
144
145
case 7: /* SB */
146
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
147
* MB and end the TB instead.
148
*/
149
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
150
- gen_goto_tb(s, 0, s->base.pc_next);
151
+ gen_goto_tb(s, 0, 4);
152
return;
153
154
default:
153
default:
155
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
154
/* cpu configured with unsupported gm blocksize. */
156
switch (dc->base.is_jmp) {
157
case DISAS_NEXT:
158
case DISAS_TOO_MANY:
159
- gen_goto_tb(dc, 1, dc->base.pc_next);
160
+ gen_goto_tb(dc, 1, 4);
161
break;
162
default:
163
case DISAS_UPDATE_EXIT:
164
diff --git a/target/arm/translate.c b/target/arm/translate.c
165
index XXXXXXX..XXXXXXX 100644
166
--- a/target/arm/translate.c
167
+++ b/target/arm/translate.c
168
@@ -XXX,XX +XXX,XX @@ static void gen_goto_ptr(void)
169
* cpu_loop_exec. Any live exit_requests will be processed as we
170
* enter the next TB.
171
*/
172
-static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
173
+static void gen_goto_tb(DisasContext *s, int n, int diff)
174
{
175
+ target_ulong dest = s->pc_curr + diff;
176
+
177
if (translator_use_goto_tb(&s->base, dest)) {
178
tcg_gen_goto_tb(n);
179
gen_set_pc_im(s, dest);
180
@@ -XXX,XX +XXX,XX @@ static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
181
* gen_jmp();
182
* on the second call to gen_jmp().
183
*/
184
- gen_goto_tb(s, tbno, dest);
185
+ gen_goto_tb(s, tbno, dest - s->pc_curr);
186
break;
187
case DISAS_UPDATE_NOCHAIN:
188
case DISAS_UPDATE_EXIT:
189
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
190
switch (dc->base.is_jmp) {
191
case DISAS_NEXT:
192
case DISAS_TOO_MANY:
193
- gen_goto_tb(dc, 1, dc->base.pc_next);
194
+ gen_goto_tb(dc, 1, curr_insn_len(dc));
195
break;
196
case DISAS_UPDATE_NOCHAIN:
197
gen_set_pc_im(dc, dc->base.pc_next);
198
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
199
gen_set_pc_im(dc, dc->base.pc_next);
200
gen_singlestep_exception(dc);
201
} else {
202
- gen_goto_tb(dc, 1, dc->base.pc_next);
203
+ gen_goto_tb(dc, 1, curr_insn_len(dc));
204
}
205
}
206
}
207
--
155
--
208
2.25.1
156
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
When the cpu support MTE, but the system does not, reduce cpu
4
support to user instructions at EL0 instead of completely
5
disabling MTE. If we encounter a cpu implementation which does
6
something else, we can revisit this setting.
7
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20221020030641.2066807-10-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20230811214031.171020-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
target/arm/cpu-param.h | 2 +
13
target/arm/cpu.c | 7 ++++---
9
target/arm/translate.h | 50 +++++++++++++++-
14
1 file changed, 4 insertions(+), 3 deletions(-)
10
target/arm/cpu.c | 23 ++++----
11
target/arm/translate-a64.c | 64 +++++++++++++-------
12
target/arm/translate-m-nocp.c | 2 +-
13
target/arm/translate.c | 108 +++++++++++++++++++++++-----------
14
6 files changed, 178 insertions(+), 71 deletions(-)
15
15
16
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu-param.h
19
+++ b/target/arm/cpu-param.h
20
@@ -XXX,XX +XXX,XX @@
21
# define TARGET_PAGE_BITS_VARY
22
# define TARGET_PAGE_BITS_MIN 10
23
24
+# define TARGET_TB_PCREL 1
25
+
26
/*
27
* Cache the attrs and shareability fields from the page table entry.
28
*
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate.h
32
+++ b/target/arm/translate.h
33
@@ -XXX,XX +XXX,XX @@
34
35
36
/* internal defines */
37
+
38
+/*
39
+ * Save pc_save across a branch, so that we may restore the value from
40
+ * before the branch at the point the label is emitted.
41
+ */
42
+typedef struct DisasLabel {
43
+ TCGLabel *label;
44
+ target_ulong pc_save;
45
+} DisasLabel;
46
+
47
typedef struct DisasContext {
48
DisasContextBase base;
49
const ARMISARegisters *isar;
50
51
/* The address of the current instruction being translated. */
52
target_ulong pc_curr;
53
+ /*
54
+ * For TARGET_TB_PCREL, the full value of cpu_pc is not known
55
+ * (although the page offset is known). For convenience, the
56
+ * translation loop uses the full virtual address that triggered
57
+ * the translation, from base.pc_start through pc_curr.
58
+ * For efficiency, we do not update cpu_pc for every instruction.
59
+ * Instead, pc_save has the value of pc_curr at the time of the
60
+ * last update to cpu_pc, which allows us to compute the addend
61
+ * needed to bring cpu_pc current: pc_curr - pc_save.
62
+ * If cpu_pc now contains the destination of an indirect branch,
63
+ * pc_save contains -1 to indicate that relative updates are no
64
+ * longer possible.
65
+ */
66
+ target_ulong pc_save;
67
target_ulong page_start;
68
uint32_t insn;
69
/* Nonzero if this instruction has been conditionally skipped. */
70
int condjmp;
71
/* The label that will be jumped to when the instruction is skipped. */
72
- TCGLabel *condlabel;
73
+ DisasLabel condlabel;
74
/* Thumb-2 conditional execution bits. */
75
int condexec_mask;
76
int condexec_cond;
77
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
78
* after decode (ie after any UNDEF checks)
79
*/
80
bool eci_handled;
81
- /* TCG op to rewind to if this turns out to be an invalid ECI state */
82
- TCGOp *insn_eci_rewind;
83
int sctlr_b;
84
MemOp be_data;
85
#if !defined(CONFIG_USER_ONLY)
86
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
87
*/
88
uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
89
90
+/*
91
+ * gen_disas_label:
92
+ * Create a label and cache a copy of pc_save.
93
+ */
94
+static inline DisasLabel gen_disas_label(DisasContext *s)
95
+{
96
+ return (DisasLabel){
97
+ .label = gen_new_label(),
98
+ .pc_save = s->pc_save,
99
+ };
100
+}
101
+
102
+/*
103
+ * set_disas_label:
104
+ * Emit a label and restore the cached copy of pc_save.
105
+ */
106
+static inline void set_disas_label(DisasContext *s, DisasLabel l)
107
+{
108
+ gen_set_label(l.label);
109
+ s->pc_save = l.pc_save;
110
+}
111
+
112
/*
113
* Helpers for implementing sets of trans_* functions.
114
* Defer the implementation of NAME to FUNC, with optional extra arguments.
115
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
116
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
117
--- a/target/arm/cpu.c
18
--- a/target/arm/cpu.c
118
+++ b/target/arm/cpu.c
19
+++ b/target/arm/cpu.c
119
@@ -XXX,XX +XXX,XX @@ static vaddr arm_cpu_get_pc(CPUState *cs)
20
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
120
void arm_cpu_synchronize_from_tb(CPUState *cs,
21
121
const TranslationBlock *tb)
22
#ifndef CONFIG_USER_ONLY
122
{
23
/*
123
- ARMCPU *cpu = ARM_CPU(cs);
24
- * Disable the MTE feature bits if we do not have tag-memory
124
- CPUARMState *env = &cpu->env;
25
- * provided by the machine.
125
-
26
+ * If we do not have tag-memory provided by the machine,
126
- /*
27
+ * reduce MTE support to instructions enabled at EL0.
127
- * It's OK to look at env for the current mode here, because it's
28
+ * This matches Cortex-A710 BROADCASTMTE input being LOW.
128
- * never possible for an AArch64 TB to chain to an AArch32 TB.
129
- */
130
- if (is_a64(env)) {
131
- env->pc = tb_pc(tb);
132
- } else {
133
- env->regs[15] = tb_pc(tb);
134
+ /* The program counter is always up to date with TARGET_TB_PCREL. */
135
+ if (!TARGET_TB_PCREL) {
136
+ CPUARMState *env = cs->env_ptr;
137
+ /*
138
+ * It's OK to look at env for the current mode here, because it's
139
+ * never possible for an AArch64 TB to chain to an AArch32 TB.
140
+ */
141
+ if (is_a64(env)) {
142
+ env->pc = tb_pc(tb);
143
+ } else {
144
+ env->regs[15] = tb_pc(tb);
145
+ }
146
}
147
}
148
#endif /* CONFIG_TCG */
149
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-a64.c
152
+++ b/target/arm/translate-a64.c
153
@@ -XXX,XX +XXX,XX @@ static void reset_btype(DisasContext *s)
154
155
static void gen_pc_plus_diff(DisasContext *s, TCGv_i64 dest, target_long diff)
156
{
157
- tcg_gen_movi_i64(dest, s->pc_curr + diff);
158
+ assert(s->pc_save != -1);
159
+ if (TARGET_TB_PCREL) {
160
+ tcg_gen_addi_i64(dest, cpu_pc, (s->pc_curr - s->pc_save) + diff);
161
+ } else {
162
+ tcg_gen_movi_i64(dest, s->pc_curr + diff);
163
+ }
164
}
165
166
void gen_a64_update_pc(DisasContext *s, target_long diff)
167
{
168
gen_pc_plus_diff(s, cpu_pc, diff);
169
+ s->pc_save = s->pc_curr + diff;
170
}
171
172
/*
173
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
174
* then loading an address into the PC will clear out any tag.
175
*/
176
gen_top_byte_ignore(s, cpu_pc, src, s->tbii);
177
+ s->pc_save = -1;
178
}
179
180
/*
181
@@ -XXX,XX +XXX,XX @@ static inline bool use_goto_tb(DisasContext *s, uint64_t dest)
182
183
static void gen_goto_tb(DisasContext *s, int n, int64_t diff)
184
{
185
- uint64_t dest = s->pc_curr + diff;
186
-
187
- if (use_goto_tb(s, dest)) {
188
- tcg_gen_goto_tb(n);
189
- gen_a64_update_pc(s, diff);
190
+ if (use_goto_tb(s, s->pc_curr + diff)) {
191
+ /*
192
+ * For pcrel, the pc must always be up-to-date on entry to
193
+ * the linked TB, so that it can use simple additions for all
194
+ * further adjustments. For !pcrel, the linked TB is compiled
195
+ * to know its full virtual address, so we can delay the
196
+ * update to pc to the unlinked path. A long chain of links
197
+ * can thus avoid many updates to the PC.
198
+ */
199
+ if (TARGET_TB_PCREL) {
200
+ gen_a64_update_pc(s, diff);
201
+ tcg_gen_goto_tb(n);
202
+ } else {
203
+ tcg_gen_goto_tb(n);
204
+ gen_a64_update_pc(s, diff);
205
+ }
206
tcg_gen_exit_tb(s->base.tb, n);
207
s->base.is_jmp = DISAS_NORETURN;
208
} else {
209
@@ -XXX,XX +XXX,XX @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
210
{
211
unsigned int sf, op, rt;
212
int64_t diff;
213
- TCGLabel *label_match;
214
+ DisasLabel match;
215
TCGv_i64 tcg_cmp;
216
217
sf = extract32(insn, 31, 1);
218
@@ -XXX,XX +XXX,XX @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
219
diff = sextract32(insn, 5, 19) * 4;
220
221
tcg_cmp = read_cpu_reg(s, rt, sf);
222
- label_match = gen_new_label();
223
-
224
reset_btype(s);
225
- tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
226
- tcg_cmp, 0, label_match);
227
228
+ match = gen_disas_label(s);
229
+ tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
230
+ tcg_cmp, 0, match.label);
231
gen_goto_tb(s, 0, 4);
232
- gen_set_label(label_match);
233
+ set_disas_label(s, match);
234
gen_goto_tb(s, 1, diff);
235
}
236
237
@@ -XXX,XX +XXX,XX @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
238
{
239
unsigned int bit_pos, op, rt;
240
int64_t diff;
241
- TCGLabel *label_match;
242
+ DisasLabel match;
243
TCGv_i64 tcg_cmp;
244
245
bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
246
@@ -XXX,XX +XXX,XX @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
247
248
tcg_cmp = tcg_temp_new_i64();
249
tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos));
250
- label_match = gen_new_label();
251
252
reset_btype(s);
253
+
254
+ match = gen_disas_label(s);
255
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
256
- tcg_cmp, 0, label_match);
257
+ tcg_cmp, 0, match.label);
258
tcg_temp_free_i64(tcg_cmp);
259
gen_goto_tb(s, 0, 4);
260
- gen_set_label(label_match);
261
+ set_disas_label(s, match);
262
gen_goto_tb(s, 1, diff);
263
}
264
265
@@ -XXX,XX +XXX,XX @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
266
reset_btype(s);
267
if (cond < 0x0e) {
268
/* genuinely conditional branches */
269
- TCGLabel *label_match = gen_new_label();
270
- arm_gen_test_cc(cond, label_match);
271
+ DisasLabel match = gen_disas_label(s);
272
+ arm_gen_test_cc(cond, match.label);
273
gen_goto_tb(s, 0, 4);
274
- gen_set_label(label_match);
275
+ set_disas_label(s, match);
276
gen_goto_tb(s, 1, diff);
277
} else {
278
/* 0xe and 0xf are both "always" conditions */
279
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
280
281
dc->isar = &arm_cpu->isar;
282
dc->condjmp = 0;
283
-
284
+ dc->pc_save = dc->base.pc_first;
285
dc->aarch64 = true;
286
dc->thumb = false;
287
dc->sctlr_b = 0;
288
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu)
289
static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
290
{
291
DisasContext *dc = container_of(dcbase, DisasContext, base);
292
+ target_ulong pc_arg = dc->base.pc_next;
293
294
- tcg_gen_insn_start(dc->base.pc_next, 0, 0);
295
+ if (TARGET_TB_PCREL) {
296
+ pc_arg &= ~TARGET_PAGE_MASK;
297
+ }
298
+ tcg_gen_insn_start(pc_arg, 0, 0);
299
dc->insn_start = tcg_last_op();
300
}
301
302
diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c
303
index XXXXXXX..XXXXXXX 100644
304
--- a/target/arm/translate-m-nocp.c
305
+++ b/target/arm/translate-m-nocp.c
306
@@ -XXX,XX +XXX,XX @@ static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
307
tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
308
tcg_gen_or_i32(sfpa, sfpa, aspen);
309
arm_gen_condlabel(s);
310
- tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
311
+ tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel.label);
312
313
if (s->fp_excp_el != 0) {
314
gen_exception_insn_el(s, 0, EXCP_NOCP,
315
diff --git a/target/arm/translate.c b/target/arm/translate.c
316
index XXXXXXX..XXXXXXX 100644
317
--- a/target/arm/translate.c
318
+++ b/target/arm/translate.c
319
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
320
void arm_gen_condlabel(DisasContext *s)
321
{
322
if (!s->condjmp) {
323
- s->condlabel = gen_new_label();
324
+ s->condlabel = gen_disas_label(s);
325
s->condjmp = 1;
326
}
327
}
328
@@ -XXX,XX +XXX,XX @@ static target_long jmp_diff(DisasContext *s, target_long diff)
329
330
static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, target_long diff)
331
{
332
- tcg_gen_movi_i32(var, s->pc_curr + diff);
333
+ assert(s->pc_save != -1);
334
+ if (TARGET_TB_PCREL) {
335
+ tcg_gen_addi_i32(var, cpu_R[15], (s->pc_curr - s->pc_save) + diff);
336
+ } else {
337
+ tcg_gen_movi_i32(var, s->pc_curr + diff);
338
+ }
339
}
340
341
/* Set a variable to the value of a CPU register. */
342
@@ -XXX,XX +XXX,XX @@ void store_reg(DisasContext *s, int reg, TCGv_i32 var)
343
*/
29
*/
344
tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
30
if (cpu->tag_memory == NULL) {
345
s->base.is_jmp = DISAS_JUMP;
31
cpu->isar.id_aa64pfr1 =
346
+ s->pc_save = -1;
32
- FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
347
} else if (reg == 13 && arm_dc_feature(s, ARM_FEATURE_M)) {
33
+ FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 1);
348
/* For M-profile SP bits [1:0] are always zero */
349
tcg_gen_andi_i32(var, var, ~3);
350
@@ -XXX,XX +XXX,XX @@ void gen_set_condexec(DisasContext *s)
351
352
void gen_update_pc(DisasContext *s, target_long diff)
353
{
354
- tcg_gen_movi_i32(cpu_R[15], s->pc_curr + diff);
355
+ gen_pc_plus_diff(s, cpu_R[15], diff);
356
+ s->pc_save = s->pc_curr + diff;
357
}
358
359
/* Set PC and Thumb state from var. var is marked as dead. */
360
@@ -XXX,XX +XXX,XX @@ static inline void gen_bx(DisasContext *s, TCGv_i32 var)
361
tcg_gen_andi_i32(cpu_R[15], var, ~1);
362
tcg_gen_andi_i32(var, var, 1);
363
store_cpu_field(var, thumb);
364
+ s->pc_save = -1;
365
}
366
367
/*
368
@@ -XXX,XX +XXX,XX @@ static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
369
static inline void gen_bx_excret_final_code(DisasContext *s)
370
{
371
/* Generate the code to finish possible exception return and end the TB */
372
- TCGLabel *excret_label = gen_new_label();
373
+ DisasLabel excret_label = gen_disas_label(s);
374
uint32_t min_magic;
375
376
if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
377
@@ -XXX,XX +XXX,XX @@ static inline void gen_bx_excret_final_code(DisasContext *s)
378
}
379
380
/* Is the new PC value in the magic range indicating exception return? */
381
- tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
382
+ tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label.label);
383
/* No: end the TB as we would for a DISAS_JMP */
384
if (s->ss_active) {
385
gen_singlestep_exception(s);
386
} else {
387
tcg_gen_exit_tb(NULL, 0);
388
}
389
- gen_set_label(excret_label);
390
+ set_disas_label(s, excret_label);
391
/* Yes: this is an exception return.
392
* At this point in runtime env->regs[15] and env->thumb will hold
393
* the exception-return magic number, which do_v7m_exception_exit()
394
@@ -XXX,XX +XXX,XX @@ static void gen_goto_ptr(void)
395
*/
396
static void gen_goto_tb(DisasContext *s, int n, target_long diff)
397
{
398
- target_ulong dest = s->pc_curr + diff;
399
-
400
- if (translator_use_goto_tb(&s->base, dest)) {
401
- tcg_gen_goto_tb(n);
402
- gen_update_pc(s, diff);
403
+ if (translator_use_goto_tb(&s->base, s->pc_curr + diff)) {
404
+ /*
405
+ * For pcrel, the pc must always be up-to-date on entry to
406
+ * the linked TB, so that it can use simple additions for all
407
+ * further adjustments. For !pcrel, the linked TB is compiled
408
+ * to know its full virtual address, so we can delay the
409
+ * update to pc to the unlinked path. A long chain of links
410
+ * can thus avoid many updates to the PC.
411
+ */
412
+ if (TARGET_TB_PCREL) {
413
+ gen_update_pc(s, diff);
414
+ tcg_gen_goto_tb(n);
415
+ } else {
416
+ tcg_gen_goto_tb(n);
417
+ gen_update_pc(s, diff);
418
+ }
419
tcg_gen_exit_tb(s->base.tb, n);
420
} else {
421
gen_update_pc(s, diff);
422
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
423
static void arm_skip_unless(DisasContext *s, uint32_t cond)
424
{
425
arm_gen_condlabel(s);
426
- arm_gen_test_cc(cond ^ 1, s->condlabel);
427
+ arm_gen_test_cc(cond ^ 1, s->condlabel.label);
428
}
429
430
431
@@ -XXX,XX +XXX,XX @@ static bool trans_WLS(DisasContext *s, arg_WLS *a)
432
{
433
/* M-profile low-overhead while-loop start */
434
TCGv_i32 tmp;
435
- TCGLabel *nextlabel;
436
+ DisasLabel nextlabel;
437
438
if (!dc_isar_feature(aa32_lob, s)) {
439
return false;
440
@@ -XXX,XX +XXX,XX @@ static bool trans_WLS(DisasContext *s, arg_WLS *a)
441
}
34
}
442
}
35
#endif
443
444
- nextlabel = gen_new_label();
445
- tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel);
446
+ nextlabel = gen_disas_label(s);
447
+ tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel.label);
448
tmp = load_reg(s, a->rn);
449
store_reg(s, 14, tmp);
450
if (a->size != 4) {
451
@@ -XXX,XX +XXX,XX @@ static bool trans_WLS(DisasContext *s, arg_WLS *a)
452
}
453
gen_jmp_tb(s, curr_insn_len(s), 1);
454
455
- gen_set_label(nextlabel);
456
+ set_disas_label(s, nextlabel);
457
gen_jmp(s, jmp_diff(s, a->imm));
458
return true;
459
}
460
@@ -XXX,XX +XXX,XX @@ static bool trans_LE(DisasContext *s, arg_LE *a)
461
* any faster.
462
*/
463
TCGv_i32 tmp;
464
- TCGLabel *loopend;
465
+ DisasLabel loopend;
466
bool fpu_active;
467
468
if (!dc_isar_feature(aa32_lob, s)) {
469
@@ -XXX,XX +XXX,XX @@ static bool trans_LE(DisasContext *s, arg_LE *a)
470
471
if (!a->tp && dc_isar_feature(aa32_mve, s) && fpu_active) {
472
/* Need to do a runtime check for LTPSIZE != 4 */
473
- TCGLabel *skipexc = gen_new_label();
474
+ DisasLabel skipexc = gen_disas_label(s);
475
tmp = load_cpu_field(v7m.ltpsize);
476
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 4, skipexc);
477
+ tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 4, skipexc.label);
478
tcg_temp_free_i32(tmp);
479
gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized());
480
- gen_set_label(skipexc);
481
+ set_disas_label(s, skipexc);
482
}
483
484
if (a->f) {
485
@@ -XXX,XX +XXX,XX @@ static bool trans_LE(DisasContext *s, arg_LE *a)
486
* loop decrement value is 1. For LETP we need to calculate the decrement
487
* value from LTPSIZE.
488
*/
489
- loopend = gen_new_label();
490
+ loopend = gen_disas_label(s);
491
if (!a->tp) {
492
- tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, loopend);
493
+ tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, loopend.label);
494
tcg_gen_addi_i32(cpu_R[14], cpu_R[14], -1);
495
} else {
496
/*
497
@@ -XXX,XX +XXX,XX @@ static bool trans_LE(DisasContext *s, arg_LE *a)
498
tcg_gen_shl_i32(decr, tcg_constant_i32(1), decr);
499
tcg_temp_free_i32(ltpsize);
500
501
- tcg_gen_brcond_i32(TCG_COND_LEU, cpu_R[14], decr, loopend);
502
+ tcg_gen_brcond_i32(TCG_COND_LEU, cpu_R[14], decr, loopend.label);
503
504
tcg_gen_sub_i32(cpu_R[14], cpu_R[14], decr);
505
tcg_temp_free_i32(decr);
506
@@ -XXX,XX +XXX,XX @@ static bool trans_LE(DisasContext *s, arg_LE *a)
507
/* Jump back to the loop start */
508
gen_jmp(s, jmp_diff(s, -a->imm));
509
510
- gen_set_label(loopend);
511
+ set_disas_label(s, loopend);
512
if (a->tp) {
513
/* Exits from tail-pred loops must reset LTPSIZE to 4 */
514
store_cpu_field(tcg_constant_i32(4), v7m.ltpsize);
515
@@ -XXX,XX +XXX,XX @@ static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
516
517
arm_gen_condlabel(s);
518
tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
519
- tmp, 0, s->condlabel);
520
+ tmp, 0, s->condlabel.label);
521
tcg_temp_free_i32(tmp);
522
gen_jmp(s, jmp_diff(s, a->imm));
523
return true;
524
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
525
526
dc->isar = &cpu->isar;
527
dc->condjmp = 0;
528
-
529
+ dc->pc_save = dc->base.pc_first;
530
dc->aarch64 = false;
531
dc->thumb = EX_TBFLAG_AM32(tb_flags, THUMB);
532
dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
533
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
534
*/
535
dc->eci = dc->condexec_mask = dc->condexec_cond = 0;
536
dc->eci_handled = false;
537
- dc->insn_eci_rewind = NULL;
538
if (condexec & 0xf) {
539
dc->condexec_mask = (condexec & 0xf) << 1;
540
dc->condexec_cond = condexec >> 4;
541
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
542
* fields here.
543
*/
544
uint32_t condexec_bits;
545
+ target_ulong pc_arg = dc->base.pc_next;
546
547
+ if (TARGET_TB_PCREL) {
548
+ pc_arg &= ~TARGET_PAGE_MASK;
549
+ }
550
if (dc->eci) {
551
condexec_bits = dc->eci << 4;
552
} else {
553
condexec_bits = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
554
}
555
- tcg_gen_insn_start(dc->base.pc_next, condexec_bits, 0);
556
+ tcg_gen_insn_start(pc_arg, condexec_bits, 0);
557
dc->insn_start = tcg_last_op();
558
}
559
560
@@ -XXX,XX +XXX,XX @@ static bool arm_check_ss_active(DisasContext *dc)
561
562
static void arm_post_translate_insn(DisasContext *dc)
563
{
564
- if (dc->condjmp && !dc->base.is_jmp) {
565
- gen_set_label(dc->condlabel);
566
+ if (dc->condjmp && dc->base.is_jmp == DISAS_NEXT) {
567
+ if (dc->pc_save != dc->condlabel.pc_save) {
568
+ gen_update_pc(dc, dc->condlabel.pc_save - dc->pc_save);
569
+ }
570
+ gen_set_label(dc->condlabel.label);
571
dc->condjmp = 0;
572
}
573
translator_loop_temp_check(&dc->base);
574
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
575
uint32_t pc = dc->base.pc_next;
576
uint32_t insn;
577
bool is_16bit;
578
+ /* TCG op to rewind to if this turns out to be an invalid ECI state */
579
+ TCGOp *insn_eci_rewind = NULL;
580
+ target_ulong insn_eci_pc_save = -1;
581
582
/* Misaligned thumb PC is architecturally impossible. */
583
assert((dc->base.pc_next & 1) == 0);
584
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
585
* insn" case. We will rewind to the marker (ie throwing away
586
* all the generated code) and instead emit "take exception".
587
*/
588
- dc->insn_eci_rewind = tcg_last_op();
589
+ insn_eci_rewind = tcg_last_op();
590
+ insn_eci_pc_save = dc->pc_save;
591
}
592
593
if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
594
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
595
* Insn wasn't valid for ECI/ICI at all: undo what we
596
* just generated and instead emit an exception
597
*/
598
- tcg_remove_ops_after(dc->insn_eci_rewind);
599
+ tcg_remove_ops_after(insn_eci_rewind);
600
+ dc->pc_save = insn_eci_pc_save;
601
dc->condjmp = 0;
602
gen_exception_insn(dc, 0, EXCP_INVSTATE, syn_uncategorized());
603
}
604
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
605
606
if (dc->condjmp) {
607
/* "Condition failed" instruction codepath for the branch/trap insn */
608
- gen_set_label(dc->condlabel);
609
+ set_disas_label(dc, dc->condlabel);
610
gen_set_condexec(dc);
611
if (unlikely(dc->ss_active)) {
612
gen_update_pc(dc, curr_insn_len(dc));
613
@@ -XXX,XX +XXX,XX @@ void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
614
target_ulong *data)
615
{
616
if (is_a64(env)) {
617
- env->pc = data[0];
618
+ if (TARGET_TB_PCREL) {
619
+ env->pc = (env->pc & TARGET_PAGE_MASK) | data[0];
620
+ } else {
621
+ env->pc = data[0];
622
+ }
623
env->condexec_bits = 0;
624
env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
625
} else {
626
- env->regs[15] = data[0];
627
+ if (TARGET_TB_PCREL) {
628
+ env->regs[15] = (env->regs[15] & TARGET_PAGE_MASK) | data[0];
629
+ } else {
630
+ env->regs[15] = data[0];
631
+ }
632
env->condexec_bits = data[1];
633
env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
634
}
36
}
635
--
37
--
636
2.25.1
38
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In preparation for TARGET_TB_PCREL, reduce reliance on absolute values.
3
Do not hard-code the constants for Neoverse V1.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20230811214031.171020-6-richard.henderson@linaro.org
7
Message-id: 20221020030641.2066807-8-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
target/arm/translate-a64.c | 41 +++++++++++++++++++++++++++-----------
10
target/arm/tcg/cpu64.c | 48 ++++++++++++++++++++++++++++--------------
11
1 file changed, 29 insertions(+), 12 deletions(-)
11
1 file changed, 32 insertions(+), 16 deletions(-)
12
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
15
--- a/target/arm/tcg/cpu64.c
16
+++ b/target/arm/translate-a64.c
16
+++ b/target/arm/tcg/cpu64.c
17
@@ -XXX,XX +XXX,XX @@ static void reset_btype(DisasContext *s)
17
@@ -XXX,XX +XXX,XX @@
18
}
18
#include "qemu/module.h"
19
}
19
#include "qapi/visitor.h"
20
20
#include "hw/qdev-properties.h"
21
+static void gen_pc_plus_diff(DisasContext *s, TCGv_i64 dest, target_long diff)
21
+#include "qemu/units.h"
22
#include "internals.h"
23
#include "cpregs.h"
24
25
+static uint64_t make_ccsidr64(unsigned assoc, unsigned linesize,
26
+ unsigned cachesize)
22
+{
27
+{
23
+ tcg_gen_movi_i64(dest, s->pc_curr + diff);
28
+ unsigned lg_linesize = ctz32(linesize);
29
+ unsigned sets;
30
+
31
+ /*
32
+ * The 64-bit CCSIDR_EL1 format is:
33
+ * [55:32] number of sets - 1
34
+ * [23:3] associativity - 1
35
+ * [2:0] log2(linesize) - 4
36
+ * so 0 == 16 bytes, 1 == 32 bytes, 2 == 64 bytes, etc
37
+ */
38
+ assert(assoc != 0);
39
+ assert(is_power_of_2(linesize));
40
+ assert(lg_linesize >= 4 && lg_linesize <= 7 + 4);
41
+
42
+ /* sets * associativity * linesize == cachesize. */
43
+ sets = cachesize / (assoc * linesize);
44
+ assert(cachesize % (assoc * linesize) == 0);
45
+
46
+ return ((uint64_t)(sets - 1) << 32)
47
+ | ((assoc - 1) << 3)
48
+ | (lg_linesize - 4);
24
+}
49
+}
25
+
50
+
26
void gen_a64_update_pc(DisasContext *s, target_long diff)
51
static void aarch64_a35_initfn(Object *obj)
27
{
52
{
28
- tcg_gen_movi_i64(cpu_pc, s->pc_curr + diff);
53
ARMCPU *cpu = ARM_CPU(obj);
29
+ gen_pc_plus_diff(s, cpu_pc, diff);
54
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_v1_initfn(Object *obj)
30
}
55
* The Neoverse-V1 r1p2 TRM lists 32-bit format CCSIDR_EL1 values,
31
56
* but also says it implements CCIDX, which means they should be
32
/*
57
* 64-bit format. So we here use values which are based on the textual
33
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
58
- * information in chapter 2 of the TRM (and on the fact that
34
59
- * sets * associativity * linesize == cachesize).
35
if (insn & (1U << 31)) {
60
- *
36
/* BL Branch with link */
61
- * The 64-bit CCSIDR_EL1 format is:
37
- tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
62
- * [55:32] number of sets - 1
38
+ gen_pc_plus_diff(s, cpu_reg(s, 30), curr_insn_len(s));
63
- * [23:3] associativity - 1
39
}
64
- * [2:0] log2(linesize) - 4
40
65
- * so 0 == 16 bytes, 1 == 32 bytes, 2 == 64 bytes, etc
41
/* B Branch / BL Branch with link */
66
- *
42
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
67
- * L1: 4-way set associative 64-byte line size, total size 64K,
43
default:
68
- * so sets is 256.
44
goto do_unallocated;
69
+ * information in chapter 2 of the TRM:
45
}
70
*
46
- gen_a64_set_pc(s, dst);
71
+ * L1: 4-way set associative 64-byte line size, total size 64K.
47
/* BLR also needs to load return address */
72
* L2: 8-way set associative, 64 byte line size, either 512K or 1MB.
48
if (opc == 1) {
73
- * We pick 1MB, so this has 2048 sets.
49
- tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
74
- *
50
+ TCGv_i64 lr = cpu_reg(s, 30);
75
* L3: No L3 (this matches the CLIDR_EL1 value).
51
+ if (dst == lr) {
76
*/
52
+ TCGv_i64 tmp = new_tmp_a64(s);
77
- cpu->ccsidr[0] = 0x000000ff0000001aull; /* 64KB L1 dcache */
53
+ tcg_gen_mov_i64(tmp, dst);
78
- cpu->ccsidr[1] = 0x000000ff0000001aull; /* 64KB L1 icache */
54
+ dst = tmp;
79
- cpu->ccsidr[2] = 0x000007ff0000003aull; /* 1MB L2 cache */
55
+ }
80
+ cpu->ccsidr[0] = make_ccsidr64(4, 64, 64 * KiB); /* L1 dcache */
56
+ gen_pc_plus_diff(s, lr, curr_insn_len(s));
81
+ cpu->ccsidr[1] = cpu->ccsidr[0]; /* L1 icache */
57
}
82
+ cpu->ccsidr[2] = make_ccsidr64(8, 64, 1 * MiB); /* L2 cache */
58
+ gen_a64_set_pc(s, dst);
83
59
break;
84
/* From 3.2.115 SCTLR_EL3 */
60
85
cpu->reset_sctlr = 0x30c50838;
61
case 8: /* BRAA */
62
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
63
} else {
64
dst = cpu_reg(s, rn);
65
}
66
- gen_a64_set_pc(s, dst);
67
/* BLRAA also needs to load return address */
68
if (opc == 9) {
69
- tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
70
+ TCGv_i64 lr = cpu_reg(s, 30);
71
+ if (dst == lr) {
72
+ TCGv_i64 tmp = new_tmp_a64(s);
73
+ tcg_gen_mov_i64(tmp, dst);
74
+ dst = tmp;
75
+ }
76
+ gen_pc_plus_diff(s, lr, curr_insn_len(s));
77
}
78
+ gen_a64_set_pc(s, dst);
79
break;
80
81
case 4: /* ERET */
82
@@ -XXX,XX +XXX,XX @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
83
84
tcg_rt = cpu_reg(s, rt);
85
86
- clean_addr = tcg_constant_i64(s->pc_curr + imm);
87
+ clean_addr = new_tmp_a64(s);
88
+ gen_pc_plus_diff(s, clean_addr, imm);
89
if (is_vector) {
90
do_fp_ld(s, rt, clean_addr, size);
91
} else {
92
@@ -XXX,XX +XXX,XX @@ static void disas_ldst(DisasContext *s, uint32_t insn)
93
static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
94
{
95
unsigned int page, rd;
96
- uint64_t base;
97
- uint64_t offset;
98
+ int64_t offset;
99
100
page = extract32(insn, 31, 1);
101
/* SignExtend(immhi:immlo) -> offset */
102
offset = sextract64(insn, 5, 19);
103
offset = offset << 2 | extract32(insn, 29, 2);
104
rd = extract32(insn, 0, 5);
105
- base = s->pc_curr;
106
107
if (page) {
108
/* ADRP (page based) */
109
- base &= ~0xfff;
110
offset <<= 12;
111
+ /* The page offset is ok for TARGET_TB_PCREL. */
112
+ offset -= s->pc_curr & 0xfff;
113
}
114
115
- tcg_gen_movi_i64(cpu_reg(s, rd), base + offset);
116
+ gen_pc_plus_diff(s, cpu_reg(s, rd), offset);
117
}
118
119
/*
120
--
86
--
121
2.25.1
87
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We had been marking this ARM_MMU_IDX_NOTLB, move it to a real tlb.
3
Access to many of the special registers is enabled or disabled
4
Flush the tlb when invalidating stage 1+2 translations. Re-use
4
by ACTLR_EL[23], which we implement as constant 0, which means
5
alle1_tlbmask() for other instances of EL1&0 + Stage2.
5
that all writes outside EL3 should trap.
6
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20221011031911.2408754-6-richard.henderson@linaro.org
9
Message-id: 20230811214031.171020-7-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
target/arm/cpu-param.h | 2 +-
12
target/arm/cpregs.h | 2 ++
13
target/arm/cpu.h | 23 ++++---
13
target/arm/helper.c | 4 ++--
14
target/arm/helper.c | 151 ++++++++++++++++++++++++++++++-----------
14
target/arm/tcg/cpu64.c | 46 +++++++++++++++++++++++++++++++++---------
15
3 files changed, 127 insertions(+), 49 deletions(-)
15
3 files changed, 41 insertions(+), 11 deletions(-)
16
16
17
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
17
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu-param.h
19
--- a/target/arm/cpregs.h
20
+++ b/target/arm/cpu-param.h
20
+++ b/target/arm/cpregs.h
21
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
22
bool guarded;
22
void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
23
#endif
23
#endif
24
24
25
-#define NB_MMU_MODES 10
25
+CPAccessResult access_tvm_trvm(CPUARMState *, const ARMCPRegInfo *, bool);
26
+#define NB_MMU_MODES 12
27
28
#endif
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
33
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
34
* EL2 (aka NS PL2)
35
* EL3 (aka S PL1)
36
* Physical (NS & S)
37
+ * Stage2 (NS & S)
38
*
39
- * for a total of 10 different mmu_idx.
40
+ * for a total of 12 different mmu_idx.
41
*
42
* R profile CPUs have an MPU, but can use the same set of MMU indexes
43
* as A profile. They only need to distinguish EL0 and EL1 (and
44
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
45
ARMMMUIdx_Phys_NS = 8 | ARM_MMU_IDX_A,
46
ARMMMUIdx_Phys_S = 9 | ARM_MMU_IDX_A,
47
48
+ /*
49
+ * Used for second stage of an S12 page table walk, or for descriptor
50
+ * loads during first stage of an S1 page table walk. Note that both
51
+ * are in use simultaneously for SecureEL2: the security state for
52
+ * the S2 ptw is selected by the NS bit from the S1 ptw.
53
+ */
54
+ ARMMMUIdx_Stage2 = 10 | ARM_MMU_IDX_A,
55
+ ARMMMUIdx_Stage2_S = 11 | ARM_MMU_IDX_A,
56
+
26
+
57
/*
27
#endif /* TARGET_ARM_CPREGS_H */
58
* These are not allocated TLBs and are used only for AT system
59
* instructions or for the first stage of an S12 page table walk.
60
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
61
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
62
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
63
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
64
- /*
65
- * Not allocated a TLB: used only for second stage of an S12 page
66
- * table walk, or for descriptor loads during first stage of an S1
67
- * page table walk. Note that if we ever want to have a TLB for this
68
- * then various TLB flush insns which currently are no-ops or flush
69
- * only stage 1 MMU indexes will need to change to flush stage 2.
70
- */
71
- ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
72
- ARMMMUIdx_Stage2_S = 4 | ARM_MMU_IDX_NOTLB,
73
74
/*
75
* M-profile.
76
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
77
TO_CORE_BIT(E20_2),
78
TO_CORE_BIT(E20_2_PAN),
79
TO_CORE_BIT(E3),
80
+ TO_CORE_BIT(Stage2),
81
+ TO_CORE_BIT(Stage2_S),
82
83
TO_CORE_BIT(MUser),
84
TO_CORE_BIT(MPriv),
85
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
86
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/helper.c
30
--- a/target/arm/helper.c
88
+++ b/target/arm/helper.c
31
+++ b/target/arm/helper.c
89
@@ -XXX,XX +XXX,XX @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
32
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
90
raw_write(env, ri, value);
91
}
33
}
92
34
93
+static int alle1_tlbmask(CPUARMState *env)
35
/* Check for traps from EL1 due to HCR_EL2.TVM and HCR_EL2.TRVM. */
36
-static CPAccessResult access_tvm_trvm(CPUARMState *env, const ARMCPRegInfo *ri,
37
- bool isread)
38
+CPAccessResult access_tvm_trvm(CPUARMState *env, const ARMCPRegInfo *ri,
39
+ bool isread)
40
{
41
if (arm_current_el(env) == 1) {
42
uint64_t trap = isread ? HCR_TRVM : HCR_TVM;
43
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/tcg/cpu64.c
46
+++ b/target/arm/tcg/cpu64.c
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_a64fx_initfn(Object *obj)
48
/* TODO: Add A64FX specific HPC extension registers */
49
}
50
51
+static CPAccessResult access_actlr_w(CPUARMState *env, const ARMCPRegInfo *r,
52
+ bool read)
94
+{
53
+{
95
+ /*
54
+ if (!read) {
96
+ * Note that the 'ALL' scope must invalidate both stage 1 and
55
+ int el = arm_current_el(env);
97
+ * stage 2 translations, whereas most other scopes only invalidate
56
+
98
+ * stage 1 translations.
57
+ /* Because ACTLR_EL2 is constant 0, writes below EL2 trap to EL2. */
99
+ */
58
+ if (el < 2 && arm_is_el2_enabled(env)) {
100
+ return (ARMMMUIdxBit_E10_1 |
59
+ return CP_ACCESS_TRAP_EL2;
101
+ ARMMMUIdxBit_E10_1_PAN |
60
+ }
102
+ ARMMMUIdxBit_E10_0 |
61
+ /* Because ACTLR_EL3 is constant 0, writes below EL3 trap to EL3. */
103
+ ARMMMUIdxBit_Stage2 |
62
+ if (el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
104
+ ARMMMUIdxBit_Stage2_S);
63
+ return CP_ACCESS_TRAP_EL3;
64
+ }
65
+ }
66
+ return CP_ACCESS_OK;
105
+}
67
+}
106
+
68
+
107
+
69
static const ARMCPRegInfo neoverse_n1_cp_reginfo[] = {
108
/* IS variants of TLB operations must affect all cores */
70
{ .name = "ATCR_EL1", .state = ARM_CP_STATE_AA64,
109
static void tlbiall_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
71
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 7, .opc2 = 0,
110
uint64_t value)
72
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
111
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
73
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
112
{
74
+ /* Traps and enables are the same as for TCR_EL1. */
113
CPUState *cs = env_cpu(env);
75
+ .accessfn = access_tvm_trvm, .fgt = FGT_TCR_EL1, },
114
76
{ .name = "ATCR_EL2", .state = ARM_CP_STATE_AA64,
115
- tlb_flush_by_mmuidx(cs,
77
.opc0 = 3, .opc1 = 4, .crn = 15, .crm = 7, .opc2 = 0,
116
- ARMMMUIdxBit_E10_1 |
78
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
117
- ARMMMUIdxBit_E10_1_PAN |
79
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo neoverse_n1_cp_reginfo[] = {
118
- ARMMMUIdxBit_E10_0);
80
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
119
+ tlb_flush_by_mmuidx(cs, alle1_tlbmask(env));
81
{ .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
120
}
82
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 0,
121
83
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
122
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
84
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
123
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
85
+ .accessfn = access_actlr_w },
124
{
86
{ .name = "CPUACTLR2_EL1", .state = ARM_CP_STATE_AA64,
125
CPUState *cs = env_cpu(env);
87
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 1,
126
88
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
127
- tlb_flush_by_mmuidx_all_cpus_synced(cs,
89
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
128
- ARMMMUIdxBit_E10_1 |
90
+ .accessfn = access_actlr_w },
129
- ARMMMUIdxBit_E10_1_PAN |
91
{ .name = "CPUACTLR3_EL1", .state = ARM_CP_STATE_AA64,
130
- ARMMMUIdxBit_E10_0);
92
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 2,
131
+ tlb_flush_by_mmuidx_all_cpus_synced(cs, alle1_tlbmask(env));
93
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
132
}
94
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
133
95
+ .accessfn = access_actlr_w },
134
135
@@ -XXX,XX +XXX,XX @@ static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
136
ARMMMUIdxBit_E2);
137
}
138
139
+static void tlbiipas2_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
140
+ uint64_t value)
141
+{
142
+ CPUState *cs = env_cpu(env);
143
+ uint64_t pageaddr = (value & MAKE_64BIT_MASK(0, 28)) << 12;
144
+
145
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
146
+}
147
+
148
+static void tlbiipas2is_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
149
+ uint64_t value)
150
+{
151
+ CPUState *cs = env_cpu(env);
152
+ uint64_t pageaddr = (value & MAKE_64BIT_MASK(0, 28)) << 12;
153
+
154
+ tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, ARMMMUIdxBit_Stage2);
155
+}
156
+
157
static const ARMCPRegInfo cp_reginfo[] = {
158
/* Define the secure and non-secure FCSE identifier CP registers
159
* separately because there is no secure bank in V8 (no _EL3). This allows
160
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
161
162
/*
96
/*
163
* A change in VMID to the stage2 page table (Stage2) invalidates
97
* Report CPUCFR_EL1.SCU as 1, as we do not implement the DSU
164
- * the combined stage 1&2 tlbs (EL10_1 and EL10_0).
98
* (and in particular its system registers).
165
+ * the stage2 and combined stage 1&2 tlbs (EL10_1 and EL10_0).
99
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo neoverse_n1_cp_reginfo[] = {
166
*/
100
.access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 4 },
167
if (raw_read(env, ri) != value) {
101
{ .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
168
- uint16_t mask = ARMMMUIdxBit_E10_1 |
102
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 4,
169
- ARMMMUIdxBit_E10_1_PAN |
103
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0x961563010 },
170
- ARMMMUIdxBit_E10_0;
104
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0x961563010,
171
- tlb_flush_by_mmuidx(cs, mask);
105
+ .accessfn = access_actlr_w },
172
+ tlb_flush_by_mmuidx(cs, alle1_tlbmask(env));
106
{ .name = "CPUPCR_EL3", .state = ARM_CP_STATE_AA64,
173
raw_write(env, ri, value);
107
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 1,
174
}
108
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
175
}
109
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo neoverse_n1_cp_reginfo[] = {
176
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
110
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
177
}
111
{ .name = "CPUPWRCTLR_EL1", .state = ARM_CP_STATE_AA64,
178
}
112
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
179
113
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
180
-static int alle1_tlbmask(CPUARMState *env)
114
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
181
-{
115
+ .accessfn = access_actlr_w },
182
- /*
116
{ .name = "ERXPFGCDN_EL1", .state = ARM_CP_STATE_AA64,
183
- * Note that the 'ALL' scope must invalidate both stage 1 and
117
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 2,
184
- * stage 2 translations, whereas most other scopes only invalidate
118
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
185
- * stage 1 translations.
119
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
186
- */
120
+ .accessfn = access_actlr_w },
187
- return (ARMMMUIdxBit_E10_1 |
121
{ .name = "ERXPFGCTL_EL1", .state = ARM_CP_STATE_AA64,
188
- ARMMMUIdxBit_E10_1_PAN |
122
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 1,
189
- ARMMMUIdxBit_E10_0);
123
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
190
-}
124
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
191
-
125
+ .accessfn = access_actlr_w },
192
static int e2_tlbmask(CPUARMState *env)
126
{ .name = "ERXPFGF_EL1", .state = ARM_CP_STATE_AA64,
193
{
127
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
194
return (ARMMMUIdxBit_E20_0 |
128
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
195
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
129
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
196
ARMMMUIdxBit_E3, bits);
130
+ .accessfn = access_actlr_w },
197
}
131
};
198
132
199
+static int ipas2e1_tlbmask(CPUARMState *env, int64_t value)
133
static void define_neoverse_n1_cp_reginfo(ARMCPU *cpu)
200
+{
201
+ /*
202
+ * The MSB of value is the NS field, which only applies if SEL2
203
+ * is implemented and SCR_EL3.NS is not set (i.e. in secure mode).
204
+ */
205
+ return (value >= 0
206
+ && cpu_isar_feature(aa64_sel2, env_archcpu(env))
207
+ && arm_is_secure_below_el3(env)
208
+ ? ARMMMUIdxBit_Stage2_S
209
+ : ARMMMUIdxBit_Stage2);
210
+}
211
+
212
+static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
213
+ uint64_t value)
214
+{
215
+ CPUState *cs = env_cpu(env);
216
+ int mask = ipas2e1_tlbmask(env, value);
217
+ uint64_t pageaddr = sextract64(value << 12, 0, 56);
218
+
219
+ if (tlb_force_broadcast(env)) {
220
+ tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask);
221
+ } else {
222
+ tlb_flush_page_by_mmuidx(cs, pageaddr, mask);
223
+ }
224
+}
225
+
226
+static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
227
+ uint64_t value)
228
+{
229
+ CPUState *cs = env_cpu(env);
230
+ int mask = ipas2e1_tlbmask(env, value);
231
+ uint64_t pageaddr = sextract64(value << 12, 0, 56);
232
+
233
+ tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr, mask);
234
+}
235
+
236
#ifdef TARGET_AARCH64
237
typedef struct {
238
uint64_t base;
239
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_rvae3is_write(CPUARMState *env,
240
241
do_rvae_write(env, value, ARMMMUIdxBit_E3, true);
242
}
243
+
244
+static void tlbi_aa64_ripas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
245
+ uint64_t value)
246
+{
247
+ do_rvae_write(env, value, ipas2e1_tlbmask(env, value),
248
+ tlb_force_broadcast(env));
249
+}
250
+
251
+static void tlbi_aa64_ripas2e1is_write(CPUARMState *env,
252
+ const ARMCPRegInfo *ri,
253
+ uint64_t value)
254
+{
255
+ do_rvae_write(env, value, ipas2e1_tlbmask(env, value), true);
256
+}
257
#endif
258
259
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
260
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
261
.writefn = tlbi_aa64_vae1_write },
262
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
263
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
264
- .access = PL2_W, .type = ARM_CP_NOP },
265
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
266
+ .writefn = tlbi_aa64_ipas2e1is_write },
267
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
268
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
269
- .access = PL2_W, .type = ARM_CP_NOP },
270
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
271
+ .writefn = tlbi_aa64_ipas2e1is_write },
272
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
273
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
274
.access = PL2_W, .type = ARM_CP_NO_RAW,
275
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
276
.writefn = tlbi_aa64_alle1is_write },
277
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
278
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
279
- .access = PL2_W, .type = ARM_CP_NOP },
280
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
281
+ .writefn = tlbi_aa64_ipas2e1_write },
282
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
283
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
284
- .access = PL2_W, .type = ARM_CP_NOP },
285
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
286
+ .writefn = tlbi_aa64_ipas2e1_write },
287
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
288
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
289
.access = PL2_W, .type = ARM_CP_NO_RAW,
290
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
291
.writefn = tlbimva_hyp_is_write },
292
{ .name = "TLBIIPAS2",
293
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
294
- .type = ARM_CP_NOP, .access = PL2_W },
295
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
296
+ .writefn = tlbiipas2_hyp_write },
297
{ .name = "TLBIIPAS2IS",
298
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
299
- .type = ARM_CP_NOP, .access = PL2_W },
300
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
301
+ .writefn = tlbiipas2is_hyp_write },
302
{ .name = "TLBIIPAS2L",
303
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
304
- .type = ARM_CP_NOP, .access = PL2_W },
305
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
306
+ .writefn = tlbiipas2_hyp_write },
307
{ .name = "TLBIIPAS2LIS",
308
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
309
- .type = ARM_CP_NOP, .access = PL2_W },
310
+ .type = ARM_CP_NO_RAW, .access = PL2_W,
311
+ .writefn = tlbiipas2is_hyp_write },
312
/* 32 bit cache operations */
313
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
314
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
315
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
316
.writefn = tlbi_aa64_rvae1_write },
317
{ .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64,
318
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2,
319
- .access = PL2_W, .type = ARM_CP_NOP },
320
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
321
+ .writefn = tlbi_aa64_ripas2e1is_write },
322
{ .name = "TLBI_RIPAS2LE1IS", .state = ARM_CP_STATE_AA64,
323
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 6,
324
- .access = PL2_W, .type = ARM_CP_NOP },
325
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
326
+ .writefn = tlbi_aa64_ripas2e1is_write },
327
{ .name = "TLBI_RVAE2IS", .state = ARM_CP_STATE_AA64,
328
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 1,
329
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
330
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
331
.writefn = tlbi_aa64_rvae2is_write },
332
{ .name = "TLBI_RIPAS2E1", .state = ARM_CP_STATE_AA64,
333
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 2,
334
- .access = PL2_W, .type = ARM_CP_NOP },
335
- { .name = "TLBI_RIPAS2LE1", .state = ARM_CP_STATE_AA64,
336
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
337
+ .writefn = tlbi_aa64_ripas2e1_write },
338
+ { .name = "TLBI_RIPAS2LE1", .state = ARM_CP_STATE_AA64,
339
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 6,
340
- .access = PL2_W, .type = ARM_CP_NOP },
341
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
342
+ .writefn = tlbi_aa64_ripas2e1_write },
343
{ .name = "TLBI_RVAE2OS", .state = ARM_CP_STATE_AA64,
344
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 1,
345
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
346
--
134
--
347
2.25.1
135
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Not yet used, but add mmu indexes for 1-1 mapping
3
There is only one additional EL1 register modeled, which
4
to physical addresses.
4
also needs to use access_actlr_w.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230811214031.171020-8-richard.henderson@linaro.org
8
Message-id: 20221011031911.2408754-5-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/cpu-param.h | 2 +-
11
target/arm/tcg/cpu64.c | 3 ++-
12
target/arm/cpu.h | 7 ++++++-
12
1 file changed, 2 insertions(+), 1 deletion(-)
13
target/arm/ptw.c | 19 +++++++++++++++++--
14
3 files changed, 24 insertions(+), 4 deletions(-)
15
13
16
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
14
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu-param.h
16
--- a/target/arm/tcg/cpu64.c
19
+++ b/target/arm/cpu-param.h
17
+++ b/target/arm/tcg/cpu64.c
20
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void define_neoverse_n1_cp_reginfo(ARMCPU *cpu)
21
bool guarded;
19
static const ARMCPRegInfo neoverse_v1_cp_reginfo[] = {
22
#endif
20
{ .name = "CPUECTLR2_EL1", .state = ARM_CP_STATE_AA64,
23
21
.opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 5,
24
-#define NB_MMU_MODES 8
22
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
25
+#define NB_MMU_MODES 10
23
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0,
26
24
+ .accessfn = access_actlr_w },
27
#endif
25
{ .name = "CPUPPMCR_EL3", .state = ARM_CP_STATE_AA64,
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 0,
29
index XXXXXXX..XXXXXXX 100644
27
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
30
--- a/target/arm/cpu.h
31
+++ b/target/arm/cpu.h
32
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
33
* EL2 EL2&0 +PAN
34
* EL2 (aka NS PL2)
35
* EL3 (aka S PL1)
36
+ * Physical (NS & S)
37
*
38
- * for a total of 8 different mmu_idx.
39
+ * for a total of 10 different mmu_idx.
40
*
41
* R profile CPUs have an MPU, but can use the same set of MMU indexes
42
* as A profile. They only need to distinguish EL0 and EL1 (and
43
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
44
ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A,
45
ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A,
46
47
+ /* TLBs with 1-1 mapping to the physical address spaces. */
48
+ ARMMMUIdx_Phys_NS = 8 | ARM_MMU_IDX_A,
49
+ ARMMMUIdx_Phys_S = 9 | ARM_MMU_IDX_A,
50
+
51
/*
52
* These are not allocated TLBs and are used only for AT system
53
* instructions or for the first stage of an S12 page table walk.
54
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/ptw.c
57
+++ b/target/arm/ptw.c
58
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
59
case ARMMMUIdx_E3:
60
break;
61
62
+ case ARMMMUIdx_Phys_NS:
63
+ case ARMMMUIdx_Phys_S:
64
+ /* No translation for physical address spaces. */
65
+ return true;
66
+
67
default:
68
g_assert_not_reached();
69
}
70
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
71
{
72
uint8_t memattr = 0x00; /* Device nGnRnE */
73
uint8_t shareability = 0; /* non-sharable */
74
+ int r_el;
75
76
- if (mmu_idx != ARMMMUIdx_Stage2 && mmu_idx != ARMMMUIdx_Stage2_S) {
77
- int r_el = regime_el(env, mmu_idx);
78
+ switch (mmu_idx) {
79
+ case ARMMMUIdx_Stage2:
80
+ case ARMMMUIdx_Stage2_S:
81
+ case ARMMMUIdx_Phys_NS:
82
+ case ARMMMUIdx_Phys_S:
83
+ break;
84
85
+ default:
86
+ r_el = regime_el(env, mmu_idx);
87
if (arm_el_is_aa64(env, r_el)) {
88
int pamax = arm_pamax(env_archcpu(env));
89
uint64_t tcr = env->cp15.tcr_el[r_el];
90
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
91
shareability = 2; /* outer sharable */
92
}
93
result->cacheattrs.is_s2_format = false;
94
+ break;
95
}
96
97
result->f.phys_addr = address;
98
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
99
is_secure = arm_is_secure_below_el3(env);
100
break;
101
case ARMMMUIdx_Stage2:
102
+ case ARMMMUIdx_Phys_NS:
103
case ARMMMUIdx_MPrivNegPri:
104
case ARMMMUIdx_MUserNegPri:
105
case ARMMMUIdx_MPriv:
106
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
107
break;
108
case ARMMMUIdx_E3:
109
case ARMMMUIdx_Stage2_S:
110
+ case ARMMMUIdx_Phys_S:
111
case ARMMMUIdx_MSPrivNegPri:
112
case ARMMMUIdx_MSUserNegPri:
113
case ARMMMUIdx_MSPriv:
114
--
28
--
115
2.25.1
29
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Consolidate most of the inputs and outputs of S1_ptw_translate
3
Like FEAT_TRF (Self-hosted Trace Extension), suppress tracing
4
into a single structure. Plumb this through arm_ld*_ptw from
4
external to the cpu, which is out of scope for QEMU.
5
the controlling get_phys_addr_* routine.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <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: 20221011031911.2408754-8-richard.henderson@linaro.org
8
Message-id: 20230811214031.171020-10-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/ptw.c | 140 ++++++++++++++++++++++++++---------------------
11
target/arm/cpu.c | 3 +++
13
1 file changed, 79 insertions(+), 61 deletions(-)
12
1 file changed, 3 insertions(+)
14
13
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/ptw.c
16
--- a/target/arm/cpu.c
18
+++ b/target/arm/ptw.c
17
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
20
#include "idau.h"
19
/* FEAT_SPE (Statistical Profiling Extension) */
21
20
cpu->isar.id_aa64dfr0 =
22
21
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMSVER, 0);
23
-static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
22
+ /* FEAT_TRBE (Trace Buffer Extension) */
24
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
23
+ cpu->isar.id_aa64dfr0 =
25
- bool is_secure, bool s1_is_el0,
24
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEBUFFER, 0);
26
+typedef struct S1Translate {
25
/* FEAT_TRF (Self-hosted Trace Extension) */
27
+ ARMMMUIdx in_mmu_idx;
26
cpu->isar.id_aa64dfr0 =
28
+ bool in_secure;
27
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEFILT, 0);
29
+ bool out_secure;
30
+ hwaddr out_phys;
31
+} S1Translate;
32
+
33
+static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
34
+ uint64_t address,
35
+ MMUAccessType access_type, bool s1_is_el0,
36
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
37
__attribute__((nonnull));
38
39
@@ -XXX,XX +XXX,XX @@ static bool ptw_attrs_are_device(uint64_t hcr, ARMCacheAttrs cacheattrs)
40
}
41
42
/* Translate a S1 pagetable walk through S2 if needed. */
43
-static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
44
- hwaddr addr, bool *is_secure_ptr,
45
- ARMMMUFaultInfo *fi)
46
+static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
47
+ hwaddr addr, ARMMMUFaultInfo *fi)
48
{
49
- bool is_secure = *is_secure_ptr;
50
+ bool is_secure = ptw->in_secure;
51
ARMMMUIdx s2_mmu_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
52
53
- if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
54
+ if (arm_mmu_idx_is_stage1_of_2(ptw->in_mmu_idx) &&
55
!regime_translation_disabled(env, s2_mmu_idx, is_secure)) {
56
GetPhysAddrResult s2 = {};
57
+ S1Translate s2ptw = {
58
+ .in_mmu_idx = s2_mmu_idx,
59
+ .in_secure = is_secure,
60
+ };
61
uint64_t hcr;
62
int ret;
63
64
- ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx,
65
- is_secure, false, &s2, fi);
66
+ ret = get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
67
+ false, &s2, fi);
68
if (ret) {
69
assert(fi->type != ARMFault_None);
70
fi->s2addr = addr;
71
fi->stage2 = true;
72
fi->s1ptw = true;
73
fi->s1ns = !is_secure;
74
- return ~0;
75
+ return false;
76
}
77
78
hcr = arm_hcr_el2_eff_secstate(env, is_secure);
79
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
80
fi->stage2 = true;
81
fi->s1ptw = true;
82
fi->s1ns = !is_secure;
83
- return ~0;
84
+ return false;
85
}
86
87
if (arm_is_secure_below_el3(env)) {
88
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
89
} else {
90
is_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
91
}
92
- *is_secure_ptr = is_secure;
93
} else {
94
assert(!is_secure);
95
}
96
97
addr = s2.f.phys_addr;
98
}
99
- return addr;
100
+
101
+ ptw->out_secure = is_secure;
102
+ ptw->out_phys = addr;
103
+ return true;
104
}
105
106
/* All loads done in the course of a page table walk go through here. */
107
-static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure,
108
- ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
109
+static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
110
+ ARMMMUFaultInfo *fi)
111
{
112
CPUState *cs = env_cpu(env);
113
MemTxAttrs attrs = {};
114
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure,
115
AddressSpace *as;
116
uint32_t data;
117
118
- addr = S1_ptw_translate(env, mmu_idx, addr, &is_secure, fi);
119
- attrs.secure = is_secure;
120
- as = arm_addressspace(cs, attrs);
121
- if (fi->s1ptw) {
122
+ if (!S1_ptw_translate(env, ptw, addr, fi)) {
123
return 0;
124
}
125
- if (regime_translation_big_endian(env, mmu_idx)) {
126
+ addr = ptw->out_phys;
127
+ attrs.secure = ptw->out_secure;
128
+ as = arm_addressspace(cs, attrs);
129
+ if (regime_translation_big_endian(env, ptw->in_mmu_idx)) {
130
data = address_space_ldl_be(as, addr, attrs, &result);
131
} else {
132
data = address_space_ldl_le(as, addr, attrs, &result);
133
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, hwaddr addr, bool is_secure,
134
return 0;
135
}
136
137
-static uint64_t arm_ldq_ptw(CPUARMState *env, hwaddr addr, bool is_secure,
138
- ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
139
+static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
140
+ ARMMMUFaultInfo *fi)
141
{
142
CPUState *cs = env_cpu(env);
143
MemTxAttrs attrs = {};
144
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, hwaddr addr, bool is_secure,
145
AddressSpace *as;
146
uint64_t data;
147
148
- addr = S1_ptw_translate(env, mmu_idx, addr, &is_secure, fi);
149
- attrs.secure = is_secure;
150
- as = arm_addressspace(cs, attrs);
151
- if (fi->s1ptw) {
152
+ if (!S1_ptw_translate(env, ptw, addr, fi)) {
153
return 0;
154
}
155
- if (regime_translation_big_endian(env, mmu_idx)) {
156
+ addr = ptw->out_phys;
157
+ attrs.secure = ptw->out_secure;
158
+ as = arm_addressspace(cs, attrs);
159
+ if (regime_translation_big_endian(env, ptw->in_mmu_idx)) {
160
data = address_space_ldq_be(as, addr, attrs, &result);
161
} else {
162
data = address_space_ldq_le(as, addr, attrs, &result);
163
@@ -XXX,XX +XXX,XX @@ static int simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
164
return simple_ap_to_rw_prot_is_user(ap, regime_is_user(env, mmu_idx));
165
}
166
167
-static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
168
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
169
- bool is_secure, GetPhysAddrResult *result,
170
- ARMMMUFaultInfo *fi)
171
+static bool get_phys_addr_v5(CPUARMState *env, S1Translate *ptw,
172
+ uint32_t address, MMUAccessType access_type,
173
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
174
{
175
int level = 1;
176
uint32_t table;
177
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
178
179
/* Pagetable walk. */
180
/* Lookup l1 descriptor. */
181
- if (!get_level1_table_address(env, mmu_idx, &table, address)) {
182
+ if (!get_level1_table_address(env, ptw->in_mmu_idx, &table, address)) {
183
/* Section translation fault if page walk is disabled by PD0 or PD1 */
184
fi->type = ARMFault_Translation;
185
goto do_fault;
186
}
187
- desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi);
188
+ desc = arm_ldl_ptw(env, ptw, table, fi);
189
if (fi->type != ARMFault_None) {
190
goto do_fault;
191
}
192
type = (desc & 3);
193
domain = (desc >> 5) & 0x0f;
194
- if (regime_el(env, mmu_idx) == 1) {
195
+ if (regime_el(env, ptw->in_mmu_idx) == 1) {
196
dacr = env->cp15.dacr_ns;
197
} else {
198
dacr = env->cp15.dacr_s;
199
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
200
/* Fine pagetable. */
201
table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
202
}
203
- desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi);
204
+ desc = arm_ldl_ptw(env, ptw, table, fi);
205
if (fi->type != ARMFault_None) {
206
goto do_fault;
207
}
208
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
209
g_assert_not_reached();
210
}
211
}
212
- result->f.prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
213
+ result->f.prot = ap_to_rw_prot(env, ptw->in_mmu_idx, ap, domain_prot);
214
result->f.prot |= result->f.prot ? PAGE_EXEC : 0;
215
if (!(result->f.prot & (1 << access_type))) {
216
/* Access permission fault. */
217
@@ -XXX,XX +XXX,XX @@ do_fault:
218
return true;
219
}
220
221
-static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
222
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
223
- bool is_secure, GetPhysAddrResult *result,
224
- ARMMMUFaultInfo *fi)
225
+static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
226
+ uint32_t address, MMUAccessType access_type,
227
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
228
{
229
ARMCPU *cpu = env_archcpu(env);
230
+ ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
231
int level = 1;
232
uint32_t table;
233
uint32_t desc;
234
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
235
fi->type = ARMFault_Translation;
236
goto do_fault;
237
}
238
- desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi);
239
+ desc = arm_ldl_ptw(env, ptw, table, fi);
240
if (fi->type != ARMFault_None) {
241
goto do_fault;
242
}
243
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
244
ns = extract32(desc, 3, 1);
245
/* Lookup l2 entry. */
246
table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
247
- desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi);
248
+ desc = arm_ldl_ptw(env, ptw, table, fi);
249
if (fi->type != ARMFault_None) {
250
goto do_fault;
251
}
252
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
253
* the WnR bit is never set (the caller must do this).
254
*
255
* @env: CPUARMState
256
+ * @ptw: Current and next stage parameters for the walk.
257
* @address: virtual address to get physical address for
258
* @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
259
- * @mmu_idx: MMU index indicating required translation regime
260
- * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page
261
- * table walk), must be true if this is stage 2 of a stage 1+2
262
+ * @s1_is_el0: if @ptw->in_mmu_idx is ARMMMUIdx_Stage2
263
+ * (so this is a stage 2 page table walk),
264
+ * must be true if this is stage 2 of a stage 1+2
265
* walk for an EL0 access. If @mmu_idx is anything else,
266
* @s1_is_el0 is ignored.
267
* @result: set on translation success,
268
* @fi: set to fault info if the translation fails
269
*/
270
-static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
271
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
272
- bool is_secure, bool s1_is_el0,
273
+static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
274
+ uint64_t address,
275
+ MMUAccessType access_type, bool s1_is_el0,
276
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
277
{
278
ARMCPU *cpu = env_archcpu(env);
279
+ ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
280
+ bool is_secure = ptw->in_secure;
281
/* Read an LPAE long-descriptor translation table. */
282
ARMFaultType fault_type = ARMFault_Translation;
283
uint32_t level;
284
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
285
descaddr |= (address >> (stride * (4 - level))) & indexmask;
286
descaddr &= ~7ULL;
287
nstable = extract32(tableattrs, 4, 1);
288
- descriptor = arm_ldq_ptw(env, descaddr, !nstable, mmu_idx, fi);
289
+ ptw->in_secure = !nstable;
290
+ descriptor = arm_ldq_ptw(env, ptw, descaddr, fi);
291
if (fi->type != ARMFault_None) {
292
goto do_fault;
293
}
294
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
295
ARMMMUFaultInfo *fi)
296
{
297
ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
298
+ S1Translate ptw;
299
300
if (mmu_idx != s1_mmu_idx) {
301
/*
302
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
303
int ret;
304
bool ipa_secure, s2walk_secure;
305
ARMCacheAttrs cacheattrs1;
306
- ARMMMUIdx s2_mmu_idx;
307
bool is_el0;
308
uint64_t hcr;
309
310
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
311
s2walk_secure = false;
312
}
313
314
- s2_mmu_idx = (s2walk_secure
315
- ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2);
316
+ ptw.in_mmu_idx =
317
+ s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
318
+ ptw.in_secure = s2walk_secure;
319
is_el0 = mmu_idx == ARMMMUIdx_E10_0;
320
321
/*
322
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
323
cacheattrs1 = result->cacheattrs;
324
memset(result, 0, sizeof(*result));
325
326
- ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx,
327
- s2walk_secure, is_el0, result, fi);
328
+ ret = get_phys_addr_lpae(env, &ptw, ipa, access_type,
329
+ is_el0, result, fi);
330
fi->s2addr = ipa;
331
332
/* Combine the S1 and S2 perms. */
333
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
334
return get_phys_addr_disabled(env, address, access_type, mmu_idx,
335
is_secure, result, fi);
336
}
337
+
338
+ ptw.in_mmu_idx = mmu_idx;
339
+ ptw.in_secure = is_secure;
340
+
341
if (regime_using_lpae_format(env, mmu_idx)) {
342
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
343
- is_secure, false, result, fi);
344
+ return get_phys_addr_lpae(env, &ptw, address, access_type, false,
345
+ result, fi);
346
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
347
- return get_phys_addr_v6(env, address, access_type, mmu_idx,
348
- is_secure, result, fi);
349
+ return get_phys_addr_v6(env, &ptw, address, access_type, result, fi);
350
} else {
351
- return get_phys_addr_v5(env, address, access_type, mmu_idx,
352
- is_secure, result, fi);
353
+ return get_phys_addr_v5(env, &ptw, address, access_type, result, fi);
354
}
355
}
356
357
--
28
--
358
2.25.1
29
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Compare only the VMID field when considering whether we need to flush.
3
This feature allows the operating system to set TCR_ELx.HWU*
4
to allow the implementation to use the PBHA bits from the
5
block and page descriptors for for IMPLEMENTATION DEFINED
6
purposes. Since QEMU has no need to use these bits, we may
7
simply ignore them.
4
8
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20221011031911.2408754-7-richard.henderson@linaro.org
11
Message-id: 20230811214031.171020-11-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 | 4 ++--
14
docs/system/arm/emulation.rst | 1 +
11
1 file changed, 2 insertions(+), 2 deletions(-)
15
target/arm/tcg/cpu32.c | 2 +-
16
target/arm/tcg/cpu64.c | 2 +-
17
3 files changed, 3 insertions(+), 2 deletions(-)
12
18
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
21
--- a/docs/system/arm/emulation.rst
16
+++ b/target/arm/helper.c
22
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
* A change in VMID to the stage2 page table (Stage2) invalidates
24
- FEAT_HAFDBS (Hardware management of the access flag and dirty bit state)
19
* the stage2 and combined stage 1&2 tlbs (EL10_1 and EL10_0).
25
- FEAT_HCX (Support for the HCRX_EL2 register)
20
*/
26
- FEAT_HPDS (Hierarchical permission disables)
21
- if (raw_read(env, ri) != value) {
27
+- FEAT_HPDS2 (Translation table page-based hardware attributes)
22
+ if (extract64(raw_read(env, ri) ^ value, 48, 16) != 0) {
28
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
23
tlb_flush_by_mmuidx(cs, alle1_tlbmask(env));
29
- FEAT_IDST (ID space trap handling)
24
- raw_write(env, ri, value);
30
- FEAT_IESB (Implicit error synchronization event)
25
}
31
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
26
+ raw_write(env, ri, value);
32
index XXXXXXX..XXXXXXX 100644
27
}
33
--- a/target/arm/tcg/cpu32.c
28
34
+++ b/target/arm/tcg/cpu32.c
29
static const ARMCPRegInfo vmsa_pmsa_cp_reginfo[] = {
35
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
36
cpu->isar.id_mmfr3 = t;
37
38
t = cpu->isar.id_mmfr4;
39
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* FEAT_AA32HPD */
40
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 2); /* FEAT_HPDS2 */
41
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
42
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */
43
t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX */
44
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/tcg/cpu64.c
47
+++ b/target/arm/tcg/cpu64.c
48
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
49
t = FIELD_DP64(t, ID_AA64MMFR1, HAFDBS, 2); /* FEAT_HAFDBS */
50
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
51
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
52
- t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
53
+ t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 2); /* FEAT_HPDS2 */
54
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
55
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 3); /* FEAT_PAN3 */
56
t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
30
--
57
--
31
2.25.1
58
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
In preparation for TARGET_TB_PCREL, reduce reliance on absolute values.
3
This is a mandatory feature for Armv8.1 architectures but we don't
4
state the feature clearly in our emulation list. Also include
5
FEAT_CRC32 comment in aarch64_max_tcg_initfn for ease of grepping.
4
6
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20221020030641.2066807-9-richard.henderson@linaro.org
9
Message-id: 20230824075406.1515566-1-alex.bennee@linaro.org
10
Cc: qemu-stable@nongnu.org
11
Message-Id: <20230222110104.3996971-1-alex.bennee@linaro.org>
12
[PMM: pluralize 'instructions' in docs]
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
target/arm/translate.c | 38 +++++++++++++++++++++-----------------
15
docs/system/arm/emulation.rst | 1 +
11
1 file changed, 21 insertions(+), 17 deletions(-)
16
target/arm/tcg/cpu64.c | 2 +-
17
2 files changed, 2 insertions(+), 1 deletion(-)
12
18
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
21
--- a/docs/system/arm/emulation.rst
16
+++ b/target/arm/translate.c
22
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
18
}
24
- FEAT_BBM at level 2 (Translation table break-before-make levels)
19
}
25
- FEAT_BF16 (AArch64 BFloat16 instructions)
20
26
- FEAT_BTI (Branch Target Identification)
21
-/* The architectural value of PC. */
27
+- FEAT_CRC32 (CRC32 instructions)
22
-static uint32_t read_pc(DisasContext *s)
28
- FEAT_CSV2 (Cache speculation variant 2)
23
-{
29
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
24
- return s->pc_curr + (s->thumb ? 4 : 8);
30
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
25
-}
31
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
26
-
32
index XXXXXXX..XXXXXXX 100644
27
/* The pc_curr difference for an architectural jump. */
33
--- a/target/arm/tcg/cpu64.c
28
static target_long jmp_diff(DisasContext *s, target_long diff)
34
+++ b/target/arm/tcg/cpu64.c
29
{
35
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
30
return diff + (s->thumb ? 4 : 8);
36
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
31
}
37
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
32
38
t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */
33
+static void gen_pc_plus_diff(DisasContext *s, TCGv_i32 var, target_long diff)
39
- t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
34
+{
40
+ t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1); /* FEAT_CRC32 */
35
+ tcg_gen_movi_i32(var, s->pc_curr + diff);
41
t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2); /* FEAT_LSE */
36
+}
42
t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1); /* FEAT_RDM */
37
+
43
t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1); /* FEAT_SHA3 */
38
/* Set a variable to the value of a CPU register. */
39
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
40
{
41
if (reg == 15) {
42
- tcg_gen_movi_i32(var, read_pc(s));
43
+ gen_pc_plus_diff(s, var, jmp_diff(s, 0));
44
} else {
45
tcg_gen_mov_i32(var, cpu_R[reg]);
46
}
47
@@ -XXX,XX +XXX,XX @@ TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
48
TCGv_i32 tmp = tcg_temp_new_i32();
49
50
if (reg == 15) {
51
- tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
52
+ /*
53
+ * This address is computed from an aligned PC:
54
+ * subtract off the low bits.
55
+ */
56
+ gen_pc_plus_diff(s, tmp, jmp_diff(s, ofs - (s->pc_curr & 3)));
57
} else {
58
tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
59
}
60
@@ -XXX,XX +XXX,XX @@ void unallocated_encoding(DisasContext *s)
61
/* Force a TB lookup after an instruction that changes the CPU state. */
62
void gen_lookup_tb(DisasContext *s)
63
{
64
- tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
65
+ gen_pc_plus_diff(s, cpu_R[15], curr_insn_len(s));
66
s->base.is_jmp = DISAS_EXIT;
67
}
68
69
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
70
return false;
71
}
72
tmp = load_reg(s, a->rm);
73
- tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
74
+ gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb);
75
gen_bx(s, tmp);
76
return true;
77
}
78
@@ -XXX,XX +XXX,XX @@ static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
79
80
static bool trans_BL(DisasContext *s, arg_i *a)
81
{
82
- tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
83
+ gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb);
84
gen_jmp(s, jmp_diff(s, a->imm));
85
return true;
86
}
87
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
88
if (s->thumb && (a->imm & 2)) {
89
return false;
90
}
91
- tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
92
+ gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | s->thumb);
93
store_cpu_field_constant(!s->thumb, thumb);
94
/* This jump is computed from an aligned PC: subtract off the low bits. */
95
gen_jmp(s, jmp_diff(s, a->imm - (s->pc_curr & 3)));
96
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
97
static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
98
{
99
assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
100
- tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
101
+ gen_pc_plus_diff(s, cpu_R[14], jmp_diff(s, a->imm << 12));
102
return true;
103
}
104
105
@@ -XXX,XX +XXX,XX @@ static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
106
107
assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
108
tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
109
- tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
110
+ gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | 1);
111
gen_bx(s, tmp);
112
return true;
113
}
114
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
115
tmp = tcg_temp_new_i32();
116
tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
117
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
118
- tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
119
+ gen_pc_plus_diff(s, cpu_R[14], curr_insn_len(s) | 1);
120
gen_bx(s, tmp);
121
return true;
122
}
123
@@ -XXX,XX +XXX,XX @@ static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
124
tcg_gen_add_i32(addr, addr, tmp);
125
126
gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), half ? MO_UW : MO_UB);
127
- tcg_temp_free_i32(addr);
128
129
tcg_gen_add_i32(tmp, tmp, tmp);
130
- tcg_gen_addi_i32(tmp, tmp, read_pc(s));
131
+ gen_pc_plus_diff(s, addr, jmp_diff(s, 0));
132
+ tcg_gen_add_i32(tmp, tmp, addr);
133
+ tcg_temp_free_i32(addr);
134
store_reg(s, 15, tmp);
135
return true;
136
}
137
--
44
--
138
2.25.1
45
2.34.1
139
46
140
47
diff view generated by jsdifflib
1
From: Baruch Siach <baruch@tkos.co.il>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
The PL011 TRM says that "UARTIBRD = 0 is invalid and UARTFBRD is ignored
3
i.MX7 IOMUX GPR device is not equivalent to i.MX6UL IOMUXC GPR device.
4
when this is the case". But the code looks at FBRD for the invalid case.
4
In particular, register 22 is not present on i.MX6UL and this is actualy
5
Fix this.
5
The only register that is really emulated in the i.MX7 IOMUX GPR device.
6
6
7
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
7
Note: The i.MX6UL code is actually also implementing the IOMUX GPR device
8
Message-id: 1408f62a2e45665816527d4845ffde650957d5ab.1665051588.git.baruchs-c@neureality.ai
8
as an unimplemented device at the same bus adress and the 2 instantiations
9
were actualy colliding. So we go back to the unimplemented device for now.
10
11
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
12
Message-id: 48681bf51ee97646479bb261bee19abebbc8074e.1692964892.git.jcd@tribudubois.net
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
hw/char/pl011.c | 2 +-
16
include/hw/arm/fsl-imx6ul.h | 2 --
13
1 file changed, 1 insertion(+), 1 deletion(-)
17
hw/arm/fsl-imx6ul.c | 11 -----------
18
2 files changed, 13 deletions(-)
14
19
15
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
20
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/char/pl011.c
22
--- a/include/hw/arm/fsl-imx6ul.h
18
+++ b/hw/char/pl011.c
23
+++ b/include/hw/arm/fsl-imx6ul.h
19
@@ -XXX,XX +XXX,XX @@ static unsigned int pl011_get_baudrate(const PL011State *s)
24
@@ -XXX,XX +XXX,XX @@
20
{
25
#include "hw/misc/imx6ul_ccm.h"
21
uint64_t clk;
26
#include "hw/misc/imx6_src.h"
22
27
#include "hw/misc/imx7_snvs.h"
23
- if (s->fbrd == 0) {
28
-#include "hw/misc/imx7_gpr.h"
24
+ if (s->ibrd == 0) {
29
#include "hw/intc/imx_gpcv2.h"
25
return 0;
30
#include "hw/watchdog/wdt_imx2.h"
31
#include "hw/gpio/imx_gpio.h"
32
@@ -XXX,XX +XXX,XX @@ struct FslIMX6ULState {
33
IMX6SRCState src;
34
IMX7SNVSState snvs;
35
IMXGPCv2State gpcv2;
36
- IMX7GPRState gpr;
37
IMXSPIState spi[FSL_IMX6UL_NUM_ECSPIS];
38
IMXI2CState i2c[FSL_IMX6UL_NUM_I2CS];
39
IMXSerialState uart[FSL_IMX6UL_NUM_UARTS];
40
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/fsl-imx6ul.c
43
+++ b/hw/arm/fsl-imx6ul.c
44
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
45
*/
46
object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
47
48
- /*
49
- * GPR
50
- */
51
- object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX7_GPR);
52
-
53
/*
54
* GPIOs 1 to 5
55
*/
56
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
57
FSL_IMX6UL_WDOGn_IRQ[i]));
26
}
58
}
27
59
60
- /*
61
- * GPR
62
- */
63
- sysbus_realize(SYS_BUS_DEVICE(&s->gpr), &error_abort);
64
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX6UL_IOMUXC_GPR_ADDR);
65
-
66
/*
67
* SDMA
68
*/
28
--
69
--
29
2.25.1
70
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
The return type of the functions is already bool, but in a few
3
* Add Addr and size definition for most i.MX6UL devices in i.MX6UL header file.
4
instances we used an integer type with the return statement.
4
* Use those newly defined named constants whenever possible.
5
* Standardize the way we init a familly of unimplemented devices
6
- SAI
7
- PWM
8
- CAN
9
* Add/rework few comments
5
10
11
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
12
Message-id: d579043fbd4e4b490370783fda43fc02c8e9be75.1692964892.git.jcd@tribudubois.net
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20221011031911.2408754-13-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/ptw.c | 7 +++----
16
include/hw/arm/fsl-imx6ul.h | 156 +++++++++++++++++++++++++++++++-----
12
1 file changed, 3 insertions(+), 4 deletions(-)
17
hw/arm/fsl-imx6ul.c | 147 ++++++++++++++++++++++-----------
18
2 files changed, 232 insertions(+), 71 deletions(-)
13
19
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
20
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/ptw.c
22
--- a/include/hw/arm/fsl-imx6ul.h
17
+++ b/target/arm/ptw.c
23
+++ b/include/hw/arm/fsl-imx6ul.h
18
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
24
@@ -XXX,XX +XXX,XX @@
19
result->f.lg_page_size = TARGET_PAGE_BITS;
25
#include "exec/memory.h"
20
result->cacheattrs.shareability = shareability;
26
#include "cpu.h"
21
result->cacheattrs.attrs = memattr;
27
#include "qom/object.h"
22
- return 0;
28
+#include "qemu/units.h"
23
+ return false;
29
24
}
30
#define TYPE_FSL_IMX6UL "fsl-imx6ul"
25
31
OBJECT_DECLARE_SIMPLE_TYPE(FslIMX6ULState, FSL_IMX6UL)
26
static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
32
@@ -XXX,XX +XXX,XX @@ enum FslIMX6ULConfiguration {
27
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
33
FSL_IMX6UL_NUM_ADCS = 2,
28
{
34
FSL_IMX6UL_NUM_USB_PHYS = 2,
29
hwaddr ipa;
35
FSL_IMX6UL_NUM_USBS = 2,
30
int s1_prot;
36
+ FSL_IMX6UL_NUM_SAIS = 3,
31
- int ret;
37
+ FSL_IMX6UL_NUM_CANS = 2,
32
bool is_secure = ptw->in_secure;
38
+ FSL_IMX6UL_NUM_PWMS = 4,
33
- bool ipa_secure, s2walk_secure;
39
};
34
+ bool ret, ipa_secure, s2walk_secure;
40
35
ARMCacheAttrs cacheattrs1;
41
struct FslIMX6ULState {
36
bool is_el0;
42
@@ -XXX,XX +XXX,XX @@ struct FslIMX6ULState {
37
uint64_t hcr;
43
38
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
44
enum FslIMX6ULMemoryMap {
39
&& (ipa_secure
45
FSL_IMX6UL_MMDC_ADDR = 0x80000000,
40
|| !(env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))));
46
- FSL_IMX6UL_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL,
41
47
+ FSL_IMX6UL_MMDC_SIZE = (2 * GiB),
42
- return 0;
48
43
+ return false;
49
FSL_IMX6UL_QSPI1_MEM_ADDR = 0x60000000,
44
}
50
- FSL_IMX6UL_EIM_ALIAS_ADDR = 0x58000000,
45
51
- FSL_IMX6UL_EIM_CS_ADDR = 0x50000000,
46
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
52
- FSL_IMX6UL_AES_ENCRYPT_ADDR = 0x10000000,
53
- FSL_IMX6UL_QSPI1_RX_ADDR = 0x0C000000,
54
+ FSL_IMX6UL_QSPI1_MEM_SIZE = (256 * MiB),
55
56
- /* AIPS-2 */
57
+ FSL_IMX6UL_EIM_ALIAS_ADDR = 0x58000000,
58
+ FSL_IMX6UL_EIM_ALIAS_SIZE = (128 * MiB),
59
+
60
+ FSL_IMX6UL_EIM_CS_ADDR = 0x50000000,
61
+ FSL_IMX6UL_EIM_CS_SIZE = (128 * MiB),
62
+
63
+ FSL_IMX6UL_AES_ENCRYPT_ADDR = 0x10000000,
64
+ FSL_IMX6UL_AES_ENCRYPT_SIZE = (1 * MiB),
65
+
66
+ FSL_IMX6UL_QSPI1_RX_ADDR = 0x0C000000,
67
+ FSL_IMX6UL_QSPI1_RX_SIZE = (32 * MiB),
68
+
69
+ /* AIPS-2 Begin */
70
FSL_IMX6UL_UART6_ADDR = 0x021FC000,
71
+
72
FSL_IMX6UL_I2C4_ADDR = 0x021F8000,
73
+
74
FSL_IMX6UL_UART5_ADDR = 0x021F4000,
75
FSL_IMX6UL_UART4_ADDR = 0x021F0000,
76
FSL_IMX6UL_UART3_ADDR = 0x021EC000,
77
FSL_IMX6UL_UART2_ADDR = 0x021E8000,
78
+
79
FSL_IMX6UL_WDOG3_ADDR = 0x021E4000,
80
+
81
FSL_IMX6UL_QSPI_ADDR = 0x021E0000,
82
+ FSL_IMX6UL_QSPI_SIZE = 0x500,
83
+
84
FSL_IMX6UL_SYS_CNT_CTRL_ADDR = 0x021DC000,
85
+ FSL_IMX6UL_SYS_CNT_CTRL_SIZE = (16 * KiB),
86
+
87
FSL_IMX6UL_SYS_CNT_CMP_ADDR = 0x021D8000,
88
+ FSL_IMX6UL_SYS_CNT_CMP_SIZE = (16 * KiB),
89
+
90
FSL_IMX6UL_SYS_CNT_RD_ADDR = 0x021D4000,
91
+ FSL_IMX6UL_SYS_CNT_RD_SIZE = (16 * KiB),
92
+
93
FSL_IMX6UL_TZASC_ADDR = 0x021D0000,
94
+ FSL_IMX6UL_TZASC_SIZE = (16 * KiB),
95
+
96
FSL_IMX6UL_PXP_ADDR = 0x021CC000,
97
+ FSL_IMX6UL_PXP_SIZE = (16 * KiB),
98
+
99
FSL_IMX6UL_LCDIF_ADDR = 0x021C8000,
100
+ FSL_IMX6UL_LCDIF_SIZE = 0x100,
101
+
102
FSL_IMX6UL_CSI_ADDR = 0x021C4000,
103
+ FSL_IMX6UL_CSI_SIZE = 0x100,
104
+
105
FSL_IMX6UL_CSU_ADDR = 0x021C0000,
106
+ FSL_IMX6UL_CSU_SIZE = (16 * KiB),
107
+
108
FSL_IMX6UL_OCOTP_CTRL_ADDR = 0x021BC000,
109
+ FSL_IMX6UL_OCOTP_CTRL_SIZE = (4 * KiB),
110
+
111
FSL_IMX6UL_EIM_ADDR = 0x021B8000,
112
+ FSL_IMX6UL_EIM_SIZE = 0x100,
113
+
114
FSL_IMX6UL_SIM2_ADDR = 0x021B4000,
115
+
116
FSL_IMX6UL_MMDC_CFG_ADDR = 0x021B0000,
117
+ FSL_IMX6UL_MMDC_CFG_SIZE = (4 * KiB),
118
+
119
FSL_IMX6UL_ROMCP_ADDR = 0x021AC000,
120
+ FSL_IMX6UL_ROMCP_SIZE = 0x300,
121
+
122
FSL_IMX6UL_I2C3_ADDR = 0x021A8000,
123
FSL_IMX6UL_I2C2_ADDR = 0x021A4000,
124
FSL_IMX6UL_I2C1_ADDR = 0x021A0000,
125
+
126
FSL_IMX6UL_ADC2_ADDR = 0x0219C000,
127
FSL_IMX6UL_ADC1_ADDR = 0x02198000,
128
+ FSL_IMX6UL_ADCn_SIZE = 0x100,
129
+
130
FSL_IMX6UL_USDHC2_ADDR = 0x02194000,
131
FSL_IMX6UL_USDHC1_ADDR = 0x02190000,
132
- FSL_IMX6UL_SIM1_ADDR = 0x0218C000,
133
- FSL_IMX6UL_ENET1_ADDR = 0x02188000,
134
- FSL_IMX6UL_USBO2_USBMISC_ADDR = 0x02184800,
135
- FSL_IMX6UL_USBO2_USB_ADDR = 0x02184000,
136
- FSL_IMX6UL_USBO2_PL301_ADDR = 0x02180000,
137
- FSL_IMX6UL_AIPS2_CFG_ADDR = 0x0217C000,
138
- FSL_IMX6UL_CAAM_ADDR = 0x02140000,
139
- FSL_IMX6UL_A7MPCORE_DAP_ADDR = 0x02100000,
140
141
- /* AIPS-1 */
142
+ FSL_IMX6UL_SIM1_ADDR = 0x0218C000,
143
+ FSL_IMX6UL_SIMn_SIZE = (16 * KiB),
144
+
145
+ FSL_IMX6UL_ENET1_ADDR = 0x02188000,
146
+
147
+ FSL_IMX6UL_USBO2_USBMISC_ADDR = 0x02184800,
148
+ FSL_IMX6UL_USBO2_USB1_ADDR = 0x02184000,
149
+ FSL_IMX6UL_USBO2_USB2_ADDR = 0x02184200,
150
+
151
+ FSL_IMX6UL_USBO2_PL301_ADDR = 0x02180000,
152
+ FSL_IMX6UL_USBO2_PL301_SIZE = (16 * KiB),
153
+
154
+ FSL_IMX6UL_AIPS2_CFG_ADDR = 0x0217C000,
155
+ FSL_IMX6UL_AIPS2_CFG_SIZE = 0x100,
156
+
157
+ FSL_IMX6UL_CAAM_ADDR = 0x02140000,
158
+ FSL_IMX6UL_CAAM_SIZE = (16 * KiB),
159
+
160
+ FSL_IMX6UL_A7MPCORE_DAP_ADDR = 0x02100000,
161
+ FSL_IMX6UL_A7MPCORE_DAP_SIZE = (4 * KiB),
162
+ /* AIPS-2 End */
163
+
164
+ /* AIPS-1 Begin */
165
FSL_IMX6UL_PWM8_ADDR = 0x020FC000,
166
FSL_IMX6UL_PWM7_ADDR = 0x020F8000,
167
FSL_IMX6UL_PWM6_ADDR = 0x020F4000,
168
FSL_IMX6UL_PWM5_ADDR = 0x020F0000,
169
+
170
FSL_IMX6UL_SDMA_ADDR = 0x020EC000,
171
+ FSL_IMX6UL_SDMA_SIZE = 0x300,
172
+
173
FSL_IMX6UL_GPT2_ADDR = 0x020E8000,
174
+
175
FSL_IMX6UL_IOMUXC_GPR_ADDR = 0x020E4000,
176
+ FSL_IMX6UL_IOMUXC_GPR_SIZE = 0x40,
177
+
178
FSL_IMX6UL_IOMUXC_ADDR = 0x020E0000,
179
+ FSL_IMX6UL_IOMUXC_SIZE = 0x700,
180
+
181
FSL_IMX6UL_GPC_ADDR = 0x020DC000,
182
+
183
FSL_IMX6UL_SRC_ADDR = 0x020D8000,
184
+
185
FSL_IMX6UL_EPIT2_ADDR = 0x020D4000,
186
FSL_IMX6UL_EPIT1_ADDR = 0x020D0000,
187
+
188
FSL_IMX6UL_SNVS_HP_ADDR = 0x020CC000,
189
+
190
FSL_IMX6UL_USBPHY2_ADDR = 0x020CA000,
191
- FSL_IMX6UL_USBPHY2_SIZE = (4 * 1024),
192
FSL_IMX6UL_USBPHY1_ADDR = 0x020C9000,
193
- FSL_IMX6UL_USBPHY1_SIZE = (4 * 1024),
194
+
195
FSL_IMX6UL_ANALOG_ADDR = 0x020C8000,
196
+ FSL_IMX6UL_ANALOG_SIZE = 0x300,
197
+
198
FSL_IMX6UL_CCM_ADDR = 0x020C4000,
199
+
200
FSL_IMX6UL_WDOG2_ADDR = 0x020C0000,
201
FSL_IMX6UL_WDOG1_ADDR = 0x020BC000,
202
+
203
FSL_IMX6UL_KPP_ADDR = 0x020B8000,
204
+ FSL_IMX6UL_KPP_SIZE = 0x10,
205
+
206
FSL_IMX6UL_ENET2_ADDR = 0x020B4000,
207
+
208
FSL_IMX6UL_SNVS_LP_ADDR = 0x020B0000,
209
+ FSL_IMX6UL_SNVS_LP_SIZE = (16 * KiB),
210
+
211
FSL_IMX6UL_GPIO5_ADDR = 0x020AC000,
212
FSL_IMX6UL_GPIO4_ADDR = 0x020A8000,
213
FSL_IMX6UL_GPIO3_ADDR = 0x020A4000,
214
FSL_IMX6UL_GPIO2_ADDR = 0x020A0000,
215
FSL_IMX6UL_GPIO1_ADDR = 0x0209C000,
216
+
217
FSL_IMX6UL_GPT1_ADDR = 0x02098000,
218
+
219
FSL_IMX6UL_CAN2_ADDR = 0x02094000,
220
FSL_IMX6UL_CAN1_ADDR = 0x02090000,
221
+ FSL_IMX6UL_CANn_SIZE = (4 * KiB),
222
+
223
FSL_IMX6UL_PWM4_ADDR = 0x0208C000,
224
FSL_IMX6UL_PWM3_ADDR = 0x02088000,
225
FSL_IMX6UL_PWM2_ADDR = 0x02084000,
226
FSL_IMX6UL_PWM1_ADDR = 0x02080000,
227
+ FSL_IMX6UL_PWMn_SIZE = 0x20,
228
+
229
FSL_IMX6UL_AIPS1_CFG_ADDR = 0x0207C000,
230
+ FSL_IMX6UL_AIPS1_CFG_SIZE = (16 * KiB),
231
+
232
FSL_IMX6UL_BEE_ADDR = 0x02044000,
233
+ FSL_IMX6UL_BEE_SIZE = (16 * KiB),
234
+
235
FSL_IMX6UL_TOUCH_CTRL_ADDR = 0x02040000,
236
+ FSL_IMX6UL_TOUCH_CTRL_SIZE = 0x100,
237
+
238
FSL_IMX6UL_SPBA_ADDR = 0x0203C000,
239
+ FSL_IMX6UL_SPBA_SIZE = 0x100,
240
+
241
FSL_IMX6UL_ASRC_ADDR = 0x02034000,
242
+ FSL_IMX6UL_ASRC_SIZE = 0x100,
243
+
244
FSL_IMX6UL_SAI3_ADDR = 0x02030000,
245
FSL_IMX6UL_SAI2_ADDR = 0x0202C000,
246
FSL_IMX6UL_SAI1_ADDR = 0x02028000,
247
+ FSL_IMX6UL_SAIn_SIZE = 0x200,
248
+
249
FSL_IMX6UL_UART8_ADDR = 0x02024000,
250
FSL_IMX6UL_UART1_ADDR = 0x02020000,
251
FSL_IMX6UL_UART7_ADDR = 0x02018000,
252
+
253
FSL_IMX6UL_ECSPI4_ADDR = 0x02014000,
254
FSL_IMX6UL_ECSPI3_ADDR = 0x02010000,
255
FSL_IMX6UL_ECSPI2_ADDR = 0x0200C000,
256
FSL_IMX6UL_ECSPI1_ADDR = 0x02008000,
257
+
258
FSL_IMX6UL_SPDIF_ADDR = 0x02004000,
259
+ FSL_IMX6UL_SPDIF_SIZE = 0x100,
260
+ /* AIPS-1 End */
261
+
262
+ FSL_IMX6UL_BCH_ADDR = 0x01808000,
263
+ FSL_IMX6UL_BCH_SIZE = 0x200,
264
+
265
+ FSL_IMX6UL_GPMI_ADDR = 0x01806000,
266
+ FSL_IMX6UL_GPMI_SIZE = 0x200,
267
268
FSL_IMX6UL_APBH_DMA_ADDR = 0x01804000,
269
- FSL_IMX6UL_APBH_DMA_SIZE = (32 * 1024),
270
+ FSL_IMX6UL_APBH_DMA_SIZE = (4 * KiB),
271
272
FSL_IMX6UL_A7MPCORE_ADDR = 0x00A00000,
273
274
FSL_IMX6UL_OCRAM_ALIAS_ADDR = 0x00920000,
275
- FSL_IMX6UL_OCRAM_ALIAS_SIZE = 0x00060000,
276
+ FSL_IMX6UL_OCRAM_ALIAS_SIZE = (384 * KiB),
277
+
278
FSL_IMX6UL_OCRAM_MEM_ADDR = 0x00900000,
279
- FSL_IMX6UL_OCRAM_MEM_SIZE = 0x00020000,
280
+ FSL_IMX6UL_OCRAM_MEM_SIZE = (128 * KiB),
281
+
282
FSL_IMX6UL_CAAM_MEM_ADDR = 0x00100000,
283
- FSL_IMX6UL_CAAM_MEM_SIZE = 0x00008000,
284
+ FSL_IMX6UL_CAAM_MEM_SIZE = (32 * KiB),
285
+
286
FSL_IMX6UL_ROM_ADDR = 0x00000000,
287
- FSL_IMX6UL_ROM_SIZE = 0x00018000,
288
+ FSL_IMX6UL_ROM_SIZE = (96 * KiB),
289
};
290
291
enum FslIMX6ULIRQs {
292
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
293
index XXXXXXX..XXXXXXX 100644
294
--- a/hw/arm/fsl-imx6ul.c
295
+++ b/hw/arm/fsl-imx6ul.c
296
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
297
object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
298
299
/*
300
- * GPIOs 1 to 5
301
+ * GPIOs
302
*/
303
for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
304
snprintf(name, NAME_SIZE, "gpio%d", i);
305
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
306
}
307
308
/*
309
- * GPT 1, 2
310
+ * GPTs
311
*/
312
for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
313
snprintf(name, NAME_SIZE, "gpt%d", i);
314
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
315
}
316
317
/*
318
- * EPIT 1, 2
319
+ * EPITs
320
*/
321
for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
322
snprintf(name, NAME_SIZE, "epit%d", i + 1);
323
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
324
}
325
326
/*
327
- * eCSPI
328
+ * eCSPIs
329
*/
330
for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
331
snprintf(name, NAME_SIZE, "spi%d", i + 1);
332
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
333
}
334
335
/*
336
- * I2C
337
+ * I2Cs
338
*/
339
for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
340
snprintf(name, NAME_SIZE, "i2c%d", i + 1);
341
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
342
}
343
344
/*
345
- * UART
346
+ * UARTs
347
*/
348
for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
349
snprintf(name, NAME_SIZE, "uart%d", i);
350
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
351
}
352
353
/*
354
- * Ethernet
355
+ * Ethernets
356
*/
357
for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
358
snprintf(name, NAME_SIZE, "eth%d", i);
359
object_initialize_child(obj, name, &s->eth[i], TYPE_IMX_ENET);
360
}
361
362
- /* USB */
363
+ /*
364
+ * USB PHYs
365
+ */
366
for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
367
snprintf(name, NAME_SIZE, "usbphy%d", i);
368
object_initialize_child(obj, name, &s->usbphy[i], TYPE_IMX_USBPHY);
369
}
370
+
371
+ /*
372
+ * USBs
373
+ */
374
for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
375
snprintf(name, NAME_SIZE, "usb%d", i);
376
object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
377
}
378
379
/*
380
- * SDHCI
381
+ * SDHCIs
382
*/
383
for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
384
snprintf(name, NAME_SIZE, "usdhc%d", i);
385
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
386
}
387
388
/*
389
- * Watchdog
390
+ * Watchdogs
391
*/
392
for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
393
snprintf(name, NAME_SIZE, "wdt%d", i);
394
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
395
* A7MPCORE DAP
396
*/
397
create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
398
- 0x100000);
399
+ FSL_IMX6UL_A7MPCORE_DAP_SIZE);
400
401
/*
402
- * GPT 1, 2
403
+ * GPTs
404
*/
405
for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
406
static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
407
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
408
}
409
410
/*
411
- * EPIT 1, 2
412
+ * EPITs
413
*/
414
for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
415
static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
416
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
417
}
418
419
/*
420
- * GPIO
421
+ * GPIOs
422
*/
423
for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
424
static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
425
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
426
}
427
428
/*
429
- * IOMUXC and IOMUXC_GPR
430
+ * IOMUXC
431
*/
432
- for (i = 0; i < 1; i++) {
433
- static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
434
- FSL_IMX6UL_IOMUXC_ADDR,
435
- FSL_IMX6UL_IOMUXC_GPR_ADDR,
436
- };
437
-
438
- snprintf(name, NAME_SIZE, "iomuxc%d", i);
439
- create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
440
- }
441
+ create_unimplemented_device("iomuxc", FSL_IMX6UL_IOMUXC_ADDR,
442
+ FSL_IMX6UL_IOMUXC_SIZE);
443
+ create_unimplemented_device("iomuxc_gpr", FSL_IMX6UL_IOMUXC_GPR_ADDR,
444
+ FSL_IMX6UL_IOMUXC_GPR_SIZE);
445
446
/*
447
* CCM
448
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
449
sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
450
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR);
451
452
- /* Initialize all ECSPI */
453
+ /*
454
+ * ECSPIs
455
+ */
456
for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
457
static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = {
458
FSL_IMX6UL_ECSPI1_ADDR,
459
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
460
}
461
462
/*
463
- * I2C
464
+ * I2Cs
465
*/
466
for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
467
static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = {
468
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
469
}
470
471
/*
472
- * UART
473
+ * UARTs
474
*/
475
for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
476
static const hwaddr FSL_IMX6UL_UARTn_ADDR[FSL_IMX6UL_NUM_UARTS] = {
477
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
478
}
479
480
/*
481
- * Ethernet
482
+ * Ethernets
483
*
484
* We must use two loops since phy_connected affects the other interface
485
* and we have to set all properties before calling sysbus_realize().
486
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
487
FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
488
}
489
490
- /* USB */
491
+ /*
492
+ * USB PHYs
493
+ */
494
for (i = 0; i < FSL_IMX6UL_NUM_USB_PHYS; i++) {
495
+ static const hwaddr
496
+ FSL_IMX6UL_USB_PHYn_ADDR[FSL_IMX6UL_NUM_USB_PHYS] = {
497
+ FSL_IMX6UL_USBPHY1_ADDR,
498
+ FSL_IMX6UL_USBPHY2_ADDR,
499
+ };
500
+
501
sysbus_realize(SYS_BUS_DEVICE(&s->usbphy[i]), &error_abort);
502
sysbus_mmio_map(SYS_BUS_DEVICE(&s->usbphy[i]), 0,
503
- FSL_IMX6UL_USBPHY1_ADDR + i * 0x1000);
504
+ FSL_IMX6UL_USB_PHYn_ADDR[i]);
505
}
506
507
+ /*
508
+ * USBs
509
+ */
510
for (i = 0; i < FSL_IMX6UL_NUM_USBS; i++) {
511
+ static const hwaddr FSL_IMX6UL_USB02_USBn_ADDR[FSL_IMX6UL_NUM_USBS] = {
512
+ FSL_IMX6UL_USBO2_USB1_ADDR,
513
+ FSL_IMX6UL_USBO2_USB2_ADDR,
514
+ };
515
+
516
static const int FSL_IMX6UL_USBn_IRQ[] = {
517
FSL_IMX6UL_USB1_IRQ,
518
FSL_IMX6UL_USB2_IRQ,
519
};
520
+
521
sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), &error_abort);
522
sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
523
- FSL_IMX6UL_USBO2_USB_ADDR + i * 0x200);
524
+ FSL_IMX6UL_USB02_USBn_ADDR[i]);
525
sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0,
526
qdev_get_gpio_in(DEVICE(&s->a7mpcore),
527
FSL_IMX6UL_USBn_IRQ[i]));
528
}
529
530
/*
531
- * USDHC
532
+ * USDHCs
533
*/
534
for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
535
static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = {
536
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
537
sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR);
538
539
/*
540
- * Watchdog
541
+ * Watchdogs
542
*/
543
for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
544
static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = {
545
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
546
FSL_IMX6UL_WDOG2_ADDR,
547
FSL_IMX6UL_WDOG3_ADDR,
548
};
549
+
550
static const int FSL_IMX6UL_WDOGn_IRQ[FSL_IMX6UL_NUM_WDTS] = {
551
FSL_IMX6UL_WDOG1_IRQ,
552
FSL_IMX6UL_WDOG2_IRQ,
553
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
554
/*
555
* SDMA
556
*/
557
- create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR, 0x4000);
558
+ create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR,
559
+ FSL_IMX6UL_SDMA_SIZE);
560
561
/*
562
- * SAI (Audio SSI (Synchronous Serial Interface))
563
+ * SAIs (Audio SSI (Synchronous Serial Interface))
564
*/
565
- create_unimplemented_device("sai1", FSL_IMX6UL_SAI1_ADDR, 0x4000);
566
- create_unimplemented_device("sai2", FSL_IMX6UL_SAI2_ADDR, 0x4000);
567
- create_unimplemented_device("sai3", FSL_IMX6UL_SAI3_ADDR, 0x4000);
568
+ for (i = 0; i < FSL_IMX6UL_NUM_SAIS; i++) {
569
+ static const hwaddr FSL_IMX6UL_SAIn_ADDR[FSL_IMX6UL_NUM_SAIS] = {
570
+ FSL_IMX6UL_SAI1_ADDR,
571
+ FSL_IMX6UL_SAI2_ADDR,
572
+ FSL_IMX6UL_SAI3_ADDR,
573
+ };
574
+
575
+ snprintf(name, NAME_SIZE, "sai%d", i);
576
+ create_unimplemented_device(name, FSL_IMX6UL_SAIn_ADDR[i],
577
+ FSL_IMX6UL_SAIn_SIZE);
578
+ }
579
580
/*
581
- * PWM
582
+ * PWMs
583
*/
584
- create_unimplemented_device("pwm1", FSL_IMX6UL_PWM1_ADDR, 0x4000);
585
- create_unimplemented_device("pwm2", FSL_IMX6UL_PWM2_ADDR, 0x4000);
586
- create_unimplemented_device("pwm3", FSL_IMX6UL_PWM3_ADDR, 0x4000);
587
- create_unimplemented_device("pwm4", FSL_IMX6UL_PWM4_ADDR, 0x4000);
588
+ for (i = 0; i < FSL_IMX6UL_NUM_PWMS; i++) {
589
+ static const hwaddr FSL_IMX6UL_PWMn_ADDR[FSL_IMX6UL_NUM_PWMS] = {
590
+ FSL_IMX6UL_PWM1_ADDR,
591
+ FSL_IMX6UL_PWM2_ADDR,
592
+ FSL_IMX6UL_PWM3_ADDR,
593
+ FSL_IMX6UL_PWM4_ADDR,
594
+ };
595
+
596
+ snprintf(name, NAME_SIZE, "pwm%d", i);
597
+ create_unimplemented_device(name, FSL_IMX6UL_PWMn_ADDR[i],
598
+ FSL_IMX6UL_PWMn_SIZE);
599
+ }
600
601
/*
602
* Audio ASRC (asynchronous sample rate converter)
603
*/
604
- create_unimplemented_device("asrc", FSL_IMX6UL_ASRC_ADDR, 0x4000);
605
+ create_unimplemented_device("asrc", FSL_IMX6UL_ASRC_ADDR,
606
+ FSL_IMX6UL_ASRC_SIZE);
607
608
/*
609
- * CAN
610
+ * CANs
611
*/
612
- create_unimplemented_device("can1", FSL_IMX6UL_CAN1_ADDR, 0x4000);
613
- create_unimplemented_device("can2", FSL_IMX6UL_CAN2_ADDR, 0x4000);
614
+ for (i = 0; i < FSL_IMX6UL_NUM_CANS; i++) {
615
+ static const hwaddr FSL_IMX6UL_CANn_ADDR[FSL_IMX6UL_NUM_CANS] = {
616
+ FSL_IMX6UL_CAN1_ADDR,
617
+ FSL_IMX6UL_CAN2_ADDR,
618
+ };
619
+
620
+ snprintf(name, NAME_SIZE, "can%d", i);
621
+ create_unimplemented_device(name, FSL_IMX6UL_CANn_ADDR[i],
622
+ FSL_IMX6UL_CANn_SIZE);
623
+ }
624
625
/*
626
* APHB_DMA
627
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
628
};
629
630
snprintf(name, NAME_SIZE, "adc%d", i);
631
- create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i], 0x4000);
632
+ create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i],
633
+ FSL_IMX6UL_ADCn_SIZE);
634
}
635
636
/*
637
* LCD
638
*/
639
- create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR, 0x4000);
640
+ create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
641
+ FSL_IMX6UL_LCDIF_SIZE);
642
643
/*
644
* ROM memory
47
--
645
--
48
2.25.1
646
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
In preparation for TARGET_TB_PCREL, reduce reliance on absolute values.
3
* Add TZASC as unimplemented device.
4
- Allow bare metal application to access this (unimplemented) device
5
* Add CSU as unimplemented device.
6
- Allow bare metal application to access this (unimplemented) device
7
* Add 4 missing PWM devices
4
8
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20221020030641.2066807-5-richard.henderson@linaro.org
11
Message-id: 59e4dc56e14eccfefd379275ec19048dff9c10b3.1692964892.git.jcd@tribudubois.net
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/translate.h | 5 +++--
14
include/hw/arm/fsl-imx6ul.h | 2 +-
11
target/arm/translate-a64.c | 28 ++++++++++-------------
15
hw/arm/fsl-imx6ul.c | 16 ++++++++++++++++
12
target/arm/translate-m-nocp.c | 6 ++---
16
2 files changed, 17 insertions(+), 1 deletion(-)
13
target/arm/translate-mve.c | 2 +-
14
target/arm/translate-vfp.c | 6 ++---
15
target/arm/translate.c | 42 +++++++++++++++++------------------
16
6 files changed, 43 insertions(+), 46 deletions(-)
17
17
18
diff --git a/target/arm/translate.h b/target/arm/translate.h
18
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.h
20
--- a/include/hw/arm/fsl-imx6ul.h
21
+++ b/target/arm/translate.h
21
+++ b/include/hw/arm/fsl-imx6ul.h
22
@@ -XXX,XX +XXX,XX @@ void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
22
@@ -XXX,XX +XXX,XX @@ enum FslIMX6ULConfiguration {
23
void arm_gen_test_cc(int cc, TCGLabel *label);
23
FSL_IMX6UL_NUM_USBS = 2,
24
MemOp pow2_align(unsigned i);
24
FSL_IMX6UL_NUM_SAIS = 3,
25
void unallocated_encoding(DisasContext *s);
25
FSL_IMX6UL_NUM_CANS = 2,
26
-void gen_exception_insn_el(DisasContext *s, uint64_t pc, int excp,
26
- FSL_IMX6UL_NUM_PWMS = 4,
27
+void gen_exception_insn_el(DisasContext *s, target_long pc_diff, int excp,
27
+ FSL_IMX6UL_NUM_PWMS = 8,
28
uint32_t syn, uint32_t target_el);
28
};
29
-void gen_exception_insn(DisasContext *s, uint64_t pc, int excp, uint32_t syn);
29
30
+void gen_exception_insn(DisasContext *s, target_long pc_diff,
30
struct FslIMX6ULState {
31
+ int excp, uint32_t syn);
31
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
32
33
/* Return state of Alternate Half-precision flag, caller frees result */
34
static inline TCGv_i32 get_ahp_flag(void)
35
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
36
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-a64.c
33
--- a/hw/arm/fsl-imx6ul.c
38
+++ b/target/arm/translate-a64.c
34
+++ b/hw/arm/fsl-imx6ul.c
39
@@ -XXX,XX +XXX,XX @@ static bool fp_access_check_only(DisasContext *s)
35
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
40
assert(!s->fp_access_checked);
36
FSL_IMX6UL_PWM2_ADDR,
41
s->fp_access_checked = true;
37
FSL_IMX6UL_PWM3_ADDR,
42
38
FSL_IMX6UL_PWM4_ADDR,
43
- gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF,
39
+ FSL_IMX6UL_PWM5_ADDR,
44
+ gen_exception_insn_el(s, 0, EXCP_UDEF,
40
+ FSL_IMX6UL_PWM6_ADDR,
45
syn_fp_access_trap(1, 0xe, false, 0),
41
+ FSL_IMX6UL_PWM7_ADDR,
46
s->fp_excp_el);
42
+ FSL_IMX6UL_PWM8_ADDR,
47
return false;
43
};
48
@@ -XXX,XX +XXX,XX @@ static bool fp_access_check(DisasContext *s)
44
49
return false;
45
snprintf(name, NAME_SIZE, "pwm%d", i);
50
}
46
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
51
if (s->sme_trap_nonstreaming && s->is_nonstreaming) {
47
create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR,
52
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
48
FSL_IMX6UL_LCDIF_SIZE);
53
+ gen_exception_insn(s, 0, EXCP_UDEF,
49
54
syn_smetrap(SME_ET_Streaming, false));
50
+ /*
55
return false;
51
+ * CSU
56
}
52
+ */
57
@@ -XXX,XX +XXX,XX @@ bool sve_access_check(DisasContext *s)
53
+ create_unimplemented_device("csu", FSL_IMX6UL_CSU_ADDR,
58
goto fail_exit;
54
+ FSL_IMX6UL_CSU_SIZE);
59
}
55
+
60
} else if (s->sve_excp_el) {
56
+ /*
61
- gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF,
57
+ * TZASC
62
+ gen_exception_insn_el(s, 0, EXCP_UDEF,
58
+ */
63
syn_sve_access_trap(), s->sve_excp_el);
59
+ create_unimplemented_device("tzasc", FSL_IMX6UL_TZASC_ADDR,
64
goto fail_exit;
60
+ FSL_IMX6UL_TZASC_SIZE);
65
}
61
+
66
@@ -XXX,XX +XXX,XX @@ bool sve_access_check(DisasContext *s)
62
/*
67
static bool sme_access_check(DisasContext *s)
63
* ROM memory
68
{
69
if (s->sme_excp_el) {
70
- gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF,
71
+ gen_exception_insn_el(s, 0, EXCP_UDEF,
72
syn_smetrap(SME_ET_AccessTrap, false),
73
s->sme_excp_el);
74
return false;
75
@@ -XXX,XX +XXX,XX @@ bool sme_enabled_check_with_svcr(DisasContext *s, unsigned req)
76
return false;
77
}
78
if (FIELD_EX64(req, SVCR, SM) && !s->pstate_sm) {
79
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
80
+ gen_exception_insn(s, 0, EXCP_UDEF,
81
syn_smetrap(SME_ET_NotStreaming, false));
82
return false;
83
}
84
if (FIELD_EX64(req, SVCR, ZA) && !s->pstate_za) {
85
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
86
+ gen_exception_insn(s, 0, EXCP_UDEF,
87
syn_smetrap(SME_ET_InactiveZA, false));
88
return false;
89
}
90
@@ -XXX,XX +XXX,XX @@ static void gen_sysreg_undef(DisasContext *s, bool isread,
91
} else {
92
syndrome = syn_uncategorized();
93
}
94
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syndrome);
95
+ gen_exception_insn(s, 0, EXCP_UDEF, syndrome);
96
}
97
98
/* MRS - move from system register
99
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
100
switch (op2_ll) {
101
case 1: /* SVC */
102
gen_ss_advance(s);
103
- gen_exception_insn(s, s->base.pc_next, EXCP_SWI,
104
- syn_aa64_svc(imm16));
105
+ gen_exception_insn(s, 4, EXCP_SWI, syn_aa64_svc(imm16));
106
break;
107
case 2: /* HVC */
108
if (s->current_el == 0) {
109
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
110
gen_a64_update_pc(s, 0);
111
gen_helper_pre_hvc(cpu_env);
112
gen_ss_advance(s);
113
- gen_exception_insn_el(s, s->base.pc_next, EXCP_HVC,
114
- syn_aa64_hvc(imm16), 2);
115
+ gen_exception_insn_el(s, 4, EXCP_HVC, syn_aa64_hvc(imm16), 2);
116
break;
117
case 3: /* SMC */
118
if (s->current_el == 0) {
119
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
120
gen_a64_update_pc(s, 0);
121
gen_helper_pre_smc(cpu_env, tcg_constant_i32(syn_aa64_smc(imm16)));
122
gen_ss_advance(s);
123
- gen_exception_insn_el(s, s->base.pc_next, EXCP_SMC,
124
- syn_aa64_smc(imm16), 3);
125
+ gen_exception_insn_el(s, 4, EXCP_SMC, syn_aa64_smc(imm16), 3);
126
break;
127
default:
128
unallocated_encoding(s);
129
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
130
* Illegal execution state. This has priority over BTI
131
* exceptions, but comes after instruction abort exceptions.
132
*/
133
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_illegalstate());
134
+ gen_exception_insn(s, 0, EXCP_UDEF, syn_illegalstate());
135
return;
136
}
137
138
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
139
if (s->btype != 0
140
&& s->guarded_page
141
&& !btype_destination_ok(insn, s->bt, s->btype)) {
142
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
143
- syn_btitrap(s->btype));
144
+ gen_exception_insn(s, 0, EXCP_UDEF, syn_btitrap(s->btype));
145
return;
146
}
147
} else {
148
diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/translate-m-nocp.c
151
+++ b/target/arm/translate-m-nocp.c
152
@@ -XXX,XX +XXX,XX @@ static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
153
tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
154
155
if (s->fp_excp_el != 0) {
156
- gen_exception_insn_el(s, s->pc_curr, EXCP_NOCP,
157
+ gen_exception_insn_el(s, 0, EXCP_NOCP,
158
syn_uncategorized(), s->fp_excp_el);
159
return true;
160
}
161
@@ -XXX,XX +XXX,XX @@ static bool trans_NOCP(DisasContext *s, arg_nocp *a)
162
}
163
164
if (a->cp != 10) {
165
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized());
166
+ gen_exception_insn(s, 0, EXCP_NOCP, syn_uncategorized());
167
return true;
168
}
169
170
if (s->fp_excp_el != 0) {
171
- gen_exception_insn_el(s, s->pc_curr, EXCP_NOCP,
172
+ gen_exception_insn_el(s, 0, EXCP_NOCP,
173
syn_uncategorized(), s->fp_excp_el);
174
return true;
175
}
176
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
177
index XXXXXXX..XXXXXXX 100644
178
--- a/target/arm/translate-mve.c
179
+++ b/target/arm/translate-mve.c
180
@@ -XXX,XX +XXX,XX @@ bool mve_eci_check(DisasContext *s)
181
return true;
182
default:
183
/* Reserved value: INVSTATE UsageFault */
184
- gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized());
185
+ gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized());
186
return false;
187
}
188
}
189
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
190
index XXXXXXX..XXXXXXX 100644
191
--- a/target/arm/translate-vfp.c
192
+++ b/target/arm/translate-vfp.c
193
@@ -XXX,XX +XXX,XX @@ static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled)
194
int coproc = arm_dc_feature(s, ARM_FEATURE_V8) ? 0 : 0xa;
195
uint32_t syn = syn_fp_access_trap(1, 0xe, false, coproc);
196
197
- gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF, syn, s->fp_excp_el);
198
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syn, s->fp_excp_el);
199
return false;
200
}
201
202
@@ -XXX,XX +XXX,XX @@ static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled)
203
* appear to be any insns which touch VFP which are allowed.
204
*/
64
*/
205
if (s->sme_trap_nonstreaming) {
206
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
207
+ gen_exception_insn(s, 0, EXCP_UDEF,
208
syn_smetrap(SME_ET_Streaming,
209
curr_insn_len(s) == 2));
210
return false;
211
@@ -XXX,XX +XXX,XX @@ bool vfp_access_check_m(DisasContext *s, bool skip_context_update)
212
* the encoding space handled by the patterns in m-nocp.decode,
213
* and for them we may need to raise NOCP here.
214
*/
215
- gen_exception_insn_el(s, s->pc_curr, EXCP_NOCP,
216
+ gen_exception_insn_el(s, 0, EXCP_NOCP,
217
syn_uncategorized(), s->fp_excp_el);
218
return false;
219
}
220
diff --git a/target/arm/translate.c b/target/arm/translate.c
221
index XXXXXXX..XXXXXXX 100644
222
--- a/target/arm/translate.c
223
+++ b/target/arm/translate.c
224
@@ -XXX,XX +XXX,XX @@ static void gen_exception(int excp, uint32_t syndrome)
225
tcg_constant_i32(syndrome));
226
}
227
228
-static void gen_exception_insn_el_v(DisasContext *s, uint64_t pc, int excp,
229
- uint32_t syn, TCGv_i32 tcg_el)
230
+static void gen_exception_insn_el_v(DisasContext *s, target_long pc_diff,
231
+ int excp, uint32_t syn, TCGv_i32 tcg_el)
232
{
233
if (s->aarch64) {
234
- gen_a64_update_pc(s, pc - s->pc_curr);
235
+ gen_a64_update_pc(s, pc_diff);
236
} else {
237
gen_set_condexec(s);
238
- gen_update_pc(s, pc - s->pc_curr);
239
+ gen_update_pc(s, pc_diff);
240
}
241
gen_exception_el_v(excp, syn, tcg_el);
242
s->base.is_jmp = DISAS_NORETURN;
243
}
244
245
-void gen_exception_insn_el(DisasContext *s, uint64_t pc, int excp,
246
+void gen_exception_insn_el(DisasContext *s, target_long pc_diff, int excp,
247
uint32_t syn, uint32_t target_el)
248
{
249
- gen_exception_insn_el_v(s, pc, excp, syn, tcg_constant_i32(target_el));
250
+ gen_exception_insn_el_v(s, pc_diff, excp, syn,
251
+ tcg_constant_i32(target_el));
252
}
253
254
-void gen_exception_insn(DisasContext *s, uint64_t pc, int excp, uint32_t syn)
255
+void gen_exception_insn(DisasContext *s, target_long pc_diff,
256
+ int excp, uint32_t syn)
257
{
258
if (s->aarch64) {
259
- gen_a64_update_pc(s, pc - s->pc_curr);
260
+ gen_a64_update_pc(s, pc_diff);
261
} else {
262
gen_set_condexec(s);
263
- gen_update_pc(s, pc - s->pc_curr);
264
+ gen_update_pc(s, pc_diff);
265
}
266
gen_exception(excp, syn);
267
s->base.is_jmp = DISAS_NORETURN;
268
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
269
void unallocated_encoding(DisasContext *s)
270
{
271
/* Unallocated and reserved encodings are uncategorized */
272
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized());
273
+ gen_exception_insn(s, 0, EXCP_UDEF, syn_uncategorized());
274
}
275
276
/* Force a TB lookup after an instruction that changes the CPU state. */
277
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
278
tcg_el = tcg_constant_i32(3);
279
}
280
281
- gen_exception_insn_el_v(s, s->pc_curr, EXCP_UDEF,
282
+ gen_exception_insn_el_v(s, 0, EXCP_UDEF,
283
syn_uncategorized(), tcg_el);
284
tcg_temp_free_i32(tcg_el);
285
return false;
286
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
287
288
undef:
289
/* If we get here then some access check did not pass */
290
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized());
291
+ gen_exception_insn(s, 0, EXCP_UDEF, syn_uncategorized());
292
return false;
293
}
294
295
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
296
* For the UNPREDICTABLE cases we choose to UNDEF.
297
*/
298
if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
299
- gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF,
300
- syn_uncategorized(), 3);
301
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syn_uncategorized(), 3);
302
return;
303
}
304
305
@@ -XXX,XX +XXX,XX @@ static bool trans_WLS(DisasContext *s, arg_WLS *a)
306
* Do the check-and-raise-exception by hand.
307
*/
308
if (s->fp_excp_el) {
309
- gen_exception_insn_el(s, s->pc_curr, EXCP_NOCP,
310
+ gen_exception_insn_el(s, 0, EXCP_NOCP,
311
syn_uncategorized(), s->fp_excp_el);
312
return true;
313
}
314
@@ -XXX,XX +XXX,XX @@ static bool trans_LE(DisasContext *s, arg_LE *a)
315
tmp = load_cpu_field(v7m.ltpsize);
316
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 4, skipexc);
317
tcg_temp_free_i32(tmp);
318
- gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized());
319
+ gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized());
320
gen_set_label(skipexc);
321
}
322
323
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
324
* UsageFault exception.
325
*/
326
if (arm_dc_feature(s, ARM_FEATURE_M)) {
327
- gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized());
328
+ gen_exception_insn(s, 0, EXCP_INVSTATE, syn_uncategorized());
329
return;
330
}
331
332
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
333
* Illegal execution state. This has priority over BTI
334
* exceptions, but comes after instruction abort exceptions.
335
*/
336
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_illegalstate());
337
+ gen_exception_insn(s, 0, EXCP_UDEF, syn_illegalstate());
338
return;
339
}
340
341
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
342
* Illegal execution state. This has priority over BTI
343
* exceptions, but comes after instruction abort exceptions.
344
*/
345
- gen_exception_insn(dc, dc->pc_curr, EXCP_UDEF, syn_illegalstate());
346
+ gen_exception_insn(dc, 0, EXCP_UDEF, syn_illegalstate());
347
return;
348
}
349
350
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
351
*/
352
tcg_remove_ops_after(dc->insn_eci_rewind);
353
dc->condjmp = 0;
354
- gen_exception_insn(dc, dc->pc_curr, EXCP_INVSTATE,
355
- syn_uncategorized());
356
+ gen_exception_insn(dc, 0, EXCP_INVSTATE, syn_uncategorized());
357
}
358
359
arm_post_translate_insn(dc);
360
--
65
--
361
2.25.1
66
2.34.1
362
67
363
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
Hoist this test out of arm_ld[lq]_ptw into S1_ptw_translate.
3
* Add Addr and size definition for all i.MX7 devices in i.MX7 header file.
4
* Use those newly defined named constants whenever possible.
5
* Standardize the way we init a familly of unimplemented devices
6
- SAI
7
- PWM
8
- CAN
9
* Add/rework few comments
4
10
11
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
12
Message-id: 59e195d33e4d486a8d131392acd46633c8c10ed7.1692964892.git.jcd@tribudubois.net
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20221011031911.2408754-10-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
15
---
10
target/arm/ptw.c | 6 ++++--
16
include/hw/arm/fsl-imx7.h | 330 ++++++++++++++++++++++++++++----------
11
1 file changed, 4 insertions(+), 2 deletions(-)
17
hw/arm/fsl-imx7.c | 130 ++++++++++-----
18
2 files changed, 335 insertions(+), 125 deletions(-)
12
19
13
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
20
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/ptw.c
22
--- a/include/hw/arm/fsl-imx7.h
16
+++ b/target/arm/ptw.c
23
+++ b/include/hw/arm/fsl-imx7.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
24
@@ -XXX,XX +XXX,XX @@
18
bool in_secure;
25
#include "hw/misc/imx7_ccm.h"
19
bool in_debug;
26
#include "hw/misc/imx7_snvs.h"
20
bool out_secure;
27
#include "hw/misc/imx7_gpr.h"
21
+ bool out_be;
28
-#include "hw/misc/imx6_src.h"
22
hwaddr out_phys;
29
#include "hw/watchdog/wdt_imx2.h"
23
} S1Translate;
30
#include "hw/gpio/imx_gpio.h"
24
31
#include "hw/char/imx_serial.h"
25
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
32
@@ -XXX,XX +XXX,XX @@
26
33
#include "hw/usb/chipidea.h"
27
ptw->out_secure = is_secure;
34
#include "cpu.h"
28
ptw->out_phys = addr;
35
#include "qom/object.h"
29
+ ptw->out_be = regime_translation_big_endian(env, ptw->in_mmu_idx);
36
+#include "qemu/units.h"
30
return true;
37
38
#define TYPE_FSL_IMX7 "fsl-imx7"
39
OBJECT_DECLARE_SIMPLE_TYPE(FslIMX7State, FSL_IMX7)
40
@@ -XXX,XX +XXX,XX @@ enum FslIMX7Configuration {
41
FSL_IMX7_NUM_ECSPIS = 4,
42
FSL_IMX7_NUM_USBS = 3,
43
FSL_IMX7_NUM_ADCS = 2,
44
+ FSL_IMX7_NUM_SAIS = 3,
45
+ FSL_IMX7_NUM_CANS = 2,
46
+ FSL_IMX7_NUM_PWMS = 4,
47
};
48
49
struct FslIMX7State {
50
@@ -XXX,XX +XXX,XX @@ struct FslIMX7State {
51
52
enum FslIMX7MemoryMap {
53
FSL_IMX7_MMDC_ADDR = 0x80000000,
54
- FSL_IMX7_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL,
55
+ FSL_IMX7_MMDC_SIZE = (2 * GiB),
56
57
- FSL_IMX7_GPIO1_ADDR = 0x30200000,
58
- FSL_IMX7_GPIO2_ADDR = 0x30210000,
59
- FSL_IMX7_GPIO3_ADDR = 0x30220000,
60
- FSL_IMX7_GPIO4_ADDR = 0x30230000,
61
- FSL_IMX7_GPIO5_ADDR = 0x30240000,
62
- FSL_IMX7_GPIO6_ADDR = 0x30250000,
63
- FSL_IMX7_GPIO7_ADDR = 0x30260000,
64
+ FSL_IMX7_QSPI1_MEM_ADDR = 0x60000000,
65
+ FSL_IMX7_QSPI1_MEM_SIZE = (256 * MiB),
66
67
- FSL_IMX7_IOMUXC_LPSR_GPR_ADDR = 0x30270000,
68
+ FSL_IMX7_PCIE1_MEM_ADDR = 0x40000000,
69
+ FSL_IMX7_PCIE1_MEM_SIZE = (256 * MiB),
70
71
- FSL_IMX7_WDOG1_ADDR = 0x30280000,
72
- FSL_IMX7_WDOG2_ADDR = 0x30290000,
73
- FSL_IMX7_WDOG3_ADDR = 0x302A0000,
74
- FSL_IMX7_WDOG4_ADDR = 0x302B0000,
75
+ FSL_IMX7_QSPI1_RX_BUF_ADDR = 0x34000000,
76
+ FSL_IMX7_QSPI1_RX_BUF_SIZE = (32 * MiB),
77
78
- FSL_IMX7_IOMUXC_LPSR_ADDR = 0x302C0000,
79
+ /* PCIe Peripherals */
80
+ FSL_IMX7_PCIE_REG_ADDR = 0x33800000,
81
82
- FSL_IMX7_GPT1_ADDR = 0x302D0000,
83
- FSL_IMX7_GPT2_ADDR = 0x302E0000,
84
- FSL_IMX7_GPT3_ADDR = 0x302F0000,
85
- FSL_IMX7_GPT4_ADDR = 0x30300000,
86
+ /* MMAP Peripherals */
87
+ FSL_IMX7_DMA_APBH_ADDR = 0x33000000,
88
+ FSL_IMX7_DMA_APBH_SIZE = 0x8000,
89
90
- FSL_IMX7_IOMUXC_ADDR = 0x30330000,
91
- FSL_IMX7_IOMUXC_GPR_ADDR = 0x30340000,
92
- FSL_IMX7_IOMUXCn_SIZE = 0x1000,
93
+ /* GPV configuration */
94
+ FSL_IMX7_GPV6_ADDR = 0x32600000,
95
+ FSL_IMX7_GPV5_ADDR = 0x32500000,
96
+ FSL_IMX7_GPV4_ADDR = 0x32400000,
97
+ FSL_IMX7_GPV3_ADDR = 0x32300000,
98
+ FSL_IMX7_GPV2_ADDR = 0x32200000,
99
+ FSL_IMX7_GPV1_ADDR = 0x32100000,
100
+ FSL_IMX7_GPV0_ADDR = 0x32000000,
101
+ FSL_IMX7_GPVn_SIZE = (1 * MiB),
102
103
- FSL_IMX7_OCOTP_ADDR = 0x30350000,
104
- FSL_IMX7_OCOTP_SIZE = 0x10000,
105
+ /* Arm Peripherals */
106
+ FSL_IMX7_A7MPCORE_ADDR = 0x31000000,
107
108
- FSL_IMX7_ANALOG_ADDR = 0x30360000,
109
- FSL_IMX7_SNVS_ADDR = 0x30370000,
110
- FSL_IMX7_CCM_ADDR = 0x30380000,
111
+ /* AIPS-3 Begin */
112
113
- FSL_IMX7_SRC_ADDR = 0x30390000,
114
- FSL_IMX7_SRC_SIZE = 0x1000,
115
+ FSL_IMX7_ENET2_ADDR = 0x30BF0000,
116
+ FSL_IMX7_ENET1_ADDR = 0x30BE0000,
117
118
- FSL_IMX7_ADC1_ADDR = 0x30610000,
119
- FSL_IMX7_ADC2_ADDR = 0x30620000,
120
- FSL_IMX7_ADCn_SIZE = 0x1000,
121
+ FSL_IMX7_SDMA_ADDR = 0x30BD0000,
122
+ FSL_IMX7_SDMA_SIZE = (4 * KiB),
123
124
- FSL_IMX7_PWM1_ADDR = 0x30660000,
125
- FSL_IMX7_PWM2_ADDR = 0x30670000,
126
- FSL_IMX7_PWM3_ADDR = 0x30680000,
127
- FSL_IMX7_PWM4_ADDR = 0x30690000,
128
- FSL_IMX7_PWMn_SIZE = 0x10000,
129
+ FSL_IMX7_EIM_ADDR = 0x30BC0000,
130
+ FSL_IMX7_EIM_SIZE = (4 * KiB),
131
132
- FSL_IMX7_PCIE_PHY_ADDR = 0x306D0000,
133
- FSL_IMX7_PCIE_PHY_SIZE = 0x10000,
134
+ FSL_IMX7_QSPI_ADDR = 0x30BB0000,
135
+ FSL_IMX7_QSPI_SIZE = 0x8000,
136
137
- FSL_IMX7_GPC_ADDR = 0x303A0000,
138
+ FSL_IMX7_SIM2_ADDR = 0x30BA0000,
139
+ FSL_IMX7_SIM1_ADDR = 0x30B90000,
140
+ FSL_IMX7_SIMn_SIZE = (4 * KiB),
141
+
142
+ FSL_IMX7_USDHC3_ADDR = 0x30B60000,
143
+ FSL_IMX7_USDHC2_ADDR = 0x30B50000,
144
+ FSL_IMX7_USDHC1_ADDR = 0x30B40000,
145
+
146
+ FSL_IMX7_USB3_ADDR = 0x30B30000,
147
+ FSL_IMX7_USBMISC3_ADDR = 0x30B30200,
148
+ FSL_IMX7_USB2_ADDR = 0x30B20000,
149
+ FSL_IMX7_USBMISC2_ADDR = 0x30B20200,
150
+ FSL_IMX7_USB1_ADDR = 0x30B10000,
151
+ FSL_IMX7_USBMISC1_ADDR = 0x30B10200,
152
+ FSL_IMX7_USBMISCn_SIZE = 0x200,
153
+
154
+ FSL_IMX7_USB_PL301_ADDR = 0x30AD0000,
155
+ FSL_IMX7_USB_PL301_SIZE = (64 * KiB),
156
+
157
+ FSL_IMX7_SEMAPHORE_HS_ADDR = 0x30AC0000,
158
+ FSL_IMX7_SEMAPHORE_HS_SIZE = (64 * KiB),
159
+
160
+ FSL_IMX7_MUB_ADDR = 0x30AB0000,
161
+ FSL_IMX7_MUA_ADDR = 0x30AA0000,
162
+ FSL_IMX7_MUn_SIZE = (KiB),
163
+
164
+ FSL_IMX7_UART7_ADDR = 0x30A90000,
165
+ FSL_IMX7_UART6_ADDR = 0x30A80000,
166
+ FSL_IMX7_UART5_ADDR = 0x30A70000,
167
+ FSL_IMX7_UART4_ADDR = 0x30A60000,
168
+
169
+ FSL_IMX7_I2C4_ADDR = 0x30A50000,
170
+ FSL_IMX7_I2C3_ADDR = 0x30A40000,
171
+ FSL_IMX7_I2C2_ADDR = 0x30A30000,
172
+ FSL_IMX7_I2C1_ADDR = 0x30A20000,
173
+
174
+ FSL_IMX7_CAN2_ADDR = 0x30A10000,
175
+ FSL_IMX7_CAN1_ADDR = 0x30A00000,
176
+ FSL_IMX7_CANn_SIZE = (4 * KiB),
177
+
178
+ FSL_IMX7_AIPS3_CONF_ADDR = 0x309F0000,
179
+ FSL_IMX7_AIPS3_CONF_SIZE = (64 * KiB),
180
181
FSL_IMX7_CAAM_ADDR = 0x30900000,
182
- FSL_IMX7_CAAM_SIZE = 0x40000,
183
+ FSL_IMX7_CAAM_SIZE = (256 * KiB),
184
185
- FSL_IMX7_CAN1_ADDR = 0x30A00000,
186
- FSL_IMX7_CAN2_ADDR = 0x30A10000,
187
- FSL_IMX7_CANn_SIZE = 0x10000,
188
+ FSL_IMX7_SPBA_ADDR = 0x308F0000,
189
+ FSL_IMX7_SPBA_SIZE = (4 * KiB),
190
191
- FSL_IMX7_I2C1_ADDR = 0x30A20000,
192
- FSL_IMX7_I2C2_ADDR = 0x30A30000,
193
- FSL_IMX7_I2C3_ADDR = 0x30A40000,
194
- FSL_IMX7_I2C4_ADDR = 0x30A50000,
195
+ FSL_IMX7_SAI3_ADDR = 0x308C0000,
196
+ FSL_IMX7_SAI2_ADDR = 0x308B0000,
197
+ FSL_IMX7_SAI1_ADDR = 0x308A0000,
198
+ FSL_IMX7_SAIn_SIZE = (4 * KiB),
199
200
- FSL_IMX7_ECSPI1_ADDR = 0x30820000,
201
- FSL_IMX7_ECSPI2_ADDR = 0x30830000,
202
- FSL_IMX7_ECSPI3_ADDR = 0x30840000,
203
- FSL_IMX7_ECSPI4_ADDR = 0x30630000,
204
-
205
- FSL_IMX7_LCDIF_ADDR = 0x30730000,
206
- FSL_IMX7_LCDIF_SIZE = 0x1000,
207
-
208
- FSL_IMX7_UART1_ADDR = 0x30860000,
209
+ FSL_IMX7_UART3_ADDR = 0x30880000,
210
/*
211
* Some versions of the reference manual claim that UART2 is @
212
* 0x30870000, but experiments with HW + DT files in upstream
213
@@ -XXX,XX +XXX,XX @@ enum FslIMX7MemoryMap {
214
* actually located @ 0x30890000
215
*/
216
FSL_IMX7_UART2_ADDR = 0x30890000,
217
- FSL_IMX7_UART3_ADDR = 0x30880000,
218
- FSL_IMX7_UART4_ADDR = 0x30A60000,
219
- FSL_IMX7_UART5_ADDR = 0x30A70000,
220
- FSL_IMX7_UART6_ADDR = 0x30A80000,
221
- FSL_IMX7_UART7_ADDR = 0x30A90000,
222
+ FSL_IMX7_UART1_ADDR = 0x30860000,
223
224
- FSL_IMX7_SAI1_ADDR = 0x308A0000,
225
- FSL_IMX7_SAI2_ADDR = 0x308B0000,
226
- FSL_IMX7_SAI3_ADDR = 0x308C0000,
227
- FSL_IMX7_SAIn_SIZE = 0x10000,
228
+ FSL_IMX7_ECSPI3_ADDR = 0x30840000,
229
+ FSL_IMX7_ECSPI2_ADDR = 0x30830000,
230
+ FSL_IMX7_ECSPI1_ADDR = 0x30820000,
231
+ FSL_IMX7_ECSPIn_SIZE = (4 * KiB),
232
233
- FSL_IMX7_ENET1_ADDR = 0x30BE0000,
234
- FSL_IMX7_ENET2_ADDR = 0x30BF0000,
235
+ /* AIPS-3 End */
236
237
- FSL_IMX7_USB1_ADDR = 0x30B10000,
238
- FSL_IMX7_USBMISC1_ADDR = 0x30B10200,
239
- FSL_IMX7_USB2_ADDR = 0x30B20000,
240
- FSL_IMX7_USBMISC2_ADDR = 0x30B20200,
241
- FSL_IMX7_USB3_ADDR = 0x30B30000,
242
- FSL_IMX7_USBMISC3_ADDR = 0x30B30200,
243
- FSL_IMX7_USBMISCn_SIZE = 0x200,
244
+ /* AIPS-2 Begin */
245
246
- FSL_IMX7_USDHC1_ADDR = 0x30B40000,
247
- FSL_IMX7_USDHC2_ADDR = 0x30B50000,
248
- FSL_IMX7_USDHC3_ADDR = 0x30B60000,
249
+ FSL_IMX7_AXI_DEBUG_MON_ADDR = 0x307E0000,
250
+ FSL_IMX7_AXI_DEBUG_MON_SIZE = (64 * KiB),
251
252
- FSL_IMX7_SDMA_ADDR = 0x30BD0000,
253
- FSL_IMX7_SDMA_SIZE = 0x1000,
254
+ FSL_IMX7_PERFMON2_ADDR = 0x307D0000,
255
+ FSL_IMX7_PERFMON1_ADDR = 0x307C0000,
256
+ FSL_IMX7_PERFMONn_SIZE = (64 * KiB),
257
+
258
+ FSL_IMX7_DDRC_ADDR = 0x307A0000,
259
+ FSL_IMX7_DDRC_SIZE = (4 * KiB),
260
+
261
+ FSL_IMX7_DDRC_PHY_ADDR = 0x30790000,
262
+ FSL_IMX7_DDRC_PHY_SIZE = (4 * KiB),
263
+
264
+ FSL_IMX7_TZASC_ADDR = 0x30780000,
265
+ FSL_IMX7_TZASC_SIZE = (64 * KiB),
266
+
267
+ FSL_IMX7_MIPI_DSI_ADDR = 0x30760000,
268
+ FSL_IMX7_MIPI_DSI_SIZE = (4 * KiB),
269
+
270
+ FSL_IMX7_MIPI_CSI_ADDR = 0x30750000,
271
+ FSL_IMX7_MIPI_CSI_SIZE = 0x4000,
272
+
273
+ FSL_IMX7_LCDIF_ADDR = 0x30730000,
274
+ FSL_IMX7_LCDIF_SIZE = 0x8000,
275
+
276
+ FSL_IMX7_CSI_ADDR = 0x30710000,
277
+ FSL_IMX7_CSI_SIZE = (4 * KiB),
278
+
279
+ FSL_IMX7_PXP_ADDR = 0x30700000,
280
+ FSL_IMX7_PXP_SIZE = 0x4000,
281
+
282
+ FSL_IMX7_EPDC_ADDR = 0x306F0000,
283
+ FSL_IMX7_EPDC_SIZE = (4 * KiB),
284
+
285
+ FSL_IMX7_PCIE_PHY_ADDR = 0x306D0000,
286
+ FSL_IMX7_PCIE_PHY_SIZE = (4 * KiB),
287
+
288
+ FSL_IMX7_SYSCNT_CTRL_ADDR = 0x306C0000,
289
+ FSL_IMX7_SYSCNT_CMP_ADDR = 0x306B0000,
290
+ FSL_IMX7_SYSCNT_RD_ADDR = 0x306A0000,
291
+
292
+ FSL_IMX7_PWM4_ADDR = 0x30690000,
293
+ FSL_IMX7_PWM3_ADDR = 0x30680000,
294
+ FSL_IMX7_PWM2_ADDR = 0x30670000,
295
+ FSL_IMX7_PWM1_ADDR = 0x30660000,
296
+ FSL_IMX7_PWMn_SIZE = (4 * KiB),
297
+
298
+ FSL_IMX7_FlEXTIMER2_ADDR = 0x30650000,
299
+ FSL_IMX7_FlEXTIMER1_ADDR = 0x30640000,
300
+ FSL_IMX7_FLEXTIMERn_SIZE = (4 * KiB),
301
+
302
+ FSL_IMX7_ECSPI4_ADDR = 0x30630000,
303
+
304
+ FSL_IMX7_ADC2_ADDR = 0x30620000,
305
+ FSL_IMX7_ADC1_ADDR = 0x30610000,
306
+ FSL_IMX7_ADCn_SIZE = (4 * KiB),
307
+
308
+ FSL_IMX7_AIPS2_CONF_ADDR = 0x305F0000,
309
+ FSL_IMX7_AIPS2_CONF_SIZE = (64 * KiB),
310
+
311
+ /* AIPS-2 End */
312
+
313
+ /* AIPS-1 Begin */
314
+
315
+ FSL_IMX7_CSU_ADDR = 0x303E0000,
316
+ FSL_IMX7_CSU_SIZE = (64 * KiB),
317
+
318
+ FSL_IMX7_RDC_ADDR = 0x303D0000,
319
+ FSL_IMX7_RDC_SIZE = (4 * KiB),
320
+
321
+ FSL_IMX7_SEMAPHORE2_ADDR = 0x303C0000,
322
+ FSL_IMX7_SEMAPHORE1_ADDR = 0x303B0000,
323
+ FSL_IMX7_SEMAPHOREn_SIZE = (4 * KiB),
324
+
325
+ FSL_IMX7_GPC_ADDR = 0x303A0000,
326
+
327
+ FSL_IMX7_SRC_ADDR = 0x30390000,
328
+ FSL_IMX7_SRC_SIZE = (4 * KiB),
329
+
330
+ FSL_IMX7_CCM_ADDR = 0x30380000,
331
+
332
+ FSL_IMX7_SNVS_HP_ADDR = 0x30370000,
333
+
334
+ FSL_IMX7_ANALOG_ADDR = 0x30360000,
335
+
336
+ FSL_IMX7_OCOTP_ADDR = 0x30350000,
337
+ FSL_IMX7_OCOTP_SIZE = 0x10000,
338
+
339
+ FSL_IMX7_IOMUXC_GPR_ADDR = 0x30340000,
340
+ FSL_IMX7_IOMUXC_GPR_SIZE = (4 * KiB),
341
+
342
+ FSL_IMX7_IOMUXC_ADDR = 0x30330000,
343
+ FSL_IMX7_IOMUXC_SIZE = (4 * KiB),
344
+
345
+ FSL_IMX7_KPP_ADDR = 0x30320000,
346
+ FSL_IMX7_KPP_SIZE = (4 * KiB),
347
+
348
+ FSL_IMX7_ROMCP_ADDR = 0x30310000,
349
+ FSL_IMX7_ROMCP_SIZE = (4 * KiB),
350
+
351
+ FSL_IMX7_GPT4_ADDR = 0x30300000,
352
+ FSL_IMX7_GPT3_ADDR = 0x302F0000,
353
+ FSL_IMX7_GPT2_ADDR = 0x302E0000,
354
+ FSL_IMX7_GPT1_ADDR = 0x302D0000,
355
+
356
+ FSL_IMX7_IOMUXC_LPSR_ADDR = 0x302C0000,
357
+ FSL_IMX7_IOMUXC_LPSR_SIZE = (4 * KiB),
358
+
359
+ FSL_IMX7_WDOG4_ADDR = 0x302B0000,
360
+ FSL_IMX7_WDOG3_ADDR = 0x302A0000,
361
+ FSL_IMX7_WDOG2_ADDR = 0x30290000,
362
+ FSL_IMX7_WDOG1_ADDR = 0x30280000,
363
+
364
+ FSL_IMX7_IOMUXC_LPSR_GPR_ADDR = 0x30270000,
365
+
366
+ FSL_IMX7_GPIO7_ADDR = 0x30260000,
367
+ FSL_IMX7_GPIO6_ADDR = 0x30250000,
368
+ FSL_IMX7_GPIO5_ADDR = 0x30240000,
369
+ FSL_IMX7_GPIO4_ADDR = 0x30230000,
370
+ FSL_IMX7_GPIO3_ADDR = 0x30220000,
371
+ FSL_IMX7_GPIO2_ADDR = 0x30210000,
372
+ FSL_IMX7_GPIO1_ADDR = 0x30200000,
373
+
374
+ FSL_IMX7_AIPS1_CONF_ADDR = 0x301F0000,
375
+ FSL_IMX7_AIPS1_CONF_SIZE = (64 * KiB),
376
377
- FSL_IMX7_A7MPCORE_ADDR = 0x31000000,
378
FSL_IMX7_A7MPCORE_DAP_ADDR = 0x30000000,
379
+ FSL_IMX7_A7MPCORE_DAP_SIZE = (1 * MiB),
380
381
- FSL_IMX7_PCIE_REG_ADDR = 0x33800000,
382
- FSL_IMX7_PCIE_REG_SIZE = 16 * 1024,
383
+ /* AIPS-1 End */
384
385
- FSL_IMX7_GPR_ADDR = 0x30340000,
386
+ FSL_IMX7_EIM_CS0_ADDR = 0x28000000,
387
+ FSL_IMX7_EIM_CS0_SIZE = (128 * MiB),
388
389
- FSL_IMX7_DMA_APBH_ADDR = 0x33000000,
390
- FSL_IMX7_DMA_APBH_SIZE = 0x2000,
391
+ FSL_IMX7_OCRAM_PXP_ADDR = 0x00940000,
392
+ FSL_IMX7_OCRAM_PXP_SIZE = (32 * KiB),
393
+
394
+ FSL_IMX7_OCRAM_EPDC_ADDR = 0x00920000,
395
+ FSL_IMX7_OCRAM_EPDC_SIZE = (128 * KiB),
396
+
397
+ FSL_IMX7_OCRAM_MEM_ADDR = 0x00900000,
398
+ FSL_IMX7_OCRAM_MEM_SIZE = (128 * KiB),
399
+
400
+ FSL_IMX7_TCMU_ADDR = 0x00800000,
401
+ FSL_IMX7_TCMU_SIZE = (32 * KiB),
402
+
403
+ FSL_IMX7_TCML_ADDR = 0x007F8000,
404
+ FSL_IMX7_TCML_SIZE = (32 * KiB),
405
+
406
+ FSL_IMX7_OCRAM_S_ADDR = 0x00180000,
407
+ FSL_IMX7_OCRAM_S_SIZE = (32 * KiB),
408
+
409
+ FSL_IMX7_CAAM_MEM_ADDR = 0x00100000,
410
+ FSL_IMX7_CAAM_MEM_SIZE = (32 * KiB),
411
+
412
+ FSL_IMX7_ROM_ADDR = 0x00000000,
413
+ FSL_IMX7_ROM_SIZE = (96 * KiB),
414
};
415
416
enum FslIMX7IRQs {
417
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
418
index XXXXXXX..XXXXXXX 100644
419
--- a/hw/arm/fsl-imx7.c
420
+++ b/hw/arm/fsl-imx7.c
421
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
422
char name[NAME_SIZE];
423
int i;
424
425
+ /*
426
+ * CPUs
427
+ */
428
for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX7_NUM_CPUS); i++) {
429
snprintf(name, NAME_SIZE, "cpu%d", i);
430
object_initialize_child(obj, name, &s->cpu[i],
431
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
432
TYPE_A15MPCORE_PRIV);
433
434
/*
435
- * GPIOs 1 to 7
436
+ * GPIOs
437
*/
438
for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
439
snprintf(name, NAME_SIZE, "gpio%d", i);
440
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
441
}
442
443
/*
444
- * GPT1, 2, 3, 4
445
+ * GPTs
446
*/
447
for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
448
snprintf(name, NAME_SIZE, "gpt%d", i);
449
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
450
*/
451
object_initialize_child(obj, "gpcv2", &s->gpcv2, TYPE_IMX_GPCV2);
452
453
+ /*
454
+ * ECSPIs
455
+ */
456
for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
457
snprintf(name, NAME_SIZE, "spi%d", i + 1);
458
object_initialize_child(obj, name, &s->spi[i], TYPE_IMX_SPI);
459
}
460
461
-
462
+ /*
463
+ * I2Cs
464
+ */
465
for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
466
snprintf(name, NAME_SIZE, "i2c%d", i + 1);
467
object_initialize_child(obj, name, &s->i2c[i], TYPE_IMX_I2C);
468
}
469
470
/*
471
- * UART
472
+ * UARTs
473
*/
474
for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
475
snprintf(name, NAME_SIZE, "uart%d", i);
476
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
477
}
478
479
/*
480
- * Ethernet
481
+ * Ethernets
482
*/
483
for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
484
snprintf(name, NAME_SIZE, "eth%d", i);
485
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
486
}
487
488
/*
489
- * SDHCI
490
+ * SDHCIs
491
*/
492
for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
493
snprintf(name, NAME_SIZE, "usdhc%d", i);
494
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
495
object_initialize_child(obj, "snvs", &s->snvs, TYPE_IMX7_SNVS);
496
497
/*
498
- * Watchdog
499
+ * Watchdogs
500
*/
501
for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
502
snprintf(name, NAME_SIZE, "wdt%d", i);
503
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
504
*/
505
object_initialize_child(obj, "gpr", &s->gpr, TYPE_IMX7_GPR);
506
507
+ /*
508
+ * PCIE
509
+ */
510
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
511
512
+ /*
513
+ * USBs
514
+ */
515
for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
516
snprintf(name, NAME_SIZE, "usb%d", i);
517
object_initialize_child(obj, name, &s->usb[i], TYPE_CHIPIDEA);
518
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
519
return;
520
}
521
522
+ /*
523
+ * CPUs
524
+ */
525
for (i = 0; i < smp_cpus; i++) {
526
o = OBJECT(&s->cpu[i]);
527
528
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
529
* A7MPCORE DAP
530
*/
531
create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
532
- 0x100000);
533
+ FSL_IMX7_A7MPCORE_DAP_SIZE);
534
535
/*
536
- * GPT1, 2, 3, 4
537
+ * GPTs
538
*/
539
for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
540
static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
541
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
542
FSL_IMX7_GPTn_IRQ[i]));
543
}
544
545
+ /*
546
+ * GPIOs
547
+ */
548
for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
549
static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
550
FSL_IMX7_GPIO1_ADDR,
551
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
552
/*
553
* IOMUXC and IOMUXC_LPSR
554
*/
555
- for (i = 0; i < FSL_IMX7_NUM_IOMUXCS; i++) {
556
- static const hwaddr FSL_IMX7_IOMUXCn_ADDR[FSL_IMX7_NUM_IOMUXCS] = {
557
- FSL_IMX7_IOMUXC_ADDR,
558
- FSL_IMX7_IOMUXC_LPSR_ADDR,
559
- };
560
-
561
- snprintf(name, NAME_SIZE, "iomuxc%d", i);
562
- create_unimplemented_device(name, FSL_IMX7_IOMUXCn_ADDR[i],
563
- FSL_IMX7_IOMUXCn_SIZE);
564
- }
565
+ create_unimplemented_device("iomuxc", FSL_IMX7_IOMUXC_ADDR,
566
+ FSL_IMX7_IOMUXC_SIZE);
567
+ create_unimplemented_device("iomuxc_lspr", FSL_IMX7_IOMUXC_LPSR_ADDR,
568
+ FSL_IMX7_IOMUXC_LPSR_SIZE);
569
570
/*
571
* CCM
572
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
573
sysbus_realize(SYS_BUS_DEVICE(&s->gpcv2), &error_abort);
574
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX7_GPC_ADDR);
575
576
- /* Initialize all ECSPI */
577
+ /*
578
+ * ECSPIs
579
+ */
580
for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
581
static const hwaddr FSL_IMX7_SPIn_ADDR[FSL_IMX7_NUM_ECSPIS] = {
582
FSL_IMX7_ECSPI1_ADDR,
583
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
584
FSL_IMX7_SPIn_IRQ[i]));
585
}
586
587
+ /*
588
+ * I2Cs
589
+ */
590
for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
591
static const hwaddr FSL_IMX7_I2Cn_ADDR[FSL_IMX7_NUM_I2CS] = {
592
FSL_IMX7_I2C1_ADDR,
593
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
594
}
595
596
/*
597
- * UART
598
+ * UARTs
599
*/
600
for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
601
static const hwaddr FSL_IMX7_UARTn_ADDR[FSL_IMX7_NUM_UARTS] = {
602
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
603
}
604
605
/*
606
- * Ethernet
607
+ * Ethernets
608
*
609
* We must use two loops since phy_connected affects the other interface
610
* and we have to set all properties before calling sysbus_realize().
611
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
612
}
613
614
/*
615
- * USDHC
616
+ * USDHCs
617
*/
618
for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
619
static const hwaddr FSL_IMX7_USDHCn_ADDR[FSL_IMX7_NUM_USDHCS] = {
620
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
621
* SNVS
622
*/
623
sysbus_realize(SYS_BUS_DEVICE(&s->snvs), &error_abort);
624
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_ADDR);
625
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_HP_ADDR);
626
627
/*
628
* SRC
629
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
630
create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
631
632
/*
633
- * Watchdog
634
+ * Watchdogs
635
*/
636
for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
637
static const hwaddr FSL_IMX7_WDOGn_ADDR[FSL_IMX7_NUM_WDTS] = {
638
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
639
create_unimplemented_device("caam", FSL_IMX7_CAAM_ADDR, FSL_IMX7_CAAM_SIZE);
640
641
/*
642
- * PWM
643
+ * PWMs
644
*/
645
- create_unimplemented_device("pwm1", FSL_IMX7_PWM1_ADDR, FSL_IMX7_PWMn_SIZE);
646
- create_unimplemented_device("pwm2", FSL_IMX7_PWM2_ADDR, FSL_IMX7_PWMn_SIZE);
647
- create_unimplemented_device("pwm3", FSL_IMX7_PWM3_ADDR, FSL_IMX7_PWMn_SIZE);
648
- create_unimplemented_device("pwm4", FSL_IMX7_PWM4_ADDR, FSL_IMX7_PWMn_SIZE);
649
+ for (i = 0; i < FSL_IMX7_NUM_PWMS; i++) {
650
+ static const hwaddr FSL_IMX7_PWMn_ADDR[FSL_IMX7_NUM_PWMS] = {
651
+ FSL_IMX7_PWM1_ADDR,
652
+ FSL_IMX7_PWM2_ADDR,
653
+ FSL_IMX7_PWM3_ADDR,
654
+ FSL_IMX7_PWM4_ADDR,
655
+ };
656
+
657
+ snprintf(name, NAME_SIZE, "pwm%d", i);
658
+ create_unimplemented_device(name, FSL_IMX7_PWMn_ADDR[i],
659
+ FSL_IMX7_PWMn_SIZE);
660
+ }
661
662
/*
663
- * CAN
664
+ * CANs
665
*/
666
- create_unimplemented_device("can1", FSL_IMX7_CAN1_ADDR, FSL_IMX7_CANn_SIZE);
667
- create_unimplemented_device("can2", FSL_IMX7_CAN2_ADDR, FSL_IMX7_CANn_SIZE);
668
+ for (i = 0; i < FSL_IMX7_NUM_CANS; i++) {
669
+ static const hwaddr FSL_IMX7_CANn_ADDR[FSL_IMX7_NUM_CANS] = {
670
+ FSL_IMX7_CAN1_ADDR,
671
+ FSL_IMX7_CAN2_ADDR,
672
+ };
673
+
674
+ snprintf(name, NAME_SIZE, "can%d", i);
675
+ create_unimplemented_device(name, FSL_IMX7_CANn_ADDR[i],
676
+ FSL_IMX7_CANn_SIZE);
677
+ }
678
679
/*
680
- * SAI (Audio SSI (Synchronous Serial Interface))
681
+ * SAIs (Audio SSI (Synchronous Serial Interface))
682
*/
683
- create_unimplemented_device("sai1", FSL_IMX7_SAI1_ADDR, FSL_IMX7_SAIn_SIZE);
684
- create_unimplemented_device("sai2", FSL_IMX7_SAI2_ADDR, FSL_IMX7_SAIn_SIZE);
685
- create_unimplemented_device("sai2", FSL_IMX7_SAI3_ADDR, FSL_IMX7_SAIn_SIZE);
686
+ for (i = 0; i < FSL_IMX7_NUM_SAIS; i++) {
687
+ static const hwaddr FSL_IMX7_SAIn_ADDR[FSL_IMX7_NUM_SAIS] = {
688
+ FSL_IMX7_SAI1_ADDR,
689
+ FSL_IMX7_SAI2_ADDR,
690
+ FSL_IMX7_SAI3_ADDR,
691
+ };
692
+
693
+ snprintf(name, NAME_SIZE, "sai%d", i);
694
+ create_unimplemented_device(name, FSL_IMX7_SAIn_ADDR[i],
695
+ FSL_IMX7_SAIn_SIZE);
696
+ }
697
698
/*
699
* OCOTP
700
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
701
create_unimplemented_device("ocotp", FSL_IMX7_OCOTP_ADDR,
702
FSL_IMX7_OCOTP_SIZE);
703
704
+ /*
705
+ * GPR
706
+ */
707
sysbus_realize(SYS_BUS_DEVICE(&s->gpr), &error_abort);
708
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_GPR_ADDR);
709
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_IOMUXC_GPR_ADDR);
710
711
+ /*
712
+ * PCIE
713
+ */
714
sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
715
sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
716
717
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
718
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_IRQ);
719
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
720
721
-
722
+ /*
723
+ * USBs
724
+ */
725
for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
726
static const hwaddr FSL_IMX7_USBMISCn_ADDR[FSL_IMX7_NUM_USBS] = {
727
FSL_IMX7_USBMISC1_ADDR,
728
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
729
*/
730
create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
731
FSL_IMX7_PCIE_PHY_SIZE);
732
+
31
}
733
}
32
734
33
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
735
static Property fsl_imx7_properties[] = {
34
addr = ptw->out_phys;
35
attrs.secure = ptw->out_secure;
36
as = arm_addressspace(cs, attrs);
37
- if (regime_translation_big_endian(env, ptw->in_mmu_idx)) {
38
+ if (ptw->out_be) {
39
data = address_space_ldl_be(as, addr, attrs, &result);
40
} else {
41
data = address_space_ldl_le(as, addr, attrs, &result);
42
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw, hwaddr addr,
43
addr = ptw->out_phys;
44
attrs.secure = ptw->out_secure;
45
as = arm_addressspace(cs, attrs);
46
- if (regime_translation_big_endian(env, ptw->in_mmu_idx)) {
47
+ if (ptw->out_be) {
48
data = address_space_ldq_be(as, addr, attrs, &result);
49
} else {
50
data = address_space_ldq_le(as, addr, attrs, &result);
51
--
736
--
52
2.25.1
737
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
In preparation for TARGET_TB_PCREL, reduce reliance on
3
* Add TZASC as unimplemented device.
4
absolute values by passing in pc difference.
4
- Allow bare metal application to access this (unimplemented) device
5
* Add CSU as unimplemented device.
6
- Allow bare metal application to access this (unimplemented) device
7
* Add various memory segments
8
- OCRAM
9
- OCRAM EPDC
10
- OCRAM PXP
11
- OCRAM S
12
- ROM
13
- CAAM
5
14
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20221020030641.2066807-4-richard.henderson@linaro.org
17
Message-id: f887a3483996ba06d40bd62ffdfb0ecf68621987.1692964892.git.jcd@tribudubois.net
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
19
---
11
target/arm/translate-a32.h | 2 +-
20
include/hw/arm/fsl-imx7.h | 7 +++++
12
target/arm/translate.h | 6 ++--
21
hw/arm/fsl-imx7.c | 63 +++++++++++++++++++++++++++++++++++++++
13
target/arm/translate-a64.c | 32 +++++++++---------
22
2 files changed, 70 insertions(+)
14
target/arm/translate-vfp.c | 2 +-
15
target/arm/translate.c | 68 ++++++++++++++++++++------------------
16
5 files changed, 56 insertions(+), 54 deletions(-)
17
23
18
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
24
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
19
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a32.h
26
--- a/include/hw/arm/fsl-imx7.h
21
+++ b/target/arm/translate-a32.h
27
+++ b/include/hw/arm/fsl-imx7.h
22
@@ -XXX,XX +XXX,XX @@ void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop);
28
@@ -XXX,XX +XXX,XX @@ struct FslIMX7State {
23
TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs);
29
IMX7GPRState gpr;
24
void gen_set_cpsr(TCGv_i32 var, uint32_t mask);
30
ChipideaState usb[FSL_IMX7_NUM_USBS];
25
void gen_set_condexec(DisasContext *s);
31
DesignwarePCIEHost pcie;
26
-void gen_set_pc_im(DisasContext *s, target_ulong val);
32
+ MemoryRegion rom;
27
+void gen_update_pc(DisasContext *s, target_long diff);
33
+ MemoryRegion caam;
28
void gen_lookup_tb(DisasContext *s);
34
+ MemoryRegion ocram;
29
long vfp_reg_offset(bool dp, unsigned reg);
35
+ MemoryRegion ocram_epdc;
30
long neon_full_reg_offset(unsigned reg);
36
+ MemoryRegion ocram_pxp;
31
diff --git a/target/arm/translate.h b/target/arm/translate.h
37
+ MemoryRegion ocram_s;
38
+
39
uint32_t phy_num[FSL_IMX7_NUM_ETHS];
40
bool phy_connected[FSL_IMX7_NUM_ETHS];
41
};
42
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
32
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate.h
44
--- a/hw/arm/fsl-imx7.c
34
+++ b/target/arm/translate.h
45
+++ b/hw/arm/fsl-imx7.c
35
@@ -XXX,XX +XXX,XX @@ static inline int curr_insn_len(DisasContext *s)
46
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
36
* For instructions which want an immediate exit to the main loop, as opposed
47
create_unimplemented_device("pcie-phy", FSL_IMX7_PCIE_PHY_ADDR,
37
* to attempting to use lookup_and_goto_ptr. Unlike DISAS_UPDATE_EXIT, this
48
FSL_IMX7_PCIE_PHY_SIZE);
38
* doesn't write the PC on exiting the translation loop so you need to ensure
49
39
- * something (gen_a64_set_pc_im or runtime helper) has done so before we reach
50
+ /*
40
+ * something (gen_a64_update_pc or runtime helper) has done so before we reach
51
+ * CSU
41
* return from cpu_tb_exec.
52
+ */
42
*/
53
+ create_unimplemented_device("csu", FSL_IMX7_CSU_ADDR,
43
#define DISAS_EXIT DISAS_TARGET_9
54
+ FSL_IMX7_CSU_SIZE);
44
@@ -XXX,XX +XXX,XX @@ static inline int curr_insn_len(DisasContext *s)
55
+
45
56
+ /*
46
#ifdef TARGET_AARCH64
57
+ * TZASC
47
void a64_translate_init(void);
58
+ */
48
-void gen_a64_set_pc_im(uint64_t val);
59
+ create_unimplemented_device("tzasc", FSL_IMX7_TZASC_ADDR,
49
+void gen_a64_update_pc(DisasContext *s, target_long diff);
60
+ FSL_IMX7_TZASC_SIZE);
50
extern const TranslatorOps aarch64_translator_ops;
61
+
51
#else
62
+ /*
52
static inline void a64_translate_init(void)
63
+ * OCRAM memory
53
{
64
+ */
65
+ memory_region_init_ram(&s->ocram, NULL, "imx7.ocram",
66
+ FSL_IMX7_OCRAM_MEM_SIZE,
67
+ &error_abort);
68
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_MEM_ADDR,
69
+ &s->ocram);
70
+
71
+ /*
72
+ * OCRAM EPDC memory
73
+ */
74
+ memory_region_init_ram(&s->ocram_epdc, NULL, "imx7.ocram_epdc",
75
+ FSL_IMX7_OCRAM_EPDC_SIZE,
76
+ &error_abort);
77
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_EPDC_ADDR,
78
+ &s->ocram_epdc);
79
+
80
+ /*
81
+ * OCRAM PXP memory
82
+ */
83
+ memory_region_init_ram(&s->ocram_pxp, NULL, "imx7.ocram_pxp",
84
+ FSL_IMX7_OCRAM_PXP_SIZE,
85
+ &error_abort);
86
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_PXP_ADDR,
87
+ &s->ocram_pxp);
88
+
89
+ /*
90
+ * OCRAM_S memory
91
+ */
92
+ memory_region_init_ram(&s->ocram_s, NULL, "imx7.ocram_s",
93
+ FSL_IMX7_OCRAM_S_SIZE,
94
+ &error_abort);
95
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_OCRAM_S_ADDR,
96
+ &s->ocram_s);
97
+
98
+ /*
99
+ * ROM memory
100
+ */
101
+ memory_region_init_rom(&s->rom, OBJECT(dev), "imx7.rom",
102
+ FSL_IMX7_ROM_SIZE, &error_abort);
103
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_ROM_ADDR,
104
+ &s->rom);
105
+
106
+ /*
107
+ * CAAM memory
108
+ */
109
+ memory_region_init_rom(&s->caam, OBJECT(dev), "imx7.caam",
110
+ FSL_IMX7_CAAM_MEM_SIZE, &error_abort);
111
+ memory_region_add_subregion(get_system_memory(), FSL_IMX7_CAAM_MEM_ADDR,
112
+ &s->caam);
54
}
113
}
55
114
56
-static inline void gen_a64_set_pc_im(uint64_t val)
115
static Property fsl_imx7_properties[] = {
57
+static inline void gen_a64_update_pc(DisasContext *s, target_long diff)
58
{
59
}
60
#endif
61
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/translate-a64.c
64
+++ b/target/arm/translate-a64.c
65
@@ -XXX,XX +XXX,XX @@ static void reset_btype(DisasContext *s)
66
}
67
}
68
69
-void gen_a64_set_pc_im(uint64_t val)
70
+void gen_a64_update_pc(DisasContext *s, target_long diff)
71
{
72
- tcg_gen_movi_i64(cpu_pc, val);
73
+ tcg_gen_movi_i64(cpu_pc, s->pc_curr + diff);
74
}
75
76
/*
77
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
78
79
static void gen_exception_internal_insn(DisasContext *s, uint64_t pc, int excp)
80
{
81
- gen_a64_set_pc_im(pc);
82
+ gen_a64_update_pc(s, pc - s->pc_curr);
83
gen_exception_internal(excp);
84
s->base.is_jmp = DISAS_NORETURN;
85
}
86
87
static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syndrome)
88
{
89
- gen_a64_set_pc_im(s->pc_curr);
90
+ gen_a64_update_pc(s, 0);
91
gen_helper_exception_bkpt_insn(cpu_env, tcg_constant_i32(syndrome));
92
s->base.is_jmp = DISAS_NORETURN;
93
}
94
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, int64_t diff)
95
96
if (use_goto_tb(s, dest)) {
97
tcg_gen_goto_tb(n);
98
- gen_a64_set_pc_im(dest);
99
+ gen_a64_update_pc(s, diff);
100
tcg_gen_exit_tb(s->base.tb, n);
101
s->base.is_jmp = DISAS_NORETURN;
102
} else {
103
- gen_a64_set_pc_im(dest);
104
+ gen_a64_update_pc(s, diff);
105
if (s->ss_active) {
106
gen_step_complete_exception(s);
107
} else {
108
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
109
uint32_t syndrome;
110
111
syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
112
- gen_a64_set_pc_im(s->pc_curr);
113
+ gen_a64_update_pc(s, 0);
114
gen_helper_access_check_cp_reg(cpu_env,
115
tcg_constant_ptr(ri),
116
tcg_constant_i32(syndrome),
117
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
118
* The readfn or writefn might raise an exception;
119
* synchronize the CPU state in case it does.
120
*/
121
- gen_a64_set_pc_im(s->pc_curr);
122
+ gen_a64_update_pc(s, 0);
123
}
124
125
/* Handle special cases first */
126
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
127
/* The pre HVC helper handles cases when HVC gets trapped
128
* as an undefined insn by runtime configuration.
129
*/
130
- gen_a64_set_pc_im(s->pc_curr);
131
+ gen_a64_update_pc(s, 0);
132
gen_helper_pre_hvc(cpu_env);
133
gen_ss_advance(s);
134
gen_exception_insn_el(s, s->base.pc_next, EXCP_HVC,
135
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
136
unallocated_encoding(s);
137
break;
138
}
139
- gen_a64_set_pc_im(s->pc_curr);
140
+ gen_a64_update_pc(s, 0);
141
gen_helper_pre_smc(cpu_env, tcg_constant_i32(syn_aa64_smc(imm16)));
142
gen_ss_advance(s);
143
gen_exception_insn_el(s, s->base.pc_next, EXCP_SMC,
144
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
145
*/
146
switch (dc->base.is_jmp) {
147
default:
148
- gen_a64_set_pc_im(dc->base.pc_next);
149
+ gen_a64_update_pc(dc, 4);
150
/* fall through */
151
case DISAS_EXIT:
152
case DISAS_JUMP:
153
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
154
break;
155
default:
156
case DISAS_UPDATE_EXIT:
157
- gen_a64_set_pc_im(dc->base.pc_next);
158
+ gen_a64_update_pc(dc, 4);
159
/* fall through */
160
case DISAS_EXIT:
161
tcg_gen_exit_tb(NULL, 0);
162
break;
163
case DISAS_UPDATE_NOCHAIN:
164
- gen_a64_set_pc_im(dc->base.pc_next);
165
+ gen_a64_update_pc(dc, 4);
166
/* fall through */
167
case DISAS_JUMP:
168
tcg_gen_lookup_and_goto_ptr();
169
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
170
case DISAS_SWI:
171
break;
172
case DISAS_WFE:
173
- gen_a64_set_pc_im(dc->base.pc_next);
174
+ gen_a64_update_pc(dc, 4);
175
gen_helper_wfe(cpu_env);
176
break;
177
case DISAS_YIELD:
178
- gen_a64_set_pc_im(dc->base.pc_next);
179
+ gen_a64_update_pc(dc, 4);
180
gen_helper_yield(cpu_env);
181
break;
182
case DISAS_WFI:
183
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
184
* This is a special case because we don't want to just halt
185
* the CPU if trying to debug across a WFI.
186
*/
187
- gen_a64_set_pc_im(dc->base.pc_next);
188
+ gen_a64_update_pc(dc, 4);
189
gen_helper_wfi(cpu_env, tcg_constant_i32(4));
190
/*
191
* The helper doesn't necessarily throw an exception, but we
192
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/target/arm/translate-vfp.c
195
+++ b/target/arm/translate-vfp.c
196
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
197
case ARM_VFP_FPSID:
198
if (s->current_el == 1) {
199
gen_set_condexec(s);
200
- gen_set_pc_im(s, s->pc_curr);
201
+ gen_update_pc(s, 0);
202
gen_helper_check_hcr_el2_trap(cpu_env,
203
tcg_constant_i32(a->rt),
204
tcg_constant_i32(a->reg));
205
diff --git a/target/arm/translate.c b/target/arm/translate.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/target/arm/translate.c
208
+++ b/target/arm/translate.c
209
@@ -XXX,XX +XXX,XX @@ void gen_set_condexec(DisasContext *s)
210
}
211
}
212
213
-void gen_set_pc_im(DisasContext *s, target_ulong val)
214
+void gen_update_pc(DisasContext *s, target_long diff)
215
{
216
- tcg_gen_movi_i32(cpu_R[15], val);
217
+ tcg_gen_movi_i32(cpu_R[15], s->pc_curr + diff);
218
}
219
220
/* Set PC and Thumb state from var. var is marked as dead. */
221
@@ -XXX,XX +XXX,XX @@ static inline void gen_bxns(DisasContext *s, int rm)
222
223
/* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
224
* we need to sync state before calling it, but:
225
- * - we don't need to do gen_set_pc_im() because the bxns helper will
226
+ * - we don't need to do gen_update_pc() because the bxns helper will
227
* always set the PC itself
228
* - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
229
* unless it's outside an IT block or the last insn in an IT block,
230
@@ -XXX,XX +XXX,XX @@ static inline void gen_blxns(DisasContext *s, int rm)
231
* We do however need to set the PC, because the blxns helper reads it.
232
* The blxns helper may throw an exception.
233
*/
234
- gen_set_pc_im(s, s->base.pc_next);
235
+ gen_update_pc(s, curr_insn_len(s));
236
gen_helper_v7m_blxns(cpu_env, var);
237
tcg_temp_free_i32(var);
238
s->base.is_jmp = DISAS_EXIT;
239
@@ -XXX,XX +XXX,XX @@ static inline void gen_hvc(DisasContext *s, int imm16)
240
* as an undefined insn by runtime configuration (ie before
241
* the insn really executes).
242
*/
243
- gen_set_pc_im(s, s->pc_curr);
244
+ gen_update_pc(s, 0);
245
gen_helper_pre_hvc(cpu_env);
246
/* Otherwise we will treat this as a real exception which
247
* happens after execution of the insn. (The distinction matters
248
@@ -XXX,XX +XXX,XX @@ static inline void gen_hvc(DisasContext *s, int imm16)
249
* for single stepping.)
250
*/
251
s->svc_imm = imm16;
252
- gen_set_pc_im(s, s->base.pc_next);
253
+ gen_update_pc(s, curr_insn_len(s));
254
s->base.is_jmp = DISAS_HVC;
255
}
256
257
@@ -XXX,XX +XXX,XX @@ static inline void gen_smc(DisasContext *s)
258
/* As with HVC, we may take an exception either before or after
259
* the insn executes.
260
*/
261
- gen_set_pc_im(s, s->pc_curr);
262
+ gen_update_pc(s, 0);
263
gen_helper_pre_smc(cpu_env, tcg_constant_i32(syn_aa32_smc()));
264
- gen_set_pc_im(s, s->base.pc_next);
265
+ gen_update_pc(s, curr_insn_len(s));
266
s->base.is_jmp = DISAS_SMC;
267
}
268
269
static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
270
{
271
gen_set_condexec(s);
272
- gen_set_pc_im(s, pc);
273
+ gen_update_pc(s, pc - s->pc_curr);
274
gen_exception_internal(excp);
275
s->base.is_jmp = DISAS_NORETURN;
276
}
277
@@ -XXX,XX +XXX,XX @@ static void gen_exception_insn_el_v(DisasContext *s, uint64_t pc, int excp,
278
uint32_t syn, TCGv_i32 tcg_el)
279
{
280
if (s->aarch64) {
281
- gen_a64_set_pc_im(pc);
282
+ gen_a64_update_pc(s, pc - s->pc_curr);
283
} else {
284
gen_set_condexec(s);
285
- gen_set_pc_im(s, pc);
286
+ gen_update_pc(s, pc - s->pc_curr);
287
}
288
gen_exception_el_v(excp, syn, tcg_el);
289
s->base.is_jmp = DISAS_NORETURN;
290
@@ -XXX,XX +XXX,XX @@ void gen_exception_insn_el(DisasContext *s, uint64_t pc, int excp,
291
void gen_exception_insn(DisasContext *s, uint64_t pc, int excp, uint32_t syn)
292
{
293
if (s->aarch64) {
294
- gen_a64_set_pc_im(pc);
295
+ gen_a64_update_pc(s, pc - s->pc_curr);
296
} else {
297
gen_set_condexec(s);
298
- gen_set_pc_im(s, pc);
299
+ gen_update_pc(s, pc - s->pc_curr);
300
}
301
gen_exception(excp, syn);
302
s->base.is_jmp = DISAS_NORETURN;
303
@@ -XXX,XX +XXX,XX @@ void gen_exception_insn(DisasContext *s, uint64_t pc, int excp, uint32_t syn)
304
static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
305
{
306
gen_set_condexec(s);
307
- gen_set_pc_im(s, s->pc_curr);
308
+ gen_update_pc(s, 0);
309
gen_helper_exception_bkpt_insn(cpu_env, tcg_constant_i32(syn));
310
s->base.is_jmp = DISAS_NORETURN;
311
}
312
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, int diff)
313
314
if (translator_use_goto_tb(&s->base, dest)) {
315
tcg_gen_goto_tb(n);
316
- gen_set_pc_im(s, dest);
317
+ gen_update_pc(s, diff);
318
tcg_gen_exit_tb(s->base.tb, n);
319
} else {
320
- gen_set_pc_im(s, dest);
321
+ gen_update_pc(s, diff);
322
gen_goto_ptr();
323
}
324
s->base.is_jmp = DISAS_NORETURN;
325
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, int diff)
326
/* Jump, specifying which TB number to use if we gen_goto_tb() */
327
static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
328
{
329
+ int diff = dest - s->pc_curr;
330
+
331
if (unlikely(s->ss_active)) {
332
/* An indirect jump so that we still trigger the debug exception. */
333
- gen_set_pc_im(s, dest);
334
+ gen_update_pc(s, diff);
335
s->base.is_jmp = DISAS_JUMP;
336
return;
337
}
338
@@ -XXX,XX +XXX,XX @@ static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
339
* gen_jmp();
340
* on the second call to gen_jmp().
341
*/
342
- gen_goto_tb(s, tbno, dest - s->pc_curr);
343
+ gen_goto_tb(s, tbno, diff);
344
break;
345
case DISAS_UPDATE_NOCHAIN:
346
case DISAS_UPDATE_EXIT:
347
@@ -XXX,XX +XXX,XX @@ static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
348
* Avoid using goto_tb so we really do exit back to the main loop
349
* and don't chain to another TB.
350
*/
351
- gen_set_pc_im(s, dest);
352
+ gen_update_pc(s, diff);
353
gen_goto_ptr();
354
s->base.is_jmp = DISAS_NORETURN;
355
break;
356
@@ -XXX,XX +XXX,XX @@ static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
357
358
/* Sync state because msr_banked() can raise exceptions */
359
gen_set_condexec(s);
360
- gen_set_pc_im(s, s->pc_curr);
361
+ gen_update_pc(s, 0);
362
tcg_reg = load_reg(s, rn);
363
gen_helper_msr_banked(cpu_env, tcg_reg,
364
tcg_constant_i32(tgtmode),
365
@@ -XXX,XX +XXX,XX @@ static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
366
367
/* Sync state because mrs_banked() can raise exceptions */
368
gen_set_condexec(s);
369
- gen_set_pc_im(s, s->pc_curr);
370
+ gen_update_pc(s, 0);
371
tcg_reg = tcg_temp_new_i32();
372
gen_helper_mrs_banked(tcg_reg, cpu_env,
373
tcg_constant_i32(tgtmode),
374
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
375
}
376
377
gen_set_condexec(s);
378
- gen_set_pc_im(s, s->pc_curr);
379
+ gen_update_pc(s, 0);
380
gen_helper_access_check_cp_reg(cpu_env,
381
tcg_constant_ptr(ri),
382
tcg_constant_i32(syndrome),
383
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
384
* synchronize the CPU state in case it does.
385
*/
386
gen_set_condexec(s);
387
- gen_set_pc_im(s, s->pc_curr);
388
+ gen_update_pc(s, 0);
389
}
390
391
/* Handle special cases first */
392
@@ -XXX,XX +XXX,XX @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
393
unallocated_encoding(s);
394
return;
395
}
396
- gen_set_pc_im(s, s->base.pc_next);
397
+ gen_update_pc(s, curr_insn_len(s));
398
s->base.is_jmp = DISAS_WFI;
399
return;
400
default:
401
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
402
addr = tcg_temp_new_i32();
403
/* get_r13_banked() will raise an exception if called from System mode */
404
gen_set_condexec(s);
405
- gen_set_pc_im(s, s->pc_curr);
406
+ gen_update_pc(s, 0);
407
gen_helper_get_r13_banked(addr, cpu_env, tcg_constant_i32(mode));
408
switch (amode) {
409
case 0: /* DA */
410
@@ -XXX,XX +XXX,XX @@ static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
411
* scheduling of other vCPUs.
412
*/
413
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
414
- gen_set_pc_im(s, s->base.pc_next);
415
+ gen_update_pc(s, curr_insn_len(s));
416
s->base.is_jmp = DISAS_YIELD;
417
}
418
return true;
419
@@ -XXX,XX +XXX,XX @@ static bool trans_WFE(DisasContext *s, arg_WFE *a)
420
* implemented so we can't sleep like WFI does.
421
*/
422
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
423
- gen_set_pc_im(s, s->base.pc_next);
424
+ gen_update_pc(s, curr_insn_len(s));
425
s->base.is_jmp = DISAS_WFE;
426
}
427
return true;
428
@@ -XXX,XX +XXX,XX @@ static bool trans_WFE(DisasContext *s, arg_WFE *a)
429
static bool trans_WFI(DisasContext *s, arg_WFI *a)
430
{
431
/* For WFI, halt the vCPU until an IRQ. */
432
- gen_set_pc_im(s, s->base.pc_next);
433
+ gen_update_pc(s, curr_insn_len(s));
434
s->base.is_jmp = DISAS_WFI;
435
return true;
436
}
437
@@ -XXX,XX +XXX,XX @@ static bool trans_SVC(DisasContext *s, arg_SVC *a)
438
(a->imm == semihost_imm)) {
439
gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
440
} else {
441
- gen_set_pc_im(s, s->base.pc_next);
442
+ gen_update_pc(s, curr_insn_len(s));
443
s->svc_imm = a->imm;
444
s->base.is_jmp = DISAS_SWI;
445
}
446
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
447
case DISAS_TOO_MANY:
448
case DISAS_UPDATE_EXIT:
449
case DISAS_UPDATE_NOCHAIN:
450
- gen_set_pc_im(dc, dc->base.pc_next);
451
+ gen_update_pc(dc, curr_insn_len(dc));
452
/* fall through */
453
default:
454
/* FIXME: Single stepping a WFI insn will not halt the CPU. */
455
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
456
gen_goto_tb(dc, 1, curr_insn_len(dc));
457
break;
458
case DISAS_UPDATE_NOCHAIN:
459
- gen_set_pc_im(dc, dc->base.pc_next);
460
+ gen_update_pc(dc, curr_insn_len(dc));
461
/* fall through */
462
case DISAS_JUMP:
463
gen_goto_ptr();
464
break;
465
case DISAS_UPDATE_EXIT:
466
- gen_set_pc_im(dc, dc->base.pc_next);
467
+ gen_update_pc(dc, curr_insn_len(dc));
468
/* fall through */
469
default:
470
/* indicate that the hash table must be used to find the next TB */
471
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
472
gen_set_label(dc->condlabel);
473
gen_set_condexec(dc);
474
if (unlikely(dc->ss_active)) {
475
- gen_set_pc_im(dc, dc->base.pc_next);
476
+ gen_update_pc(dc, curr_insn_len(dc));
477
gen_singlestep_exception(dc);
478
} else {
479
gen_goto_tb(dc, 1, curr_insn_len(dc));
480
--
116
--
481
2.25.1
117
2.34.1
482
118
483
119
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
The SRC device is normally used to start the secondary CPU.
4
5
When running Linux directly, QEMU is emulating a PSCI interface that UBOOT
6
is installing at boot time and therefore the fact that the SRC device is
7
unimplemented is hidden as Qemu respond directly to PSCI requets without
8
using the SRC device.
9
10
But if you try to run a more bare metal application (maybe uboot itself),
11
then it is not possible to start the secondary CPU as the SRC is an
12
unimplemented device.
13
14
This patch adds the ability to start the secondary CPU through the SRC
15
device so that you can use this feature in bare metal applications.
16
17
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: ce9a0162defd2acee5dc7f8a674743de0cded569.1692964892.git.jcd@tribudubois.net
5
Message-id: 20221011031911.2408754-12-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
21
---
8
target/arm/ptw.c | 191 +++++++++++++++++++++++++----------------------
22
include/hw/arm/fsl-imx7.h | 3 +-
9
1 file changed, 100 insertions(+), 91 deletions(-)
23
include/hw/misc/imx7_src.h | 66 +++++++++
10
24
hw/arm/fsl-imx7.c | 8 +-
11
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
25
hw/misc/imx7_src.c | 276 +++++++++++++++++++++++++++++++++++++
26
hw/misc/meson.build | 1 +
27
hw/misc/trace-events | 4 +
28
6 files changed, 356 insertions(+), 2 deletions(-)
29
create mode 100644 include/hw/misc/imx7_src.h
30
create mode 100644 hw/misc/imx7_src.c
31
32
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
12
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/ptw.c
34
--- a/include/hw/arm/fsl-imx7.h
14
+++ b/target/arm/ptw.c
35
+++ b/include/hw/arm/fsl-imx7.h
15
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
36
@@ -XXX,XX +XXX,XX @@
16
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
37
#include "hw/misc/imx7_ccm.h"
17
__attribute__((nonnull));
38
#include "hw/misc/imx7_snvs.h"
18
39
#include "hw/misc/imx7_gpr.h"
19
+static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
40
+#include "hw/misc/imx7_src.h"
20
+ target_ulong address,
41
#include "hw/watchdog/wdt_imx2.h"
21
+ MMUAccessType access_type,
42
#include "hw/gpio/imx_gpio.h"
22
+ GetPhysAddrResult *result,
43
#include "hw/char/imx_serial.h"
23
+ ARMMMUFaultInfo *fi)
44
@@ -XXX,XX +XXX,XX @@ struct FslIMX7State {
24
+ __attribute__((nonnull));
45
IMX7CCMState ccm;
25
+
46
IMX7AnalogState analog;
26
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
47
IMX7SNVSState snvs;
27
static const uint8_t pamax_map[] = {
48
+ IMX7SRCState src;
28
[0] = 32,
49
IMXGPCv2State gpcv2;
29
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
50
IMXSPIState spi[FSL_IMX7_NUM_ECSPIS];
30
return 0;
51
IMXI2CState i2c[FSL_IMX7_NUM_I2CS];
31
}
52
@@ -XXX,XX +XXX,XX @@ enum FslIMX7MemoryMap {
32
53
FSL_IMX7_GPC_ADDR = 0x303A0000,
33
+static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
54
34
+ target_ulong address,
55
FSL_IMX7_SRC_ADDR = 0x30390000,
35
+ MMUAccessType access_type,
56
- FSL_IMX7_SRC_SIZE = (4 * KiB),
36
+ GetPhysAddrResult *result,
57
37
+ ARMMMUFaultInfo *fi)
58
FSL_IMX7_CCM_ADDR = 0x30380000,
38
+{
59
39
+ hwaddr ipa;
60
diff --git a/include/hw/misc/imx7_src.h b/include/hw/misc/imx7_src.h
40
+ int s1_prot;
61
new file mode 100644
41
+ int ret;
62
index XXXXXXX..XXXXXXX
42
+ bool is_secure = ptw->in_secure;
63
--- /dev/null
43
+ bool ipa_secure, s2walk_secure;
64
+++ b/include/hw/misc/imx7_src.h
44
+ ARMCacheAttrs cacheattrs1;
65
@@ -XXX,XX +XXX,XX @@
45
+ bool is_el0;
66
+/*
46
+ uint64_t hcr;
67
+ * IMX7 System Reset Controller
47
+
68
+ *
48
+ ret = get_phys_addr_with_struct(env, ptw, address, access_type, result, fi);
69
+ * Copyright (C) 2023 Jean-Christophe Dubois <jcd@tribudubois.net>
49
+
70
+ *
50
+ /* If S1 fails or S2 is disabled, return early. */
71
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
51
+ if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2, is_secure)) {
72
+ * See the COPYING file in the top-level directory.
52
+ return ret;
73
+ */
74
+
75
+#ifndef IMX7_SRC_H
76
+#define IMX7_SRC_H
77
+
78
+#include "hw/sysbus.h"
79
+#include "qemu/bitops.h"
80
+#include "qom/object.h"
81
+
82
+#define SRC_SCR 0
83
+#define SRC_A7RCR0 1
84
+#define SRC_A7RCR1 2
85
+#define SRC_M4RCR 3
86
+#define SRC_ERCR 5
87
+#define SRC_HSICPHY_RCR 7
88
+#define SRC_USBOPHY1_RCR 8
89
+#define SRC_USBOPHY2_RCR 9
90
+#define SRC_MPIPHY_RCR 10
91
+#define SRC_PCIEPHY_RCR 11
92
+#define SRC_SBMR1 22
93
+#define SRC_SRSR 23
94
+#define SRC_SISR 26
95
+#define SRC_SIMR 27
96
+#define SRC_SBMR2 28
97
+#define SRC_GPR1 29
98
+#define SRC_GPR2 30
99
+#define SRC_GPR3 31
100
+#define SRC_GPR4 32
101
+#define SRC_GPR5 33
102
+#define SRC_GPR6 34
103
+#define SRC_GPR7 35
104
+#define SRC_GPR8 36
105
+#define SRC_GPR9 37
106
+#define SRC_GPR10 38
107
+#define SRC_MAX 39
108
+
109
+/* SRC_A7SCR1 */
110
+#define R_CORE1_ENABLE_SHIFT 1
111
+#define R_CORE1_ENABLE_LENGTH 1
112
+/* SRC_A7SCR0 */
113
+#define R_CORE1_RST_SHIFT 5
114
+#define R_CORE1_RST_LENGTH 1
115
+#define R_CORE0_RST_SHIFT 4
116
+#define R_CORE0_RST_LENGTH 1
117
+
118
+#define TYPE_IMX7_SRC "imx7.src"
119
+OBJECT_DECLARE_SIMPLE_TYPE(IMX7SRCState, IMX7_SRC)
120
+
121
+struct IMX7SRCState {
122
+ /* <private> */
123
+ SysBusDevice parent_obj;
124
+
125
+ /* <public> */
126
+ MemoryRegion iomem;
127
+
128
+ uint32_t regs[SRC_MAX];
129
+};
130
+
131
+#endif /* IMX7_SRC_H */
132
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/arm/fsl-imx7.c
135
+++ b/hw/arm/fsl-imx7.c
136
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_init(Object *obj)
137
*/
138
object_initialize_child(obj, "gpcv2", &s->gpcv2, TYPE_IMX_GPCV2);
139
140
+ /*
141
+ * SRC
142
+ */
143
+ object_initialize_child(obj, "src", &s->src, TYPE_IMX7_SRC);
144
+
145
/*
146
* ECSPIs
147
*/
148
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
149
/*
150
* SRC
151
*/
152
- create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
153
+ sysbus_realize(SYS_BUS_DEVICE(&s->src), &error_abort);
154
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX7_SRC_ADDR);
155
156
/*
157
* Watchdogs
158
diff --git a/hw/misc/imx7_src.c b/hw/misc/imx7_src.c
159
new file mode 100644
160
index XXXXXXX..XXXXXXX
161
--- /dev/null
162
+++ b/hw/misc/imx7_src.c
163
@@ -XXX,XX +XXX,XX @@
164
+/*
165
+ * IMX7 System Reset Controller
166
+ *
167
+ * Copyright (c) 2023 Jean-Christophe Dubois <jcd@tribudubois.net>
168
+ *
169
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
170
+ * See the COPYING file in the top-level directory.
171
+ *
172
+ */
173
+
174
+#include "qemu/osdep.h"
175
+#include "hw/misc/imx7_src.h"
176
+#include "migration/vmstate.h"
177
+#include "qemu/bitops.h"
178
+#include "qemu/log.h"
179
+#include "qemu/main-loop.h"
180
+#include "qemu/module.h"
181
+#include "target/arm/arm-powerctl.h"
182
+#include "hw/core/cpu.h"
183
+#include "hw/registerfields.h"
184
+
185
+#include "trace.h"
186
+
187
+static const char *imx7_src_reg_name(uint32_t reg)
188
+{
189
+ static char unknown[20];
190
+
191
+ switch (reg) {
192
+ case SRC_SCR:
193
+ return "SRC_SCR";
194
+ case SRC_A7RCR0:
195
+ return "SRC_A7RCR0";
196
+ case SRC_A7RCR1:
197
+ return "SRC_A7RCR1";
198
+ case SRC_M4RCR:
199
+ return "SRC_M4RCR";
200
+ case SRC_ERCR:
201
+ return "SRC_ERCR";
202
+ case SRC_HSICPHY_RCR:
203
+ return "SRC_HSICPHY_RCR";
204
+ case SRC_USBOPHY1_RCR:
205
+ return "SRC_USBOPHY1_RCR";
206
+ case SRC_USBOPHY2_RCR:
207
+ return "SRC_USBOPHY2_RCR";
208
+ case SRC_PCIEPHY_RCR:
209
+ return "SRC_PCIEPHY_RCR";
210
+ case SRC_SBMR1:
211
+ return "SRC_SBMR1";
212
+ case SRC_SRSR:
213
+ return "SRC_SRSR";
214
+ case SRC_SISR:
215
+ return "SRC_SISR";
216
+ case SRC_SIMR:
217
+ return "SRC_SIMR";
218
+ case SRC_SBMR2:
219
+ return "SRC_SBMR2";
220
+ case SRC_GPR1:
221
+ return "SRC_GPR1";
222
+ case SRC_GPR2:
223
+ return "SRC_GPR2";
224
+ case SRC_GPR3:
225
+ return "SRC_GPR3";
226
+ case SRC_GPR4:
227
+ return "SRC_GPR4";
228
+ case SRC_GPR5:
229
+ return "SRC_GPR5";
230
+ case SRC_GPR6:
231
+ return "SRC_GPR6";
232
+ case SRC_GPR7:
233
+ return "SRC_GPR7";
234
+ case SRC_GPR8:
235
+ return "SRC_GPR8";
236
+ case SRC_GPR9:
237
+ return "SRC_GPR9";
238
+ case SRC_GPR10:
239
+ return "SRC_GPR10";
240
+ default:
241
+ sprintf(unknown, "%u ?", reg);
242
+ return unknown;
53
+ }
243
+ }
54
+
244
+}
55
+ ipa = result->f.phys_addr;
245
+
56
+ ipa_secure = result->f.attrs.secure;
246
+static const VMStateDescription vmstate_imx7_src = {
57
+ if (is_secure) {
247
+ .name = TYPE_IMX7_SRC,
58
+ /* Select TCR based on the NS bit from the S1 walk. */
248
+ .version_id = 1,
59
+ s2walk_secure = !(ipa_secure
249
+ .minimum_version_id = 1,
60
+ ? env->cp15.vstcr_el2 & VSTCR_SW
250
+ .fields = (VMStateField[]) {
61
+ : env->cp15.vtcr_el2 & VTCR_NSW);
251
+ VMSTATE_UINT32_ARRAY(regs, IMX7SRCState, SRC_MAX),
252
+ VMSTATE_END_OF_LIST()
253
+ },
254
+};
255
+
256
+static void imx7_src_reset(DeviceState *dev)
257
+{
258
+ IMX7SRCState *s = IMX7_SRC(dev);
259
+
260
+ memset(s->regs, 0, sizeof(s->regs));
261
+
262
+ /* Set reset values */
263
+ s->regs[SRC_SCR] = 0xA0;
264
+ s->regs[SRC_SRSR] = 0x1;
265
+ s->regs[SRC_SIMR] = 0x1F;
266
+}
267
+
268
+static uint64_t imx7_src_read(void *opaque, hwaddr offset, unsigned size)
269
+{
270
+ uint32_t value = 0;
271
+ IMX7SRCState *s = (IMX7SRCState *)opaque;
272
+ uint32_t index = offset >> 2;
273
+
274
+ if (index < SRC_MAX) {
275
+ value = s->regs[index];
62
+ } else {
276
+ } else {
63
+ assert(!ipa_secure);
277
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
64
+ s2walk_secure = false;
278
+ HWADDR_PRIx "\n", TYPE_IMX7_SRC, __func__, offset);
65
+ }
279
+ }
66
+
280
+
67
+ is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
281
+ trace_imx7_src_read(imx7_src_reg_name(index), value);
68
+ ptw->in_mmu_idx = s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
282
+
69
+ ptw->in_secure = s2walk_secure;
283
+ return value;
70
+
284
+}
71
+ /*
285
+
72
+ * S1 is done, now do S2 translation.
286
+
73
+ * Save the stage1 results so that we may merge prot and cacheattrs later.
287
+/*
74
+ */
288
+ * The reset is asynchronous so we need to defer clearing the reset
75
+ s1_prot = result->f.prot;
289
+ * bit until the work is completed.
76
+ cacheattrs1 = result->cacheattrs;
290
+ */
77
+ memset(result, 0, sizeof(*result));
291
+
78
+
292
+struct SRCSCRResetInfo {
79
+ ret = get_phys_addr_lpae(env, ptw, ipa, access_type, is_el0, result, fi);
293
+ IMX7SRCState *s;
80
+ fi->s2addr = ipa;
294
+ uint32_t reset_bit;
81
+
295
+};
82
+ /* Combine the S1 and S2 perms. */
296
+
83
+ result->f.prot &= s1_prot;
297
+static void imx7_clear_reset_bit(CPUState *cpu, run_on_cpu_data data)
84
+
298
+{
85
+ /* If S2 fails, return early. */
299
+ struct SRCSCRResetInfo *ri = data.host_ptr;
86
+ if (ret) {
300
+ IMX7SRCState *s = ri->s;
87
+ return ret;
301
+
302
+ assert(qemu_mutex_iothread_locked());
303
+
304
+ s->regs[SRC_A7RCR0] = deposit32(s->regs[SRC_A7RCR0], ri->reset_bit, 1, 0);
305
+
306
+ trace_imx7_src_write(imx7_src_reg_name(SRC_A7RCR0), s->regs[SRC_A7RCR0]);
307
+
308
+ g_free(ri);
309
+}
310
+
311
+static void imx7_defer_clear_reset_bit(uint32_t cpuid,
312
+ IMX7SRCState *s,
313
+ uint32_t reset_shift)
314
+{
315
+ struct SRCSCRResetInfo *ri;
316
+ CPUState *cpu = arm_get_cpu_by_id(cpuid);
317
+
318
+ if (!cpu) {
319
+ return;
88
+ }
320
+ }
89
+
321
+
90
+ /* Combine the S1 and S2 cache attributes. */
322
+ ri = g_new(struct SRCSCRResetInfo, 1);
91
+ hcr = arm_hcr_el2_eff_secstate(env, is_secure);
323
+ ri->s = s;
92
+ if (hcr & HCR_DC) {
324
+ ri->reset_bit = reset_shift;
325
+
326
+ async_run_on_cpu(cpu, imx7_clear_reset_bit, RUN_ON_CPU_HOST_PTR(ri));
327
+}
328
+
329
+
330
+static void imx7_src_write(void *opaque, hwaddr offset, uint64_t value,
331
+ unsigned size)
332
+{
333
+ IMX7SRCState *s = (IMX7SRCState *)opaque;
334
+ uint32_t index = offset >> 2;
335
+ long unsigned int change_mask;
336
+ uint32_t current_value = value;
337
+
338
+ if (index >= SRC_MAX) {
339
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
340
+ HWADDR_PRIx "\n", TYPE_IMX7_SRC, __func__, offset);
341
+ return;
342
+ }
343
+
344
+ trace_imx7_src_write(imx7_src_reg_name(SRC_A7RCR0), s->regs[SRC_A7RCR0]);
345
+
346
+ change_mask = s->regs[index] ^ (uint32_t)current_value;
347
+
348
+ switch (index) {
349
+ case SRC_A7RCR0:
350
+ if (FIELD_EX32(change_mask, CORE0, RST)) {
351
+ arm_reset_cpu(0);
352
+ imx7_defer_clear_reset_bit(0, s, R_CORE0_RST_SHIFT);
353
+ }
354
+ if (FIELD_EX32(change_mask, CORE1, RST)) {
355
+ arm_reset_cpu(1);
356
+ imx7_defer_clear_reset_bit(1, s, R_CORE1_RST_SHIFT);
357
+ }
358
+ s->regs[index] = current_value;
359
+ break;
360
+ case SRC_A7RCR1:
93
+ /*
361
+ /*
94
+ * HCR.DC forces the first stage attributes to
362
+ * On real hardware when the system reset controller starts a
95
+ * Normal Non-Shareable,
363
+ * secondary CPU it runs through some boot ROM code which reads
96
+ * Inner Write-Back Read-Allocate Write-Allocate,
364
+ * the SRC_GPRX registers controlling the start address and branches
97
+ * Outer Write-Back Read-Allocate Write-Allocate.
365
+ * to it.
98
+ * Do not overwrite Tagged within attrs.
366
+ * Here we are taking a short cut and branching directly to the
367
+ * requested address (we don't want to run the boot ROM code inside
368
+ * QEMU)
99
+ */
369
+ */
100
+ if (cacheattrs1.attrs != 0xf0) {
370
+ if (FIELD_EX32(change_mask, CORE1, ENABLE)) {
101
+ cacheattrs1.attrs = 0xff;
371
+ if (FIELD_EX32(current_value, CORE1, ENABLE)) {
372
+ /* CORE 1 is brought up */
373
+ arm_set_cpu_on(1, s->regs[SRC_GPR3], s->regs[SRC_GPR4],
374
+ 3, false);
375
+ } else {
376
+ /* CORE 1 is shut down */
377
+ arm_set_cpu_off(1);
378
+ }
379
+ /* We clear the reset bits as the processor changed state */
380
+ imx7_defer_clear_reset_bit(1, s, R_CORE1_RST_SHIFT);
381
+ clear_bit(R_CORE1_RST_SHIFT, &change_mask);
102
+ }
382
+ }
103
+ cacheattrs1.shareability = 0;
383
+ s->regs[index] = current_value;
384
+ break;
385
+ default:
386
+ s->regs[index] = current_value;
387
+ break;
104
+ }
388
+ }
105
+ result->cacheattrs = combine_cacheattrs(hcr, cacheattrs1,
389
+}
106
+ result->cacheattrs);
390
+
107
+
391
+static const struct MemoryRegionOps imx7_src_ops = {
108
+ /*
392
+ .read = imx7_src_read,
109
+ * Check if IPA translates to secure or non-secure PA space.
393
+ .write = imx7_src_write,
110
+ * Note that VSTCR overrides VTCR and {N}SW overrides {N}SA.
394
+ .endianness = DEVICE_NATIVE_ENDIAN,
111
+ */
395
+ .valid = {
112
+ result->f.attrs.secure =
396
+ /*
113
+ (is_secure
397
+ * Our device would not work correctly if the guest was doing
114
+ && !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW))
398
+ * unaligned access. This might not be a limitation on the real
115
+ && (ipa_secure
399
+ * device but in practice there is no reason for a guest to access
116
+ || !(env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))));
400
+ * this device unaligned.
117
+
401
+ */
118
+ return 0;
402
+ .min_access_size = 4,
119
+}
403
+ .max_access_size = 4,
120
+
404
+ .unaligned = false,
121
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
405
+ },
122
target_ulong address,
406
+};
123
MMUAccessType access_type,
407
+
124
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
408
+static void imx7_src_realize(DeviceState *dev, Error **errp)
125
if (mmu_idx != s1_mmu_idx) {
409
+{
126
/*
410
+ IMX7SRCState *s = IMX7_SRC(dev);
127
* Call ourselves recursively to do the stage 1 and then stage 2
411
+
128
- * translations if mmu_idx is a two-stage regime.
412
+ memory_region_init_io(&s->iomem, OBJECT(dev), &imx7_src_ops, s,
129
+ * translations if mmu_idx is a two-stage regime, and EL2 present.
413
+ TYPE_IMX7_SRC, 0x1000);
130
+ * Otherwise, a stage1+stage2 translation is just stage 1.
414
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
131
*/
415
+}
132
+ ptw->in_mmu_idx = mmu_idx = s1_mmu_idx;
416
+
133
if (arm_feature(env, ARM_FEATURE_EL2)) {
417
+static void imx7_src_class_init(ObjectClass *klass, void *data)
134
- hwaddr ipa;
418
+{
135
- int s1_prot;
419
+ DeviceClass *dc = DEVICE_CLASS(klass);
136
- int ret;
420
+
137
- bool ipa_secure, s2walk_secure;
421
+ dc->realize = imx7_src_realize;
138
- ARMCacheAttrs cacheattrs1;
422
+ dc->reset = imx7_src_reset;
139
- bool is_el0;
423
+ dc->vmsd = &vmstate_imx7_src;
140
- uint64_t hcr;
424
+ dc->desc = "i.MX6 System Reset Controller";
141
-
425
+}
142
- ptw->in_mmu_idx = s1_mmu_idx;
426
+
143
- ret = get_phys_addr_with_struct(env, ptw, address, access_type,
427
+static const TypeInfo imx7_src_info = {
144
- result, fi);
428
+ .name = TYPE_IMX7_SRC,
145
-
429
+ .parent = TYPE_SYS_BUS_DEVICE,
146
- /* If S1 fails or S2 is disabled, return early. */
430
+ .instance_size = sizeof(IMX7SRCState),
147
- if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2,
431
+ .class_init = imx7_src_class_init,
148
- is_secure)) {
432
+};
149
- return ret;
433
+
150
- }
434
+static void imx7_src_register_types(void)
151
-
435
+{
152
- ipa = result->f.phys_addr;
436
+ type_register_static(&imx7_src_info);
153
- ipa_secure = result->f.attrs.secure;
437
+}
154
- if (is_secure) {
438
+
155
- /* Select TCR based on the NS bit from the S1 walk. */
439
+type_init(imx7_src_register_types)
156
- s2walk_secure = !(ipa_secure
440
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
157
- ? env->cp15.vstcr_el2 & VSTCR_SW
441
index XXXXXXX..XXXXXXX 100644
158
- : env->cp15.vtcr_el2 & VTCR_NSW);
442
--- a/hw/misc/meson.build
159
- } else {
443
+++ b/hw/misc/meson.build
160
- assert(!ipa_secure);
444
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_IMX', if_true: files(
161
- s2walk_secure = false;
445
'imx6_src.c',
162
- }
446
'imx6ul_ccm.c',
163
-
447
'imx7_ccm.c',
164
- ptw->in_mmu_idx =
448
+ 'imx7_src.c',
165
- s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
449
'imx7_gpr.c',
166
- ptw->in_secure = s2walk_secure;
450
'imx7_snvs.c',
167
- is_el0 = mmu_idx == ARMMMUIdx_E10_0;
451
'imx_ccm.c',
168
-
452
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
169
- /*
453
index XXXXXXX..XXXXXXX 100644
170
- * S1 is done, now do S2 translation.
454
--- a/hw/misc/trace-events
171
- * Save the stage1 results so that we may merge
455
+++ b/hw/misc/trace-events
172
- * prot and cacheattrs later.
456
@@ -XXX,XX +XXX,XX @@ ccm_clock_freq(uint32_t clock, uint32_t freq) "(Clock = %d) = %d"
173
- */
457
ccm_read_reg(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32
174
- s1_prot = result->f.prot;
458
ccm_write_reg(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32
175
- cacheattrs1 = result->cacheattrs;
459
176
- memset(result, 0, sizeof(*result));
460
+# imx7_src.c
177
-
461
+imx7_src_read(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32
178
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type,
462
+imx7_src_write(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32
179
- is_el0, result, fi);
463
+
180
- fi->s2addr = ipa;
464
# iotkit-sysinfo.c
181
-
465
iotkit_sysinfo_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysInfo read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
182
- /* Combine the S1 and S2 perms. */
466
iotkit_sysinfo_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysInfo write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
183
- result->f.prot &= s1_prot;
184
-
185
- /* If S2 fails, return early. */
186
- if (ret) {
187
- return ret;
188
- }
189
-
190
- /* Combine the S1 and S2 cache attributes. */
191
- hcr = arm_hcr_el2_eff_secstate(env, is_secure);
192
- if (hcr & HCR_DC) {
193
- /*
194
- * HCR.DC forces the first stage attributes to
195
- * Normal Non-Shareable,
196
- * Inner Write-Back Read-Allocate Write-Allocate,
197
- * Outer Write-Back Read-Allocate Write-Allocate.
198
- * Do not overwrite Tagged within attrs.
199
- */
200
- if (cacheattrs1.attrs != 0xf0) {
201
- cacheattrs1.attrs = 0xff;
202
- }
203
- cacheattrs1.shareability = 0;
204
- }
205
- result->cacheattrs = combine_cacheattrs(hcr, cacheattrs1,
206
- result->cacheattrs);
207
-
208
- /*
209
- * Check if IPA translates to secure or non-secure PA space.
210
- * Note that VSTCR overrides VTCR and {N}SW overrides {N}SA.
211
- */
212
- result->f.attrs.secure =
213
- (is_secure
214
- && !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW))
215
- && (ipa_secure
216
- || !(env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))));
217
-
218
- return 0;
219
- } else {
220
- /*
221
- * For non-EL2 CPUs a stage1+stage2 translation is just stage 1.
222
- */
223
- mmu_idx = stage_1_mmu_idx(mmu_idx);
224
+ return get_phys_addr_twostage(env, ptw, address, access_type,
225
+ result, fi);
226
}
227
}
228
229
--
467
--
230
2.25.1
468
2.34.1
diff view generated by jsdifflib
New patch
1
The architecture requires (R_TYTWB) that an attempt to return from EL3
2
when SCR_EL3.{NSE,NS} are {1,0} is an illegal exception return. (This
3
enforces that the CPU can't ever be executing below EL3 with the
4
NSE,NS bits indicating an invalid security state.)
1
5
6
We were missing this check; add it.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230807150618.101357-1-peter.maydell@linaro.org
11
---
12
target/arm/tcg/helper-a64.c | 9 +++++++++
13
1 file changed, 9 insertions(+)
14
15
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/tcg/helper-a64.c
18
+++ b/target/arm/tcg/helper-a64.c
19
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
20
spsr &= ~PSTATE_SS;
21
}
22
23
+ /*
24
+ * FEAT_RME forbids return from EL3 with an invalid security state.
25
+ * We don't need an explicit check for FEAT_RME here because we enforce
26
+ * in scr_write() that you can't set the NSE bit without it.
27
+ */
28
+ if (cur_el == 3 && (env->cp15.scr_el3 & (SCR_NS | SCR_NSE)) == SCR_NSE) {
29
+ goto illegal_return;
30
+ }
31
+
32
new_el = el_from_spsr(spsr);
33
if (new_el == -1) {
34
goto illegal_return;
35
--
36
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In the m48t59 device we almost always use 64-bit arithmetic when
2
dealing with time_t deltas. The one exception is in set_alarm(),
3
which currently uses a plain 'int' to hold the difference between two
4
time_t values. Switch to int64_t instead to avoid any possible
5
overflow issues.
2
6
3
A simple helper to retrieve the length of the current insn.
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
---
10
hw/rtc/m48t59.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
4
12
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
diff --git a/hw/rtc/m48t59.c b/hw/rtc/m48t59.c
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20221020030641.2066807-2-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate.h | 5 +++++
11
target/arm/translate-vfp.c | 2 +-
12
target/arm/translate.c | 5 ++---
13
3 files changed, 8 insertions(+), 4 deletions(-)
14
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
15
--- a/hw/rtc/m48t59.c
18
+++ b/target/arm/translate.h
16
+++ b/hw/rtc/m48t59.c
19
@@ -XXX,XX +XXX,XX @@ static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
17
@@ -XXX,XX +XXX,XX @@ static void alarm_cb (void *opaque)
20
s->insn_start = NULL;
18
21
}
19
static void set_alarm(M48t59State *NVRAM)
22
20
{
23
+static inline int curr_insn_len(DisasContext *s)
21
- int diff;
24
+{
22
+ int64_t diff;
25
+ return s->base.pc_next - s->pc_curr;
23
if (NVRAM->alrm_timer != NULL) {
26
+}
24
timer_del(NVRAM->alrm_timer);
27
+
25
diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
28
/* is_jmp field values */
29
#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
30
/* CPU state was modified dynamically; exit to main loop for interrupts. */
31
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-vfp.c
34
+++ b/target/arm/translate-vfp.c
35
@@ -XXX,XX +XXX,XX @@ static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled)
36
if (s->sme_trap_nonstreaming) {
37
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
38
syn_smetrap(SME_ET_Streaming,
39
- s->base.pc_next - s->pc_curr == 2));
40
+ curr_insn_len(s) == 2));
41
return false;
42
}
43
44
diff --git a/target/arm/translate.c b/target/arm/translate.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/translate.c
47
+++ b/target/arm/translate.c
48
@@ -XXX,XX +XXX,XX @@ static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
49
/* ISS not valid if writeback */
50
if (p && !w) {
51
ret = rd;
52
- if (s->base.pc_next - s->pc_curr == 2) {
53
+ if (curr_insn_len(s) == 2) {
54
ret |= ISSIs16Bit;
55
}
56
} else {
57
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
58
/* nothing more to generate */
59
break;
60
case DISAS_WFI:
61
- gen_helper_wfi(cpu_env,
62
- tcg_constant_i32(dc->base.pc_next - dc->pc_curr));
63
+ gen_helper_wfi(cpu_env, tcg_constant_i32(curr_insn_len(dc)));
64
/*
65
* The helper doesn't necessarily throw an exception, but we
66
* must go back to the main loop to check for interrupts anyway.
67
--
26
--
68
2.25.1
27
2.34.1
69
28
70
29
diff view generated by jsdifflib
1
Currently the microdrive code uses device_legacy_reset() to reset
1
In the twl92230 device, use int64_t for the two state fields
2
itself, and has its reset method call reset on the IDE bus as the
2
sec_offset and alm_sec, because we set these to values that
3
last thing it does. Switch to using device_cold_reset().
3
are either time_t or differences between two time_t values.
4
4
5
The only concrete microdrive device is the TYPE_DSCM1XXXX; it is not
5
These fields aren't saved in vmstate anywhere, so we can
6
command-line pluggable, so it is used only by the old pxa2xx Arm
6
safely widen them.
7
boards 'akita', 'borzoi', 'spitz', 'terrier' and 'tosa'.
8
9
You might think that this would result in the IDE bus being
10
reset automatically, but it does not, because the IDEBus type
11
does not set the BusClass::reset method. Instead the controller
12
must explicitly call ide_bus_reset(). We therefore leave that
13
call in md_reset().
14
15
Note also that because the PCMCIA card device is a direct subclass of
16
TYPE_DEVICE and we don't model the PCMCIA controller-to-card
17
interface as a qbus, PCMCIA cards are not on any qbus and so they
18
don't get reset when the system is reset. The reset only happens via
19
the dscm1xxxx_attach() and dscm1xxxx_detach() functions during
20
machine creation.
21
22
Because our aim here is merely to try to get rid of calls to the
23
device_legacy_reset() function, we leave these other dubious
24
reset-related issues alone. (They all stem from this code being
25
absolutely ancient.)
26
7
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
29
Message-id: 20221013174042.1602926-1-peter.maydell@linaro.org
30
---
10
---
31
hw/ide/microdrive.c | 8 ++++----
11
hw/rtc/twl92230.c | 4 ++--
32
1 file changed, 4 insertions(+), 4 deletions(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
33
13
34
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
14
diff --git a/hw/rtc/twl92230.c b/hw/rtc/twl92230.c
35
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/ide/microdrive.c
16
--- a/hw/rtc/twl92230.c
37
+++ b/hw/ide/microdrive.c
17
+++ b/hw/rtc/twl92230.c
38
@@ -XXX,XX +XXX,XX @@ static void md_attr_write(PCMCIACardState *card, uint32_t at, uint8_t value)
18
@@ -XXX,XX +XXX,XX @@ struct MenelausState {
39
case 0x00:    /* Configuration Option Register */
19
struct tm tm;
40
s->opt = value & 0xcf;
20
struct tm new;
41
if (value & OPT_SRESET) {
21
struct tm alm;
42
- device_legacy_reset(DEVICE(s));
22
- int sec_offset;
43
+ device_cold_reset(DEVICE(s));
23
- int alm_sec;
44
}
24
+ int64_t sec_offset;
45
md_interrupt_update(s);
25
+ int64_t alm_sec;
46
break;
26
int next_comp;
47
@@ -XXX,XX +XXX,XX @@ static void md_common_write(PCMCIACardState *card, uint32_t at, uint16_t value)
27
} rtc;
48
case 0xe:    /* Device Control */
28
uint16_t rtc_next_vmstate;
49
s->ctrl = value;
50
if (value & CTRL_SRST) {
51
- device_legacy_reset(DEVICE(s));
52
+ device_cold_reset(DEVICE(s));
53
}
54
md_interrupt_update(s);
55
break;
56
@@ -XXX,XX +XXX,XX @@ static int dscm1xxxx_attach(PCMCIACardState *card)
57
md->attr_base = pcc->cis[0x74] | (pcc->cis[0x76] << 8);
58
md->io_base = 0x0;
59
60
- device_legacy_reset(DEVICE(md));
61
+ device_cold_reset(DEVICE(md));
62
md_interrupt_update(md);
63
64
return 0;
65
@@ -XXX,XX +XXX,XX @@ static int dscm1xxxx_detach(PCMCIACardState *card)
66
{
67
MicroDriveState *md = MICRODRIVE(card);
68
69
- device_legacy_reset(DEVICE(md));
70
+ device_cold_reset(DEVICE(md));
71
return 0;
72
}
73
74
--
29
--
75
2.25.1
30
2.34.1
76
31
77
32
diff view generated by jsdifflib
New patch
1
In the aspeed_rtc device we store a difference between two time_t
2
values in an 'int'. This is not really correct when time_t could
3
be 64 bits. Enlarge the field to 'int64_t'.
1
4
5
This is a migration compatibility break for the aspeed boards.
6
While we are changing the vmstate, remove the accidental
7
duplicate of the offset field.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Cédric Le Goater <clg@kaod.org>
11
---
12
include/hw/rtc/aspeed_rtc.h | 2 +-
13
hw/rtc/aspeed_rtc.c | 5 ++---
14
2 files changed, 3 insertions(+), 4 deletions(-)
15
16
diff --git a/include/hw/rtc/aspeed_rtc.h b/include/hw/rtc/aspeed_rtc.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/rtc/aspeed_rtc.h
19
+++ b/include/hw/rtc/aspeed_rtc.h
20
@@ -XXX,XX +XXX,XX @@ struct AspeedRtcState {
21
qemu_irq irq;
22
23
uint32_t reg[0x18];
24
- int offset;
25
+ int64_t offset;
26
27
};
28
29
diff --git a/hw/rtc/aspeed_rtc.c b/hw/rtc/aspeed_rtc.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/rtc/aspeed_rtc.c
32
+++ b/hw/rtc/aspeed_rtc.c
33
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_rtc_ops = {
34
35
static const VMStateDescription vmstate_aspeed_rtc = {
36
.name = TYPE_ASPEED_RTC,
37
- .version_id = 1,
38
+ .version_id = 2,
39
.fields = (VMStateField[]) {
40
VMSTATE_UINT32_ARRAY(reg, AspeedRtcState, 0x18),
41
- VMSTATE_INT32(offset, AspeedRtcState),
42
- VMSTATE_INT32(offset, AspeedRtcState),
43
+ VMSTATE_INT64(offset, AspeedRtcState),
44
VMSTATE_END_OF_LIST()
45
}
46
};
47
--
48
2.34.1
49
50
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The functions qemu_get_timedate() and qemu_timedate_diff() take
2
and return a time offset as an integer. Coverity points out that
3
means that when an RTC device implementation holds an offset
4
as a time_t, as the m48t59 does, the time_t will get truncated.
5
(CID 1507157, 1517772).
2
6
3
In preparation for TARGET_TB_PCREL, reduce reliance on absolute values.
7
The functions work with time_t internally, so make them use that type
8
in their APIs.
4
9
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Note that this won't help any Y2038 issues where either the device
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
model itself is keeping the offset in a 32-bit integer, or where the
7
Message-id: 20221020030641.2066807-7-richard.henderson@linaro.org
12
hardware under emulation has Y2038 or other rollover problems. If we
13
missed any cases of the former then hopefully Coverity will warn us
14
about them since after this patch we'd be truncating a time_t in
15
assignments from qemu_timedate_diff().)
16
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
---
19
---
10
target/arm/translate.c | 37 +++++++++++++++++++++----------------
20
include/sysemu/rtc.h | 4 ++--
11
1 file changed, 21 insertions(+), 16 deletions(-)
21
softmmu/rtc.c | 4 ++--
22
2 files changed, 4 insertions(+), 4 deletions(-)
12
23
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
24
diff --git a/include/sysemu/rtc.h b/include/sysemu/rtc.h
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
26
--- a/include/sysemu/rtc.h
16
+++ b/target/arm/translate.c
27
+++ b/include/sysemu/rtc.h
17
@@ -XXX,XX +XXX,XX @@ static uint32_t read_pc(DisasContext *s)
28
@@ -XXX,XX +XXX,XX @@
18
return s->pc_curr + (s->thumb ? 4 : 8);
29
* The behaviour of the clock whose value this function returns will
30
* depend on the -rtc command line option passed by the user.
31
*/
32
-void qemu_get_timedate(struct tm *tm, int offset);
33
+void qemu_get_timedate(struct tm *tm, time_t offset);
34
35
/**
36
* qemu_timedate_diff: Return difference between a struct tm and the RTC
37
@@ -XXX,XX +XXX,XX @@ void qemu_get_timedate(struct tm *tm, int offset);
38
* a timestamp one hour further ahead than the current RTC time
39
* then this function will return 3600.
40
*/
41
-int qemu_timedate_diff(struct tm *tm);
42
+time_t qemu_timedate_diff(struct tm *tm);
43
44
#endif
45
diff --git a/softmmu/rtc.c b/softmmu/rtc.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/softmmu/rtc.c
48
+++ b/softmmu/rtc.c
49
@@ -XXX,XX +XXX,XX @@ static time_t qemu_ref_timedate(QEMUClockType clock)
50
return value;
19
}
51
}
20
52
21
+/* The pc_curr difference for an architectural jump. */
53
-void qemu_get_timedate(struct tm *tm, int offset)
22
+static target_long jmp_diff(DisasContext *s, target_long diff)
54
+void qemu_get_timedate(struct tm *tm, time_t offset)
23
+{
24
+ return diff + (s->thumb ? 4 : 8);
25
+}
26
+
27
/* Set a variable to the value of a CPU register. */
28
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
29
{
55
{
30
@@ -XXX,XX +XXX,XX @@ static void gen_goto_ptr(void)
56
time_t ti = qemu_ref_timedate(rtc_clock);
31
* cpu_loop_exec. Any live exit_requests will be processed as we
57
32
* enter the next TB.
58
@@ -XXX,XX +XXX,XX @@ void qemu_get_timedate(struct tm *tm, int offset)
33
*/
34
-static void gen_goto_tb(DisasContext *s, int n, int diff)
35
+static void gen_goto_tb(DisasContext *s, int n, target_long diff)
36
{
37
target_ulong dest = s->pc_curr + diff;
38
39
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *s, int n, int diff)
40
}
41
42
/* Jump, specifying which TB number to use if we gen_goto_tb() */
43
-static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
44
+static void gen_jmp_tb(DisasContext *s, target_long diff, int tbno)
45
{
46
- int diff = dest - s->pc_curr;
47
-
48
if (unlikely(s->ss_active)) {
49
/* An indirect jump so that we still trigger the debug exception. */
50
gen_update_pc(s, diff);
51
@@ -XXX,XX +XXX,XX @@ static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
52
}
59
}
53
}
60
}
54
61
55
-static inline void gen_jmp(DisasContext *s, uint32_t dest)
62
-int qemu_timedate_diff(struct tm *tm)
56
+static inline void gen_jmp(DisasContext *s, target_long diff)
63
+time_t qemu_timedate_diff(struct tm *tm)
57
{
64
{
58
- gen_jmp_tb(s, dest, 0);
65
time_t seconds;
59
+ gen_jmp_tb(s, diff, 0);
60
}
61
62
static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
63
@@ -XXX,XX +XXX,XX @@ static bool trans_CLRM(DisasContext *s, arg_CLRM *a)
64
65
static bool trans_B(DisasContext *s, arg_i *a)
66
{
67
- gen_jmp(s, read_pc(s) + a->imm);
68
+ gen_jmp(s, jmp_diff(s, a->imm));
69
return true;
70
}
71
72
@@ -XXX,XX +XXX,XX @@ static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
73
return true;
74
}
75
arm_skip_unless(s, a->cond);
76
- gen_jmp(s, read_pc(s) + a->imm);
77
+ gen_jmp(s, jmp_diff(s, a->imm));
78
return true;
79
}
80
81
static bool trans_BL(DisasContext *s, arg_i *a)
82
{
83
tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
84
- gen_jmp(s, read_pc(s) + a->imm);
85
+ gen_jmp(s, jmp_diff(s, a->imm));
86
return true;
87
}
88
89
@@ -XXX,XX +XXX,XX @@ static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
90
}
91
tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
92
store_cpu_field_constant(!s->thumb, thumb);
93
- gen_jmp(s, (read_pc(s) & ~3) + a->imm);
94
+ /* This jump is computed from an aligned PC: subtract off the low bits. */
95
+ gen_jmp(s, jmp_diff(s, a->imm - (s->pc_curr & 3)));
96
return true;
97
}
98
99
@@ -XXX,XX +XXX,XX @@ static bool trans_WLS(DisasContext *s, arg_WLS *a)
100
* when we take this upcoming exit from this TB, so gen_jmp_tb() is OK.
101
*/
102
}
103
- gen_jmp_tb(s, s->base.pc_next, 1);
104
+ gen_jmp_tb(s, curr_insn_len(s), 1);
105
106
gen_set_label(nextlabel);
107
- gen_jmp(s, read_pc(s) + a->imm);
108
+ gen_jmp(s, jmp_diff(s, a->imm));
109
return true;
110
}
111
112
@@ -XXX,XX +XXX,XX @@ static bool trans_LE(DisasContext *s, arg_LE *a)
113
114
if (a->f) {
115
/* Loop-forever: just jump back to the loop start */
116
- gen_jmp(s, read_pc(s) - a->imm);
117
+ gen_jmp(s, jmp_diff(s, -a->imm));
118
return true;
119
}
120
121
@@ -XXX,XX +XXX,XX @@ static bool trans_LE(DisasContext *s, arg_LE *a)
122
tcg_temp_free_i32(decr);
123
}
124
/* Jump back to the loop start */
125
- gen_jmp(s, read_pc(s) - a->imm);
126
+ gen_jmp(s, jmp_diff(s, -a->imm));
127
128
gen_set_label(loopend);
129
if (a->tp) {
130
@@ -XXX,XX +XXX,XX @@ static bool trans_LE(DisasContext *s, arg_LE *a)
131
store_cpu_field(tcg_constant_i32(4), v7m.ltpsize);
132
}
133
/* End TB, continuing to following insn */
134
- gen_jmp_tb(s, s->base.pc_next, 1);
135
+ gen_jmp_tb(s, curr_insn_len(s), 1);
136
return true;
137
}
138
139
@@ -XXX,XX +XXX,XX @@ static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
140
tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
141
tmp, 0, s->condlabel);
142
tcg_temp_free_i32(tmp);
143
- gen_jmp(s, read_pc(s) + a->imm);
144
+ gen_jmp(s, jmp_diff(s, a->imm));
145
return true;
146
}
147
66
148
--
67
--
149
2.25.1
68
2.34.1
69
70
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Where architecturally one ARM_FEATURE_X flag implies another
2
2
ARM_FEATURE_Y, we allow the CPU init function to only set X, and then
3
Before using softmmu page tables for the ptw, plumb down
3
set Y for it. Currently we do this in two places -- we set a few
4
a debug parameter so that we can query page table entries
4
flags in arm_cpu_post_init() because we need them to decide which
5
from gdbstub without modifying cpu state.
5
properties to create on the CPU object, and then we do the rest in
6
6
arm_cpu_realizefn(). However, this is fragile, because it's easy to
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
add a new property and not notice that this means that an X-implies-Y
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
check now has to move from realize to post-init.
9
Message-id: 20221011031911.2408754-9-richard.henderson@linaro.org
9
10
As a specific example, the pmsav7-dregion property is conditional
11
on ARM_FEATURE_PMSA && ARM_FEATURE_V7, which means it won't appear
12
on the Cortex-M33 and -M55, because they set ARM_FEATURE_V8 and
13
rely on V8-implies-V7, which doesn't happen until the realizefn.
14
15
Move all of these X-implies-Y checks into a new function, which
16
we call at the top of arm_cpu_post_init(), so the feature bits
17
are available at that point.
18
19
This does now give us the reverse issue, that if there's a feature
20
bit which is enabled or disabled by the setting of a property then
21
then X-implies-Y features that are dependent on that property need to
22
be in realize, not in this new function. But the only one of those
23
is the "EL3 implies VBAR" which is already in the right place, so
24
putting things this way round seems better to me.
25
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
28
Message-id: 20230724174335.2150499-2-peter.maydell@linaro.org
11
---
29
---
12
target/arm/ptw.c | 55 ++++++++++++++++++++++++++++++++----------------
30
target/arm/cpu.c | 179 +++++++++++++++++++++++++----------------------
13
1 file changed, 37 insertions(+), 18 deletions(-)
31
1 file changed, 97 insertions(+), 82 deletions(-)
14
32
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
33
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/ptw.c
35
--- a/target/arm/cpu.c
18
+++ b/target/arm/ptw.c
36
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ unsigned int gt_cntfrq_period_ns(ARMCPU *cpu)
20
typedef struct S1Translate {
38
NANOSECONDS_PER_SECOND / cpu->gt_cntfrq_hz : 1;
21
ARMMMUIdx in_mmu_idx;
22
bool in_secure;
23
+ bool in_debug;
24
bool out_secure;
25
hwaddr out_phys;
26
} S1Translate;
27
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
28
S1Translate s2ptw = {
29
.in_mmu_idx = s2_mmu_idx,
30
.in_secure = is_secure,
31
+ .in_debug = ptw->in_debug,
32
};
33
uint64_t hcr;
34
int ret;
35
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
36
return 0;
37
}
39
}
38
40
39
-bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
41
+static void arm_cpu_propagate_feature_implications(ARMCPU *cpu)
40
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
42
+{
41
- bool is_secure, GetPhysAddrResult *result,
43
+ CPUARMState *env = &cpu->env;
42
- ARMMMUFaultInfo *fi)
44
+ bool no_aa32 = false;
43
+static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
45
+
44
+ target_ulong address,
46
+ /*
45
+ MMUAccessType access_type,
47
+ * Some features automatically imply others: set the feature
46
+ GetPhysAddrResult *result,
48
+ * bits explicitly for these cases.
47
+ ARMMMUFaultInfo *fi)
49
+ */
50
+
51
+ if (arm_feature(env, ARM_FEATURE_M)) {
52
+ set_feature(env, ARM_FEATURE_PMSA);
53
+ }
54
+
55
+ if (arm_feature(env, ARM_FEATURE_V8)) {
56
+ if (arm_feature(env, ARM_FEATURE_M)) {
57
+ set_feature(env, ARM_FEATURE_V7);
58
+ } else {
59
+ set_feature(env, ARM_FEATURE_V7VE);
60
+ }
61
+ }
62
+
63
+ /*
64
+ * There exist AArch64 cpus without AArch32 support. When KVM
65
+ * queries ID_ISAR0_EL1 on such a host, the value is UNKNOWN.
66
+ * Similarly, we cannot check ID_AA64PFR0 without AArch64 support.
67
+ * As a general principle, we also do not make ID register
68
+ * consistency checks anywhere unless using TCG, because only
69
+ * for TCG would a consistency-check failure be a QEMU bug.
70
+ */
71
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
72
+ no_aa32 = !cpu_isar_feature(aa64_aa32, cpu);
73
+ }
74
+
75
+ if (arm_feature(env, ARM_FEATURE_V7VE)) {
76
+ /*
77
+ * v7 Virtualization Extensions. In real hardware this implies
78
+ * EL2 and also the presence of the Security Extensions.
79
+ * For QEMU, for backwards-compatibility we implement some
80
+ * CPUs or CPU configs which have no actual EL2 or EL3 but do
81
+ * include the various other features that V7VE implies.
82
+ * Presence of EL2 itself is ARM_FEATURE_EL2, and of the
83
+ * Security Extensions is ARM_FEATURE_EL3.
84
+ */
85
+ assert(!tcg_enabled() || no_aa32 ||
86
+ cpu_isar_feature(aa32_arm_div, cpu));
87
+ set_feature(env, ARM_FEATURE_LPAE);
88
+ set_feature(env, ARM_FEATURE_V7);
89
+ }
90
+ if (arm_feature(env, ARM_FEATURE_V7)) {
91
+ set_feature(env, ARM_FEATURE_VAPA);
92
+ set_feature(env, ARM_FEATURE_THUMB2);
93
+ set_feature(env, ARM_FEATURE_MPIDR);
94
+ if (!arm_feature(env, ARM_FEATURE_M)) {
95
+ set_feature(env, ARM_FEATURE_V6K);
96
+ } else {
97
+ set_feature(env, ARM_FEATURE_V6);
98
+ }
99
+
100
+ /*
101
+ * Always define VBAR for V7 CPUs even if it doesn't exist in
102
+ * non-EL3 configs. This is needed by some legacy boards.
103
+ */
104
+ set_feature(env, ARM_FEATURE_VBAR);
105
+ }
106
+ if (arm_feature(env, ARM_FEATURE_V6K)) {
107
+ set_feature(env, ARM_FEATURE_V6);
108
+ set_feature(env, ARM_FEATURE_MVFR);
109
+ }
110
+ if (arm_feature(env, ARM_FEATURE_V6)) {
111
+ set_feature(env, ARM_FEATURE_V5);
112
+ if (!arm_feature(env, ARM_FEATURE_M)) {
113
+ assert(!tcg_enabled() || no_aa32 ||
114
+ cpu_isar_feature(aa32_jazelle, cpu));
115
+ set_feature(env, ARM_FEATURE_AUXCR);
116
+ }
117
+ }
118
+ if (arm_feature(env, ARM_FEATURE_V5)) {
119
+ set_feature(env, ARM_FEATURE_V4T);
120
+ }
121
+ if (arm_feature(env, ARM_FEATURE_LPAE)) {
122
+ set_feature(env, ARM_FEATURE_V7MP);
123
+ }
124
+ if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
125
+ set_feature(env, ARM_FEATURE_CBAR);
126
+ }
127
+ if (arm_feature(env, ARM_FEATURE_THUMB2) &&
128
+ !arm_feature(env, ARM_FEATURE_M)) {
129
+ set_feature(env, ARM_FEATURE_THUMB_DSP);
130
+ }
131
+}
132
+
133
void arm_cpu_post_init(Object *obj)
48
{
134
{
49
+ ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
135
ARMCPU *cpu = ARM_CPU(obj);
50
ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
136
51
- S1Translate ptw;
137
- /* M profile implies PMSA. We have to do this here rather than
52
+ bool is_secure = ptw->in_secure;
138
- * in realize with the other feature-implication checks because
53
139
- * we look at the PMSA bit to see if we should add some properties.
54
if (mmu_idx != s1_mmu_idx) {
140
+ /*
55
/*
141
+ * Some features imply others. Figure this out now, because we
56
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
142
+ * are going to look at the feature bits in deciding which
57
bool is_el0;
143
+ * properties to add.
58
uint64_t hcr;
144
*/
59
145
- if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
60
- ret = get_phys_addr_with_secure(env, address, access_type,
146
- set_feature(&cpu->env, ARM_FEATURE_PMSA);
61
- s1_mmu_idx, is_secure, result, fi);
147
- }
62
+ ptw->in_mmu_idx = s1_mmu_idx;
148
+ arm_cpu_propagate_feature_implications(cpu);
63
+ ret = get_phys_addr_with_struct(env, ptw, address, access_type,
149
64
+ result, fi);
150
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
65
151
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
66
/* If S1 fails or S2 is disabled, return early. */
152
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
67
if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2,
153
CPUARMState *env = &cpu->env;
68
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
154
int pagebits;
69
s2walk_secure = false;
155
Error *local_err = NULL;
70
}
156
- bool no_aa32 = false;
71
157
72
- ptw.in_mmu_idx =
158
/* Use pc-relative instructions in system-mode */
73
+ ptw->in_mmu_idx =
159
#ifndef CONFIG_USER_ONLY
74
s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
160
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
75
- ptw.in_secure = s2walk_secure;
161
cpu->isar.id_isar3 = u;
76
+ ptw->in_secure = s2walk_secure;
77
is_el0 = mmu_idx == ARMMMUIdx_E10_0;
78
79
/*
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
81
cacheattrs1 = result->cacheattrs;
82
memset(result, 0, sizeof(*result));
83
84
- ret = get_phys_addr_lpae(env, &ptw, ipa, access_type,
85
+ ret = get_phys_addr_lpae(env, ptw, ipa, access_type,
86
is_el0, result, fi);
87
fi->s2addr = ipa;
88
89
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
90
is_secure, result, fi);
91
}
162
}
92
163
93
- ptw.in_mmu_idx = mmu_idx;
164
- /* Some features automatically imply others: */
94
- ptw.in_secure = is_secure;
165
- if (arm_feature(env, ARM_FEATURE_V8)) {
166
- if (arm_feature(env, ARM_FEATURE_M)) {
167
- set_feature(env, ARM_FEATURE_V7);
168
- } else {
169
- set_feature(env, ARM_FEATURE_V7VE);
170
- }
171
- }
95
-
172
-
96
if (regime_using_lpae_format(env, mmu_idx)) {
173
- /*
97
- return get_phys_addr_lpae(env, &ptw, address, access_type, false,
174
- * There exist AArch64 cpus without AArch32 support. When KVM
98
+ return get_phys_addr_lpae(env, ptw, address, access_type, false,
175
- * queries ID_ISAR0_EL1 on such a host, the value is UNKNOWN.
99
result, fi);
176
- * Similarly, we cannot check ID_AA64PFR0 without AArch64 support.
100
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
177
- * As a general principle, we also do not make ID register
101
- return get_phys_addr_v6(env, &ptw, address, access_type, result, fi);
178
- * consistency checks anywhere unless using TCG, because only
102
+ return get_phys_addr_v6(env, ptw, address, access_type, result, fi);
179
- * for TCG would a consistency-check failure be a QEMU bug.
103
} else {
180
- */
104
- return get_phys_addr_v5(env, &ptw, address, access_type, result, fi);
181
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
105
+ return get_phys_addr_v5(env, ptw, address, access_type, result, fi);
182
- no_aa32 = !cpu_isar_feature(aa64_aa32, cpu);
106
}
183
- }
107
}
184
-
108
185
- if (arm_feature(env, ARM_FEATURE_V7VE)) {
109
+bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
186
- /* v7 Virtualization Extensions. In real hardware this implies
110
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
187
- * EL2 and also the presence of the Security Extensions.
111
+ bool is_secure, GetPhysAddrResult *result,
188
- * For QEMU, for backwards-compatibility we implement some
112
+ ARMMMUFaultInfo *fi)
189
- * CPUs or CPU configs which have no actual EL2 or EL3 but do
113
+{
190
- * include the various other features that V7VE implies.
114
+ S1Translate ptw = {
191
- * Presence of EL2 itself is ARM_FEATURE_EL2, and of the
115
+ .in_mmu_idx = mmu_idx,
192
- * Security Extensions is ARM_FEATURE_EL3.
116
+ .in_secure = is_secure,
193
- */
117
+ };
194
- assert(!tcg_enabled() || no_aa32 ||
118
+ return get_phys_addr_with_struct(env, &ptw, address, access_type,
195
- cpu_isar_feature(aa32_arm_div, cpu));
119
+ result, fi);
196
- set_feature(env, ARM_FEATURE_LPAE);
120
+}
197
- set_feature(env, ARM_FEATURE_V7);
121
+
198
- }
122
bool get_phys_addr(CPUARMState *env, target_ulong address,
199
- if (arm_feature(env, ARM_FEATURE_V7)) {
123
MMUAccessType access_type, ARMMMUIdx mmu_idx,
200
- set_feature(env, ARM_FEATURE_VAPA);
124
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
201
- set_feature(env, ARM_FEATURE_THUMB2);
125
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
202
- set_feature(env, ARM_FEATURE_MPIDR);
126
{
203
- if (!arm_feature(env, ARM_FEATURE_M)) {
127
ARMCPU *cpu = ARM_CPU(cs);
204
- set_feature(env, ARM_FEATURE_V6K);
128
CPUARMState *env = &cpu->env;
205
- } else {
129
+ S1Translate ptw = {
206
- set_feature(env, ARM_FEATURE_V6);
130
+ .in_mmu_idx = arm_mmu_idx(env),
207
- }
131
+ .in_secure = arm_is_secure(env),
208
-
132
+ .in_debug = true,
209
- /* Always define VBAR for V7 CPUs even if it doesn't exist in
133
+ };
210
- * non-EL3 configs. This is needed by some legacy boards.
134
GetPhysAddrResult res = {};
211
- */
135
ARMMMUFaultInfo fi = {};
212
- set_feature(env, ARM_FEATURE_VBAR);
136
- ARMMMUIdx mmu_idx = arm_mmu_idx(env);
213
- }
137
bool ret;
214
- if (arm_feature(env, ARM_FEATURE_V6K)) {
138
215
- set_feature(env, ARM_FEATURE_V6);
139
- ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &res, &fi);
216
- set_feature(env, ARM_FEATURE_MVFR);
140
+ ret = get_phys_addr_with_struct(env, &ptw, addr, MMU_DATA_LOAD, &res, &fi);
217
- }
141
*attrs = res.f.attrs;
218
- if (arm_feature(env, ARM_FEATURE_V6)) {
142
219
- set_feature(env, ARM_FEATURE_V5);
143
if (ret) {
220
- if (!arm_feature(env, ARM_FEATURE_M)) {
221
- assert(!tcg_enabled() || no_aa32 ||
222
- cpu_isar_feature(aa32_jazelle, cpu));
223
- set_feature(env, ARM_FEATURE_AUXCR);
224
- }
225
- }
226
- if (arm_feature(env, ARM_FEATURE_V5)) {
227
- set_feature(env, ARM_FEATURE_V4T);
228
- }
229
- if (arm_feature(env, ARM_FEATURE_LPAE)) {
230
- set_feature(env, ARM_FEATURE_V7MP);
231
- }
232
- if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
233
- set_feature(env, ARM_FEATURE_CBAR);
234
- }
235
- if (arm_feature(env, ARM_FEATURE_THUMB2) &&
236
- !arm_feature(env, ARM_FEATURE_M)) {
237
- set_feature(env, ARM_FEATURE_THUMB_DSP);
238
- }
239
240
/*
241
* We rely on no XScale CPU having VFP so we can use the same bits in the
144
--
242
--
145
2.25.1
243
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
M-profile CPUs generally allow configuration of the number of MPU
2
regions that they have. We don't currently model this, so our
3
implementations of some of the board models provide CPUs with the
4
wrong number of regions. RTOSes like Zephyr that hardcode the
5
expected number of regions may therefore not run on the model if they
6
are set up to run on real hardware.
2
7
3
In preparation for TARGET_TB_PCREL, reduce reliance on absolute values.
8
Add properties mpu-ns-regions and mpu-s-regions to the ARMV7M object,
4
Since we always pass dc->pc_curr, fold the arithmetic to zero displacement.
9
matching the ability of hardware to configure the number of Secure
10
and NonSecure regions separately. Our actual CPU implementation
11
doesn't currently support that, and it happens that none of the MPS
12
boards we model set the number of regions differently for Secure vs
13
NonSecure, so we provide an interface to the boards and SoCs that
14
won't need to change if we ever do add that functionality in future,
15
but make it an error to configure the two properties to different
16
values.
5
17
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
(The property name on the CPU is the somewhat misnamed-for-M-profile
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
"pmsav7-dregion", so we don't follow that naming convention for
8
Message-id: 20221020030641.2066807-6-richard.henderson@linaro.org
20
the properties here. The TRM doesn't say what the CPU configuration
21
variable names are, so we pick something, and follow the lowercase
22
convention we already have for properties here.)
23
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
26
Message-id: 20230724174335.2150499-3-peter.maydell@linaro.org
10
---
27
---
11
target/arm/translate-a64.c | 6 +++---
28
include/hw/arm/armv7m.h | 8 ++++++++
12
target/arm/translate.c | 10 +++++-----
29
hw/arm/armv7m.c | 21 +++++++++++++++++++++
13
2 files changed, 8 insertions(+), 8 deletions(-)
30
2 files changed, 29 insertions(+)
14
31
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
32
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
16
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
34
--- a/include/hw/arm/armv7m.h
18
+++ b/target/arm/translate-a64.c
35
+++ b/include/hw/arm/armv7m.h
19
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
36
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M)
20
gen_helper_exception_internal(cpu_env, tcg_constant_i32(excp));
37
* + Property "vfp": enable VFP (forwarded to CPU object)
21
}
38
* + Property "dsp": enable DSP (forwarded to CPU object)
22
39
* + Property "enable-bitband": expose bitbanded IO
23
-static void gen_exception_internal_insn(DisasContext *s, uint64_t pc, int excp)
40
+ * + Property "mpu-ns-regions": number of Non-Secure MPU regions (forwarded
24
+static void gen_exception_internal_insn(DisasContext *s, int excp)
41
+ * to CPU object pmsav7-dregion property; default is whatever the default
25
{
42
+ * for the CPU is)
26
- gen_a64_update_pc(s, pc - s->pc_curr);
43
+ * + Property "mpu-s-regions": number of Secure MPU regions (default is
27
+ gen_a64_update_pc(s, 0);
44
+ * whatever the default for the CPU is; must currently be set to the same
28
gen_exception_internal(excp);
45
+ * value as mpu-ns-regions if the CPU implements the Security Extension)
29
s->base.is_jmp = DISAS_NORETURN;
46
* + Clock input "refclk" is the external reference clock for the systick timers
30
}
47
* + Clock input "cpuclk" is the main CPU clock
31
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
48
*/
32
* Secondly, "HLT 0xf000" is the A64 semihosting syscall instruction.
49
@@ -XXX,XX +XXX,XX @@ struct ARMv7MState {
33
*/
50
Object *idau;
34
if (semihosting_enabled(s->current_el == 0) && imm16 == 0xf000) {
51
uint32_t init_svtor;
35
- gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
52
uint32_t init_nsvtor;
36
+ gen_exception_internal_insn(s, EXCP_SEMIHOST);
53
+ uint32_t mpu_ns_regions;
37
} else {
54
+ uint32_t mpu_s_regions;
38
unallocated_encoding(s);
55
bool enable_bitband;
56
bool start_powered_off;
57
bool vfp;
58
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/armv7m.c
61
+++ b/hw/arm/armv7m.c
62
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
39
}
63
}
40
diff --git a/target/arm/translate.c b/target/arm/translate.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate.c
43
+++ b/target/arm/translate.c
44
@@ -XXX,XX +XXX,XX @@ static inline void gen_smc(DisasContext *s)
45
s->base.is_jmp = DISAS_SMC;
46
}
47
48
-static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
49
+static void gen_exception_internal_insn(DisasContext *s, int excp)
50
{
51
gen_set_condexec(s);
52
- gen_update_pc(s, pc - s->pc_curr);
53
+ gen_update_pc(s, 0);
54
gen_exception_internal(excp);
55
s->base.is_jmp = DISAS_NORETURN;
56
}
57
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
58
*/
59
if (semihosting_enabled(s->current_el != 0) &&
60
(imm == (s->thumb ? 0x3c : 0xf000))) {
61
- gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
62
+ gen_exception_internal_insn(s, EXCP_SEMIHOST);
63
return;
64
}
64
}
65
65
66
@@ -XXX,XX +XXX,XX @@ static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
66
+ /*
67
if (arm_dc_feature(s, ARM_FEATURE_M) &&
67
+ * Real M-profile hardware can be configured with a different number of
68
semihosting_enabled(s->current_el == 0) &&
68
+ * MPU regions for Secure vs NonSecure. QEMU's CPU implementation doesn't
69
(a->imm == 0xab)) {
69
+ * support that yet, so catch attempts to select that.
70
- gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
70
+ */
71
+ gen_exception_internal_insn(s, EXCP_SEMIHOST);
71
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
72
} else {
72
+ s->mpu_ns_regions != s->mpu_s_regions) {
73
gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
73
+ error_setg(errp,
74
}
74
+ "mpu-ns-regions and mpu-s-regions properties must have the same value");
75
@@ -XXX,XX +XXX,XX @@ static bool trans_SVC(DisasContext *s, arg_SVC *a)
75
+ return;
76
if (!arm_dc_feature(s, ARM_FEATURE_M) &&
76
+ }
77
semihosting_enabled(s->current_el == 0) &&
77
+ if (s->mpu_ns_regions != UINT_MAX &&
78
(a->imm == semihost_imm)) {
78
+ object_property_find(OBJECT(s->cpu), "pmsav7-dregion")) {
79
- gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
79
+ if (!object_property_set_uint(OBJECT(s->cpu), "pmsav7-dregion",
80
+ gen_exception_internal_insn(s, EXCP_SEMIHOST);
80
+ s->mpu_ns_regions, errp)) {
81
} else {
81
+ return;
82
gen_update_pc(s, curr_insn_len(s));
82
+ }
83
s->svc_imm = a->imm;
83
+ }
84
+
85
/*
86
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
87
* have one. Similarly, tell the NVIC where its CPU is.
88
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
89
false),
90
DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
91
DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
92
+ DEFINE_PROP_UINT32("mpu-ns-regions", ARMv7MState, mpu_ns_regions, UINT_MAX),
93
+ DEFINE_PROP_UINT32("mpu-s-regions", ARMv7MState, mpu_s_regions, UINT_MAX),
94
DEFINE_PROP_END_OF_LIST(),
95
};
96
84
--
97
--
85
2.25.1
98
2.34.1
86
99
87
100
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The IoTKit, SSE200 and SSE300 all default to 8 MPU regions. The
2
2
MPS2/MPS3 FPGA images don't override these except in the case of
3
Add a field to TARGET_PAGE_ENTRY_EXTRA to hold the guarded bit.
3
AN547, which uses 16 MPU regions.
4
In is_guarded_page, use probe_access_full instead of just guessing
4
5
that the tlb entry is still present. Also handles the FIXME about
5
Define properties on the ARMSSE object for the MPU regions (using the
6
executing from device memory.
6
same names as the documented RTL configuration settings, and
7
7
following the pattern we already have for this device of using
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
all-caps names as the RTL does), and set them in the board code.
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
10
Message-id: 20221011031911.2408754-4-richard.henderson@linaro.org
10
We don't actually need to override the default except on AN547,
11
but it's simpler code to have the board code set them always
12
rather than tracking which board subtypes want to set them to
13
a non-default value separately from what that value is.
14
15
Tho overall effect is that for mps2-an505, mps2-an521 and mps3-an524
16
we now correctly use 8 MPU regions, while mps3-an547 stays at its
17
current 16 regions.
18
19
It's possible some guest code wrongly depended on the previous
20
incorrectly modeled number of memory regions. (Such guest code
21
should ideally check the number of regions via the MPU_TYPE
22
register.) The old behaviour can be obtained with additional
23
-global arguments to QEMU:
24
25
For mps2-an521 and mps2-an524:
26
-global sse-200.CPU0_MPU_NS=16 -global sse-200.CPU0_MPU_S=16 -global sse-200.CPU1_MPU_NS=16 -global sse-200.CPU1_MPU_S=16
27
28
For mps2-an505:
29
-global sse-200.CPU0_MPU_NS=16 -global sse-200.CPU0_MPU_S=16
30
31
NB that the way the implementation allows this use of -global
32
is slightly fragile: if the board code explicitly sets the
33
properties on the sse-200 object, this overrides the -global
34
command line option. So we rely on:
35
- the boards that need fixing all happen to use the SSE defaults
36
- we can write the board code to only set the property if it
37
is different from the default, rather than having all boards
38
explicitly set the property
39
- the board that does need to use a non-default value happens
40
to need to set it to the same value (16) we previously used
41
This works, but there are some kinds of refactoring of the
42
mps2-tz.c code that would break the support for -global here.
43
44
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1772
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
46
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
47
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
48
Message-id: 20230724174335.2150499-4-peter.maydell@linaro.org
12
---
49
---
13
target/arm/cpu-param.h | 9 +++++----
50
include/hw/arm/armsse.h | 5 +++++
14
target/arm/cpu.h | 13 -------------
51
hw/arm/armsse.c | 16 ++++++++++++++++
15
target/arm/internals.h | 1 +
52
hw/arm/mps2-tz.c | 29 +++++++++++++++++++++++++++++
16
target/arm/ptw.c | 7 ++++---
53
3 files changed, 50 insertions(+)
17
target/arm/translate-a64.c | 21 ++++++++++-----------
54
18
5 files changed, 20 insertions(+), 31 deletions(-)
55
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
19
20
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
21
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu-param.h
57
--- a/include/hw/arm/armsse.h
23
+++ b/target/arm/cpu-param.h
58
+++ b/include/hw/arm/armsse.h
24
@@ -XXX,XX +XXX,XX @@
59
@@ -XXX,XX +XXX,XX @@
25
*
60
* (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an
26
* For ARMMMUIdx_Stage2*, pte_attrs is the S2 descriptor bits [5:2].
61
* SSE-200 both are present; CPU0 in an SSE-200 has neither.
27
* Otherwise, pte_attrs is the same as the MAIR_EL1 8-bit format.
62
* Since the IoTKit has only one CPU, it does not have the CPU1_* properties.
28
- * For shareability, as in the SH field of the VMSAv8-64 PTEs.
63
+ * + QOM properties "CPU0_MPU_NS", "CPU0_MPU_S", "CPU1_MPU_NS" and "CPU1_MPU_S"
29
+ * For shareability and guarded, as in the SH and GP fields respectively
64
+ * which set the number of MPU regions on the CPUs. If there is only one
30
+ * of the VMSAv8-64 PTEs.
65
+ * CPU the CPU1 properties are not present.
31
*/
66
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
32
# define TARGET_PAGE_ENTRY_EXTRA \
67
* which are wired to its NVIC lines 32 .. n+32
33
- uint8_t pte_attrs; \
68
* + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
34
- uint8_t shareability;
69
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
35
-
70
uint32_t exp_numirq;
36
+ uint8_t pte_attrs; \
71
uint32_t sram_addr_width;
37
+ uint8_t shareability; \
72
uint32_t init_svtor;
38
+ bool guarded;
73
+ uint32_t cpu_mpu_ns[SSE_MAX_CPUS];
74
+ uint32_t cpu_mpu_s[SSE_MAX_CPUS];
75
bool cpu_fpu[SSE_MAX_CPUS];
76
bool cpu_dsp[SSE_MAX_CPUS];
77
};
78
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/arm/armsse.c
81
+++ b/hw/arm/armsse.c
82
@@ -XXX,XX +XXX,XX @@ static Property iotkit_properties[] = {
83
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
84
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
85
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
86
+ DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
87
+ DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
88
DEFINE_PROP_END_OF_LIST()
89
};
90
91
@@ -XXX,XX +XXX,XX @@ static Property sse200_properties[] = {
92
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
93
DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
94
DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
95
+ DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
96
+ DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
97
+ DEFINE_PROP_UINT32("CPU1_MPU_NS", ARMSSE, cpu_mpu_ns[1], 8),
98
+ DEFINE_PROP_UINT32("CPU1_MPU_S", ARMSSE, cpu_mpu_s[1], 8),
99
DEFINE_PROP_END_OF_LIST()
100
};
101
102
@@ -XXX,XX +XXX,XX @@ static Property sse300_properties[] = {
103
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
104
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
105
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
106
+ DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
107
+ DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
108
DEFINE_PROP_END_OF_LIST()
109
};
110
111
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
112
return;
113
}
114
}
115
+ if (!object_property_set_uint(cpuobj, "mpu-ns-regions",
116
+ s->cpu_mpu_ns[i], errp)) {
117
+ return;
118
+ }
119
+ if (!object_property_set_uint(cpuobj, "mpu-s-regions",
120
+ s->cpu_mpu_s[i], errp)) {
121
+ return;
122
+ }
123
124
if (i > 0) {
125
memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
126
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/arm/mps2-tz.c
129
+++ b/hw/arm/mps2-tz.c
130
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
131
int uart_overflow_irq; /* number of the combined UART overflow IRQ */
132
uint32_t init_svtor; /* init-svtor setting for SSE */
133
uint32_t sram_addr_width; /* SRAM_ADDR_WIDTH setting for SSE */
134
+ uint32_t cpu0_mpu_ns; /* CPU0_MPU_NS setting for SSE */
135
+ uint32_t cpu0_mpu_s; /* CPU0_MPU_S setting for SSE */
136
+ uint32_t cpu1_mpu_ns; /* CPU1_MPU_NS setting for SSE */
137
+ uint32_t cpu1_mpu_s; /* CPU1_MPU_S setting for SSE */
138
const RAMInfo *raminfo;
139
const char *armsse_type;
140
uint32_t boot_ram_size; /* size of ram at address 0; 0 == find in raminfo */
141
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
142
#define MPS3_DDR_SIZE (2 * GiB)
39
#endif
143
#endif
40
144
41
#define NB_MMU_MODES 8
145
+/* For cpu{0,1}_mpu_{ns,s}, means "leave at SSE's default value" */
42
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
146
+#define MPU_REGION_DEFAULT UINT32_MAX
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/cpu.h
45
+++ b/target/arm/cpu.h
46
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
47
/* Shared between translate-sve.c and sve_helper.c. */
48
extern const uint64_t pred_esz_masks[5];
49
50
-/* Helper for the macros below, validating the argument type. */
51
-static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs *x)
52
-{
53
- return x;
54
-}
55
-
56
-/*
57
- * Lvalue macros for ARM TLB bits that we must cache in the TCG TLB.
58
- * Using these should be a bit more self-documenting than using the
59
- * generic target bits directly.
60
- */
61
-#define arm_tlb_bti_gp(x) (typecheck_memtxattrs(x)->target_tlb_bit0)
62
-
63
/*
64
* AArch64 usage of the PAGE_TARGET_* bits for linux-user.
65
* Note that with the Linux kernel, PROT_MTE may not be cleared by mprotect
66
diff --git a/target/arm/internals.h b/target/arm/internals.h
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/internals.h
69
+++ b/target/arm/internals.h
70
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCacheAttrs {
71
unsigned int attrs:8;
72
unsigned int shareability:2; /* as in the SH field of the VMSAv8-64 PTEs */
73
bool is_s2_format:1;
74
+ bool guarded:1; /* guarded bit of the v8-64 PTE */
75
} ARMCacheAttrs;
76
77
/* Fields that are valid upon success. */
78
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/ptw.c
81
+++ b/target/arm/ptw.c
82
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
83
*/
84
result->f.attrs.secure = false;
85
}
86
- /* When in aarch64 mode, and BTI is enabled, remember GP in the IOTLB. */
87
- if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) {
88
- arm_tlb_bti_gp(&result->f.attrs) = true;
89
+
147
+
90
+ /* When in aarch64 mode, and BTI is enabled, remember GP in the TLB. */
148
static const uint32_t an505_oscclk[] = {
91
+ if (aarch64 && cpu_isar_feature(aa64_bti, cpu)) {
149
40000000,
92
+ result->f.guarded = guarded;
150
24580000,
93
}
151
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
94
152
OBJECT(system_memory), &error_abort);
95
if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
153
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
96
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
154
qdev_prop_set_uint32(iotkitdev, "init-svtor", mmc->init_svtor);
97
index XXXXXXX..XXXXXXX 100644
155
+ if (mmc->cpu0_mpu_ns != MPU_REGION_DEFAULT) {
98
--- a/target/arm/translate-a64.c
156
+ qdev_prop_set_uint32(iotkitdev, "CPU0_MPU_NS", mmc->cpu0_mpu_ns);
99
+++ b/target/arm/translate-a64.c
157
+ }
100
@@ -XXX,XX +XXX,XX @@ static bool is_guarded_page(CPUARMState *env, DisasContext *s)
158
+ if (mmc->cpu0_mpu_s != MPU_REGION_DEFAULT) {
101
#ifdef CONFIG_USER_ONLY
159
+ qdev_prop_set_uint32(iotkitdev, "CPU0_MPU_S", mmc->cpu0_mpu_s);
102
return page_get_flags(addr) & PAGE_BTI;
160
+ }
103
#else
161
+ if (object_property_find(OBJECT(iotkitdev), "CPU1_MPU_NS")) {
104
+ CPUTLBEntryFull *full;
162
+ if (mmc->cpu1_mpu_ns != MPU_REGION_DEFAULT) {
105
+ void *host;
163
+ qdev_prop_set_uint32(iotkitdev, "CPU1_MPU_NS", mmc->cpu1_mpu_ns);
106
int mmu_idx = arm_to_core_mmu_idx(s->mmu_idx);
164
+ }
107
- unsigned int index = tlb_index(env, mmu_idx, addr);
165
+ if (mmc->cpu1_mpu_s != MPU_REGION_DEFAULT) {
108
- CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
166
+ qdev_prop_set_uint32(iotkitdev, "CPU1_MPU_S", mmc->cpu1_mpu_s);
109
+ int flags;
167
+ }
110
168
+ }
111
/*
169
qdev_prop_set_uint32(iotkitdev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
112
* We test this immediately after reading an insn, which means
170
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
113
- * that any normal page must be in the TLB. The only exception
171
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
114
- * would be for executing from flash or device memory, which
172
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
115
- * does not retain the TLB entry.
173
{
116
- *
174
MachineClass *mc = MACHINE_CLASS(oc);
117
- * FIXME: Assume false for those, for now. We could use
175
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
118
- * arm_cpu_get_phys_page_attrs_debug to re-read the page
176
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
119
- * table entry even for that case.
177
120
+ * that the TLB entry must be present and valid, and thus this
178
mc->init = mps2tz_common_init;
121
+ * access will never raise an exception.
179
mc->reset = mps2_machine_reset;
122
*/
180
iic->check = mps2_tz_idau_check;
123
- return (tlb_hit(entry->addr_code, addr) &&
124
- arm_tlb_bti_gp(&env_tlb(env)->d[mmu_idx].fulltlb[index].attrs));
125
+ flags = probe_access_full(env, addr, MMU_INST_FETCH, mmu_idx,
126
+ false, &host, &full, 0);
127
+ assert(!(flags & TLB_INVALID_MASK));
128
+
181
+
129
+ return full->guarded;
182
+ /* Most machines leave these at the SSE defaults */
130
#endif
183
+ mmc->cpu0_mpu_ns = MPU_REGION_DEFAULT;
184
+ mmc->cpu0_mpu_s = MPU_REGION_DEFAULT;
185
+ mmc->cpu1_mpu_ns = MPU_REGION_DEFAULT;
186
+ mmc->cpu1_mpu_s = MPU_REGION_DEFAULT;
131
}
187
}
132
188
189
static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc)
190
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
191
mmc->numirq = 96;
192
mmc->uart_overflow_irq = 48;
193
mmc->init_svtor = 0x00000000;
194
+ mmc->cpu0_mpu_s = mmc->cpu0_mpu_ns = 16;
195
mmc->sram_addr_width = 21;
196
mmc->raminfo = an547_raminfo;
197
mmc->armsse_type = TYPE_SSE300;
133
--
198
--
134
2.25.1
199
2.34.1
200
201
diff view generated by jsdifflib