1
First arm pullreq for 6.1 cycle. The big stuff here is RTH's alignment series.
1
target-arm queue: the big stuff here is the final part of
2
rth's patches for Cortex-A76 and Neoverse-N1 support;
3
also present are Gavin's NUMA series and a few other things.
2
4
3
thanks
5
thanks
4
-- PMM
6
-- PMM
5
7
6
The following changes since commit ccdf06c1db192152ac70a1dd974c624f566cb7d4:
8
The following changes since commit 554623226f800acf48a2ed568900c1c968ec9a8b:
7
9
8
Open 6.1 development tree (2021-04-30 11:15:40 +0100)
10
Merge tag 'qemu-sparc-20220508' of https://github.com/mcayland/qemu into staging (2022-05-08 17:03:26 -0500)
9
11
10
are available in the Git repository at:
12
are available in the Git repository at:
11
13
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210430
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220509
13
15
14
for you to fetch changes up to a6091108aa44e9017af4ca13c43f55a629e3744c:
16
for you to fetch changes up to ae9141d4a3265553503bf07d3574b40f84615a34:
15
17
16
hw/pci-host/gpex: Don't fault for unmapped parts of MMIO and PIO windows (2021-04-30 11:16:52 +0100)
18
hw/acpi/aml-build: Use existing CPU topology to build PPTT table (2022-05-09 11:47:55 +0100)
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
target-arm queue:
21
target-arm queue:
20
* hw/pci-host/gpex: Don't fault for unmapped parts of MMIO and PIO windows
22
* MAINTAINERS/.mailmap: update email for Leif Lindholm
21
* hw: add compat machines for 6.1
23
* hw/arm: add version information to sbsa-ref machine DT
22
* Fault misaligned accesses where the architecture requires it
24
* Enable new features for -cpu max:
23
* Fix some corner cases of MTE faults (notably with misaligned accesses)
25
FEAT_Debugv8p2, FEAT_Debugv8p4, FEAT_RAS (minimal version only),
24
* Make Thumb store insns UNDEF for Rn==1111
26
FEAT_IESB, FEAT_CSV2, FEAT_CSV2_2, FEAT_CSV3, FEAT_DGH
25
* hw/arm/smmuv3: Support 16K translation granule
27
* Emulate Cortex-A76
28
* Emulate Neoverse-N1
29
* Fix the virt board default NUMA topology
26
30
27
----------------------------------------------------------------
31
----------------------------------------------------------------
28
Cornelia Huck (1):
32
Gavin Shan (6):
29
hw: add compat machines for 6.1
33
qapi/machine.json: Add cluster-id
34
qtest/numa-test: Specify CPU topology in aarch64_numa_cpu()
35
hw/arm/virt: Consider SMP configuration in CPU topology
36
qtest/numa-test: Correct CPU and NUMA association in aarch64_numa_cpu()
37
hw/arm/virt: Fix CPU's default NUMA node ID
38
hw/acpi/aml-build: Use existing CPU topology to build PPTT table
30
39
31
Kunkun Jiang (1):
40
Leif Lindholm (2):
32
hw/arm/smmuv3: Support 16K translation granule
41
MAINTAINERS/.mailmap: update email for Leif Lindholm
42
hw/arm: add versioning to sbsa-ref machine DT
33
43
34
Peter Maydell (2):
44
Richard Henderson (24):
35
target/arm: Make Thumb store insns UNDEF for Rn==1111
45
target/arm: Handle cpreg registration for missing EL
36
hw/pci-host/gpex: Don't fault for unmapped parts of MMIO and PIO windows
46
target/arm: Drop EL3 no EL2 fallbacks
47
target/arm: Merge zcr reginfo
48
target/arm: Adjust definition of CONTEXTIDR_EL2
49
target/arm: Move cortex impdef sysregs to cpu_tcg.c
50
target/arm: Update qemu-system-arm -cpu max to cortex-a57
51
target/arm: Set ID_DFR0.PerfMon for qemu-system-arm -cpu max
52
target/arm: Split out aa32_max_features
53
target/arm: Annotate arm_max_initfn with FEAT identifiers
54
target/arm: Use field names for manipulating EL2 and EL3 modes
55
target/arm: Enable FEAT_Debugv8p2 for -cpu max
56
target/arm: Enable FEAT_Debugv8p4 for -cpu max
57
target/arm: Add minimal RAS registers
58
target/arm: Enable SCR and HCR bits for RAS
59
target/arm: Implement virtual SError exceptions
60
target/arm: Implement ESB instruction
61
target/arm: Enable FEAT_RAS for -cpu max
62
target/arm: Enable FEAT_IESB for -cpu max
63
target/arm: Enable FEAT_CSV2 for -cpu max
64
target/arm: Enable FEAT_CSV2_2 for -cpu max
65
target/arm: Enable FEAT_CSV3 for -cpu max
66
target/arm: Enable FEAT_DGH for -cpu max
67
target/arm: Define cortex-a76
68
target/arm: Define neoverse-n1
37
69
38
Richard Henderson (39):
70
docs/system/arm/emulation.rst | 10 +
39
target/arm: Fix mte_checkN
71
docs/system/arm/virt.rst | 2 +
40
target/arm: Split out mte_probe_int
72
qapi/machine.json | 6 +-
41
target/arm: Fix unaligned checks for mte_check1, mte_probe1
73
target/arm/cpregs.h | 11 +
42
test/tcg/aarch64: Add mte-5
74
target/arm/cpu.h | 23 ++
43
target/arm: Replace MTEDESC ESIZE+TSIZE with SIZEM1
75
target/arm/helper.h | 1 +
44
target/arm: Merge mte_check1, mte_checkN
76
target/arm/internals.h | 16 ++
45
target/arm: Rename mte_probe1 to mte_probe
77
target/arm/syndrome.h | 5 +
46
target/arm: Simplify sve mte checking
78
target/arm/a32.decode | 16 +-
47
target/arm: Remove log2_esize parameter to gen_mte_checkN
79
target/arm/t32.decode | 18 +-
48
target/arm: Fix decode of align in VLDST_single
80
hw/acpi/aml-build.c | 111 ++++----
49
target/arm: Rename TBFLAG_A32, SCTLR_B
81
hw/arm/sbsa-ref.c | 16 ++
50
target/arm: Rename TBFLAG_ANY, PSTATE_SS
82
hw/arm/virt.c | 21 +-
51
target/arm: Add wrapper macros for accessing tbflags
83
hw/core/machine-hmp-cmds.c | 4 +
52
target/arm: Introduce CPUARMTBFlags
84
hw/core/machine.c | 16 ++
53
target/arm: Move mode specific TB flags to tb->cs_base
85
target/arm/cpu.c | 66 ++++-
54
target/arm: Move TBFLAG_AM32 bits to the top
86
target/arm/cpu64.c | 353 ++++++++++++++-----------
55
target/arm: Move TBFLAG_ANY bits to the bottom
87
target/arm/cpu_tcg.c | 227 +++++++++++-----
56
target/arm: Add ALIGN_MEM to TBFLAG_ANY
88
target/arm/helper.c | 600 +++++++++++++++++++++++++-----------------
57
target/arm: Adjust gen_aa32_{ld, st}_i32 for align+endianness
89
target/arm/op_helper.c | 43 +++
58
target/arm: Merge gen_aa32_frob64 into gen_aa32_ld_i64
90
target/arm/translate-a64.c | 18 ++
59
target/arm: Fix SCTLR_B test for TCGv_i64 load/store
91
target/arm/translate.c | 23 ++
60
target/arm: Adjust gen_aa32_{ld, st}_i64 for align+endianness
92
tests/qtest/numa-test.c | 19 +-
61
target/arm: Enforce word alignment for LDRD/STRD
93
.mailmap | 3 +-
62
target/arm: Enforce alignment for LDA/LDAH/STL/STLH
94
MAINTAINERS | 2 +-
63
target/arm: Enforce alignment for LDM/STM
95
25 files changed, 1068 insertions(+), 562 deletions(-)
64
target/arm: Enforce alignment for RFE
65
target/arm: Enforce alignment for SRS
66
target/arm: Enforce alignment for VLDM/VSTM
67
target/arm: Enforce alignment for VLDR/VSTR
68
target/arm: Enforce alignment for VLDn (all lanes)
69
target/arm: Enforce alignment for VLDn/VSTn (multiple)
70
target/arm: Enforce alignment for VLDn/VSTn (single)
71
target/arm: Use finalize_memop for aa64 gpr load/store
72
target/arm: Use finalize_memop for aa64 fpr load/store
73
target/arm: Enforce alignment for aa64 load-acq/store-rel
74
target/arm: Use MemOp for size + endian in aa64 vector ld/st
75
target/arm: Enforce alignment for aa64 vector LDn/STn (multiple)
76
target/arm: Enforce alignment for aa64 vector LDn/STn (single)
77
target/arm: Enforce alignment for sve LD1R
78
79
include/hw/boards.h | 3 +
80
include/hw/i386/pc.h | 3 +
81
include/hw/pci-host/gpex.h | 4 +
82
target/arm/cpu.h | 105 ++++++++++-----
83
target/arm/helper-a64.h | 3 +-
84
target/arm/internals.h | 11 +-
85
target/arm/translate-a64.h | 2 +-
86
target/arm/translate.h | 38 ++++++
87
target/arm/neon-ls.decode | 4 +-
88
hw/arm/smmuv3.c | 6 +-
89
hw/arm/virt.c | 7 +-
90
hw/core/machine.c | 5 +
91
hw/i386/pc.c | 3 +
92
hw/i386/pc_piix.c | 14 +-
93
hw/i386/pc_q35.c | 13 +-
94
hw/pci-host/gpex.c | 56 +++++++-
95
hw/ppc/spapr.c | 17 ++-
96
hw/s390x/s390-virtio-ccw.c | 14 +-
97
target/arm/helper-a64.c | 2 +-
98
target/arm/helper.c | 162 ++++++++++++----------
99
target/arm/mte_helper.c | 185 ++++++++++---------------
100
target/arm/sve_helper.c | 100 +++++---------
101
target/arm/translate-a64.c | 236 ++++++++++++++++----------------
102
target/arm/translate-sve.c | 11 +-
103
target/arm/translate.c | 274 ++++++++++++++++++++++----------------
104
tests/tcg/aarch64/mte-5.c | 44 ++++++
105
target/arm/translate-neon.c.inc | 117 ++++++++++++----
106
target/arm/translate-vfp.c.inc | 20 +--
107
tests/tcg/aarch64/Makefile.target | 2 +-
108
29 files changed, 878 insertions(+), 583 deletions(-)
109
create mode 100644 tests/tcg/aarch64/mte-5.c
110
diff view generated by jsdifflib
Deleted patch
1
From: Kunkun Jiang <jiangkunkun@huawei.com>
2
1
3
The driver can query some bits in SMMUv3 IDR5 to learn which
4
translation granules are supported. Arm recommends that SMMUv3
5
implementations support at least 4K and 64K granules. But in
6
the vSMMUv3, there seems to be no reason not to support 16K
7
translation granule. In addition, if 16K is not supported,
8
vSVA will failed to be enabled in the future for 16K guest
9
kernel. So it'd better to support it.
10
11
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
12
Reviewed-by: Eric Auger <eric.auger@redhat.com>
13
Tested-by: Eric Auger <eric.auger@redhat.com>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/arm/smmuv3.c | 6 ++++--
17
1 file changed, 4 insertions(+), 2 deletions(-)
18
19
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/smmuv3.c
22
+++ b/hw/arm/smmuv3.c
23
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
24
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 1);
25
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, HAD, 1);
26
27
- /* 4K and 64K granule support */
28
+ /* 4K, 16K and 64K granule support */
29
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
30
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN16K, 1);
31
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
32
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
33
34
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
35
36
tg = CD_TG(cd, i);
37
tt->granule_sz = tg2granule(tg, i);
38
- if ((tt->granule_sz != 12 && tt->granule_sz != 16) || CD_ENDI(cd)) {
39
+ if ((tt->granule_sz != 12 && tt->granule_sz != 14 &&
40
+ tt->granule_sz != 16) || CD_ENDI(cd)) {
41
goto bad_cd;
42
}
43
44
--
45
2.20.1
46
47
diff view generated by jsdifflib
Deleted patch
1
The Arm ARM specifies that for Thumb encodings of the various plain
2
store insns, if the Rn field is 1111 then we must UNDEF. This is
3
different from the Arm encodings, where this case is either
4
UNPREDICTABLE or has well-defined behaviour. The exclusive stores,
5
store-release and STRD do not have this UNDEF case for any encoding.
6
1
7
Enforce the UNDEF for this case in the Thumb plain store insns.
8
9
Fixes: https://bugs.launchpad.net/qemu/+bug/1922887
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210408162402.5822-1-peter.maydell@linaro.org
13
---
14
target/arm/translate.c | 16 ++++++++++++++++
15
1 file changed, 16 insertions(+)
16
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.c
20
+++ b/target/arm/translate.c
21
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
22
ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
23
TCGv_i32 addr, tmp;
24
25
+ /*
26
+ * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
27
+ * is either UNPREDICTABLE or has defined behaviour
28
+ */
29
+ if (s->thumb && a->rn == 15) {
30
+ return false;
31
+ }
32
+
33
addr = op_addr_rr_pre(s, a);
34
35
tmp = load_reg(s, a->rt);
36
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
37
ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
38
TCGv_i32 addr, tmp;
39
40
+ /*
41
+ * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
42
+ * is either UNPREDICTABLE or has defined behaviour
43
+ */
44
+ if (s->thumb && a->rn == 15) {
45
+ return false;
46
+ }
47
+
48
addr = op_addr_ri_pre(s, a);
49
50
tmp = load_reg(s, a->rt);
51
--
52
2.20.1
53
54
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We were incorrectly assuming that only the first byte of an MTE access
4
is checked against the tags. But per the ARM, unaligned accesses are
5
pre-decomposed into single-byte accesses. So by the time we reach the
6
actual MTE check in the ARM pseudocode, all accesses are aligned.
7
8
Therefore, the first failure is always either the first byte of the
9
access, or the first byte of the granule.
10
11
In addition, some of the arithmetic is off for last-first -> count.
12
This does not become directly visible until a later patch that passes
13
single bytes into this function, so ptr == ptr_last.
14
15
Buglink: https://bugs.launchpad.net/bugs/1921948
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210416183106.1516563-2-richard.henderson@linaro.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
[PMM: tweaked a comment]
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
target/arm/mte_helper.c | 40 ++++++++++++++++++----------------------
23
1 file changed, 18 insertions(+), 22 deletions(-)
24
25
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/mte_helper.c
28
+++ b/target/arm/mte_helper.c
29
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
30
uint64_t ptr, uintptr_t ra)
31
{
32
int mmu_idx, ptr_tag, bit55;
33
- uint64_t ptr_last, ptr_end, prev_page, next_page;
34
- uint64_t tag_first, tag_end;
35
- uint64_t tag_byte_first, tag_byte_end;
36
- uint32_t esize, total, tag_count, tag_size, n, c;
37
+ uint64_t ptr_last, prev_page, next_page;
38
+ uint64_t tag_first, tag_last;
39
+ uint64_t tag_byte_first, tag_byte_last;
40
+ uint32_t total, tag_count, tag_size, n, c;
41
uint8_t *mem1, *mem2;
42
MMUAccessType type;
43
44
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
45
46
mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
47
type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
48
- esize = FIELD_EX32(desc, MTEDESC, ESIZE);
49
total = FIELD_EX32(desc, MTEDESC, TSIZE);
50
51
- /* Find the addr of the end of the access, and of the last element. */
52
- ptr_end = ptr + total;
53
- ptr_last = ptr_end - esize;
54
+ /* Find the addr of the end of the access */
55
+ ptr_last = ptr + total - 1;
56
57
/* Round the bounds to the tag granule, and compute the number of tags. */
58
tag_first = QEMU_ALIGN_DOWN(ptr, TAG_GRANULE);
59
- tag_end = QEMU_ALIGN_UP(ptr_last, TAG_GRANULE);
60
- tag_count = (tag_end - tag_first) / TAG_GRANULE;
61
+ tag_last = QEMU_ALIGN_DOWN(ptr_last, TAG_GRANULE);
62
+ tag_count = ((tag_last - tag_first) / TAG_GRANULE) + 1;
63
64
/* Round the bounds to twice the tag granule, and compute the bytes. */
65
tag_byte_first = QEMU_ALIGN_DOWN(ptr, 2 * TAG_GRANULE);
66
- tag_byte_end = QEMU_ALIGN_UP(ptr_last, 2 * TAG_GRANULE);
67
+ tag_byte_last = QEMU_ALIGN_DOWN(ptr_last, 2 * TAG_GRANULE);
68
69
/* Locate the page boundaries. */
70
prev_page = ptr & TARGET_PAGE_MASK;
71
next_page = prev_page + TARGET_PAGE_SIZE;
72
73
- if (likely(tag_end - prev_page <= TARGET_PAGE_SIZE)) {
74
+ if (likely(tag_last - prev_page <= TARGET_PAGE_SIZE)) {
75
/* Memory access stays on one page. */
76
- tag_size = (tag_byte_end - tag_byte_first) / (2 * TAG_GRANULE);
77
+ tag_size = ((tag_byte_last - tag_byte_first) / (2 * TAG_GRANULE)) + 1;
78
mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, total,
79
MMU_DATA_LOAD, tag_size, ra);
80
if (!mem1) {
81
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
82
mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, next_page - ptr,
83
MMU_DATA_LOAD, tag_size, ra);
84
85
- tag_size = (tag_byte_end - next_page) / (2 * TAG_GRANULE);
86
+ tag_size = ((tag_byte_last - next_page) / (2 * TAG_GRANULE)) + 1;
87
mem2 = allocation_tag_mem(env, mmu_idx, next_page, type,
88
- ptr_end - next_page,
89
+ ptr_last - next_page + 1,
90
MMU_DATA_LOAD, tag_size, ra);
91
92
/*
93
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
94
}
95
96
/*
97
- * If we failed, we know which granule. Compute the element that
98
- * is first in that granule, and signal failure on that element.
99
+ * If we failed, we know which granule. For the first granule, the
100
+ * failure address is @ptr, the first byte accessed. Otherwise the
101
+ * failure address is the first byte of the nth granule.
102
*/
103
if (unlikely(n < tag_count)) {
104
- uint64_t fail_ofs;
105
-
106
- fail_ofs = tag_first + n * TAG_GRANULE - ptr;
107
- fail_ofs = ROUND_UP(fail_ofs, esize);
108
- mte_check_fail(env, desc, ptr + fail_ofs, ra);
109
+ uint64_t fault = (n == 0 ? ptr : tag_first + n * TAG_GRANULE);
110
+ mte_check_fail(env, desc, fault, ra);
111
}
112
113
done:
114
--
115
2.20.1
116
117
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
NUVIA was acquired by Qualcomm in March 2021, but kept functioning on
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
separate infrastructure for a transitional period. We've now switched
5
Message-id: 20210419202257.161730-32-richard.henderson@linaro.org
5
over to contributing as Qualcomm Innovation Center (quicinc), so update
6
my email address to reflect this.
7
8
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
9
Message-id: 20220505113740.75565-1-quic_llindhol@quicinc.com
10
Cc: Leif Lindholm <leif@nuviainc.com>
11
Cc: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
[Fixed commit message typo]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
15
---
8
target/arm/translate-sve.c | 2 +-
16
.mailmap | 3 ++-
9
1 file changed, 1 insertion(+), 1 deletion(-)
17
MAINTAINERS | 2 +-
18
2 files changed, 3 insertions(+), 2 deletions(-)
10
19
11
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
20
diff --git a/.mailmap b/.mailmap
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-sve.c
22
--- a/.mailmap
14
+++ b/target/arm/translate-sve.c
23
+++ b/.mailmap
15
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a)
24
@@ -XXX,XX +XXX,XX @@ Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
16
clean_addr = gen_mte_check1(s, temp, false, true, msz);
25
Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
17
26
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
18
tcg_gen_qemu_ld_i64(temp, clean_addr, get_mem_index(s),
27
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
19
- s->be_data | dtype_mop[a->dtype]);
28
-Leif Lindholm <leif@nuviainc.com> <leif.lindholm@linaro.org>
20
+ finalize_memop(s, dtype_mop[a->dtype]));
29
+Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
21
30
+Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
22
/* Broadcast to *all* elements. */
31
Radoslaw Biernacki <rad@semihalf.com> <radoslaw.biernacki@linaro.org>
23
tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd),
32
Paul Burton <paulburton@kernel.org> <paul.burton@mips.com>
33
Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com>
34
diff --git a/MAINTAINERS b/MAINTAINERS
35
index XXXXXXX..XXXXXXX 100644
36
--- a/MAINTAINERS
37
+++ b/MAINTAINERS
38
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
39
SBSA-REF
40
M: Radoslaw Biernacki <rad@semihalf.com>
41
M: Peter Maydell <peter.maydell@linaro.org>
42
-R: Leif Lindholm <leif@nuviainc.com>
43
+R: Leif Lindholm <quic_llindhol@quicinc.com>
44
L: qemu-arm@nongnu.org
45
S: Maintained
46
F: hw/arm/sbsa-ref.c
24
--
47
--
25
2.20.1
48
2.25.1
26
49
27
50
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're about to split tbflags into two parts. These macros
3
More gracefully handle cpregs when EL2 and/or EL3 are missing.
4
will ensure that the correct part is used with the correct
4
If the reg is entirely inaccessible, do not register it at all.
5
set of bits.
5
If the reg is for EL2, and EL3 is present but EL2 is not,
6
either discard, squash to res0, const, or keep unchanged.
7
8
Per rule RJFFP, mark the 4 aarch32 hypervisor access registers
9
with ARM_CP_EL3_NO_EL2_KEEP, and mark all of the EL2 address
10
translation and tlb invalidation "regs" ARM_CP_EL3_NO_EL2_UNDEF.
11
Mark the 2 virtualization processor id regs ARM_CP_EL3_NO_EL2_C_NZ.
12
13
This will simplify cpreg registration for conditional arm features.
6
14
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210419202257.161730-5-richard.henderson@linaro.org
17
Message-id: 20220506180242.216785-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
target/arm/cpu.h | 22 +++++++++-
20
target/arm/cpregs.h | 11 +++
13
target/arm/helper-a64.c | 2 +-
21
target/arm/helper.c | 178 ++++++++++++++++++++++++++++++--------------
14
target/arm/helper.c | 85 +++++++++++++++++---------------------
22
2 files changed, 133 insertions(+), 56 deletions(-)
15
target/arm/translate-a64.c | 36 ++++++++--------
23
16
target/arm/translate.c | 48 ++++++++++-----------
24
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
17
5 files changed, 101 insertions(+), 92 deletions(-)
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
26
--- a/target/arm/cpregs.h
22
+++ b/target/arm/cpu.h
27
+++ b/target/arm/cpregs.h
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, TCMA, 16, 2)
28
@@ -XXX,XX +XXX,XX @@ enum {
24
FIELD(TBFLAG_A64, MTE_ACTIVE, 18, 1)
29
ARM_CP_SVE = 1 << 14,
25
FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
30
/* Flag: Do not expose in gdb sysreg xml. */
26
31
ARM_CP_NO_GDB = 1 << 15,
27
+/*
32
+ /*
28
+ * Helpers for using the above.
33
+ * Flags: If EL3 but not EL2...
29
+ */
34
+ * - UNDEF: discard the cpreg,
30
+#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
35
+ * - KEEP: retain the cpreg as is,
31
+ (DST = FIELD_DP32(DST, TBFLAG_ANY, WHICH, VAL))
36
+ * - C_NZ: set const on the cpreg, but retain resetvalue,
32
+#define DP_TBFLAG_A64(DST, WHICH, VAL) \
37
+ * - else: set const on the cpreg, zero resetvalue, aka RES0.
33
+ (DST = FIELD_DP32(DST, TBFLAG_A64, WHICH, VAL))
38
+ * See rule RJFFP in section D1.1.3 of DDI0487H.a.
34
+#define DP_TBFLAG_A32(DST, WHICH, VAL) \
39
+ */
35
+ (DST = FIELD_DP32(DST, TBFLAG_A32, WHICH, VAL))
40
+ ARM_CP_EL3_NO_EL2_UNDEF = 1 << 16,
36
+#define DP_TBFLAG_M32(DST, WHICH, VAL) \
41
+ ARM_CP_EL3_NO_EL2_KEEP = 1 << 17,
37
+ (DST = FIELD_DP32(DST, TBFLAG_M32, WHICH, VAL))
42
+ ARM_CP_EL3_NO_EL2_C_NZ = 1 << 18,
38
+#define DP_TBFLAG_AM32(DST, WHICH, VAL) \
43
};
39
+ (DST = FIELD_DP32(DST, TBFLAG_AM32, WHICH, VAL))
44
40
+
45
/*
41
+#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN, TBFLAG_ANY, WHICH)
42
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN, TBFLAG_A64, WHICH)
43
+#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN, TBFLAG_A32, WHICH)
44
+#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN, TBFLAG_M32, WHICH)
45
+#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN, TBFLAG_AM32, WHICH)
46
+
47
/**
48
* cpu_mmu_index:
49
* @env: The cpu environment
50
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
51
*/
52
static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
53
{
54
- return FIELD_EX32(env->hflags, TBFLAG_ANY, MMUIDX);
55
+ return EX_TBFLAG_ANY(env->hflags, MMUIDX);
56
}
57
58
static inline bool bswap_code(bool sctlr_b)
59
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/helper-a64.c
62
+++ b/target/arm/helper-a64.c
63
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
64
* the hflags rebuild, since we can pull the composite TBII field
65
* from there.
66
*/
67
- tbii = FIELD_EX32(env->hflags, TBFLAG_A64, TBII);
68
+ tbii = EX_TBFLAG_A64(env->hflags, TBII);
69
if ((tbii >> extract64(new_pc, 55, 1)) & 1) {
70
/* TBI is enabled. */
71
int core_mmu_idx = cpu_mmu_index(env, false);
72
diff --git a/target/arm/helper.c b/target/arm/helper.c
46
diff --git a/target/arm/helper.c b/target/arm/helper.c
73
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/helper.c
48
--- a/target/arm/helper.c
75
+++ b/target/arm/helper.c
49
+++ b/target/arm/helper.c
76
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
50
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
77
static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
51
.access = PL1_RW, .readfn = spsel_read, .writefn = spsel_write },
78
ARMMMUIdx mmu_idx, uint32_t flags)
52
{ .name = "FPEXC32_EL2", .state = ARM_CP_STATE_AA64,
53
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 3, .opc2 = 0,
54
- .access = PL2_RW, .type = ARM_CP_ALIAS | ARM_CP_FPU,
55
+ .access = PL2_RW,
56
+ .type = ARM_CP_ALIAS | ARM_CP_FPU | ARM_CP_EL3_NO_EL2_KEEP,
57
.fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]) },
58
{ .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
59
.opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
60
- .access = PL2_RW, .resetvalue = 0,
61
+ .access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
62
.writefn = dacr_write, .raw_writefn = raw_write,
63
.fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
64
{ .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
65
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
66
- .access = PL2_RW, .resetvalue = 0,
67
+ .access = PL2_RW, .resetvalue = 0, .type = ARM_CP_EL3_NO_EL2_KEEP,
68
.fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
69
{ .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
70
.type = ARM_CP_ALIAS,
71
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
72
.writefn = tlbimva_hyp_is_write },
73
{ .name = "TLBI_ALLE2", .state = ARM_CP_STATE_AA64,
74
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 0,
75
- .type = ARM_CP_NO_RAW, .access = PL2_W,
76
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
77
.writefn = tlbi_aa64_alle2_write },
78
{ .name = "TLBI_VAE2", .state = ARM_CP_STATE_AA64,
79
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 1,
80
- .type = ARM_CP_NO_RAW, .access = PL2_W,
81
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
82
.writefn = tlbi_aa64_vae2_write },
83
{ .name = "TLBI_VALE2", .state = ARM_CP_STATE_AA64,
84
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 5,
85
- .access = PL2_W, .type = ARM_CP_NO_RAW,
86
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
87
.writefn = tlbi_aa64_vae2_write },
88
{ .name = "TLBI_ALLE2IS", .state = ARM_CP_STATE_AA64,
89
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 0,
90
- .access = PL2_W, .type = ARM_CP_NO_RAW,
91
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
92
.writefn = tlbi_aa64_alle2is_write },
93
{ .name = "TLBI_VAE2IS", .state = ARM_CP_STATE_AA64,
94
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 1,
95
- .type = ARM_CP_NO_RAW, .access = PL2_W,
96
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
97
.writefn = tlbi_aa64_vae2is_write },
98
{ .name = "TLBI_VALE2IS", .state = ARM_CP_STATE_AA64,
99
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 5,
100
- .access = PL2_W, .type = ARM_CP_NO_RAW,
101
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
102
.writefn = tlbi_aa64_vae2is_write },
103
#ifndef CONFIG_USER_ONLY
104
/* Unlike the other EL2-related AT operations, these must
105
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
106
{ .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64,
107
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
108
.access = PL2_W, .accessfn = at_s1e2_access,
109
- .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
110
+ .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC | ARM_CP_EL3_NO_EL2_UNDEF,
111
+ .writefn = ats_write64 },
112
{ .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64,
113
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
114
.access = PL2_W, .accessfn = at_s1e2_access,
115
- .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
116
+ .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC | ARM_CP_EL3_NO_EL2_UNDEF,
117
+ .writefn = ats_write64 },
118
/* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE
119
* if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3
120
* with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose
121
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
122
{ .name = "DBGVCR32_EL2", .state = ARM_CP_STATE_AA64,
123
.opc0 = 2, .opc1 = 4, .crn = 0, .crm = 7, .opc2 = 0,
124
.access = PL2_RW, .accessfn = access_tda,
125
- .type = ARM_CP_NOP },
126
+ .type = ARM_CP_NOP | ARM_CP_EL3_NO_EL2_KEEP },
127
/* Dummy MDCCINT_EL1, since we don't implement the Debug Communications
128
* Channel but Linux may try to access this register. The 32-bit
129
* alias is DBGDCCINT.
130
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
131
.access = PL2_W, .type = ARM_CP_NOP },
132
{ .name = "TLBI_RVAE2IS", .state = ARM_CP_STATE_AA64,
133
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 1,
134
- .access = PL2_W, .type = ARM_CP_NO_RAW,
135
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
136
.writefn = tlbi_aa64_rvae2is_write },
137
{ .name = "TLBI_RVALE2IS", .state = ARM_CP_STATE_AA64,
138
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 5,
139
- .access = PL2_W, .type = ARM_CP_NO_RAW,
140
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
141
.writefn = tlbi_aa64_rvae2is_write },
142
{ .name = "TLBI_RIPAS2E1", .state = ARM_CP_STATE_AA64,
143
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 2,
144
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
145
.access = PL2_W, .type = ARM_CP_NOP },
146
{ .name = "TLBI_RVAE2OS", .state = ARM_CP_STATE_AA64,
147
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 1,
148
- .access = PL2_W, .type = ARM_CP_NO_RAW,
149
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
150
.writefn = tlbi_aa64_rvae2is_write },
151
{ .name = "TLBI_RVALE2OS", .state = ARM_CP_STATE_AA64,
152
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 5,
153
- .access = PL2_W, .type = ARM_CP_NO_RAW,
154
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
155
.writefn = tlbi_aa64_rvae2is_write },
156
{ .name = "TLBI_RVAE2", .state = ARM_CP_STATE_AA64,
157
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 1,
158
- .access = PL2_W, .type = ARM_CP_NO_RAW,
159
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
160
.writefn = tlbi_aa64_rvae2_write },
161
{ .name = "TLBI_RVALE2", .state = ARM_CP_STATE_AA64,
162
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 5,
163
- .access = PL2_W, .type = ARM_CP_NO_RAW,
164
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
165
.writefn = tlbi_aa64_rvae2_write },
166
{ .name = "TLBI_RVAE3IS", .state = ARM_CP_STATE_AA64,
167
.opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 1,
168
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
169
.writefn = tlbi_aa64_vae1is_write },
170
{ .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64,
171
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0,
172
- .access = PL2_W, .type = ARM_CP_NO_RAW,
173
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
174
.writefn = tlbi_aa64_alle2is_write },
175
{ .name = "TLBI_VAE2OS", .state = ARM_CP_STATE_AA64,
176
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 1,
177
- .access = PL2_W, .type = ARM_CP_NO_RAW,
178
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
179
.writefn = tlbi_aa64_vae2is_write },
180
{ .name = "TLBI_ALLE1OS", .state = ARM_CP_STATE_AA64,
181
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 4,
182
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbios_reginfo[] = {
183
.writefn = tlbi_aa64_alle1is_write },
184
{ .name = "TLBI_VALE2OS", .state = ARM_CP_STATE_AA64,
185
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 5,
186
- .access = PL2_W, .type = ARM_CP_NO_RAW,
187
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
188
.writefn = tlbi_aa64_vae2is_write },
189
{ .name = "TLBI_VMALLS12E1OS", .state = ARM_CP_STATE_AA64,
190
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 6,
191
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
192
{ .name = "VPIDR", .state = ARM_CP_STATE_AA32,
193
.cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
194
.access = PL2_RW, .accessfn = access_el3_aa32ns,
195
- .resetvalue = cpu->midr, .type = ARM_CP_ALIAS,
196
+ .resetvalue = cpu->midr,
197
+ .type = ARM_CP_ALIAS | ARM_CP_EL3_NO_EL2_C_NZ,
198
.fieldoffset = offsetoflow32(CPUARMState, cp15.vpidr_el2) },
199
{ .name = "VPIDR_EL2", .state = ARM_CP_STATE_AA64,
200
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
201
.access = PL2_RW, .resetvalue = cpu->midr,
202
+ .type = ARM_CP_EL3_NO_EL2_C_NZ,
203
.fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
204
{ .name = "VMPIDR", .state = ARM_CP_STATE_AA32,
205
.cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
206
.access = PL2_RW, .accessfn = access_el3_aa32ns,
207
- .resetvalue = vmpidr_def, .type = ARM_CP_ALIAS,
208
+ .resetvalue = vmpidr_def,
209
+ .type = ARM_CP_ALIAS | ARM_CP_EL3_NO_EL2_C_NZ,
210
.fieldoffset = offsetoflow32(CPUARMState, cp15.vmpidr_el2) },
211
{ .name = "VMPIDR_EL2", .state = ARM_CP_STATE_AA64,
212
.opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
213
- .access = PL2_RW,
214
- .resetvalue = vmpidr_def,
215
+ .access = PL2_RW, .resetvalue = vmpidr_def,
216
+ .type = ARM_CP_EL3_NO_EL2_C_NZ,
217
.fieldoffset = offsetof(CPUARMState, cp15.vmpidr_el2) },
218
};
219
define_arm_cp_regs(cpu, vpidr_regs);
220
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
221
int crm, int opc1, int opc2,
222
const char *name)
79
{
223
{
80
- flags = FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el);
224
+ CPUARMState *env = &cpu->env;
81
- flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX,
225
uint32_t key;
82
- arm_to_core_mmu_idx(mmu_idx));
226
ARMCPRegInfo *r2;
83
+ DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
227
bool is64 = r->type & ARM_CP_64BIT;
84
+ DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
228
bool ns = secstate & ARM_CP_SECSTATE_NS;
85
229
int cp = r->cp;
86
if (arm_singlestep_active(env)) {
230
- bool isbanked;
87
- flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
231
size_t name_len;
88
+ DP_TBFLAG_ANY(flags, SS_ACTIVE, 1);
232
+ bool make_const;
89
}
233
90
return flags;
234
switch (state) {
91
}
235
case ARM_CP_STATE_AA32:
92
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
236
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
93
bool sctlr_b = arm_sctlr_b(env);
94
95
if (sctlr_b) {
96
- flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR__B, 1);
97
+ DP_TBFLAG_A32(flags, SCTLR__B, 1);
98
}
99
if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
100
- flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
101
+ DP_TBFLAG_ANY(flags, BE_DATA, 1);
102
}
103
- flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
104
+ DP_TBFLAG_A32(flags, NS, !access_secure_reg(env));
105
106
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
107
}
108
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
109
uint32_t flags = 0;
110
111
if (arm_v7m_is_handler_mode(env)) {
112
- flags = FIELD_DP32(flags, TBFLAG_M32, HANDLER, 1);
113
+ DP_TBFLAG_M32(flags, HANDLER, 1);
114
}
115
116
/*
117
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
118
if (arm_feature(env, ARM_FEATURE_V8) &&
119
!((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
120
(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
121
- flags = FIELD_DP32(flags, TBFLAG_M32, STACKCHECK, 1);
122
+ DP_TBFLAG_M32(flags, STACKCHECK, 1);
123
}
124
125
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
126
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
127
{
128
int flags = 0;
129
130
- flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL,
131
- arm_debug_target_el(env));
132
+ DP_TBFLAG_ANY(flags, DEBUG_TARGET_EL, arm_debug_target_el(env));
133
return flags;
134
}
135
136
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
137
uint32_t flags = rebuild_hflags_aprofile(env);
138
139
if (arm_el_is_aa64(env, 1)) {
140
- flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
141
+ DP_TBFLAG_A32(flags, VFPEN, 1);
142
}
143
144
if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
145
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
146
- flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
147
+ DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
148
}
149
150
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
151
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
152
uint64_t sctlr;
153
int tbii, tbid;
154
155
- flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
156
+ DP_TBFLAG_ANY(flags, AARCH64_STATE, 1);
157
158
/* Get control bits for tagged addresses. */
159
tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
160
tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
161
162
- flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
163
- flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
164
+ DP_TBFLAG_A64(flags, TBII, tbii);
165
+ DP_TBFLAG_A64(flags, TBID, tbid);
166
167
if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
168
int sve_el = sve_exception_el(env, el);
169
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
170
} else {
171
zcr_len = sve_zcr_len_for_el(env, el);
172
}
173
- flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
174
- flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
175
+ DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
176
+ DP_TBFLAG_A64(flags, ZCR_LEN, zcr_len);
177
}
178
179
sctlr = regime_sctlr(env, stage1);
180
181
if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
182
- flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
183
+ DP_TBFLAG_ANY(flags, BE_DATA, 1);
184
}
185
186
if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
187
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
188
* The decision of which action to take is left to a helper.
189
*/
190
if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
191
- flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
192
+ DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1);
193
}
237
}
194
}
238
}
195
239
196
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
240
+ /*
197
/* Note that SCTLR_EL[23].BT == SCTLR_BT1. */
241
+ * Eliminate registers that are not present because the EL is missing.
198
if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
242
+ * Doing this here makes it easier to put all registers for a given
199
- flags = FIELD_DP32(flags, TBFLAG_A64, BT, 1);
243
+ * feature into the same ARMCPRegInfo array and define them all at once.
200
+ DP_TBFLAG_A64(flags, BT, 1);
244
+ */
245
+ make_const = false;
246
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
247
+ /*
248
+ * An EL2 register without EL2 but with EL3 is (usually) RES0.
249
+ * See rule RJFFP in section D1.1.3 of DDI0487H.a.
250
+ */
251
+ int min_el = ctz32(r->access) / 2;
252
+ if (min_el == 2 && !arm_feature(env, ARM_FEATURE_EL2)) {
253
+ if (r->type & ARM_CP_EL3_NO_EL2_UNDEF) {
254
+ return;
255
+ }
256
+ make_const = !(r->type & ARM_CP_EL3_NO_EL2_KEEP);
257
+ }
258
+ } else {
259
+ CPAccessRights max_el = (arm_feature(env, ARM_FEATURE_EL2)
260
+ ? PL2_RW : PL1_RW);
261
+ if ((r->access & max_el) == 0) {
262
+ return;
263
+ }
264
+ }
265
+
266
/* Combine cpreg and name into one allocation. */
267
name_len = strlen(name) + 1;
268
r2 = g_malloc(sizeof(*r2) + name_len);
269
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
270
r2->opaque = opaque;
271
}
272
273
- isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
274
- if (isbanked) {
275
+ if (make_const) {
276
+ /* This should not have been a very special register to begin. */
277
+ int old_special = r2->type & ARM_CP_SPECIAL_MASK;
278
+ assert(old_special == 0 || old_special == ARM_CP_NOP);
279
/*
280
- * Register is banked (using both entries in array).
281
- * Overwriting fieldoffset as the array is only used to define
282
- * banked registers but later only fieldoffset is used.
283
+ * Set the special function to CONST, retaining the other flags.
284
+ * This is important for e.g. ARM_CP_SVE so that we still
285
+ * take the SVE trap if CPTR_EL3.EZ == 0.
286
*/
287
- r2->fieldoffset = r->bank_fieldoffsets[ns];
288
- }
289
+ r2->type = (r2->type & ~ARM_CP_SPECIAL_MASK) | ARM_CP_CONST;
290
+ /*
291
+ * Usually, these registers become RES0, but there are a few
292
+ * special cases like VPIDR_EL2 which have a constant non-zero
293
+ * value with writes ignored.
294
+ */
295
+ if (!(r->type & ARM_CP_EL3_NO_EL2_C_NZ)) {
296
+ r2->resetvalue = 0;
297
+ }
298
+ /*
299
+ * ARM_CP_CONST has precedence, so removing the callbacks and
300
+ * offsets are not strictly necessary, but it is potentially
301
+ * less confusing to debug later.
302
+ */
303
+ r2->readfn = NULL;
304
+ r2->writefn = NULL;
305
+ r2->raw_readfn = NULL;
306
+ r2->raw_writefn = NULL;
307
+ r2->resetfn = NULL;
308
+ r2->fieldoffset = 0;
309
+ r2->bank_fieldoffsets[0] = 0;
310
+ r2->bank_fieldoffsets[1] = 0;
311
+ } else {
312
+ bool isbanked = r->bank_fieldoffsets[0] && r->bank_fieldoffsets[1];
313
314
- if (state == ARM_CP_STATE_AA32) {
315
if (isbanked) {
316
/*
317
- * If the register is banked then we don't need to migrate or
318
- * reset the 32-bit instance in certain cases:
319
- *
320
- * 1) If the register has both 32-bit and 64-bit instances then we
321
- * can count on the 64-bit instance taking care of the
322
- * non-secure bank.
323
- * 2) If ARMv8 is enabled then we can count on a 64-bit version
324
- * taking care of the secure bank. This requires that separate
325
- * 32 and 64-bit definitions are provided.
326
+ * Register is banked (using both entries in array).
327
+ * Overwriting fieldoffset as the array is only used to define
328
+ * banked registers but later only fieldoffset is used.
329
*/
330
- if ((r->state == ARM_CP_STATE_BOTH && ns) ||
331
- (arm_feature(&cpu->env, ARM_FEATURE_V8) && !ns)) {
332
+ r2->fieldoffset = r->bank_fieldoffsets[ns];
333
+ }
334
+ if (state == ARM_CP_STATE_AA32) {
335
+ if (isbanked) {
336
+ /*
337
+ * If the register is banked then we don't need to migrate or
338
+ * reset the 32-bit instance in certain cases:
339
+ *
340
+ * 1) If the register has both 32-bit and 64-bit instances
341
+ * then we can count on the 64-bit instance taking care
342
+ * of the non-secure bank.
343
+ * 2) If ARMv8 is enabled then we can count on a 64-bit
344
+ * version taking care of the secure bank. This requires
345
+ * that separate 32 and 64-bit definitions are provided.
346
+ */
347
+ if ((r->state == ARM_CP_STATE_BOTH && ns) ||
348
+ (arm_feature(env, ARM_FEATURE_V8) && !ns)) {
349
+ r2->type |= ARM_CP_ALIAS;
350
+ }
351
+ } else if ((secstate != r->secure) && !ns) {
352
+ /*
353
+ * The register is not banked so we only want to allow
354
+ * migration of the non-secure instance.
355
+ */
356
r2->type |= ARM_CP_ALIAS;
357
}
358
- } else if ((secstate != r->secure) && !ns) {
359
- /*
360
- * The register is not banked so we only want to allow migration
361
- * of the non-secure instance.
362
- */
363
- r2->type |= ARM_CP_ALIAS;
364
- }
365
366
- if (HOST_BIG_ENDIAN &&
367
- r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
368
- r2->fieldoffset += sizeof(uint32_t);
369
+ if (HOST_BIG_ENDIAN &&
370
+ r->state == ARM_CP_STATE_BOTH && r2->fieldoffset) {
371
+ r2->fieldoffset += sizeof(uint32_t);
372
+ }
201
}
373
}
202
}
374
}
203
375
204
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
376
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
205
case ARMMMUIdx_SE10_1:
377
* multiple times. Special registers (ie NOP/WFI) are
206
case ARMMMUIdx_SE10_1_PAN:
378
* never migratable and not even raw-accessible.
207
/* TODO: ARMv8.3-NV */
379
*/
208
- flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
380
- if (r->type & ARM_CP_SPECIAL_MASK) {
209
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
381
+ if (r2->type & ARM_CP_SPECIAL_MASK) {
210
break;
382
r2->type |= ARM_CP_NO_RAW;
211
case ARMMMUIdx_E20_2:
212
case ARMMMUIdx_E20_2_PAN:
213
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
214
* gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
215
*/
216
if (env->cp15.hcr_el2 & HCR_TGE) {
217
- flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
218
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
219
}
220
break;
221
default:
222
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
223
* 4) If no Allocation Tag Access, then all accesses are Unchecked.
224
*/
225
if (allocation_tag_access_enabled(env, el, sctlr)) {
226
- flags = FIELD_DP32(flags, TBFLAG_A64, ATA, 1);
227
+ DP_TBFLAG_A64(flags, ATA, 1);
228
if (tbid
229
&& !(env->pstate & PSTATE_TCO)
230
&& (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
231
- flags = FIELD_DP32(flags, TBFLAG_A64, MTE_ACTIVE, 1);
232
+ DP_TBFLAG_A64(flags, MTE_ACTIVE, 1);
233
}
234
}
235
/* And again for unprivileged accesses, if required. */
236
- if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
237
+ if (EX_TBFLAG_A64(flags, UNPRIV)
238
&& tbid
239
&& !(env->pstate & PSTATE_TCO)
240
&& (sctlr & SCTLR_TCF0)
241
&& allocation_tag_access_enabled(env, 0, sctlr)) {
242
- flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
243
+ DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1);
244
}
245
/* Cache TCMA as well as TBI. */
246
- flags = FIELD_DP32(flags, TBFLAG_A64, TCMA,
247
- aa64_va_parameter_tcma(tcr, mmu_idx));
248
+ DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx));
249
}
383
}
250
384
if (((r->crm == CP_ANY) && crm != 0) ||
251
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
252
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
253
*cs_base = 0;
254
assert_hflags_rebuild_correctly(env);
255
256
- if (FIELD_EX32(flags, TBFLAG_ANY, AARCH64_STATE)) {
257
+ if (EX_TBFLAG_ANY(flags, AARCH64_STATE)) {
258
*pc = env->pc;
259
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
260
- flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
261
+ DP_TBFLAG_A64(flags, BTYPE, env->btype);
262
}
263
} else {
264
*pc = env->regs[15];
265
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
266
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
267
FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
268
!= env->v7m.secure) {
269
- flags = FIELD_DP32(flags, TBFLAG_M32, FPCCR_S_WRONG, 1);
270
+ DP_TBFLAG_M32(flags, FPCCR_S_WRONG, 1);
271
}
272
273
if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
274
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
275
* active FP context; we must create a new FP context before
276
* executing any FP insn.
277
*/
278
- flags = FIELD_DP32(flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED, 1);
279
+ DP_TBFLAG_M32(flags, NEW_FP_CTXT_NEEDED, 1);
280
}
281
282
bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
283
if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
284
- flags = FIELD_DP32(flags, TBFLAG_M32, LSPACT, 1);
285
+ DP_TBFLAG_M32(flags, LSPACT, 1);
286
}
287
} else {
288
/*
289
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
290
* Note that VECLEN+VECSTRIDE are RES0 for M-profile.
291
*/
292
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
293
- flags = FIELD_DP32(flags, TBFLAG_A32,
294
- XSCALE_CPAR, env->cp15.c15_cpar);
295
+ DP_TBFLAG_A32(flags, XSCALE_CPAR, env->cp15.c15_cpar);
296
} else {
297
- flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN,
298
- env->vfp.vec_len);
299
- flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE,
300
- env->vfp.vec_stride);
301
+ DP_TBFLAG_A32(flags, VECLEN, env->vfp.vec_len);
302
+ DP_TBFLAG_A32(flags, VECSTRIDE, env->vfp.vec_stride);
303
}
304
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
305
- flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
306
+ DP_TBFLAG_A32(flags, VFPEN, 1);
307
}
308
}
309
310
- flags = FIELD_DP32(flags, TBFLAG_AM32, THUMB, env->thumb);
311
- flags = FIELD_DP32(flags, TBFLAG_AM32, CONDEXEC, env->condexec_bits);
312
+ DP_TBFLAG_AM32(flags, THUMB, env->thumb);
313
+ DP_TBFLAG_AM32(flags, CONDEXEC, env->condexec_bits);
314
}
315
316
/*
317
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
318
* 1 1 Active-not-pending
319
* SS_ACTIVE is set in hflags; PSTATE__SS is computed every TB.
320
*/
321
- if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
322
- (env->pstate & PSTATE_SS)) {
323
- flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE__SS, 1);
324
+ if (EX_TBFLAG_ANY(flags, SS_ACTIVE) && (env->pstate & PSTATE_SS)) {
325
+ DP_TBFLAG_ANY(flags, PSTATE__SS, 1);
326
}
327
328
*pflags = flags;
329
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
330
index XXXXXXX..XXXXXXX 100644
331
--- a/target/arm/translate-a64.c
332
+++ b/target/arm/translate-a64.c
333
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
334
!arm_el_is_aa64(env, 3);
335
dc->thumb = 0;
336
dc->sctlr_b = 0;
337
- dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
338
+ dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
339
dc->condexec_mask = 0;
340
dc->condexec_cond = 0;
341
- core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
342
+ core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
343
dc->mmu_idx = core_to_aa64_mmu_idx(core_mmu_idx);
344
- dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
345
- dc->tbid = FIELD_EX32(tb_flags, TBFLAG_A64, TBID);
346
- dc->tcma = FIELD_EX32(tb_flags, TBFLAG_A64, TCMA);
347
+ dc->tbii = EX_TBFLAG_A64(tb_flags, TBII);
348
+ dc->tbid = EX_TBFLAG_A64(tb_flags, TBID);
349
+ dc->tcma = EX_TBFLAG_A64(tb_flags, TCMA);
350
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
351
#if !defined(CONFIG_USER_ONLY)
352
dc->user = (dc->current_el == 0);
353
#endif
354
- dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
355
- dc->sve_excp_el = FIELD_EX32(tb_flags, TBFLAG_A64, SVEEXC_EL);
356
- dc->sve_len = (FIELD_EX32(tb_flags, TBFLAG_A64, ZCR_LEN) + 1) * 16;
357
- dc->pauth_active = FIELD_EX32(tb_flags, TBFLAG_A64, PAUTH_ACTIVE);
358
- dc->bt = FIELD_EX32(tb_flags, TBFLAG_A64, BT);
359
- dc->btype = FIELD_EX32(tb_flags, TBFLAG_A64, BTYPE);
360
- dc->unpriv = FIELD_EX32(tb_flags, TBFLAG_A64, UNPRIV);
361
- dc->ata = FIELD_EX32(tb_flags, TBFLAG_A64, ATA);
362
- dc->mte_active[0] = FIELD_EX32(tb_flags, TBFLAG_A64, MTE_ACTIVE);
363
- dc->mte_active[1] = FIELD_EX32(tb_flags, TBFLAG_A64, MTE0_ACTIVE);
364
+ dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
365
+ dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
366
+ dc->sve_len = (EX_TBFLAG_A64(tb_flags, ZCR_LEN) + 1) * 16;
367
+ dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
368
+ dc->bt = EX_TBFLAG_A64(tb_flags, BT);
369
+ dc->btype = EX_TBFLAG_A64(tb_flags, BTYPE);
370
+ dc->unpriv = EX_TBFLAG_A64(tb_flags, UNPRIV);
371
+ dc->ata = EX_TBFLAG_A64(tb_flags, ATA);
372
+ dc->mte_active[0] = EX_TBFLAG_A64(tb_flags, MTE_ACTIVE);
373
+ dc->mte_active[1] = EX_TBFLAG_A64(tb_flags, MTE0_ACTIVE);
374
dc->vec_len = 0;
375
dc->vec_stride = 0;
376
dc->cp_regs = arm_cpu->cp_regs;
377
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
378
* emit code to generate a software step exception
379
* end the TB
380
*/
381
- dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
382
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
383
+ dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
384
+ dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
385
dc->is_ldex = false;
386
- dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
387
+ dc->debug_target_el = EX_TBFLAG_ANY(tb_flags, DEBUG_TARGET_EL);
388
389
/* Bound the number of insns to execute to those left on the page. */
390
bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
391
diff --git a/target/arm/translate.c b/target/arm/translate.c
392
index XXXXXXX..XXXXXXX 100644
393
--- a/target/arm/translate.c
394
+++ b/target/arm/translate.c
395
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
396
*/
397
dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
398
!arm_el_is_aa64(env, 3);
399
- dc->thumb = FIELD_EX32(tb_flags, TBFLAG_AM32, THUMB);
400
- dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
401
- condexec = FIELD_EX32(tb_flags, TBFLAG_AM32, CONDEXEC);
402
+ dc->thumb = EX_TBFLAG_AM32(tb_flags, THUMB);
403
+ dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
404
+ condexec = EX_TBFLAG_AM32(tb_flags, CONDEXEC);
405
dc->condexec_mask = (condexec & 0xf) << 1;
406
dc->condexec_cond = condexec >> 4;
407
408
- core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
409
+ core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
410
dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
411
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
412
#if !defined(CONFIG_USER_ONLY)
413
dc->user = (dc->current_el == 0);
414
#endif
415
- dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
416
+ dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
417
418
if (arm_feature(env, ARM_FEATURE_M)) {
419
dc->vfp_enabled = 1;
420
dc->be_data = MO_TE;
421
- dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_M32, HANDLER);
422
+ dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
423
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
424
regime_is_secure(env, dc->mmu_idx);
425
- dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_M32, STACKCHECK);
426
- dc->v8m_fpccr_s_wrong =
427
- FIELD_EX32(tb_flags, TBFLAG_M32, FPCCR_S_WRONG);
428
+ dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
429
+ dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
430
dc->v7m_new_fp_ctxt_needed =
431
- FIELD_EX32(tb_flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED);
432
- dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_M32, LSPACT);
433
+ EX_TBFLAG_M32(tb_flags, NEW_FP_CTXT_NEEDED);
434
+ dc->v7m_lspact = EX_TBFLAG_M32(tb_flags, LSPACT);
435
} else {
436
- dc->be_data =
437
- FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
438
- dc->debug_target_el =
439
- FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
440
- dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR__B);
441
- dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
442
- dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
443
- dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
444
+ dc->debug_target_el = EX_TBFLAG_ANY(tb_flags, DEBUG_TARGET_EL);
445
+ dc->sctlr_b = EX_TBFLAG_A32(tb_flags, SCTLR__B);
446
+ dc->hstr_active = EX_TBFLAG_A32(tb_flags, HSTR_ACTIVE);
447
+ dc->ns = EX_TBFLAG_A32(tb_flags, NS);
448
+ dc->vfp_enabled = EX_TBFLAG_A32(tb_flags, VFPEN);
449
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
450
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
451
+ dc->c15_cpar = EX_TBFLAG_A32(tb_flags, XSCALE_CPAR);
452
} else {
453
- dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
454
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
455
+ dc->vec_len = EX_TBFLAG_A32(tb_flags, VECLEN);
456
+ dc->vec_stride = EX_TBFLAG_A32(tb_flags, VECSTRIDE);
457
}
458
}
459
dc->cp_regs = cpu->cp_regs;
460
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
461
* emit code to generate a software step exception
462
* end the TB
463
*/
464
- dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
465
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
466
+ dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
467
+ dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
468
dc->is_ldex = false;
469
470
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
471
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
472
DisasContext dc = { };
473
const TranslatorOps *ops = &arm_translator_ops;
474
475
- if (FIELD_EX32(tb->flags, TBFLAG_AM32, THUMB)) {
476
+ if (EX_TBFLAG_AM32(tb->flags, THUMB)) {
477
ops = &thumb_translator_ops;
478
}
479
#ifdef TARGET_AARCH64
480
- if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
481
+ if (EX_TBFLAG_ANY(tb->flags, AARCH64_STATE)) {
482
ops = &aarch64_translator_ops;
483
}
484
#endif
485
--
385
--
486
2.20.1
386
2.25.1
487
488
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Drop el3_no_el2_cp_reginfo, el3_no_el2_v8_cp_reginfo, and the local
4
vpidr_regs definition, and rely on the squashing to ARM_CP_CONST
5
while registering for v8.
6
7
This is a behavior change for v7 cpus with Security Extensions and
8
without Virtualization Extensions, in that the virtualization cpregs
9
are now correctly not present. This would be a migration compatibility
10
break, except that we have an existing bug in which migration of 32-bit
11
cpus with Security Extensions enabled does not work.
2
12
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-24-richard.henderson@linaro.org
15
Message-id: 20220506180242.216785-3-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
17
---
8
target/arm/translate-neon.c.inc | 27 ++++++++++++++++++++++-----
18
target/arm/helper.c | 158 ++++----------------------------------------
9
1 file changed, 22 insertions(+), 5 deletions(-)
19
1 file changed, 13 insertions(+), 145 deletions(-)
10
20
11
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-neon.c.inc
23
--- a/target/arm/helper.c
14
+++ b/target/arm/translate-neon.c.inc
24
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
25
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
26
.fieldoffset = offsetoflow32(CPUARMState, cp15.mdcr_el3) },
27
};
28
29
-/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */
30
-static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
31
- { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
32
- .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
33
- .access = PL2_RW,
34
- .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
35
- { .name = "HCR_EL2", .state = ARM_CP_STATE_BOTH,
36
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
37
- .access = PL2_RW,
38
- .type = ARM_CP_CONST, .resetvalue = 0 },
39
- { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
40
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
41
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
42
- { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
43
- .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
44
- .access = PL2_RW,
45
- .type = ARM_CP_CONST, .resetvalue = 0 },
46
- { .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
47
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
48
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
49
- { .name = "MAIR_EL2", .state = ARM_CP_STATE_BOTH,
50
- .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 0,
51
- .access = PL2_RW, .type = ARM_CP_CONST,
52
- .resetvalue = 0 },
53
- { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
54
- .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
55
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
56
- { .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
57
- .opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
58
- .access = PL2_RW, .type = ARM_CP_CONST,
59
- .resetvalue = 0 },
60
- { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
61
- .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
62
- .access = PL2_RW, .type = ARM_CP_CONST,
63
- .resetvalue = 0 },
64
- { .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
65
- .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 0,
66
- .access = PL2_RW, .type = ARM_CP_CONST,
67
- .resetvalue = 0 },
68
- { .name = "AFSR1_EL2", .state = ARM_CP_STATE_BOTH,
69
- .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 1, .opc2 = 1,
70
- .access = PL2_RW, .type = ARM_CP_CONST,
71
- .resetvalue = 0 },
72
- { .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
73
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
74
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
75
- { .name = "VTCR_EL2", .state = ARM_CP_STATE_BOTH,
76
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
77
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
78
- .type = ARM_CP_CONST, .resetvalue = 0 },
79
- { .name = "VTTBR", .state = ARM_CP_STATE_AA32,
80
- .cp = 15, .opc1 = 6, .crm = 2,
81
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
82
- .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
83
- { .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
84
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
85
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
86
- { .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
87
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
88
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
89
- { .name = "TPIDR_EL2", .state = ARM_CP_STATE_BOTH,
90
- .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 2,
91
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
92
- { .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
93
- .opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
94
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
95
- { .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
96
- .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
97
- .resetvalue = 0 },
98
- { .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
99
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
100
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
101
- { .name = "CNTVOFF_EL2", .state = ARM_CP_STATE_AA64,
102
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 3,
103
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
104
- { .name = "CNTVOFF", .cp = 15, .opc1 = 4, .crm = 14,
105
- .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
106
- .resetvalue = 0 },
107
- { .name = "CNTHP_CVAL_EL2", .state = ARM_CP_STATE_AA64,
108
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 2,
109
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
110
- { .name = "CNTHP_CVAL", .cp = 15, .opc1 = 6, .crm = 14,
111
- .access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_CONST,
112
- .resetvalue = 0 },
113
- { .name = "CNTHP_TVAL_EL2", .state = ARM_CP_STATE_BOTH,
114
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 0,
115
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
116
- { .name = "CNTHP_CTL_EL2", .state = ARM_CP_STATE_BOTH,
117
- .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 2, .opc2 = 1,
118
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
119
- { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
120
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
121
- .access = PL2_RW, .accessfn = access_tda,
122
- .type = ARM_CP_CONST, .resetvalue = 0 },
123
- { .name = "HPFAR_EL2", .state = ARM_CP_STATE_BOTH,
124
- .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 4,
125
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
126
- .type = ARM_CP_CONST, .resetvalue = 0 },
127
- { .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
128
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
129
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
130
- { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
131
- .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
132
- .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
133
- { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
134
- .type = ARM_CP_CONST,
135
- .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
136
- .access = PL2_RW, .resetvalue = 0 },
137
-};
138
-
139
-/* Ditto, but for registers which exist in ARMv8 but not v7 */
140
-static const ARMCPRegInfo el3_no_el2_v8_cp_reginfo[] = {
141
- { .name = "HCR2", .state = ARM_CP_STATE_AA32,
142
- .cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 4,
143
- .access = PL2_RW,
144
- .type = ARM_CP_CONST, .resetvalue = 0 },
145
-};
146
-
147
static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
16
{
148
{
17
/* Neon load/store multiple structures */
149
ARMCPU *cpu = env_archcpu(env);
18
int nregs, interleave, spacing, reg, n;
150
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
19
- MemOp endian = s->be_data;
151
define_arm_cp_regs(cpu, v8_idregs);
20
+ MemOp mop, align, endian;
152
define_arm_cp_regs(cpu, v8_cp_reginfo);
21
int mmu_idx = get_mem_index(s);
22
int size = a->size;
23
TCGv_i64 tmp64;
24
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
25
}
153
}
26
154
- if (arm_feature(env, ARM_FEATURE_EL2)) {
27
/* For our purposes, bytes are always little-endian. */
155
+
28
+ endian = s->be_data;
156
+ /*
29
if (size == 0) {
157
+ * Register the base EL2 cpregs.
30
endian = MO_LE;
158
+ * Pre v8, these registers are implemented only as part of the
159
+ * Virtualization Extensions (EL2 present). Beginning with v8,
160
+ * if EL2 is missing but EL3 is enabled, mostly these become
161
+ * RES0 from EL3, with some specific exceptions.
162
+ */
163
+ if (arm_feature(env, ARM_FEATURE_EL2)
164
+ || (arm_feature(env, ARM_FEATURE_EL3)
165
+ && arm_feature(env, ARM_FEATURE_V8))) {
166
uint64_t vmpidr_def = mpidr_read_val(env);
167
ARMCPRegInfo vpidr_regs[] = {
168
{ .name = "VPIDR", .state = ARM_CP_STATE_AA32,
169
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
170
};
171
define_one_arm_cp_reg(cpu, &rvbar);
172
}
173
- } else {
174
- /* If EL2 is missing but higher ELs are enabled, we need to
175
- * register the no_el2 reginfos.
176
- */
177
- if (arm_feature(env, ARM_FEATURE_EL3)) {
178
- /* When EL3 exists but not EL2, VPIDR and VMPIDR take the value
179
- * of MIDR_EL1 and MPIDR_EL1.
180
- */
181
- ARMCPRegInfo vpidr_regs[] = {
182
- { .name = "VPIDR_EL2", .state = ARM_CP_STATE_BOTH,
183
- .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 0,
184
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
185
- .type = ARM_CP_CONST, .resetvalue = cpu->midr,
186
- .fieldoffset = offsetof(CPUARMState, cp15.vpidr_el2) },
187
- { .name = "VMPIDR_EL2", .state = ARM_CP_STATE_BOTH,
188
- .opc0 = 3, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 5,
189
- .access = PL2_RW, .accessfn = access_el3_aa32ns,
190
- .type = ARM_CP_NO_RAW,
191
- .writefn = arm_cp_write_ignore, .readfn = mpidr_read },
192
- };
193
- define_arm_cp_regs(cpu, vpidr_regs);
194
- define_arm_cp_regs(cpu, el3_no_el2_cp_reginfo);
195
- if (arm_feature(env, ARM_FEATURE_V8)) {
196
- define_arm_cp_regs(cpu, el3_no_el2_v8_cp_reginfo);
197
- }
198
- }
31
}
199
}
32
+
200
+
33
+ /* Enforce alignment requested by the instruction */
201
+ /* Register the base EL3 cpregs. */
34
+ if (a->align) {
202
if (arm_feature(env, ARM_FEATURE_EL3)) {
35
+ align = pow2_align(a->align + 2); /* 4 ** a->align */
203
define_arm_cp_regs(cpu, el3_cp_reginfo);
36
+ } else {
204
ARMCPRegInfo el3_regs[] = {
37
+ align = s->align_mem ? MO_ALIGN : 0;
38
+ }
39
+
40
/*
41
* Consecutive little-endian elements from a single register
42
* can be promoted to a larger little-endian operation.
43
*/
44
if (interleave == 1 && endian == MO_LE) {
45
+ /* Retain any natural alignment. */
46
+ if (align == MO_ALIGN) {
47
+ align = pow2_align(size);
48
+ }
49
size = 3;
50
}
51
+
52
tmp64 = tcg_temp_new_i64();
53
addr = tcg_temp_new_i32();
54
tmp = tcg_const_i32(1 << size);
55
load_reg_var(s, addr, a->rn);
56
+
57
+ mop = endian | size | align;
58
for (reg = 0; reg < nregs; reg++) {
59
for (n = 0; n < 8 >> size; n++) {
60
int xs;
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
62
int tt = a->vd + reg + spacing * xs;
63
64
if (a->l) {
65
- gen_aa32_ld_internal_i64(s, tmp64, addr, mmu_idx,
66
- endian | size);
67
+ gen_aa32_ld_internal_i64(s, tmp64, addr, mmu_idx, mop);
68
neon_store_element64(tt, n, size, tmp64);
69
} else {
70
neon_load_element64(tmp64, tt, n, size);
71
- gen_aa32_st_internal_i64(s, tmp64, addr, mmu_idx,
72
- endian | size);
73
+ gen_aa32_st_internal_i64(s, tmp64, addr, mmu_idx, mop);
74
}
75
tcg_gen_add_i32(addr, addr, tmp);
76
+
77
+ /* Subsequent memory operations inherit alignment */
78
+ mop &= ~MO_AMASK;
79
}
80
}
81
}
82
--
205
--
83
2.20.1
206
2.25.1
84
85
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now that we have all of the proper macros defined, expanding
3
Drop zcr_no_el2_reginfo and merge the 3 registers into one array,
4
the CPUARMTBFlags structure and populating the two TB fields
4
now that ZCR_EL2 can be squashed to RES0 and ZCR_EL3 dropped
5
is relatively simple.
5
while registering.
6
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210419202257.161730-7-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-4-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.h | 49 ++++++++++++++++++++++++------------------
12
target/arm/helper.c | 55 ++++++++++++++-------------------------------
13
target/arm/translate.h | 2 +-
13
1 file changed, 17 insertions(+), 38 deletions(-)
14
target/arm/helper.c | 10 +++++----
15
3 files changed, 35 insertions(+), 26 deletions(-)
16
14
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct ARMPACKey {
22
/* See the commentary above the TBFLAG field definitions. */
23
typedef struct CPUARMTBFlags {
24
uint32_t flags;
25
+ target_ulong flags2;
26
} CPUARMTBFlags;
27
28
typedef struct CPUARMState {
29
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
30
#include "exec/cpu-all.h"
31
32
/*
33
- * Bit usage in the TB flags field: bit 31 indicates whether we are
34
- * in 32 or 64 bit mode. The meaning of the other bits depends on that.
35
- * We put flags which are shared between 32 and 64 bit mode at the top
36
- * of the word, and flags which apply to only one mode at the bottom.
37
+ * We have more than 32-bits worth of state per TB, so we split the data
38
+ * between tb->flags and tb->cs_base, which is otherwise unused for ARM.
39
+ * We collect these two parts in CPUARMTBFlags where they are named
40
+ * flags and flags2 respectively.
41
*
42
- * 31 20 18 14 9 0
43
- * +--------------+-----+-----+----------+--------------+
44
- * | | | TBFLAG_A32 | |
45
- * | | +-----+----------+ TBFLAG_AM32 |
46
- * | TBFLAG_ANY | |TBFLAG_M32| |
47
- * | +-----------+----------+--------------|
48
- * | | TBFLAG_A64 |
49
- * +--------------+-------------------------------------+
50
- * 31 20 0
51
+ * The flags that are shared between all execution modes, TBFLAG_ANY,
52
+ * are stored in flags. The flags that are specific to a given mode
53
+ * are stores in flags2. Since cs_base is sized on the configured
54
+ * address size, flags2 always has 64-bits for A64, and a minimum of
55
+ * 32-bits for A32 and M32.
56
+ *
57
+ * The bits for 32-bit A-profile and M-profile partially overlap:
58
+ *
59
+ * 18 9 0
60
+ * +----------------+--------------+
61
+ * | TBFLAG_A32 | |
62
+ * +-----+----------+ TBFLAG_AM32 |
63
+ * | |TBFLAG_M32| |
64
+ * +-----+----------+--------------+
65
+ * 14 9 0
66
*
67
* Unless otherwise noted, these bits are cached in env->hflags.
68
*/
69
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
70
#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
71
(DST.flags = FIELD_DP32(DST.flags, TBFLAG_ANY, WHICH, VAL))
72
#define DP_TBFLAG_A64(DST, WHICH, VAL) \
73
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A64, WHICH, VAL))
74
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A64, WHICH, VAL))
75
#define DP_TBFLAG_A32(DST, WHICH, VAL) \
76
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A32, WHICH, VAL))
77
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A32, WHICH, VAL))
78
#define DP_TBFLAG_M32(DST, WHICH, VAL) \
79
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_M32, WHICH, VAL))
80
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_M32, WHICH, VAL))
81
#define DP_TBFLAG_AM32(DST, WHICH, VAL) \
82
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_AM32, WHICH, VAL))
83
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_AM32, WHICH, VAL))
84
85
#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_ANY, WHICH)
86
-#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A64, WHICH)
87
-#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A32, WHICH)
88
-#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_M32, WHICH)
89
-#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_AM32, WHICH)
90
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A64, WHICH)
91
+#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A32, WHICH)
92
+#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_M32, WHICH)
93
+#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_AM32, WHICH)
94
95
/**
96
* cpu_mmu_index:
97
diff --git a/target/arm/translate.h b/target/arm/translate.h
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/arm/translate.h
100
+++ b/target/arm/translate.h
101
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
102
*/
103
static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb)
104
{
105
- return (CPUARMTBFlags){ tb->flags };
106
+ return (CPUARMTBFlags){ tb->flags, tb->cs_base };
107
}
108
109
/*
110
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
111
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
113
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
114
@@ -XXX,XX +XXX,XX @@ static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
19
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
115
CPUARMTBFlags c = env->hflags;
116
CPUARMTBFlags r = rebuild_hflags_internal(env);
117
118
- if (unlikely(c.flags != r.flags)) {
119
- fprintf(stderr, "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
120
- c.flags, r.flags);
121
+ if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) {
122
+ fprintf(stderr, "TCG hflags mismatch "
123
+ "(current:(0x%08x,0x" TARGET_FMT_lx ")"
124
+ " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n",
125
+ c.flags, c.flags2, r.flags, r.flags2);
126
abort();
127
}
20
}
128
#endif
21
}
129
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
22
130
{
23
-static const ARMCPRegInfo zcr_el1_reginfo = {
131
CPUARMTBFlags flags;
24
- .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
132
25
- .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
133
- *cs_base = 0;
26
- .access = PL1_RW, .type = ARM_CP_SVE,
134
assert_hflags_rebuild_correctly(env);
27
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
135
flags = env->hflags;
28
- .writefn = zcr_write, .raw_writefn = raw_write
136
29
-};
137
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
30
-
31
-static const ARMCPRegInfo zcr_el2_reginfo = {
32
- .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
33
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
34
- .access = PL2_RW, .type = ARM_CP_SVE,
35
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
36
- .writefn = zcr_write, .raw_writefn = raw_write
37
-};
38
-
39
-static const ARMCPRegInfo zcr_no_el2_reginfo = {
40
- .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
41
- .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
42
- .access = PL2_RW, .type = ARM_CP_SVE,
43
- .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
44
-};
45
-
46
-static const ARMCPRegInfo zcr_el3_reginfo = {
47
- .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
48
- .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
49
- .access = PL3_RW, .type = ARM_CP_SVE,
50
- .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
51
- .writefn = zcr_write, .raw_writefn = raw_write
52
+static const ARMCPRegInfo zcr_reginfo[] = {
53
+ { .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
54
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
55
+ .access = PL1_RW, .type = ARM_CP_SVE,
56
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
57
+ .writefn = zcr_write, .raw_writefn = raw_write },
58
+ { .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
59
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
60
+ .access = PL2_RW, .type = ARM_CP_SVE,
61
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
62
+ .writefn = zcr_write, .raw_writefn = raw_write },
63
+ { .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
64
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
65
+ .access = PL3_RW, .type = ARM_CP_SVE,
66
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
67
+ .writefn = zcr_write, .raw_writefn = raw_write },
68
};
69
70
void hw_watchpoint_update(ARMCPU *cpu, int n)
71
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
138
}
72
}
139
73
140
*pflags = flags.flags;
74
if (cpu_isar_feature(aa64_sve, cpu)) {
141
+ *cs_base = flags.flags2;
75
- define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
142
}
76
- if (arm_feature(env, ARM_FEATURE_EL2)) {
77
- define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
78
- } else {
79
- define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
80
- }
81
- if (arm_feature(env, ARM_FEATURE_EL3)) {
82
- define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
83
- }
84
+ define_arm_cp_regs(cpu, zcr_reginfo);
85
}
143
86
144
#ifdef TARGET_AARCH64
87
#ifdef TARGET_AARCH64
145
--
88
--
146
2.20.1
89
2.25.1
147
148
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
This register is present for either VHE or Debugv8p2.
2
4
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-30-richard.henderson@linaro.org
7
Message-id: 20220506180242.216785-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/translate-a64.c | 15 +++++++++++----
10
target/arm/helper.c | 15 +++++++++++----
9
1 file changed, 11 insertions(+), 4 deletions(-)
11
1 file changed, 11 insertions(+), 4 deletions(-)
10
12
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
15
--- a/target/arm/helper.c
14
+++ b/target/arm/translate-a64.c
16
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo jazelle_regs[] = {
16
bool is_postidx = extract32(insn, 23, 1);
18
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
17
bool is_q = extract32(insn, 30, 1);
19
};
18
TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
20
19
- MemOp endian = s->be_data;
21
+static const ARMCPRegInfo contextidr_el2 = {
20
+ MemOp endian, align, mop;
22
+ .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
21
23
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
22
int total; /* total bytes */
24
+ .access = PL2_RW,
23
int elements; /* elements per vector */
25
+ .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2])
24
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
26
+};
27
+
28
static const ARMCPRegInfo vhe_reginfo[] = {
29
- { .name = "CONTEXTIDR_EL2", .state = ARM_CP_STATE_AA64,
30
- .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 1,
31
- .access = PL2_RW,
32
- .fieldoffset = offsetof(CPUARMState, cp15.contextidr_el[2]) },
33
{ .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
34
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 1,
35
.access = PL2_RW, .writefn = vmsa_tcr_ttbr_el2_write,
36
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
37
define_one_arm_cp_reg(cpu, &ssbs_reginfo);
25
}
38
}
26
39
27
/* For our purposes, bytes are always little-endian. */
40
+ if (cpu_isar_feature(aa64_vh, cpu) ||
28
+ endian = s->be_data;
41
+ cpu_isar_feature(aa64_debugv8p2, cpu)) {
29
if (size == 0) {
42
+ define_one_arm_cp_reg(cpu, &contextidr_el2);
30
endian = MO_LE;
43
+ }
44
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
45
define_arm_cp_regs(cpu, vhe_reginfo);
31
}
46
}
32
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
33
* Consecutive little-endian elements from a single register
34
* can be promoted to a larger little-endian operation.
35
*/
36
+ align = MO_ALIGN;
37
if (selem == 1 && endian == MO_LE) {
38
+ align = pow2_align(size);
39
size = 3;
40
}
41
- elements = (is_q ? 16 : 8) >> size;
42
+ if (!s->align_mem) {
43
+ align = 0;
44
+ }
45
+ mop = endian | size | align;
46
47
+ elements = (is_q ? 16 : 8) >> size;
48
tcg_ebytes = tcg_const_i64(1 << size);
49
for (r = 0; r < rpt; r++) {
50
int e;
51
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
52
for (xs = 0; xs < selem; xs++) {
53
int tt = (rt + r + xs) % 32;
54
if (is_store) {
55
- do_vec_st(s, tt, e, clean_addr, size | endian);
56
+ do_vec_st(s, tt, e, clean_addr, mop);
57
} else {
58
- do_vec_ld(s, tt, e, clean_addr, size | endian);
59
+ do_vec_ld(s, tt, e, clean_addr, mop);
60
}
61
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
62
}
63
--
47
--
64
2.20.1
48
2.25.1
65
66
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For consistency with the mte_check1 + mte_checkN merge
3
Previously we were defining some of these in user-only mode,
4
to mte_check, rename the probe function as well.
4
but none of them are accessible from user-only, therefore
5
5
define them only in system mode.
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
7
This will shortly be used from cpu_tcg.c also.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210416183106.1516563-8-richard.henderson@linaro.org
11
Message-id: 20220506180242.216785-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/internals.h | 2 +-
14
target/arm/internals.h | 6 ++++
12
target/arm/mte_helper.c | 6 +++---
15
target/arm/cpu64.c | 64 +++---------------------------------------
13
target/arm/sve_helper.c | 6 +++---
16
target/arm/cpu_tcg.c | 59 ++++++++++++++++++++++++++++++++++++++
14
3 files changed, 7 insertions(+), 7 deletions(-)
17
3 files changed, 69 insertions(+), 60 deletions(-)
15
18
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
21
--- a/target/arm/internals.h
19
+++ b/target/arm/internals.h
22
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TCMA, 6, 2)
23
@@ -XXX,XX +XXX,XX @@ int aarch64_fpu_gdb_get_reg(CPUARMState *env, GByteArray *buf, int reg);
21
FIELD(MTEDESC, WRITE, 8, 1)
24
int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg);
22
FIELD(MTEDESC, SIZEM1, 9, SIMD_DATA_BITS - 9) /* size - 1 */
25
#endif
23
26
24
-bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr);
27
+#ifdef CONFIG_USER_ONLY
25
+bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
28
+static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
26
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
29
+#else
27
30
+void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
28
static inline int allocation_tag_from_addr(uint64_t ptr)
31
+#endif
29
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
32
+
33
#endif
34
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
30
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/mte_helper.c
36
--- a/target/arm/cpu64.c
32
+++ b/target/arm/mte_helper.c
37
+++ b/target/arm/cpu64.c
33
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
38
@@ -XXX,XX +XXX,XX @@
34
* exception for inaccessible pages, and resolves the virtual address
39
#include "hvf_arm.h"
35
* into the softmmu tlb.
40
#include "qapi/visitor.h"
36
*
41
#include "hw/qdev-properties.h"
37
- * When RA == 0, this is for mte_probe1. The page is expected to be
42
-#include "cpregs.h"
38
+ * When RA == 0, this is for mte_probe. The page is expected to be
43
+#include "internals.h"
39
* valid. Indicate to probe_access_flags no-fault, then assert that
44
40
* we received a valid page.
45
41
*/
46
-#ifndef CONFIG_USER_ONLY
42
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mte_check)(CPUARMState *env, uint32_t desc, uint64_t ptr)
47
-static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
48
-{
49
- ARMCPU *cpu = env_archcpu(env);
50
-
51
- /* Number of cores is in [25:24]; otherwise we RAZ */
52
- return (cpu->core_count - 1) << 24;
53
-}
54
-#endif
55
-
56
-static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
57
-#ifndef CONFIG_USER_ONLY
58
- { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
59
- .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
60
- .access = PL1_RW, .readfn = a57_a53_l2ctlr_read,
61
- .writefn = arm_cp_write_ignore },
62
- { .name = "L2CTLR",
63
- .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
64
- .access = PL1_RW, .readfn = a57_a53_l2ctlr_read,
65
- .writefn = arm_cp_write_ignore },
66
-#endif
67
- { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
68
- .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
69
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
70
- { .name = "L2ECTLR",
71
- .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
72
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
73
- { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
74
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
75
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
76
- { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
77
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
78
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
79
- { .name = "CPUACTLR",
80
- .cp = 15, .opc1 = 0, .crm = 15,
81
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
82
- { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
83
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
84
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
85
- { .name = "CPUECTLR",
86
- .cp = 15, .opc1 = 1, .crm = 15,
87
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
88
- { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
89
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2,
90
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
91
- { .name = "CPUMERRSR",
92
- .cp = 15, .opc1 = 2, .crm = 15,
93
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
94
- { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64,
95
- .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3,
96
- .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
97
- { .name = "L2MERRSR",
98
- .cp = 15, .opc1 = 3, .crm = 15,
99
- .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
100
-};
101
-
102
static void aarch64_a57_initfn(Object *obj)
103
{
104
ARMCPU *cpu = ARM_CPU(obj);
105
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
106
cpu->gic_num_lrs = 4;
107
cpu->gic_vpribits = 5;
108
cpu->gic_vprebits = 5;
109
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
110
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
43
}
111
}
44
112
45
/*
113
static void aarch64_a53_initfn(Object *obj)
46
- * No-fault version of mte_check1, to be used by SVE for MemSingleNF.
114
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
47
+ * No-fault version of mte_check, to be used by SVE for MemSingleNF.
115
cpu->gic_num_lrs = 4;
48
* Returns false if the access is Checked and the check failed. This
116
cpu->gic_vpribits = 5;
49
* is only intended to probe the tag -- the validity of the page must
117
cpu->gic_vprebits = 5;
50
* be checked beforehand.
118
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
51
*/
119
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
52
-bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
120
}
53
+bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr)
121
54
{
122
static void aarch64_a72_initfn(Object *obj)
55
uint64_t fault;
123
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
56
int ret = mte_probe_int(env, desc, ptr, 0, &fault);
124
cpu->gic_num_lrs = 4;
57
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
125
cpu->gic_vpribits = 5;
126
cpu->gic_vprebits = 5;
127
- define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
128
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
129
}
130
131
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
132
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
58
index XXXXXXX..XXXXXXX 100644
133
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/sve_helper.c
134
--- a/target/arm/cpu_tcg.c
60
+++ b/target/arm/sve_helper.c
135
+++ b/target/arm/cpu_tcg.c
61
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
136
@@ -XXX,XX +XXX,XX @@
62
/* Watchpoint hit, see below. */
137
#endif
63
goto do_fault;
138
#include "cpregs.h"
64
}
139
65
- if (mtedesc && !mte_probe1(env, mtedesc, addr + mem_off)) {
140
+#ifndef CONFIG_USER_ONLY
66
+ if (mtedesc && !mte_probe(env, mtedesc, addr + mem_off)) {
141
+static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
67
goto do_fault;
142
+{
68
}
143
+ ARMCPU *cpu = env_archcpu(env);
69
/*
144
+
70
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
145
+ /* Number of cores is in [25:24]; otherwise we RAZ */
71
& BP_MEM_READ)) {
146
+ return (cpu->core_count - 1) << 24;
72
goto do_fault;
147
+}
73
}
148
+
74
- if (mtedesc && !mte_probe1(env, mtedesc, addr + mem_off)) {
149
+static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
75
+ if (mtedesc && !mte_probe(env, mtedesc, addr + mem_off)) {
150
+ { .name = "L2CTLR_EL1", .state = ARM_CP_STATE_AA64,
76
goto do_fault;
151
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 2,
77
}
152
+ .access = PL1_RW, .readfn = l2ctlr_read,
78
host_fn(vd, reg_off, host + mem_off);
153
+ .writefn = arm_cp_write_ignore },
79
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
154
+ { .name = "L2CTLR",
80
}
155
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 2,
81
if (mtedesc &&
156
+ .access = PL1_RW, .readfn = l2ctlr_read,
82
arm_tlb_mte_tagged(&info.attrs) &&
157
+ .writefn = arm_cp_write_ignore },
83
- !mte_probe1(env, mtedesc, addr)) {
158
+ { .name = "L2ECTLR_EL1", .state = ARM_CP_STATE_AA64,
84
+ !mte_probe(env, mtedesc, addr)) {
159
+ .opc0 = 3, .opc1 = 1, .crn = 11, .crm = 0, .opc2 = 3,
85
goto fault;
160
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
86
}
161
+ { .name = "L2ECTLR",
162
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 0, .opc2 = 3,
163
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
164
+ { .name = "L2ACTLR", .state = ARM_CP_STATE_BOTH,
165
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 0, .opc2 = 0,
166
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
167
+ { .name = "CPUACTLR_EL1", .state = ARM_CP_STATE_AA64,
168
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 0,
169
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
170
+ { .name = "CPUACTLR",
171
+ .cp = 15, .opc1 = 0, .crm = 15,
172
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
173
+ { .name = "CPUECTLR_EL1", .state = ARM_CP_STATE_AA64,
174
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 1,
175
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
176
+ { .name = "CPUECTLR",
177
+ .cp = 15, .opc1 = 1, .crm = 15,
178
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
179
+ { .name = "CPUMERRSR_EL1", .state = ARM_CP_STATE_AA64,
180
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 2,
181
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
182
+ { .name = "CPUMERRSR",
183
+ .cp = 15, .opc1 = 2, .crm = 15,
184
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
185
+ { .name = "L2MERRSR_EL1", .state = ARM_CP_STATE_AA64,
186
+ .opc0 = 3, .opc1 = 1, .crn = 15, .crm = 2, .opc2 = 3,
187
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
188
+ { .name = "L2MERRSR",
189
+ .cp = 15, .opc1 = 3, .crm = 15,
190
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
191
+};
192
+
193
+void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu)
194
+{
195
+ define_arm_cp_regs(cpu, cortex_a72_a57_a53_cp_reginfo);
196
+}
197
+#endif /* !CONFIG_USER_ONLY */
198
+
199
/* CPU models. These are not needed for the AArch64 linux-user build. */
200
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
87
201
88
--
202
--
89
2.20.1
203
2.25.1
90
91
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Instead of starting with cortex-a15 and adding v8 features to
4
a v7 cpu, begin with a v8 cpu stripped of its aarch64 features.
5
This fixes the long-standing to-do where we only enabled v8
6
features for user-only.
2
7
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-17-richard.henderson@linaro.org
10
Message-id: 20220506180242.216785-7-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/translate.c | 4 ++--
13
target/arm/cpu_tcg.c | 151 ++++++++++++++++++++++++++-----------------
9
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 92 insertions(+), 59 deletions(-)
10
15
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
18
--- a/target/arm/cpu_tcg.c
14
+++ b/target/arm/translate.c
19
+++ b/target/arm/cpu_tcg.c
15
@@ -XXX,XX +XXX,XX @@ static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
20
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
16
addr = load_reg(s, a->rn);
21
static void arm_max_initfn(Object *obj)
17
tmp = load_reg(s, a->rt);
22
{
18
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
23
ARMCPU *cpu = ARM_CPU(obj);
19
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop);
24
+ uint32_t t;
20
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
25
21
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
26
- cortex_a15_initfn(obj);
22
27
+ /* aarch64_a57_initfn, advertising none of the aarch64 features */
23
tcg_temp_free_i32(tmp);
28
+ cpu->dtb_compatible = "arm,cortex-a57";
24
@@ -XXX,XX +XXX,XX @@ static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
29
+ set_feature(&cpu->env, ARM_FEATURE_V8);
25
30
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
26
addr = load_reg(s, a->rn);
31
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
27
tmp = tcg_temp_new_i32();
32
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
28
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop);
33
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
29
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
34
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
30
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
35
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
31
tcg_temp_free_i32(addr);
36
+ cpu->midr = 0x411fd070;
37
+ cpu->revidr = 0x00000000;
38
+ cpu->reset_fpsid = 0x41034070;
39
+ cpu->isar.mvfr0 = 0x10110222;
40
+ cpu->isar.mvfr1 = 0x12111111;
41
+ cpu->isar.mvfr2 = 0x00000043;
42
+ cpu->ctr = 0x8444c004;
43
+ cpu->reset_sctlr = 0x00c50838;
44
+ cpu->isar.id_pfr0 = 0x00000131;
45
+ cpu->isar.id_pfr1 = 0x00011011;
46
+ cpu->isar.id_dfr0 = 0x03010066;
47
+ cpu->id_afr0 = 0x00000000;
48
+ cpu->isar.id_mmfr0 = 0x10101105;
49
+ cpu->isar.id_mmfr1 = 0x40000000;
50
+ cpu->isar.id_mmfr2 = 0x01260000;
51
+ cpu->isar.id_mmfr3 = 0x02102211;
52
+ cpu->isar.id_isar0 = 0x02101110;
53
+ cpu->isar.id_isar1 = 0x13112111;
54
+ cpu->isar.id_isar2 = 0x21232042;
55
+ cpu->isar.id_isar3 = 0x01112131;
56
+ cpu->isar.id_isar4 = 0x00011142;
57
+ cpu->isar.id_isar5 = 0x00011121;
58
+ cpu->isar.id_isar6 = 0;
59
+ cpu->isar.dbgdidr = 0x3516d000;
60
+ cpu->clidr = 0x0a200023;
61
+ cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
62
+ cpu->ccsidr[1] = 0x201fe012; /* 48KB L1 icache */
63
+ cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
64
+ define_cortex_a72_a57_a53_cp_reginfo(cpu);
65
66
- /* old-style VFP short-vector support */
67
- cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
68
+ /* Add additional features supported by QEMU */
69
+ t = cpu->isar.id_isar5;
70
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
71
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
72
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
73
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
74
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
75
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
76
+ cpu->isar.id_isar5 = t;
77
+
78
+ t = cpu->isar.id_isar6;
79
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
80
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
81
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
82
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
83
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
84
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
85
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
86
+ cpu->isar.id_isar6 = t;
87
+
88
+ t = cpu->isar.mvfr1;
89
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
90
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
91
+ cpu->isar.mvfr1 = t;
92
+
93
+ t = cpu->isar.mvfr2;
94
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
95
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
96
+ cpu->isar.mvfr2 = t;
97
+
98
+ t = cpu->isar.id_mmfr3;
99
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
100
+ cpu->isar.id_mmfr3 = t;
101
+
102
+ t = cpu->isar.id_mmfr4;
103
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
104
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
105
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
106
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
107
+ cpu->isar.id_mmfr4 = t;
108
+
109
+ t = cpu->isar.id_pfr0;
110
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1);
111
+ cpu->isar.id_pfr0 = t;
112
+
113
+ t = cpu->isar.id_pfr2;
114
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
115
+ cpu->isar.id_pfr2 = t;
116
117
#ifdef CONFIG_USER_ONLY
118
/*
119
- * We don't set these in system emulation mode for the moment,
120
- * since we don't correctly set (all of) the ID registers to
121
- * advertise them.
122
+ * Break with true ARMv8 and add back old-style VFP short-vector support.
123
+ * Only do this for user-mode, where -cpu max is the default, so that
124
+ * older v6 and v7 programs are more likely to work without adjustment.
125
*/
126
- set_feature(&cpu->env, ARM_FEATURE_V8);
127
- {
128
- uint32_t t;
129
-
130
- t = cpu->isar.id_isar5;
131
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
132
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
133
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
134
- t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
135
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
136
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
137
- cpu->isar.id_isar5 = t;
138
-
139
- t = cpu->isar.id_isar6;
140
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
141
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
142
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
143
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
144
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
145
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
146
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
147
- cpu->isar.id_isar6 = t;
148
-
149
- t = cpu->isar.mvfr1;
150
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
151
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
152
- cpu->isar.mvfr1 = t;
153
-
154
- t = cpu->isar.mvfr2;
155
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
156
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
157
- cpu->isar.mvfr2 = t;
158
-
159
- t = cpu->isar.id_mmfr3;
160
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
161
- cpu->isar.id_mmfr3 = t;
162
-
163
- t = cpu->isar.id_mmfr4;
164
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
165
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
166
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
167
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
168
- cpu->isar.id_mmfr4 = t;
169
-
170
- t = cpu->isar.id_pfr0;
171
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
172
- cpu->isar.id_pfr0 = t;
173
-
174
- t = cpu->isar.id_pfr2;
175
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
176
- cpu->isar.id_pfr2 = t;
177
- }
178
-#endif /* CONFIG_USER_ONLY */
179
+ cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
180
+#endif
181
}
182
#endif /* !TARGET_AARCH64 */
32
183
33
--
184
--
34
2.20.1
185
2.25.1
35
36
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 set this for qemu-system-aarch64, but failed to do so
4
for the strictly 32-bit emulation.
5
6
Fixes: 3bec78447a9 ("target/arm: Provide ARMv8.4-PMU in '-cpu max'")
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-31-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-8-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/translate-a64.c | 9 +++++----
12
target/arm/cpu_tcg.c | 4 ++++
9
1 file changed, 5 insertions(+), 4 deletions(-)
13
1 file changed, 4 insertions(+)
10
14
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
17
--- a/target/arm/cpu_tcg.c
14
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/cpu_tcg.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
16
int index = is_q << 3 | S << 2 | size;
20
t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
17
int xs, total;
21
cpu->isar.id_pfr2 = t;
18
TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
22
19
+ MemOp mop;
23
+ t = cpu->isar.id_dfr0;
20
24
+ t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
21
if (extract32(insn, 31, 1)) {
25
+ cpu->isar.id_dfr0 = t;
22
unallocated_encoding(s);
26
+
23
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
27
#ifdef CONFIG_USER_ONLY
24
28
/*
25
clean_addr = gen_mte_checkN(s, tcg_rn, !is_load, is_postidx || rn != 31,
29
* Break with true ARMv8 and add back old-style VFP short-vector support.
26
total);
27
+ mop = finalize_memop(s, scale);
28
29
tcg_ebytes = tcg_const_i64(1 << scale);
30
for (xs = 0; xs < selem; xs++) {
31
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
32
/* Load and replicate to all elements */
33
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
34
35
- tcg_gen_qemu_ld_i64(tcg_tmp, clean_addr,
36
- get_mem_index(s), s->be_data + scale);
37
+ tcg_gen_qemu_ld_i64(tcg_tmp, clean_addr, get_mem_index(s), mop);
38
tcg_gen_gvec_dup_i64(scale, vec_full_reg_offset(s, rt),
39
(is_q + 1) * 8, vec_full_reg_size(s),
40
tcg_tmp);
41
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
42
} else {
43
/* Load/store one element per register */
44
if (is_load) {
45
- do_vec_ld(s, rt, index, clean_addr, scale | s->be_data);
46
+ do_vec_ld(s, rt, index, clean_addr, mop);
47
} else {
48
- do_vec_st(s, rt, index, clean_addr, scale | s->be_data);
49
+ do_vec_st(s, rt, index, clean_addr, mop);
50
}
51
}
52
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
53
--
30
--
54
2.20.1
31
2.25.1
55
56
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
After recent changes, mte_checkN does not use ESIZE,
3
Share the code to set AArch32 max features so that we no
4
and mte_check1 never used TSIZE. We can combine the
4
longer have code drift between qemu{-system,}-{arm,aarch64}.
5
two into a single field: SIZEM1.
6
5
7
Choose to pass size - 1 because size == 0 is never used,
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
our immediate need in mte_probe_int is for the address
9
of the last byte (ptr + size - 1), and since almost all
10
operations are powers of 2, this makes the immediate
11
constant one bit smaller.
12
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210416183106.1516563-6-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-9-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
target/arm/internals.h | 4 ++--
11
target/arm/internals.h | 2 +
19
target/arm/mte_helper.c | 18 ++++++++----------
12
target/arm/cpu64.c | 50 +-----------------
20
target/arm/translate-a64.c | 5 ++---
13
target/arm/cpu_tcg.c | 114 ++++++++++++++++++++++-------------------
21
target/arm/translate-sve.c | 5 ++---
14
3 files changed, 65 insertions(+), 101 deletions(-)
22
4 files changed, 14 insertions(+), 18 deletions(-)
23
15
24
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/internals.h
18
--- a/target/arm/internals.h
27
+++ b/target/arm/internals.h
19
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ static inline void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu) { }
21
void define_cortex_a72_a57_a53_cp_reginfo(ARMCPU *cpu);
22
#endif
23
24
+void aa32_max_features(ARMCPU *cpu);
25
+
26
#endif
27
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu64.c
30
+++ b/target/arm/cpu64.c
31
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
32
{
33
ARMCPU *cpu = ARM_CPU(obj);
34
uint64_t t;
35
- uint32_t u;
36
37
if (kvm_enabled() || hvf_enabled()) {
38
/* With KVM or HVF, '-cpu max' is identical to '-cpu host' */
39
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
40
t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1);
41
cpu->isar.id_aa64zfr0 = t;
42
43
- /* Replicate the same data to the 32-bit id registers. */
44
- u = cpu->isar.id_isar5;
45
- u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
46
- u = FIELD_DP32(u, ID_ISAR5, SHA1, 1);
47
- u = FIELD_DP32(u, ID_ISAR5, SHA2, 1);
48
- u = FIELD_DP32(u, ID_ISAR5, CRC32, 1);
49
- u = FIELD_DP32(u, ID_ISAR5, RDM, 1);
50
- u = FIELD_DP32(u, ID_ISAR5, VCMA, 1);
51
- cpu->isar.id_isar5 = u;
52
-
53
- u = cpu->isar.id_isar6;
54
- u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1);
55
- u = FIELD_DP32(u, ID_ISAR6, DP, 1);
56
- u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
57
- u = FIELD_DP32(u, ID_ISAR6, SB, 1);
58
- u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
59
- u = FIELD_DP32(u, ID_ISAR6, BF16, 1);
60
- u = FIELD_DP32(u, ID_ISAR6, I8MM, 1);
61
- cpu->isar.id_isar6 = u;
62
-
63
- u = cpu->isar.id_pfr0;
64
- u = FIELD_DP32(u, ID_PFR0, DIT, 1);
65
- cpu->isar.id_pfr0 = u;
66
-
67
- u = cpu->isar.id_pfr2;
68
- u = FIELD_DP32(u, ID_PFR2, SSBS, 1);
69
- cpu->isar.id_pfr2 = u;
70
-
71
- u = cpu->isar.id_mmfr3;
72
- u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
73
- cpu->isar.id_mmfr3 = u;
74
-
75
- u = cpu->isar.id_mmfr4;
76
- u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
77
- u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
78
- u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
79
- u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
80
- cpu->isar.id_mmfr4 = u;
81
-
82
t = cpu->isar.id_aa64dfr0;
83
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
84
cpu->isar.id_aa64dfr0 = t;
85
86
- u = cpu->isar.id_dfr0;
87
- u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
88
- cpu->isar.id_dfr0 = u;
89
-
90
- u = cpu->isar.mvfr1;
91
- u = FIELD_DP32(u, MVFR1, FPHP, 3); /* v8.2-FP16 */
92
- u = FIELD_DP32(u, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
93
- cpu->isar.mvfr1 = u;
94
+ /* Replicate the same data to the 32-bit id registers. */
95
+ aa32_max_features(cpu);
96
97
#ifdef CONFIG_USER_ONLY
98
/*
99
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/cpu_tcg.c
102
+++ b/target/arm/cpu_tcg.c
28
@@ -XXX,XX +XXX,XX @@
103
@@ -XXX,XX +XXX,XX @@
29
#define TARGET_ARM_INTERNALS_H
104
#endif
30
105
#include "cpregs.h"
31
#include "hw/registerfields.h"
106
32
+#include "tcg/tcg-gvec-desc.h"
107
+
33
#include "syndrome.h"
108
+/* Share AArch32 -cpu max features with AArch64. */
34
109
+void aa32_max_features(ARMCPU *cpu)
35
/* register banks for CPU modes */
110
+{
36
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, MIDX, 0, 4)
111
+ uint32_t t;
37
FIELD(MTEDESC, TBI, 4, 2)
112
+
38
FIELD(MTEDESC, TCMA, 6, 2)
113
+ /* Add additional features supported by QEMU */
39
FIELD(MTEDESC, WRITE, 8, 1)
114
+ t = cpu->isar.id_isar5;
40
-FIELD(MTEDESC, ESIZE, 9, 5)
115
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2);
41
-FIELD(MTEDESC, TSIZE, 14, 10) /* mte_checkN only */
116
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
42
+FIELD(MTEDESC, SIZEM1, 9, SIMD_DATA_BITS - 9) /* size - 1 */
117
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
43
118
+ t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
44
bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr);
119
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
45
uint64_t mte_check1(CPUARMState *env, uint32_t desc,
120
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
46
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
121
+ cpu->isar.id_isar5 = t;
47
index XXXXXXX..XXXXXXX 100644
122
+
48
--- a/target/arm/mte_helper.c
123
+ t = cpu->isar.id_isar6;
49
+++ b/target/arm/mte_helper.c
124
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
50
@@ -XXX,XX +XXX,XX @@ static int checkN(uint8_t *mem, int odd, int cmp, int count)
125
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1);
51
* Return positive on success with tbi enabled.
126
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
52
*/
127
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
53
static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
128
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
54
- uintptr_t ra, uint32_t total, uint64_t *fault)
129
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
55
+ uintptr_t ra, uint64_t *fault)
130
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
131
+ cpu->isar.id_isar6 = t;
132
+
133
+ t = cpu->isar.mvfr1;
134
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
135
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
136
+ cpu->isar.mvfr1 = t;
137
+
138
+ t = cpu->isar.mvfr2;
139
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
140
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
141
+ cpu->isar.mvfr2 = t;
142
+
143
+ t = cpu->isar.id_mmfr3;
144
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
145
+ cpu->isar.id_mmfr3 = t;
146
+
147
+ t = cpu->isar.id_mmfr4;
148
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
149
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
150
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
151
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
152
+ cpu->isar.id_mmfr4 = t;
153
+
154
+ t = cpu->isar.id_pfr0;
155
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1);
156
+ cpu->isar.id_pfr0 = t;
157
+
158
+ t = cpu->isar.id_pfr2;
159
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
160
+ cpu->isar.id_pfr2 = t;
161
+
162
+ t = cpu->isar.id_dfr0;
163
+ t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
164
+ cpu->isar.id_dfr0 = t;
165
+}
166
+
167
#ifndef CONFIG_USER_ONLY
168
static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
56
{
169
{
57
int mmu_idx, ptr_tag, bit55;
170
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
58
uint64_t ptr_last, prev_page, next_page;
171
static void arm_max_initfn(Object *obj)
59
uint64_t tag_first, tag_last;
60
uint64_t tag_byte_first, tag_byte_last;
61
- uint32_t tag_count, tag_size, n, c;
62
+ uint32_t sizem1, tag_count, tag_size, n, c;
63
uint8_t *mem1, *mem2;
64
MMUAccessType type;
65
66
@@ -XXX,XX +XXX,XX @@ static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
67
68
mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
69
type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
70
+ sizem1 = FIELD_EX32(desc, MTEDESC, SIZEM1);
71
72
/* Find the addr of the end of the access */
73
- ptr_last = ptr + total - 1;
74
+ ptr_last = ptr + sizem1;
75
76
/* Round the bounds to the tag granule, and compute the number of tags. */
77
tag_first = QEMU_ALIGN_DOWN(ptr, TAG_GRANULE);
78
@@ -XXX,XX +XXX,XX @@ static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
79
if (likely(tag_last - prev_page <= TARGET_PAGE_SIZE)) {
80
/* Memory access stays on one page. */
81
tag_size = ((tag_byte_last - tag_byte_first) / (2 * TAG_GRANULE)) + 1;
82
- mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, total,
83
+ mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, sizem1 + 1,
84
MMU_DATA_LOAD, tag_size, ra);
85
if (!mem1) {
86
return 1;
87
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
88
uint64_t ptr, uintptr_t ra)
89
{
172
{
90
uint64_t fault;
173
ARMCPU *cpu = ARM_CPU(obj);
91
- uint32_t total = FIELD_EX32(desc, MTEDESC, TSIZE);
174
- uint32_t t;
92
- int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
175
93
+ int ret = mte_probe_int(env, desc, ptr, ra, &fault);
176
/* aarch64_a57_initfn, advertising none of the aarch64 features */
94
177
cpu->dtb_compatible = "arm,cortex-a57";
95
if (unlikely(ret == 0)) {
178
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
96
mte_check_fail(env, desc, fault, ra);
179
cpu->ccsidr[2] = 0x70ffe07a; /* 2048KB L2 cache */
97
@@ -XXX,XX +XXX,XX @@ uint64_t mte_check1(CPUARMState *env, uint32_t desc,
180
define_cortex_a72_a57_a53_cp_reginfo(cpu);
98
uint64_t ptr, uintptr_t ra)
181
99
{
182
- /* Add additional features supported by QEMU */
100
uint64_t fault;
183
- t = cpu->isar.id_isar5;
101
- uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
184
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
102
- int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
185
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
103
+ int ret = mte_probe_int(env, desc, ptr, ra, &fault);
186
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
104
187
- t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
105
if (unlikely(ret == 0)) {
188
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
106
mte_check_fail(env, desc, fault, ra);
189
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
107
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
190
- cpu->isar.id_isar5 = t;
108
bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
191
-
109
{
192
- t = cpu->isar.id_isar6;
110
uint64_t fault;
193
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
111
- uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
194
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
112
- int ret = mte_probe_int(env, desc, ptr, 0, total, &fault);
195
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
113
+ int ret = mte_probe_int(env, desc, ptr, 0, &fault);
196
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
114
197
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
115
return ret != 0;
198
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
116
}
199
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
117
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
200
- cpu->isar.id_isar6 = t;
118
index XXXXXXX..XXXXXXX 100644
201
-
119
--- a/target/arm/translate-a64.c
202
- t = cpu->isar.mvfr1;
120
+++ b/target/arm/translate-a64.c
203
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
121
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr,
204
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
122
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
205
- cpu->isar.mvfr1 = t;
123
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
206
-
124
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
207
- t = cpu->isar.mvfr2;
125
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << log2_size);
208
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
126
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << log2_size) - 1);
209
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
127
tcg_desc = tcg_const_i32(desc);
210
- cpu->isar.mvfr2 = t;
128
211
-
129
ret = new_tmp_a64(s);
212
- t = cpu->isar.id_mmfr3;
130
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
213
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
131
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
214
- cpu->isar.id_mmfr3 = t;
132
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
215
-
133
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
216
- t = cpu->isar.id_mmfr4;
134
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << log2_esize);
217
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
135
- desc = FIELD_DP32(desc, MTEDESC, TSIZE, total_size);
218
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
136
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, total_size - 1);
219
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
137
tcg_desc = tcg_const_i32(desc);
220
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
138
221
- cpu->isar.id_mmfr4 = t;
139
ret = new_tmp_a64(s);
222
-
140
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
223
- t = cpu->isar.id_pfr0;
141
index XXXXXXX..XXXXXXX 100644
224
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
142
--- a/target/arm/translate-sve.c
225
- cpu->isar.id_pfr0 = t;
143
+++ b/target/arm/translate-sve.c
226
-
144
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
227
- t = cpu->isar.id_pfr2;
145
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
228
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
146
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
229
- cpu->isar.id_pfr2 = t;
147
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
230
-
148
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << msz);
231
- t = cpu->isar.id_dfr0;
149
- desc = FIELD_DP32(desc, MTEDESC, TSIZE, mte_n << msz);
232
- t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
150
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
233
- cpu->isar.id_dfr0 = t;
151
desc <<= SVE_MTEDESC_SHIFT;
234
+ aa32_max_features(cpu);
152
} else {
235
153
addr = clean_data_tbi(s, addr);
236
#ifdef CONFIG_USER_ONLY
154
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
237
/*
155
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
156
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
157
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
158
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << msz);
159
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
160
desc <<= SVE_MTEDESC_SHIFT;
161
}
162
desc = simd_desc(vsz, vsz, desc | scale);
163
--
238
--
164
2.20.1
239
2.25.1
165
166
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is the only caller. Adjust some commentary to talk
3
Update the legacy feature names to the current names.
4
about SCTLR_B instead of the vanishing function.
4
Provide feature names for id changes that were not marked.
5
Sort the field updates into increasing bitfield order.
5
6
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210419202257.161730-13-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-10-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/translate.c | 37 ++++++++++++++++---------------------
12
target/arm/cpu64.c | 100 +++++++++++++++++++++----------------------
12
1 file changed, 16 insertions(+), 21 deletions(-)
13
target/arm/cpu_tcg.c | 48 ++++++++++-----------
14
2 files changed, 74 insertions(+), 74 deletions(-)
13
15
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
18
--- a/target/arm/cpu64.c
17
+++ b/target/arm/translate.c
19
+++ b/target/arm/cpu64.c
18
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
20
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
19
gen_aa32_st_i32(s, val, a32, index, OPC); \
21
cpu->midr = t;
20
}
22
21
23
t = cpu->isar.id_aa64isar0;
22
-static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
24
- t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */
23
-{
25
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
24
- /* Not needed for user-mode BE32, where we use MO_BE instead. */
26
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* SHA512 */
25
- if (!IS_USER_ONLY && s->sctlr_b) {
27
+ t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* FEAT_PMULL */
26
- tcg_gen_rotri_i64(val, val, 32);
28
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1); /* FEAT_SHA1 */
27
- }
29
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2); /* FEAT_SHA512 */
28
-}
30
t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
29
-
31
- t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2);
30
static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
32
- t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1);
31
int index, MemOp opc)
33
- t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1);
32
{
34
- t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1);
33
TCGv addr = gen_aa32_addr(s, a32, opc);
35
- t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
34
tcg_gen_qemu_ld_i64(val, addr, index, opc);
36
- t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
35
- gen_aa32_frob64(s, val);
37
- t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
36
+
38
- t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
37
+ /* Not needed for user-mode BE32, where we use MO_BE instead. */
39
- t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
38
+ if (!IS_USER_ONLY && s->sctlr_b) {
40
- t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
39
+ tcg_gen_rotri_i64(val, val, 32);
41
+ t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2); /* FEAT_LSE */
40
+ }
42
+ t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1); /* FEAT_RDM */
41
+
43
+ t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1); /* FEAT_SHA3 */
42
tcg_temp_free(addr);
44
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1); /* FEAT_SM3 */
45
+ t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1); /* FEAT_SM4 */
46
+ t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1); /* FEAT_DotProd */
47
+ t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1); /* FEAT_FHM */
48
+ t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* FEAT_FlagM2 */
49
+ t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
50
+ t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1); /* FEAT_RNG */
51
cpu->isar.id_aa64isar0 = t;
52
53
t = cpu->isar.id_aa64isar1;
54
- t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
55
- t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
56
- t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
57
- t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
58
- t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
59
- t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1);
60
- t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
61
- t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */
62
- t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1);
63
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2); /* FEAT_DPB2 */
64
+ t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1); /* FEAT_JSCVT */
65
+ t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1); /* FEAT_FCMA */
66
+ t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* FEAT_LRCPC2 */
67
+ t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1); /* FEAT_FRINTTS */
68
+ t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1); /* FEAT_SB */
69
+ t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); /* FEAT_SPECRES */
70
+ t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1); /* FEAT_BF16 */
71
+ t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
72
cpu->isar.id_aa64isar1 = t;
73
74
t = cpu->isar.id_aa64pfr0;
75
+ t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */
76
+ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */
77
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
78
- t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
79
- t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
80
- t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1);
81
- t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1);
82
+ t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
83
+ t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
84
cpu->isar.id_aa64pfr0 = t;
85
86
t = cpu->isar.id_aa64pfr1;
87
- t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
88
- t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
89
+ t = FIELD_DP64(t, ID_AA64PFR1, BT, 1); /* FEAT_BTI */
90
+ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2); /* FEAT_SSBS2 */
91
/*
92
* Begin with full support for MTE. This will be downgraded to MTE=0
93
* during realize if the board provides no tag memory, much like
94
* we do for EL2 with the virtualization=on property.
95
*/
96
- t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3);
97
+ t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
98
cpu->isar.id_aa64pfr1 = t;
99
100
t = cpu->isar.id_aa64mmfr0;
101
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
102
cpu->isar.id_aa64mmfr0 = t;
103
104
t = cpu->isar.id_aa64mmfr1;
105
- t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
106
- t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
107
- t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
108
- t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
109
- t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
110
- t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
111
+ t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* FEAT_VMID16 */
112
+ t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
113
+ t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
114
+ t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
115
+ t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* FEAT_PAN2 */
116
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
117
cpu->isar.id_aa64mmfr1 = t;
118
119
t = cpu->isar.id_aa64mmfr2;
120
- t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
121
- t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
122
- t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */
123
- t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
124
- t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
125
- t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
126
+ t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* FEAT_TTCNP */
127
+ t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
128
+ t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
129
+ t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
130
+ t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
131
+ t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2); /* FEAT_BBM at level 2 */
132
cpu->isar.id_aa64mmfr2 = t;
133
134
t = cpu->isar.id_aa64zfr0;
135
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
136
- t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* PMULL */
137
- t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1);
138
- t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1);
139
- t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1);
140
- t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1);
141
- t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1);
142
- t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1);
143
- t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1);
144
+ t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* FEAT_SVE_PMULL128 */
145
+ t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1); /* FEAT_SVE_BitPerm */
146
+ t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1); /* FEAT_BF16 */
147
+ t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1); /* FEAT_SVE_SHA3 */
148
+ t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1); /* FEAT_SVE_SM4 */
149
+ t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1); /* FEAT_I8MM */
150
+ t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1); /* FEAT_F32MM */
151
+ t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1); /* FEAT_F64MM */
152
cpu->isar.id_aa64zfr0 = t;
153
154
t = cpu->isar.id_aa64dfr0;
155
- t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
156
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
157
cpu->isar.id_aa64dfr0 = t;
158
159
/* Replicate the same data to the 32-bit id registers. */
160
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/target/arm/cpu_tcg.c
163
+++ b/target/arm/cpu_tcg.c
164
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
165
166
/* Add additional features supported by QEMU */
167
t = cpu->isar.id_isar5;
168
- t = FIELD_DP32(t, ID_ISAR5, AES, 2);
169
- t = FIELD_DP32(t, ID_ISAR5, SHA1, 1);
170
- t = FIELD_DP32(t, ID_ISAR5, SHA2, 1);
171
+ t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */
172
+ t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */
173
+ t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */
174
t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
175
- t = FIELD_DP32(t, ID_ISAR5, RDM, 1);
176
- t = FIELD_DP32(t, ID_ISAR5, VCMA, 1);
177
+ t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */
178
+ t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */
179
cpu->isar.id_isar5 = t;
180
181
t = cpu->isar.id_isar6;
182
- t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
183
- t = FIELD_DP32(t, ID_ISAR6, DP, 1);
184
- t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
185
- t = FIELD_DP32(t, ID_ISAR6, SB, 1);
186
- t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
187
- t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
188
- t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
189
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); /* FEAT_JSCVT */
190
+ t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */
191
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */
192
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1); /* FEAT_SB */
193
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */
194
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */
195
+ t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */
196
cpu->isar.id_isar6 = t;
197
198
t = cpu->isar.mvfr1;
199
- t = FIELD_DP32(t, MVFR1, FPHP, 3); /* v8.2-FP16 */
200
- t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* v8.2-FP16 */
201
+ t = FIELD_DP32(t, MVFR1, FPHP, 3); /* FEAT_FP16 */
202
+ t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* FEAT_FP16 */
203
cpu->isar.mvfr1 = t;
204
205
t = cpu->isar.mvfr2;
206
- t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
207
- t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
208
+ t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
209
+ t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
210
cpu->isar.mvfr2 = t;
211
212
t = cpu->isar.id_mmfr3;
213
- t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* ATS1E1 */
214
+ t = FIELD_DP32(t, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */
215
cpu->isar.id_mmfr3 = t;
216
217
t = cpu->isar.id_mmfr4;
218
- t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
219
- t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
220
- t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
221
- t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
222
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* FEAT_AA32HPD */
223
+ t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
224
+ t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */
225
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX*/
226
cpu->isar.id_mmfr4 = t;
227
228
t = cpu->isar.id_pfr0;
229
- t = FIELD_DP32(t, ID_PFR0, DIT, 1);
230
+ t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
231
cpu->isar.id_pfr0 = t;
232
233
t = cpu->isar.id_pfr2;
234
- t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
235
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */
236
cpu->isar.id_pfr2 = t;
237
238
t = cpu->isar.id_dfr0;
239
- t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
240
+ t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* FEAT_PMUv3p4 */
241
cpu->isar.id_dfr0 = t;
43
}
242
}
44
243
45
@@ -XXX,XX +XXX,XX @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
46
TCGv_i32 tmp2 = tcg_temp_new_i32();
47
TCGv_i64 t64 = tcg_temp_new_i64();
48
49
- /* For AArch32, architecturally the 32-bit word at the lowest
50
+ /*
51
+ * For AArch32, architecturally the 32-bit word at the lowest
52
* address is always Rt and the one at addr+4 is Rt2, even if
53
* the CPU is big-endian. That means we don't want to do a
54
- * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
55
- * for an architecturally 64-bit access, but instead do a
56
- * 64-bit access using MO_BE if appropriate and then split
57
- * the two halves.
58
- * This only makes a difference for BE32 user-mode, where
59
- * frob64() must not flip the two halves of the 64-bit data
60
- * but this code must treat BE32 user-mode like BE32 system.
61
+ * gen_aa32_ld_i64(), which checks SCTLR_B as if for an
62
+ * architecturally 64-bit access, but instead do a 64-bit access
63
+ * using MO_BE if appropriate and then split the two halves.
64
*/
65
TCGv taddr = gen_aa32_addr(s, addr, opc);
66
67
@@ -XXX,XX +XXX,XX @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
68
TCGv_i64 n64 = tcg_temp_new_i64();
69
70
t2 = load_reg(s, rt2);
71
- /* For AArch32, architecturally the 32-bit word at the lowest
72
+
73
+ /*
74
+ * For AArch32, architecturally the 32-bit word at the lowest
75
* address is always Rt and the one at addr+4 is Rt2, even if
76
* the CPU is big-endian. Since we're going to treat this as a
77
* single 64-bit BE store, we need to put the two halves in the
78
* opposite order for BE to LE, so that they end up in the right
79
- * places.
80
- * We don't want gen_aa32_frob64() because that does the wrong
81
- * thing for BE32 usermode.
82
+ * places. We don't want gen_aa32_st_i64, because that checks
83
+ * SCTLR_B as if for an architectural 64-bit access.
84
*/
85
if (s->be_data == MO_BE) {
86
tcg_gen_concat_i32_i64(n64, t2, t1);
87
--
244
--
88
2.20.1
245
2.25.1
89
90
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Use FIELD_DP{32,64} to manipulate id_pfr1 and id_aa64pfr0
4
during arm_cpu_realizefn.
2
5
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-28-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-11-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/translate-a64.c | 23 ++++++++++++++---------
11
target/arm/cpu.c | 22 +++++++++++++---------
9
1 file changed, 14 insertions(+), 9 deletions(-)
12
1 file changed, 13 insertions(+), 9 deletions(-)
10
13
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
16
--- a/target/arm/cpu.c
14
+++ b/target/arm/translate-a64.c
17
+++ b/target/arm/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
16
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
19
*/
17
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn),
20
unset_feature(env, ARM_FEATURE_EL3);
18
true, rn != 31, size);
21
19
- do_gpr_st(s, cpu_reg(s, rt), clean_addr, size, true, rt,
22
- /* Disable the security extension feature bits in the processor feature
20
+ /* TODO: ARMv8.4-LSE SCTLR.nAA */
23
- * registers as well. These are id_pfr1[7:4] and id_aa64pfr0[15:12].
21
+ do_gpr_st(s, cpu_reg(s, rt), clean_addr, size | MO_ALIGN, true, rt,
24
+ /*
22
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
25
+ * Disable the security extension feature bits in the processor
23
return;
26
+ * feature registers as well.
24
27
*/
25
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
28
- cpu->isar.id_pfr1 &= ~0xf0;
26
}
29
- cpu->isar.id_aa64pfr0 &= ~0xf000;
27
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn),
30
+ cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0);
28
false, rn != 31, size);
31
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
29
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, true, rt,
32
+ ID_AA64PFR0, EL3, 0);
30
- disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
31
+ /* TODO: ARMv8.4-LSE SCTLR.nAA */
32
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size | MO_ALIGN, false, true,
33
+ rt, disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
34
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
35
return;
36
37
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
38
int size = extract32(insn, 30, 2);
39
TCGv_i64 clean_addr, dirty_addr;
40
bool is_store = false;
41
- bool is_signed = false;
42
bool extend = false;
43
bool iss_sf;
44
+ MemOp mop;
45
46
if (!dc_isar_feature(aa64_rcpc_8_4, s)) {
47
unallocated_encoding(s);
48
return;
49
}
33
}
50
34
51
+ /* TODO: ARMv8.4-LSE SCTLR.nAA */
35
if (!cpu->has_el2) {
52
+ mop = size | MO_ALIGN;
36
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
53
+
54
switch (opc) {
55
case 0: /* STLURB */
56
is_store = true;
57
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
58
unallocated_encoding(s);
59
return;
60
}
61
- is_signed = true;
62
+ mop |= MO_SIGN;
63
break;
64
case 3: /* LDAPURS* 32-bit variant */
65
if (size > 1) {
66
unallocated_encoding(s);
67
return;
68
}
69
- is_signed = true;
70
+ mop |= MO_SIGN;
71
extend = true; /* zero-extend 32->64 after signed load */
72
break;
73
default:
74
g_assert_not_reached();
75
}
37
}
76
38
77
- iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
39
if (!arm_feature(env, ARM_FEATURE_EL2)) {
78
+ iss_sf = disas_ldst_compute_iss_sf(size, (mop & MO_SIGN) != 0, opc);
40
- /* Disable the hypervisor feature bits in the processor feature
79
41
- * registers if we don't have EL2. These are id_pfr1[15:12] and
80
if (rn == 31) {
42
- * id_aa64pfr0_el1[11:8].
81
gen_check_sp_alignment(s);
43
+ /*
82
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
44
+ * Disable the hypervisor feature bits in the processor feature
83
if (is_store) {
45
+ * registers if we don't have EL2.
84
/* Store-Release semantics */
85
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
86
- do_gpr_st(s, cpu_reg(s, rt), clean_addr, size, true, rt, iss_sf, true);
87
+ do_gpr_st(s, cpu_reg(s, rt), clean_addr, mop, true, rt, iss_sf, true);
88
} else {
89
/*
90
* Load-AcquirePC semantics; we implement as the slightly more
91
* restrictive Load-Acquire.
92
*/
46
*/
93
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size + is_signed * MO_SIGN,
47
- cpu->isar.id_aa64pfr0 &= ~0xf00;
94
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, mop,
48
- cpu->isar.id_pfr1 &= ~0xf000;
95
extend, true, rt, iss_sf, true);
49
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
96
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
50
+ ID_AA64PFR0, EL2, 0);
51
+ cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1,
52
+ ID_PFR1, VIRTUALIZATION, 0);
97
}
53
}
54
55
#ifndef CONFIG_USER_ONLY
98
--
56
--
99
2.20.1
57
2.25.1
100
101
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Just because operating on a TCGv_i64 temporary does not
3
The only portion of FEAT_Debugv8p2 that is relevant to QEMU
4
mean that we're performing a 64-bit operation. Restrict
4
is CONTEXTIDR_EL2, which is also conditionally implemented
5
the frobbing to actual 64-bit operations.
5
with FEAT_VHE. The rest of the debug extension concerns the
6
6
External debug interface, which is outside the scope of QEMU.
7
This bug is not currently visible because all current
8
users of these two functions always pass MO_64.
9
7
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210419202257.161730-14-richard.henderson@linaro.org
10
Message-id: 20220506180242.216785-12-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
12
---
15
target/arm/translate.c | 4 ++--
13
docs/system/arm/emulation.rst | 1 +
16
1 file changed, 2 insertions(+), 2 deletions(-)
14
target/arm/cpu.c | 1 +
15
target/arm/cpu64.c | 1 +
16
target/arm/cpu_tcg.c | 2 ++
17
4 files changed, 5 insertions(+)
17
18
18
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
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
21
--- a/docs/system/arm/emulation.rst
21
+++ b/target/arm/translate.c
22
+++ b/docs/system/arm/emulation.rst
22
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
23
tcg_gen_qemu_ld_i64(val, addr, index, opc);
24
- FEAT_BTI (Branch Target Identification)
24
25
- FEAT_DIT (Data Independent Timing instructions)
25
/* Not needed for user-mode BE32, where we use MO_BE instead. */
26
- FEAT_DPB (DC CVAP instruction)
26
- if (!IS_USER_ONLY && s->sctlr_b) {
27
+- FEAT_Debugv8p2 (Debug changes for v8.2)
27
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
28
- FEAT_DotProd (Advanced SIMD dot product instructions)
28
tcg_gen_rotri_i64(val, val, 32);
29
- FEAT_FCMA (Floating-point complex number instructions)
30
- FEAT_FHM (Floating-point half-precision multiplication instructions)
31
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.c
34
+++ b/target/arm/cpu.c
35
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
36
* feature registers as well.
37
*/
38
cpu->isar.id_pfr1 = FIELD_DP32(cpu->isar.id_pfr1, ID_PFR1, SECURITY, 0);
39
+ cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
40
cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
41
ID_AA64PFR0, EL3, 0);
29
}
42
}
30
43
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
44
index XXXXXXX..XXXXXXX 100644
32
TCGv addr = gen_aa32_addr(s, a32, opc);
45
--- a/target/arm/cpu64.c
33
46
+++ b/target/arm/cpu64.c
34
/* Not needed for user-mode BE32, where we use MO_BE instead. */
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
- if (!IS_USER_ONLY && s->sctlr_b) {
48
cpu->isar.id_aa64zfr0 = t;
36
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
49
37
TCGv_i64 tmp = tcg_temp_new_i64();
50
t = cpu->isar.id_aa64dfr0;
38
tcg_gen_rotri_i64(tmp, val, 32);
51
+ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 8); /* FEAT_Debugv8p2 */
39
tcg_gen_qemu_st_i64(tmp, addr, index, opc);
52
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
53
cpu->isar.id_aa64dfr0 = t;
54
55
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/cpu_tcg.c
58
+++ b/target/arm/cpu_tcg.c
59
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
60
cpu->isar.id_pfr2 = t;
61
62
t = cpu->isar.id_dfr0;
63
+ t = FIELD_DP32(t, ID_DFR0, COPDBG, 8); /* FEAT_Debugv8p2 */
64
+ t = FIELD_DP32(t, ID_DFR0, COPSDBG, 8); /* FEAT_Debugv8p2 */
65
t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* FEAT_PMUv3p4 */
66
cpu->isar.id_dfr0 = t;
67
}
40
--
68
--
41
2.20.1
69
2.25.1
42
43
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 encoding of size = 2 and size = 3 had the incorrect decode
3
This extension concerns changes to the External Debug interface,
4
for align, overlapping the stride field. This error was hidden
4
with Secure and Non-secure access to the debug registers, and all
5
by what should have been unnecessary masking in translate.
5
of it is outside the scope of QEMU. Indicating support for this
6
is mandatory with FEAT_SEL2, which we do implement.
6
7
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210419202257.161730-2-richard.henderson@linaro.org
10
Message-id: 20220506180242.216785-13-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
target/arm/neon-ls.decode | 4 ++--
13
docs/system/arm/emulation.rst | 1 +
13
target/arm/translate-neon.c.inc | 4 ++--
14
target/arm/cpu64.c | 2 +-
14
2 files changed, 4 insertions(+), 4 deletions(-)
15
target/arm/cpu_tcg.c | 4 ++--
16
3 files changed, 4 insertions(+), 3 deletions(-)
15
17
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
18
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-ls.decode
20
--- a/docs/system/arm/emulation.rst
19
+++ b/target/arm/neon-ls.decode
21
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
22
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
23
- FEAT_DIT (Data Independent Timing instructions)
22
VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
24
- FEAT_DPB (DC CVAP instruction)
23
vd=%vd_dp size=0 stride=1
25
- FEAT_Debugv8p2 (Debug changes for v8.2)
24
-VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
26
+- FEAT_Debugv8p4 (Debug changes for v8.4)
25
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 . align:1 rm:4 \
27
- FEAT_DotProd (Advanced SIMD dot product instructions)
26
vd=%vd_dp size=1 stride=%imm1_5_p1
28
- FEAT_FCMA (Floating-point complex number instructions)
27
-VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
29
- FEAT_FHM (Floating-point half-precision multiplication instructions)
28
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 . align:2 rm:4 \
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
29
vd=%vd_dp size=2 stride=%imm1_6_p1
30
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
31
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-neon.c.inc
32
--- a/target/arm/cpu64.c
33
+++ b/target/arm/translate-neon.c.inc
33
+++ b/target/arm/cpu64.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
34
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
switch (nregs) {
35
cpu->isar.id_aa64zfr0 = t;
36
case 1:
36
37
if (((a->align & (1 << a->size)) != 0) ||
37
t = cpu->isar.id_aa64dfr0;
38
- (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
38
- t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 8); /* FEAT_Debugv8p2 */
39
+ (a->size == 2 && (a->align == 1 || a->align == 2))) {
39
+ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */
40
return false;
40
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
41
}
41
cpu->isar.id_aa64dfr0 = t;
42
break;
42
43
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
43
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
44
}
44
index XXXXXXX..XXXXXXX 100644
45
break;
45
--- a/target/arm/cpu_tcg.c
46
case 4:
46
+++ b/target/arm/cpu_tcg.c
47
- if ((a->size == 2) && ((a->align & 3) == 3)) {
47
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
48
+ if (a->size == 2 && a->align == 3) {
48
cpu->isar.id_pfr2 = t;
49
return false;
49
50
}
50
t = cpu->isar.id_dfr0;
51
break;
51
- t = FIELD_DP32(t, ID_DFR0, COPDBG, 8); /* FEAT_Debugv8p2 */
52
- t = FIELD_DP32(t, ID_DFR0, COPSDBG, 8); /* FEAT_Debugv8p2 */
53
+ t = FIELD_DP32(t, ID_DFR0, COPDBG, 9); /* FEAT_Debugv8p4 */
54
+ t = FIELD_DP32(t, ID_DFR0, COPSDBG, 9); /* FEAT_Debugv8p4 */
55
t = FIELD_DP32(t, ID_DFR0, PERFMON, 5); /* FEAT_PMUv3p4 */
56
cpu->isar.id_dfr0 = t;
57
}
52
--
58
--
53
2.20.1
59
2.25.1
54
55
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use this to signal when memory access alignment is required.
3
Add only the system registers required to implement zero error
4
This value comes from the CCR register for M-profile, and
4
records. This means that all values for ERRSELR are out of range,
5
from the SCTLR register for A-profile.
5
which means that it and all of the indexed error record registers
6
need not be implemented.
7
8
Add the EL2 registers required for injecting virtual SError.
6
9
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210419202257.161730-11-richard.henderson@linaro.org
12
Message-id: 20220506180242.216785-14-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
target/arm/cpu.h | 2 ++
15
target/arm/cpu.h | 5 +++
13
target/arm/translate.h | 2 ++
16
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
14
target/arm/helper.c | 19 +++++++++++++++++--
17
2 files changed, 89 insertions(+)
15
target/arm/translate-a64.c | 1 +
16
target/arm/translate.c | 7 +++----
17
5 files changed, 25 insertions(+), 6 deletions(-)
18
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, MMUIDX, 4, 4)
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
24
FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
24
uint64_t tfsr_el[4]; /* tfsre0_el1 is index 0. */
25
/* For A-profile only, target EL for debug exceptions. */
25
uint64_t gcr_el1;
26
FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 10, 2)
26
uint64_t rgsr_el1;
27
+/* Memory operations require alignment: SCTLR_ELx.A or CCR.UNALIGN_TRP */
27
+
28
+FIELD(TBFLAG_ANY, ALIGN_MEM, 12, 1)
28
+ /* Minimal RAS registers */
29
29
+ uint64_t disr_el1;
30
/*
30
+ uint64_t vdisr_el2;
31
* Bit usage when in AArch32 state, both A- and M-profile.
31
+ uint64_t vsesr_el2;
32
diff --git a/target/arm/translate.h b/target/arm/translate.h
32
} cp15;
33
index XXXXXXX..XXXXXXX 100644
33
34
--- a/target/arm/translate.h
34
struct {
35
+++ b/target/arm/translate.h
36
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
37
bool bt;
38
/* True if any CP15 access is trapped by HSTR_EL2 */
39
bool hstr_active;
40
+ /* True if memory operations require alignment */
41
+ bool align_mem;
42
/*
43
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
44
* < 0, set by the current instruction.
45
diff --git a/target/arm/helper.c b/target/arm/helper.c
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
46
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/helper.c
37
--- a/target/arm/helper.c
48
+++ b/target/arm/helper.c
38
+++ b/target/arm/helper.c
49
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
39
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
50
ARMMMUIdx mmu_idx)
40
.access = PL0_R, .type = ARM_CP_CONST|ARM_CP_64BIT, .resetvalue = 0 },
51
{
41
};
52
CPUARMTBFlags flags = {};
42
53
+ uint32_t ccr = env->v7m.ccr[env->v7m.secure];
43
+/*
54
+
44
+ * Check for traps to RAS registers, which are controlled
55
+ /* Without HaveMainExt, CCR.UNALIGN_TRP is RES1. */
45
+ * by HCR_EL2.TERR and SCR_EL3.TERR.
56
+ if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) {
46
+ */
57
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
47
+static CPAccessResult access_terr(CPUARMState *env, const ARMCPRegInfo *ri,
58
+ }
48
+ bool isread)
59
49
+{
60
if (arm_v7m_is_handler_mode(env)) {
61
DP_TBFLAG_M32(flags, HANDLER, 1);
62
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
63
*/
64
if (arm_feature(env, ARM_FEATURE_V8) &&
65
!((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
66
- (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
67
+ (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
68
DP_TBFLAG_M32(flags, STACKCHECK, 1);
69
}
70
71
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
72
ARMMMUIdx mmu_idx)
73
{
74
CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
75
+ int el = arm_current_el(env);
50
+ int el = arm_current_el(env);
76
+
51
+
77
+ if (arm_sctlr(env, el) & SCTLR_A) {
52
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TERR)) {
78
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
53
+ return CP_ACCESS_TRAP_EL2;
79
+ }
54
+ }
80
55
+ if (el < 3 && (env->cp15.scr_el3 & SCR_TERR)) {
81
if (arm_el_is_aa64(env, 1)) {
56
+ return CP_ACCESS_TRAP_EL3;
82
DP_TBFLAG_A32(flags, VFPEN, 1);
57
+ }
58
+ return CP_ACCESS_OK;
59
+}
60
+
61
+static uint64_t disr_read(CPUARMState *env, const ARMCPRegInfo *ri)
62
+{
63
+ int el = arm_current_el(env);
64
+
65
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_AMO)) {
66
+ return env->cp15.vdisr_el2;
67
+ }
68
+ if (el < 3 && (env->cp15.scr_el3 & SCR_EA)) {
69
+ return 0; /* RAZ/WI */
70
+ }
71
+ return env->cp15.disr_el1;
72
+}
73
+
74
+static void disr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t val)
75
+{
76
+ int el = arm_current_el(env);
77
+
78
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_AMO)) {
79
+ env->cp15.vdisr_el2 = val;
80
+ return;
81
+ }
82
+ if (el < 3 && (env->cp15.scr_el3 & SCR_EA)) {
83
+ return; /* RAZ/WI */
84
+ }
85
+ env->cp15.disr_el1 = val;
86
+}
87
+
88
+/*
89
+ * Minimal RAS implementation with no Error Records.
90
+ * Which means that all of the Error Record registers:
91
+ * ERXADDR_EL1
92
+ * ERXCTLR_EL1
93
+ * ERXFR_EL1
94
+ * ERXMISC0_EL1
95
+ * ERXMISC1_EL1
96
+ * ERXMISC2_EL1
97
+ * ERXMISC3_EL1
98
+ * ERXPFGCDN_EL1 (RASv1p1)
99
+ * ERXPFGCTL_EL1 (RASv1p1)
100
+ * ERXPFGF_EL1 (RASv1p1)
101
+ * ERXSTATUS_EL1
102
+ * and
103
+ * ERRSELR_EL1
104
+ * may generate UNDEFINED, which is the effect we get by not
105
+ * listing them at all.
106
+ */
107
+static const ARMCPRegInfo minimal_ras_reginfo[] = {
108
+ { .name = "DISR_EL1", .state = ARM_CP_STATE_BOTH,
109
+ .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 1, .opc2 = 1,
110
+ .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.disr_el1),
111
+ .readfn = disr_read, .writefn = disr_write, .raw_writefn = raw_write },
112
+ { .name = "ERRIDR_EL1", .state = ARM_CP_STATE_BOTH,
113
+ .opc0 = 3, .opc1 = 0, .crn = 5, .crm = 3, .opc2 = 0,
114
+ .access = PL1_R, .accessfn = access_terr,
115
+ .type = ARM_CP_CONST, .resetvalue = 0 },
116
+ { .name = "VDISR_EL2", .state = ARM_CP_STATE_BOTH,
117
+ .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 1, .opc2 = 1,
118
+ .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.vdisr_el2) },
119
+ { .name = "VSESR_EL2", .state = ARM_CP_STATE_BOTH,
120
+ .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 3,
121
+ .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.vsesr_el2) },
122
+};
123
+
124
/* Return the exception level to which exceptions should be taken
125
* via SVEAccessTrap. If an exception should be routed through
126
* AArch64.AdvSIMDFPAccessTrap, return 0; fp_exception_el should
127
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
128
if (cpu_isar_feature(aa64_ssbs, cpu)) {
129
define_one_arm_cp_reg(cpu, &ssbs_reginfo);
83
}
130
}
84
131
+ if (cpu_isar_feature(any_ras, cpu)) {
85
- if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
132
+ define_arm_cp_regs(cpu, minimal_ras_reginfo);
86
+ if (el < 2 && env->cp15.hstr_el2 &&
87
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
88
DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
89
}
90
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
91
92
sctlr = regime_sctlr(env, stage1);
93
94
+ if (sctlr & SCTLR_A) {
95
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
96
+ }
133
+ }
97
+
134
98
if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
135
if (cpu_isar_feature(aa64_vh, cpu) ||
99
DP_TBFLAG_ANY(flags, BE_DATA, 1);
136
cpu_isar_feature(aa64_debugv8p2, cpu)) {
100
}
101
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/arm/translate-a64.c
104
+++ b/target/arm/translate-a64.c
105
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
106
dc->user = (dc->current_el == 0);
107
#endif
108
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
109
+ dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
110
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
111
dc->sve_len = (EX_TBFLAG_A64(tb_flags, ZCR_LEN) + 1) * 16;
112
dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
113
diff --git a/target/arm/translate.c b/target/arm/translate.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/translate.c
116
+++ b/target/arm/translate.c
117
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
118
{
119
TCGv addr;
120
121
- if (arm_dc_feature(s, ARM_FEATURE_M) &&
122
- !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
123
+ if (s->align_mem) {
124
opc |= MO_ALIGN;
125
}
126
127
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
128
{
129
TCGv addr;
130
131
- if (arm_dc_feature(s, ARM_FEATURE_M) &&
132
- !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
133
+ if (s->align_mem) {
134
opc |= MO_ALIGN;
135
}
136
137
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
138
dc->user = (dc->current_el == 0);
139
#endif
140
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
141
+ dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
142
143
if (arm_feature(env, ARM_FEATURE_M)) {
144
dc->vfp_enabled = 1;
145
--
137
--
146
2.20.1
138
2.25.1
147
148
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Enable writes to the TERR and TEA bits when RAS is enabled.
4
These bits are otherwise RES0.
2
5
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-23-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-15-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/translate.h | 1 +
11
target/arm/helper.c | 9 +++++++++
9
target/arm/translate.c | 15 +++++++++++++
12
1 file changed, 9 insertions(+)
10
target/arm/translate-neon.c.inc | 37 +++++++++++++++++++++++++--------
11
3 files changed, 44 insertions(+), 9 deletions(-)
12
13
13
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.h
16
--- a/target/arm/helper.c
16
+++ b/target/arm/translate.h
17
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ void arm_test_cc(DisasCompare *cmp, int cc);
18
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
18
void arm_free_cc(DisasCompare *cmp);
19
void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
20
void arm_gen_test_cc(int cc, TCGLabel *label);
21
+MemOp pow2_align(unsigned i);
22
23
/* Return state of Alternate Half-precision flag, caller frees result */
24
static inline TCGv_i32 get_ahp_flag(void)
25
diff --git a/target/arm/translate.c b/target/arm/translate.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate.c
28
+++ b/target/arm/translate.c
29
@@ -XXX,XX +XXX,XX @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
30
#define IS_USER_ONLY 0
31
#endif
32
33
+MemOp pow2_align(unsigned i)
34
+{
35
+ static const MemOp mop_align[] = {
36
+ 0, MO_ALIGN_2, MO_ALIGN_4, MO_ALIGN_8, MO_ALIGN_16,
37
+ /*
38
+ * FIXME: TARGET_PAGE_BITS_MIN affects TLB_FLAGS_MASK such
39
+ * that 256-bit alignment (MO_ALIGN_32) cannot be supported:
40
+ * see get_alignment_bits(). Enforce only 128-bit alignment for now.
41
+ */
42
+ MO_ALIGN_16
43
+ };
44
+ g_assert(i < ARRAY_SIZE(mop_align));
45
+ return mop_align[i];
46
+}
47
+
48
/*
49
* Abstractions of "generate code to do a guest load/store for
50
* AArch32", where a vaddr is always 32 bits (and is zero
51
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-neon.c.inc
54
+++ b/target/arm/translate-neon.c.inc
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
56
int size = a->size;
57
int nregs = a->n + 1;
58
TCGv_i32 addr, tmp;
59
+ MemOp mop, align;
60
61
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
62
return false;
63
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
64
return false;
65
}
66
67
+ align = 0;
68
if (size == 3) {
69
if (nregs != 4 || a->a == 0) {
70
return false;
71
}
19
}
72
/* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
20
valid_mask &= ~SCR_NET;
73
- size = 2;
21
74
- }
22
+ if (cpu_isar_feature(aa64_ras, cpu)) {
75
- if (nregs == 1 && a->a == 1 && size == 0) {
23
+ valid_mask |= SCR_TERR;
76
- return false;
24
+ }
77
- }
25
if (cpu_isar_feature(aa64_lor, cpu)) {
78
- if (nregs == 3 && a->a == 1) {
26
valid_mask |= SCR_TLOR;
79
- return false;
27
}
80
+ size = MO_32;
28
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
81
+ align = MO_ALIGN_16;
29
}
82
+ } else if (a->a) {
30
} else {
83
+ switch (nregs) {
31
valid_mask &= ~(SCR_RW | SCR_ST);
84
+ case 1:
32
+ if (cpu_isar_feature(aa32_ras, cpu)) {
85
+ if (size == 0) {
33
+ valid_mask |= SCR_TERR;
86
+ return false;
87
+ }
88
+ align = MO_ALIGN;
89
+ break;
90
+ case 2:
91
+ align = pow2_align(size + 1);
92
+ break;
93
+ case 3:
94
+ return false;
95
+ case 4:
96
+ align = pow2_align(size + 2);
97
+ break;
98
+ default:
99
+ g_assert_not_reached();
100
+ }
34
+ }
101
}
35
}
102
36
103
if (!vfp_access_check(s)) {
37
if (!arm_feature(env, ARM_FEATURE_EL2)) {
104
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
38
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
105
*/
39
if (cpu_isar_feature(aa64_vh, cpu)) {
106
stride = a->t ? 2 : 1;
40
valid_mask |= HCR_E2H;
107
vec_size = nregs == 1 ? stride * 8 : 8;
108
-
109
+ mop = size | align;
110
tmp = tcg_temp_new_i32();
111
addr = tcg_temp_new_i32();
112
load_reg_var(s, addr, a->rn);
113
for (reg = 0; reg < nregs; reg++) {
114
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), size);
115
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop);
116
if ((vd & 1) && vec_size == 16) {
117
/*
118
* We cannot write 16 bytes at once because the
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
120
}
41
}
121
tcg_gen_addi_i32(addr, addr, 1 << size);
42
+ if (cpu_isar_feature(aa64_ras, cpu)) {
122
vd += stride;
43
+ valid_mask |= HCR_TERR | HCR_TEA;
123
+
44
+ }
124
+ /* Subsequent memory operations inherit alignment */
45
if (cpu_isar_feature(aa64_lor, cpu)) {
125
+ mop &= ~MO_AMASK;
46
valid_mask |= HCR_TLOR;
126
}
47
}
127
tcg_temp_free_i32(tmp);
128
tcg_temp_free_i32(addr);
129
--
48
--
130
2.20.1
49
2.25.1
131
132
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're about to rearrange the macro expansion surrounding tbflags,
3
Virtual SError exceptions are raised by setting HCR_EL2.VSE,
4
and this field name will be expanded using the bit definition of
4
and are routed to EL1 just like other virtual exceptions.
5
the same name, resulting in a token pasting error.
6
7
So SCTLR_B -> SCTLR__B in the 3 uses, and document it.
8
5
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210419202257.161730-3-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-16-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 | 2 +-
11
target/arm/cpu.h | 2 ++
15
target/arm/helper.c | 2 +-
12
target/arm/internals.h | 8 ++++++++
16
target/arm/translate.c | 2 +-
13
target/arm/syndrome.h | 5 +++++
17
3 files changed, 3 insertions(+), 3 deletions(-)
14
target/arm/cpu.c | 38 +++++++++++++++++++++++++++++++++++++-
15
target/arm/helper.c | 40 +++++++++++++++++++++++++++++++++++++++-
16
5 files changed, 91 insertions(+), 2 deletions(-)
18
17
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, VECSTRIDE, 12, 2) /* Not cached. */
22
@@ -XXX,XX +XXX,XX @@
23
#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
24
#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
25
#define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */
26
+#define EXCP_VSERR 24
27
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
28
29
#define ARMV7M_EXCP_RESET 1
30
@@ -XXX,XX +XXX,XX @@ enum {
31
#define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1
32
#define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_EXT_2
33
#define CPU_INTERRUPT_VFIQ CPU_INTERRUPT_TGT_EXT_3
34
+#define CPU_INTERRUPT_VSERR CPU_INTERRUPT_TGT_INT_0
35
36
/* The usual mapping for an AArch64 system register to its AArch32
37
* counterpart is for the 32 bit world to have access to the lower
38
diff --git a/target/arm/internals.h b/target/arm/internals.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/internals.h
41
+++ b/target/arm/internals.h
42
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_virq(ARMCPU *cpu);
24
*/
43
*/
25
FIELD(TBFLAG_A32, XSCALE_CPAR, 12, 2)
44
void arm_cpu_update_vfiq(ARMCPU *cpu);
26
FIELD(TBFLAG_A32, VFPEN, 14, 1) /* Partially cached, minus FPEXC. */
45
27
-FIELD(TBFLAG_A32, SCTLR_B, 15, 1)
46
+/**
28
+FIELD(TBFLAG_A32, SCTLR__B, 15, 1) /* Cannot overlap with SCTLR_B */
47
+ * arm_cpu_update_vserr: Update CPU_INTERRUPT_VSERR bit
29
FIELD(TBFLAG_A32, HSTR_ACTIVE, 16, 1)
48
+ *
30
/*
49
+ * Update the CPU_INTERRUPT_VSERR bit in cs->interrupt_request,
31
* Indicates whether cp register reads and writes by guest code should access
50
+ * following a change to the HCR_EL2.VSE bit.
51
+ */
52
+void arm_cpu_update_vserr(ARMCPU *cpu);
53
+
54
/**
55
* arm_mmu_idx_el:
56
* @env: The cpu environment
57
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/syndrome.h
60
+++ b/target/arm/syndrome.h
61
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_pcalignment(void)
62
return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
63
}
64
65
+static inline uint32_t syn_serror(uint32_t extra)
66
+{
67
+ return (EC_SERROR << ARM_EL_EC_SHIFT) | ARM_EL_IL | extra;
68
+}
69
+
70
#endif /* TARGET_ARM_SYNDROME_H */
71
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/cpu.c
74
+++ b/target/arm/cpu.c
75
@@ -XXX,XX +XXX,XX @@ static bool arm_cpu_has_work(CPUState *cs)
76
return (cpu->power_state != PSCI_OFF)
77
&& cs->interrupt_request &
78
(CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
79
- | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ
80
+ | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | CPU_INTERRUPT_VSERR
81
| CPU_INTERRUPT_EXITTB);
82
}
83
84
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
85
return false;
86
}
87
return !(env->daif & PSTATE_I);
88
+ case EXCP_VSERR:
89
+ if (!(hcr_el2 & HCR_AMO) || (hcr_el2 & HCR_TGE)) {
90
+ /* VIRQs are only taken when hypervized. */
91
+ return false;
92
+ }
93
+ return !(env->daif & PSTATE_A);
94
default:
95
g_assert_not_reached();
96
}
97
@@ -XXX,XX +XXX,XX @@ static bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
98
goto found;
99
}
100
}
101
+ if (interrupt_request & CPU_INTERRUPT_VSERR) {
102
+ excp_idx = EXCP_VSERR;
103
+ target_el = 1;
104
+ if (arm_excp_unmasked(cs, excp_idx, target_el,
105
+ cur_el, secure, hcr_el2)) {
106
+ /* Taking a virtual abort clears HCR_EL2.VSE */
107
+ env->cp15.hcr_el2 &= ~HCR_VSE;
108
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_VSERR);
109
+ goto found;
110
+ }
111
+ }
112
return false;
113
114
found:
115
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_vfiq(ARMCPU *cpu)
116
}
117
}
118
119
+void arm_cpu_update_vserr(ARMCPU *cpu)
120
+{
121
+ /*
122
+ * Update the interrupt level for VSERR, which is the HCR_EL2.VSE bit.
123
+ */
124
+ CPUARMState *env = &cpu->env;
125
+ CPUState *cs = CPU(cpu);
126
+
127
+ bool new_state = env->cp15.hcr_el2 & HCR_VSE;
128
+
129
+ if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VSERR) != 0)) {
130
+ if (new_state) {
131
+ cpu_interrupt(cs, CPU_INTERRUPT_VSERR);
132
+ } else {
133
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_VSERR);
134
+ }
135
+ }
136
+}
137
+
138
#ifndef CONFIG_USER_ONLY
139
static void arm_cpu_set_irq(void *opaque, int irq, int level)
140
{
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
141
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
143
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
144
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
145
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
37
bool sctlr_b = arm_sctlr_b(env);
146
}
38
147
}
39
if (sctlr_b) {
148
40
- flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, 1);
149
- /* External aborts are not possible in QEMU so A bit is always clear */
41
+ flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR__B, 1);
150
+ if (hcr_el2 & HCR_AMO) {
42
}
151
+ if (cs->interrupt_request & CPU_INTERRUPT_VSERR) {
43
if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
152
+ ret |= CPSR_A;
44
flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
153
+ }
45
diff --git a/target/arm/translate.c b/target/arm/translate.c
154
+ }
46
index XXXXXXX..XXXXXXX 100644
155
+
47
--- a/target/arm/translate.c
156
return ret;
48
+++ b/target/arm/translate.c
157
}
49
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
158
50
FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
159
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
51
dc->debug_target_el =
160
g_assert(qemu_mutex_iothread_locked());
52
FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
161
arm_cpu_update_virq(cpu);
53
- dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
162
arm_cpu_update_vfiq(cpu);
54
+ dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR__B);
163
+ arm_cpu_update_vserr(cpu);
55
dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
164
}
56
dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
165
57
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
166
static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
167
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(CPUState *cs)
168
[EXCP_LSERR] = "v8M LSERR UsageFault",
169
[EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
170
[EXCP_DIVBYZERO] = "v7M DIVBYZERO UsageFault",
171
+ [EXCP_VSERR] = "Virtual SERR",
172
};
173
174
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
175
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
176
mask = CPSR_A | CPSR_I | CPSR_F;
177
offset = 4;
178
break;
179
+ case EXCP_VSERR:
180
+ {
181
+ /*
182
+ * Note that this is reported as a data abort, but the DFAR
183
+ * has an UNKNOWN value. Construct the SError syndrome from
184
+ * AET and ExT fields.
185
+ */
186
+ ARMMMUFaultInfo fi = { .type = ARMFault_AsyncExternal, };
187
+
188
+ if (extended_addresses_enabled(env)) {
189
+ env->exception.fsr = arm_fi_to_lfsc(&fi);
190
+ } else {
191
+ env->exception.fsr = arm_fi_to_sfsc(&fi);
192
+ }
193
+ env->exception.fsr |= env->cp15.vsesr_el2 & 0xd000;
194
+ A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);
195
+ qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x\n",
196
+ env->exception.fsr);
197
+
198
+ new_mode = ARM_CPU_MODE_ABT;
199
+ addr = 0x10;
200
+ mask = CPSR_A | CPSR_I;
201
+ offset = 8;
202
+ }
203
+ break;
204
case EXCP_SMC:
205
new_mode = ARM_CPU_MODE_MON;
206
addr = 0x08;
207
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
208
case EXCP_VFIQ:
209
addr += 0x100;
210
break;
211
+ case EXCP_VSERR:
212
+ addr += 0x180;
213
+ /* Construct the SError syndrome from IDS and ISS fields. */
214
+ env->exception.syndrome = syn_serror(env->cp15.vsesr_el2 & 0x1ffffff);
215
+ env->cp15.esr_el[new_el] = env->exception.syndrome;
216
+ break;
217
default:
218
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
219
}
58
--
220
--
59
2.20.1
221
2.25.1
60
61
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're about to rearrange the macro expansion surrounding tbflags,
3
Check for and defer any pending virtual SError.
4
and this field name will be expanded using the bit definition of
5
the same name, resulting in a token pasting error.
6
7
So PSTATE_SS -> PSTATE__SS in the uses, and document it.
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: 20210419202257.161730-4-richard.henderson@linaro.org
7
Message-id: 20220506180242.216785-17-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
9
---
14
target/arm/cpu.h | 2 +-
10
target/arm/helper.h | 1 +
15
target/arm/helper.c | 4 ++--
11
target/arm/a32.decode | 16 ++++++++------
16
target/arm/translate-a64.c | 2 +-
12
target/arm/t32.decode | 18 ++++++++--------
17
target/arm/translate.c | 2 +-
13
target/arm/op_helper.c | 43 ++++++++++++++++++++++++++++++++++++++
18
4 files changed, 5 insertions(+), 5 deletions(-)
14
target/arm/translate-a64.c | 17 +++++++++++++++
15
target/arm/translate.c | 23 ++++++++++++++++++++
16
6 files changed, 103 insertions(+), 15 deletions(-)
19
17
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
20
--- a/target/arm/helper.h
23
+++ b/target/arm/cpu.h
21
+++ b/target/arm/helper.h
24
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(wfe, void, env)
25
*/
23
DEF_HELPER_1(yield, void, env)
26
FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1)
24
DEF_HELPER_1(pre_hvc, void, env)
27
FIELD(TBFLAG_ANY, SS_ACTIVE, 30, 1)
25
DEF_HELPER_2(pre_smc, void, env, i32)
28
-FIELD(TBFLAG_ANY, PSTATE_SS, 29, 1) /* Not cached. */
26
+DEF_HELPER_1(vesb, void, env)
29
+FIELD(TBFLAG_ANY, PSTATE__SS, 29, 1) /* Not cached. */
27
30
FIELD(TBFLAG_ANY, BE_DATA, 28, 1)
28
DEF_HELPER_3(cpsr_write, void, env, i32, i32)
31
FIELD(TBFLAG_ANY, MMUIDX, 24, 4)
29
DEF_HELPER_2(cpsr_write_eret, void, env, i32)
32
/* Target EL if we take a floating-point-disabled exception */
30
diff --git a/target/arm/a32.decode b/target/arm/a32.decode
33
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/a32.decode
35
--- a/target/arm/helper.c
33
+++ b/target/arm/a32.decode
36
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ SMULTT .... 0001 0110 .... 0000 .... 1110 .... @rd0mn
37
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
35
38
* 0 x Inactive (the TB flag for SS is always 0)
36
{
39
* 1 0 Active-pending
37
{
40
* 1 1 Active-not-pending
38
- YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
41
- * SS_ACTIVE is set in hflags; PSTATE_SS is computed every TB.
39
- WFE ---- 0011 0010 0000 1111 ---- 0000 0010
42
+ * SS_ACTIVE is set in hflags; PSTATE__SS is computed every TB.
40
- WFI ---- 0011 0010 0000 1111 ---- 0000 0011
43
*/
41
+ [
44
if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
42
+ YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
45
(env->pstate & PSTATE_SS)) {
43
+ WFE ---- 0011 0010 0000 1111 ---- 0000 0010
46
- flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
44
+ WFI ---- 0011 0010 0000 1111 ---- 0000 0011
47
+ flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE__SS, 1);
45
46
- # TODO: Implement SEV, SEVL; may help SMP performance.
47
- # SEV ---- 0011 0010 0000 1111 ---- 0000 0100
48
- # SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
49
+ # TODO: Implement SEV, SEVL; may help SMP performance.
50
+ # SEV ---- 0011 0010 0000 1111 ---- 0000 0100
51
+ # SEVL ---- 0011 0010 0000 1111 ---- 0000 0101
52
+
53
+ ESB ---- 0011 0010 0000 1111 ---- 0001 0000
54
+ ]
55
56
# The canonical nop ends in 00000000, but the whole of the
57
# rest of the space executes as nop if otherwise unsupported.
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
61
+++ b/target/arm/t32.decode
62
@@ -XXX,XX +XXX,XX @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
63
[
64
# Hints, and CPS
65
{
66
- YIELD 1111 0011 1010 1111 1000 0000 0000 0001
67
- WFE 1111 0011 1010 1111 1000 0000 0000 0010
68
- WFI 1111 0011 1010 1111 1000 0000 0000 0011
69
+ [
70
+ YIELD 1111 0011 1010 1111 1000 0000 0000 0001
71
+ WFE 1111 0011 1010 1111 1000 0000 0000 0010
72
+ WFI 1111 0011 1010 1111 1000 0000 0000 0011
73
74
- # TODO: Implement SEV, SEVL; may help SMP performance.
75
- # SEV 1111 0011 1010 1111 1000 0000 0000 0100
76
- # SEVL 1111 0011 1010 1111 1000 0000 0000 0101
77
+ # TODO: Implement SEV, SEVL; may help SMP performance.
78
+ # SEV 1111 0011 1010 1111 1000 0000 0000 0100
79
+ # SEVL 1111 0011 1010 1111 1000 0000 0000 0101
80
81
- # For M-profile minimal-RAS ESB can be a NOP, which is the
82
- # default behaviour since it is in the hint space.
83
- # ESB 1111 0011 1010 1111 1000 0000 0001 0000
84
+ ESB 1111 0011 1010 1111 1000 0000 0001 0000
85
+ ]
86
87
# The canonical nop ends in 0000 0000, but the whole rest
88
# of the space is "reserved hint, behaves as nop".
89
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/op_helper.c
92
+++ b/target/arm/op_helper.c
93
@@ -XXX,XX +XXX,XX @@ void HELPER(probe_access)(CPUARMState *env, target_ulong ptr,
94
access_type, mmu_idx, ra);
48
}
95
}
49
96
}
50
*pflags = flags;
97
+
98
+/*
99
+ * This function corresponds to AArch64.vESBOperation().
100
+ * Note that the AArch32 version is not functionally different.
101
+ */
102
+void HELPER(vesb)(CPUARMState *env)
103
+{
104
+ /*
105
+ * The EL2Enabled() check is done inside arm_hcr_el2_eff,
106
+ * and will return HCR_EL2.VSE == 0, so nothing happens.
107
+ */
108
+ uint64_t hcr = arm_hcr_el2_eff(env);
109
+ bool enabled = !(hcr & HCR_TGE) && (hcr & HCR_AMO);
110
+ bool pending = enabled && (hcr & HCR_VSE);
111
+ bool masked = (env->daif & PSTATE_A);
112
+
113
+ /* If VSE pending and masked, defer the exception. */
114
+ if (pending && masked) {
115
+ uint32_t syndrome;
116
+
117
+ if (arm_el_is_aa64(env, 1)) {
118
+ /* Copy across IDS and ISS from VSESR. */
119
+ syndrome = env->cp15.vsesr_el2 & 0x1ffffff;
120
+ } else {
121
+ ARMMMUFaultInfo fi = { .type = ARMFault_AsyncExternal };
122
+
123
+ if (extended_addresses_enabled(env)) {
124
+ syndrome = arm_fi_to_lfsc(&fi);
125
+ } else {
126
+ syndrome = arm_fi_to_sfsc(&fi);
127
+ }
128
+ /* Copy across AET and ExT from VSESR. */
129
+ syndrome |= env->cp15.vsesr_el2 & 0xd000;
130
+ }
131
+
132
+ /* Set VDISR_EL2.A along with the syndrome. */
133
+ env->cp15.vdisr_el2 = syndrome | (1u << 31);
134
+
135
+ /* Clear pending virtual SError */
136
+ env->cp15.hcr_el2 &= ~HCR_VSE;
137
+ cpu_reset_interrupt(env_cpu(env), CPU_INTERRUPT_VSERR);
138
+ }
139
+}
51
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
140
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
52
index XXXXXXX..XXXXXXX 100644
141
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-a64.c
142
--- a/target/arm/translate-a64.c
54
+++ b/target/arm/translate-a64.c
143
+++ b/target/arm/translate-a64.c
55
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
144
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
56
* end the TB
145
gen_helper_autib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
57
*/
146
}
58
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
147
break;
59
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
148
+ case 0b10000: /* ESB */
60
+ dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
149
+ /* Without RAS, we must implement this as NOP. */
61
dc->is_ldex = false;
150
+ if (dc_isar_feature(aa64_ras, s)) {
62
dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
151
+ /*
63
152
+ * QEMU does not have a source of physical SErrors,
153
+ * so we are only concerned with virtual SErrors.
154
+ * The pseudocode in the ARM for this case is
155
+ * if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then
156
+ * AArch64.vESBOperation();
157
+ * Most of the condition can be evaluated at translation time.
158
+ * Test for EL2 present, and defer test for SEL2 to runtime.
159
+ */
160
+ if (s->current_el <= 1 && arm_dc_feature(s, ARM_FEATURE_EL2)) {
161
+ gen_helper_vesb(cpu_env);
162
+ }
163
+ }
164
+ break;
165
case 0b11000: /* PACIAZ */
166
if (s->pauth_active) {
167
gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30],
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
168
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
169
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
170
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
171
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
172
@@ -XXX,XX +XXX,XX @@ static bool trans_WFI(DisasContext *s, arg_WFI *a)
69
* end the TB
173
return true;
70
*/
174
}
71
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
175
72
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
176
+static bool trans_ESB(DisasContext *s, arg_ESB *a)
73
+ dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
177
+{
74
dc->is_ldex = false;
178
+ /*
75
179
+ * For M-profile, minimal-RAS ESB can be a NOP.
76
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
180
+ * Without RAS, we must implement this as NOP.
181
+ */
182
+ if (!arm_dc_feature(s, ARM_FEATURE_M) && dc_isar_feature(aa32_ras, s)) {
183
+ /*
184
+ * QEMU does not have a source of physical SErrors,
185
+ * so we are only concerned with virtual SErrors.
186
+ * The pseudocode in the ARM for this case is
187
+ * if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then
188
+ * AArch32.vESBOperation();
189
+ * Most of the condition can be evaluated at translation time.
190
+ * Test for EL2 present, and defer test for SEL2 to runtime.
191
+ */
192
+ if (s->current_el <= 1 && arm_dc_feature(s, ARM_FEATURE_EL2)) {
193
+ gen_helper_vesb(cpu_env);
194
+ }
195
+ }
196
+ return true;
197
+}
198
+
199
static bool trans_NOP(DisasContext *s, arg_NOP *a)
200
{
201
return true;
77
--
202
--
78
2.20.1
203
2.25.1
79
80
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-29-richard.henderson@linaro.org
5
Message-id: 20220506180242.216785-18-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/translate-a64.c | 20 ++++++++++----------
8
docs/system/arm/emulation.rst | 1 +
9
1 file changed, 10 insertions(+), 10 deletions(-)
9
target/arm/cpu64.c | 1 +
10
target/arm/cpu_tcg.c | 1 +
11
3 files changed, 3 insertions(+)
10
12
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
15
--- a/docs/system/arm/emulation.rst
14
+++ b/target/arm/translate-a64.c
16
+++ b/docs/system/arm/emulation.rst
15
@@ -XXX,XX +XXX,XX @@ static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
17
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
16
18
- FEAT_PMULL (PMULL, PMULL2 instructions)
17
/* Store from vector register to memory */
19
- FEAT_PMUv3p1 (PMU Extensions v3.1)
18
static void do_vec_st(DisasContext *s, int srcidx, int element,
20
- FEAT_PMUv3p4 (PMU Extensions v3.4)
19
- TCGv_i64 tcg_addr, int size, MemOp endian)
21
+- FEAT_RAS (Reliability, availability, and serviceability)
20
+ TCGv_i64 tcg_addr, MemOp mop)
22
- FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
21
{
23
- FEAT_RNG (Random number generator)
22
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
24
- FEAT_SB (Speculation Barrier)
23
25
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
24
- read_vec_element(s, tcg_tmp, srcidx, element, size);
26
index XXXXXXX..XXXXXXX 100644
25
- tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
27
--- a/target/arm/cpu64.c
26
+ read_vec_element(s, tcg_tmp, srcidx, element, mop & MO_SIZE);
28
+++ b/target/arm/cpu64.c
27
+ tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), mop);
29
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
28
30
t = cpu->isar.id_aa64pfr0;
29
tcg_temp_free_i64(tcg_tmp);
31
t = FIELD_DP64(t, ID_AA64PFR0, FP, 1); /* FEAT_FP16 */
30
}
32
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); /* FEAT_FP16 */
31
33
+ t = FIELD_DP64(t, ID_AA64PFR0, RAS, 1); /* FEAT_RAS */
32
/* Load from memory to vector register */
34
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
33
static void do_vec_ld(DisasContext *s, int destidx, int element,
35
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
34
- TCGv_i64 tcg_addr, int size, MemOp endian)
36
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
35
+ TCGv_i64 tcg_addr, MemOp mop)
37
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
36
{
38
index XXXXXXX..XXXXXXX 100644
37
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
39
--- a/target/arm/cpu_tcg.c
38
40
+++ b/target/arm/cpu_tcg.c
39
- tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
41
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
40
- write_vec_element(s, tcg_tmp, destidx, element, size);
42
41
+ tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), mop);
43
t = cpu->isar.id_pfr0;
42
+ write_vec_element(s, tcg_tmp, destidx, element, mop & MO_SIZE);
44
t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
43
45
+ t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
44
tcg_temp_free_i64(tcg_tmp);
46
cpu->isar.id_pfr0 = t;
45
}
47
46
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
48
t = cpu->isar.id_pfr2;
47
for (xs = 0; xs < selem; xs++) {
48
int tt = (rt + r + xs) % 32;
49
if (is_store) {
50
- do_vec_st(s, tt, e, clean_addr, size, endian);
51
+ do_vec_st(s, tt, e, clean_addr, size | endian);
52
} else {
53
- do_vec_ld(s, tt, e, clean_addr, size, endian);
54
+ do_vec_ld(s, tt, e, clean_addr, size | endian);
55
}
56
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
57
}
58
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
59
} else {
60
/* Load/store one element per register */
61
if (is_load) {
62
- do_vec_ld(s, rt, index, clean_addr, scale, s->be_data);
63
+ do_vec_ld(s, rt, index, clean_addr, scale | s->be_data);
64
} else {
65
- do_vec_st(s, rt, index, clean_addr, scale, s->be_data);
66
+ do_vec_st(s, rt, index, clean_addr, scale | s->be_data);
67
}
68
}
69
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
70
--
49
--
71
2.20.1
50
2.25.1
72
73
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now that these bits have been moved out of tb->flags,
3
This feature is AArch64 only, and applies to physical SErrors,
4
where TBFLAG_ANY was filling from the top, move AM32
4
which QEMU does not implement, thus the feature is a nop.
5
to fill from the top, and A32 and M32 to fill from the
6
bottom. This means fewer changes when adding new bits.
7
5
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210419202257.161730-9-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-19-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/cpu.h | 42 +++++++++++++++++++++---------------------
11
docs/system/arm/emulation.rst | 1 +
14
1 file changed, 21 insertions(+), 21 deletions(-)
12
target/arm/cpu64.c | 1 +
13
2 files changed, 2 insertions(+)
15
14
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
17
--- a/docs/system/arm/emulation.rst
19
+++ b/target/arm/cpu.h
18
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
19
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
*
20
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
22
* The bits for 32-bit A-profile and M-profile partially overlap:
21
- FEAT_HPDS (Hierarchical permission disables)
23
*
22
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
24
- * 18 9 0
23
+- FEAT_IESB (Implicit error synchronization event)
25
- * +----------------+--------------+
24
- FEAT_JSCVT (JavaScript conversion instructions)
26
- * | TBFLAG_A32 | |
25
- FEAT_LOR (Limited ordering regions)
27
- * +-----+----------+ TBFLAG_AM32 |
26
- FEAT_LPA (Large Physical Address space)
28
- * | |TBFLAG_M32| |
27
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
29
- * +-----+----------+--------------+
28
index XXXXXXX..XXXXXXX 100644
30
- * 14 9 0
29
--- a/target/arm/cpu64.c
31
+ * 31 23 11 10 0
30
+++ b/target/arm/cpu64.c
32
+ * +-------------+----------+----------------+
31
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
33
+ * | | | TBFLAG_A32 |
32
t = cpu->isar.id_aa64mmfr2;
34
+ * | TBFLAG_AM32 | +-----+----------+
33
t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* FEAT_TTCNP */
35
+ * | | |TBFLAG_M32|
34
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1); /* FEAT_UAO */
36
+ * +-------------+----------------+----------+
35
+ t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1); /* FEAT_IESB */
37
+ * 31 23 5 4 0
36
t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
38
*
37
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* FEAT_TTST */
39
* Unless otherwise noted, these bits are cached in env->hflags.
38
t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1); /* FEAT_TTL */
40
*/
41
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 20, 2)
42
/*
43
* Bit usage when in AArch32 state, both A- and M-profile.
44
*/
45
-FIELD(TBFLAG_AM32, CONDEXEC, 0, 8) /* Not cached. */
46
-FIELD(TBFLAG_AM32, THUMB, 8, 1) /* Not cached. */
47
+FIELD(TBFLAG_AM32, CONDEXEC, 24, 8) /* Not cached. */
48
+FIELD(TBFLAG_AM32, THUMB, 23, 1) /* Not cached. */
49
50
/*
51
* Bit usage when in AArch32 state, for A-profile only.
52
*/
53
-FIELD(TBFLAG_A32, VECLEN, 9, 3) /* Not cached. */
54
-FIELD(TBFLAG_A32, VECSTRIDE, 12, 2) /* Not cached. */
55
+FIELD(TBFLAG_A32, VECLEN, 0, 3) /* Not cached. */
56
+FIELD(TBFLAG_A32, VECSTRIDE, 3, 2) /* Not cached. */
57
/*
58
* We store the bottom two bits of the CPAR as TB flags and handle
59
* checks on the other bits at runtime. This shares the same bits as
60
* VECSTRIDE, which is OK as no XScale CPU has VFP.
61
* Not cached, because VECLEN+VECSTRIDE are not cached.
62
*/
63
-FIELD(TBFLAG_A32, XSCALE_CPAR, 12, 2)
64
-FIELD(TBFLAG_A32, VFPEN, 14, 1) /* Partially cached, minus FPEXC. */
65
-FIELD(TBFLAG_A32, SCTLR__B, 15, 1) /* Cannot overlap with SCTLR_B */
66
-FIELD(TBFLAG_A32, HSTR_ACTIVE, 16, 1)
67
+FIELD(TBFLAG_A32, XSCALE_CPAR, 5, 2)
68
+FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
69
+FIELD(TBFLAG_A32, SCTLR__B, 8, 1) /* Cannot overlap with SCTLR_B */
70
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 9, 1)
71
/*
72
* Indicates whether cp register reads and writes by guest code should access
73
* the secure or nonsecure bank of banked registers; note that this is not
74
* the same thing as the current security state of the processor!
75
*/
76
-FIELD(TBFLAG_A32, NS, 17, 1)
77
+FIELD(TBFLAG_A32, NS, 10, 1)
78
79
/*
80
* Bit usage when in AArch32 state, for M-profile only.
81
*/
82
/* Handler (ie not Thread) mode */
83
-FIELD(TBFLAG_M32, HANDLER, 9, 1)
84
+FIELD(TBFLAG_M32, HANDLER, 0, 1)
85
/* Whether we should generate stack-limit checks */
86
-FIELD(TBFLAG_M32, STACKCHECK, 10, 1)
87
+FIELD(TBFLAG_M32, STACKCHECK, 1, 1)
88
/* Set if FPCCR.LSPACT is set */
89
-FIELD(TBFLAG_M32, LSPACT, 11, 1) /* Not cached. */
90
+FIELD(TBFLAG_M32, LSPACT, 2, 1) /* Not cached. */
91
/* Set if we must create a new FP context */
92
-FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 12, 1) /* Not cached. */
93
+FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 3, 1) /* Not cached. */
94
/* Set if FPCCR.S does not match current security state */
95
-FIELD(TBFLAG_M32, FPCCR_S_WRONG, 13, 1) /* Not cached. */
96
+FIELD(TBFLAG_M32, FPCCR_S_WRONG, 4, 1) /* Not cached. */
97
98
/*
99
* Bit usage when in AArch64 state
100
--
39
--
101
2.20.1
40
2.25.1
102
103
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now that other bits have been moved out of tb->flags,
3
This extension concerns branch speculation, which TCG does
4
there's no point in filling from the top.
4
not implement. Thus we can trivially enable this feature.
5
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210419202257.161730-10-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-20-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.h | 14 +++++++-------
11
docs/system/arm/emulation.rst | 1 +
12
1 file changed, 7 insertions(+), 7 deletions(-)
12
target/arm/cpu64.c | 1 +
13
target/arm/cpu_tcg.c | 1 +
14
3 files changed, 3 insertions(+)
13
15
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
18
--- a/docs/system/arm/emulation.rst
17
+++ b/target/arm/cpu.h
19
+++ b/docs/system/arm/emulation.rst
18
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
19
*
21
- FEAT_BBM at level 2 (Translation table break-before-make levels)
20
* Unless otherwise noted, these bits are cached in env->hflags.
22
- FEAT_BF16 (AArch64 BFloat16 instructions)
21
*/
23
- FEAT_BTI (Branch Target Identification)
22
-FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1)
24
+- FEAT_CSV2 (Cache speculation variant 2)
23
-FIELD(TBFLAG_ANY, SS_ACTIVE, 30, 1)
25
- FEAT_DIT (Data Independent Timing instructions)
24
-FIELD(TBFLAG_ANY, PSTATE__SS, 29, 1) /* Not cached. */
26
- FEAT_DPB (DC CVAP instruction)
25
-FIELD(TBFLAG_ANY, BE_DATA, 28, 1)
27
- FEAT_Debugv8p2 (Debug changes for v8.2)
26
-FIELD(TBFLAG_ANY, MMUIDX, 24, 4)
28
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
27
+FIELD(TBFLAG_ANY, AARCH64_STATE, 0, 1)
29
index XXXXXXX..XXXXXXX 100644
28
+FIELD(TBFLAG_ANY, SS_ACTIVE, 1, 1)
30
--- a/target/arm/cpu64.c
29
+FIELD(TBFLAG_ANY, PSTATE__SS, 2, 1) /* Not cached. */
31
+++ b/target/arm/cpu64.c
30
+FIELD(TBFLAG_ANY, BE_DATA, 3, 1)
32
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
31
+FIELD(TBFLAG_ANY, MMUIDX, 4, 4)
33
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
32
/* Target EL if we take a floating-point-disabled exception */
34
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
33
-FIELD(TBFLAG_ANY, FPEXC_EL, 22, 2)
35
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
34
+FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
36
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 1); /* FEAT_CSV2 */
35
/* For A-profile only, target EL for debug exceptions. */
37
cpu->isar.id_aa64pfr0 = t;
36
-FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 20, 2)
38
37
+FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 10, 2)
39
t = cpu->isar.id_aa64pfr1;
38
40
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
39
/*
41
index XXXXXXX..XXXXXXX 100644
40
* Bit usage when in AArch32 state, both A- and M-profile.
42
--- a/target/arm/cpu_tcg.c
43
+++ b/target/arm/cpu_tcg.c
44
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
45
cpu->isar.id_mmfr4 = t;
46
47
t = cpu->isar.id_pfr0;
48
+ t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CVS2 */
49
t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
50
t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
51
cpu->isar.id_pfr0 = t;
41
--
52
--
42
2.20.1
53
2.25.1
43
44
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 splitting tb->flags across multiple
3
There is no branch prediction in TCG, therefore there is no
4
fields, introduce a structure to hold the value(s).
4
need to actually include the context number into the predictor.
5
So far this only migrates the one uint32_t and fixes
5
Therefore all we need to do is add the state for SCXTNUM_ELx.
6
all of the places that require adjustment to match.
7
6
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210419202257.161730-6-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-21-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
target/arm/cpu.h | 26 ++++++++++++---------
12
docs/system/arm/emulation.rst | 3 ++
14
target/arm/translate.h | 11 +++++++++
13
target/arm/cpu.h | 16 +++++++++
15
target/arm/helper.c | 48 +++++++++++++++++++++-----------------
14
target/arm/cpu.c | 5 +++
16
target/arm/translate-a64.c | 2 +-
15
target/arm/cpu64.c | 3 +-
17
target/arm/translate.c | 7 +++---
16
target/arm/helper.c | 61 ++++++++++++++++++++++++++++++++++-
18
5 files changed, 57 insertions(+), 37 deletions(-)
17
5 files changed, 86 insertions(+), 2 deletions(-)
19
18
19
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
20
index XXXXXXX..XXXXXXX 100644
21
--- a/docs/system/arm/emulation.rst
22
+++ b/docs/system/arm/emulation.rst
23
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
24
- FEAT_BF16 (AArch64 BFloat16 instructions)
25
- FEAT_BTI (Branch Target Identification)
26
- FEAT_CSV2 (Cache speculation variant 2)
27
+- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
28
+- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
29
+- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
30
- FEAT_DIT (Data Independent Timing instructions)
31
- FEAT_DPB (DC CVAP instruction)
32
- FEAT_Debugv8p2 (Debug changes for v8.2)
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
33
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
35
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
36
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct ARMPACKey {
37
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
25
} ARMPACKey;
38
ARMPACKey apdb;
39
ARMPACKey apga;
40
} keys;
41
+
42
+ uint64_t scxtnum_el[4];
26
#endif
43
#endif
27
44
28
+/* See the commentary above the TBFLAG field definitions. */
45
#if defined(CONFIG_USER_ONLY)
29
+typedef struct CPUARMTBFlags {
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
30
+ uint32_t flags;
47
#define SCTLR_WXN (1U << 19)
31
+} CPUARMTBFlags;
48
#define SCTLR_ST (1U << 20) /* up to ??, RAZ in v6 */
32
49
#define SCTLR_UWXN (1U << 20) /* v7 onward, AArch32 only */
33
typedef struct CPUARMState {
50
+#define SCTLR_TSCXT (1U << 20) /* FEAT_CSV2_1p2, AArch64 only */
34
/* Regs for current mode. */
51
#define SCTLR_FI (1U << 21) /* up to v7, v8 RES0 */
35
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
52
#define SCTLR_IESB (1U << 21) /* v8.2-IESB, AArch64 only */
36
uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.nRW */
53
#define SCTLR_U (1U << 22) /* up to v6, RAO in v7 */
37
54
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
38
/* Cached TBFLAGS state. See below for which bits are included. */
55
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
39
- uint32_t hflags;
56
}
40
+ CPUARMTBFlags hflags;
57
41
58
+static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
42
/* Frequently accessed CPSR bits are stored separately for efficiency.
43
This contains all the other bits. Use cpsr_{read,write} to access
44
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
45
* Helpers for using the above.
46
*/
47
#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
48
- (DST = FIELD_DP32(DST, TBFLAG_ANY, WHICH, VAL))
49
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_ANY, WHICH, VAL))
50
#define DP_TBFLAG_A64(DST, WHICH, VAL) \
51
- (DST = FIELD_DP32(DST, TBFLAG_A64, WHICH, VAL))
52
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A64, WHICH, VAL))
53
#define DP_TBFLAG_A32(DST, WHICH, VAL) \
54
- (DST = FIELD_DP32(DST, TBFLAG_A32, WHICH, VAL))
55
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A32, WHICH, VAL))
56
#define DP_TBFLAG_M32(DST, WHICH, VAL) \
57
- (DST = FIELD_DP32(DST, TBFLAG_M32, WHICH, VAL))
58
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_M32, WHICH, VAL))
59
#define DP_TBFLAG_AM32(DST, WHICH, VAL) \
60
- (DST = FIELD_DP32(DST, TBFLAG_AM32, WHICH, VAL))
61
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_AM32, WHICH, VAL))
62
63
-#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN, TBFLAG_ANY, WHICH)
64
-#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN, TBFLAG_A64, WHICH)
65
-#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN, TBFLAG_A32, WHICH)
66
-#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN, TBFLAG_M32, WHICH)
67
-#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN, TBFLAG_AM32, WHICH)
68
+#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_ANY, WHICH)
69
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A64, WHICH)
70
+#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A32, WHICH)
71
+#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_M32, WHICH)
72
+#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_AM32, WHICH)
73
74
/**
75
* cpu_mmu_index:
76
diff --git a/target/arm/translate.h b/target/arm/translate.h
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate.h
79
+++ b/target/arm/translate.h
80
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
81
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
82
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
83
84
+/**
85
+ * arm_tbflags_from_tb:
86
+ * @tb: the TranslationBlock
87
+ *
88
+ * Extract the flag values from @tb.
89
+ */
90
+static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb)
91
+{
59
+{
92
+ return (CPUARMTBFlags){ tb->flags };
60
+ int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
61
+ if (key >= 2) {
62
+ return true; /* FEAT_CSV2_2 */
63
+ }
64
+ if (key == 1) {
65
+ key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
66
+ return key >= 2; /* FEAT_CSV2_1p2 */
67
+ }
68
+ return false;
93
+}
69
+}
94
+
70
+
95
/*
71
static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
96
* Enum for argument to fpstatus_ptr().
72
{
97
*/
73
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
74
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/cpu.c
77
+++ b/target/arm/cpu.c
78
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
79
*/
80
env->cp15.gcr_el1 = 0x1ffff;
81
}
82
+ /*
83
+ * Disable access to SCXTNUM_EL0 from CSV2_1p2.
84
+ * This is not yet exposed from the Linux kernel in any way.
85
+ */
86
+ env->cp15.sctlr_el[1] |= SCTLR_TSCXT;
87
#else
88
/* Reset into the highest available EL */
89
if (arm_feature(env, ARM_FEATURE_EL3)) {
90
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/cpu64.c
93
+++ b/target/arm/cpu64.c
94
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
95
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
96
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
97
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
98
- t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 1); /* FEAT_CSV2 */
99
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
100
cpu->isar.id_aa64pfr0 = t;
101
102
t = cpu->isar.id_aa64pfr1;
103
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
104
* we do for EL2 with the virtualization=on property.
105
*/
106
t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
107
+ t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
108
cpu->isar.id_aa64pfr1 = t;
109
110
t = cpu->isar.id_aa64mmfr0;
98
diff --git a/target/arm/helper.c b/target/arm/helper.c
111
diff --git a/target/arm/helper.c b/target/arm/helper.c
99
index XXXXXXX..XXXXXXX 100644
112
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/helper.c
113
--- a/target/arm/helper.c
101
+++ b/target/arm/helper.c
114
+++ b/target/arm/helper.c
102
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
115
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
103
}
116
if (cpu_isar_feature(aa64_mte, cpu)) {
117
valid_mask |= SCR_ATA;
118
}
119
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
120
+ valid_mask |= SCR_ENSCXT;
121
+ }
122
} else {
123
valid_mask &= ~(SCR_RW | SCR_ST);
124
if (cpu_isar_feature(aa32_ras, cpu)) {
125
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
126
if (cpu_isar_feature(aa64_mte, cpu)) {
127
valid_mask |= HCR_ATA | HCR_DCT | HCR_TID5;
128
}
129
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
130
+ valid_mask |= HCR_ENSCXT;
131
+ }
132
}
133
134
/* Clear RES0 bits. */
135
@@ -XXX,XX +XXX,XX @@ static void define_arm_vh_e2h_redirects_aliases(ARMCPU *cpu)
136
{ K(3, 0, 5, 6, 0), K(3, 4, 5, 6, 0), K(3, 5, 5, 6, 0),
137
"TFSR_EL1", "TFSR_EL2", "TFSR_EL12", isar_feature_aa64_mte },
138
139
+ { K(3, 0, 13, 0, 7), K(3, 4, 13, 0, 7), K(3, 5, 13, 0, 7),
140
+ "SCXTNUM_EL1", "SCXTNUM_EL2", "SCXTNUM_EL12",
141
+ isar_feature_aa64_scxtnum },
142
+
143
/* TODO: ARMv8.2-SPE -- PMSCR_EL2 */
144
/* TODO: ARMv8.4-Trace -- TRFCR_EL2 */
145
};
146
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo mte_el0_cacheop_reginfo[] = {
147
},
148
};
149
150
-#endif
151
+static CPAccessResult access_scxtnum(CPUARMState *env, const ARMCPRegInfo *ri,
152
+ bool isread)
153
+{
154
+ uint64_t hcr = arm_hcr_el2_eff(env);
155
+ int el = arm_current_el(env);
156
+
157
+ if (el == 0 && !((hcr & HCR_E2H) && (hcr & HCR_TGE))) {
158
+ if (env->cp15.sctlr_el[1] & SCTLR_TSCXT) {
159
+ if (hcr & HCR_TGE) {
160
+ return CP_ACCESS_TRAP_EL2;
161
+ }
162
+ return CP_ACCESS_TRAP;
163
+ }
164
+ } else if (el < 2 && (env->cp15.sctlr_el[2] & SCTLR_TSCXT)) {
165
+ return CP_ACCESS_TRAP_EL2;
166
+ }
167
+ if (el < 2 && arm_is_el2_enabled(env) && !(hcr & HCR_ENSCXT)) {
168
+ return CP_ACCESS_TRAP_EL2;
169
+ }
170
+ if (el < 3
171
+ && arm_feature(env, ARM_FEATURE_EL3)
172
+ && !(env->cp15.scr_el3 & SCR_ENSCXT)) {
173
+ return CP_ACCESS_TRAP_EL3;
174
+ }
175
+ return CP_ACCESS_OK;
176
+}
177
+
178
+static const ARMCPRegInfo scxtnum_reginfo[] = {
179
+ { .name = "SCXTNUM_EL0", .state = ARM_CP_STATE_AA64,
180
+ .opc0 = 3, .opc1 = 3, .crn = 13, .crm = 0, .opc2 = 7,
181
+ .access = PL0_RW, .accessfn = access_scxtnum,
182
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[0]) },
183
+ { .name = "SCXTNUM_EL1", .state = ARM_CP_STATE_AA64,
184
+ .opc0 = 3, .opc1 = 0, .crn = 13, .crm = 0, .opc2 = 7,
185
+ .access = PL1_RW, .accessfn = access_scxtnum,
186
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[1]) },
187
+ { .name = "SCXTNUM_EL2", .state = ARM_CP_STATE_AA64,
188
+ .opc0 = 3, .opc1 = 4, .crn = 13, .crm = 0, .opc2 = 7,
189
+ .access = PL2_RW, .accessfn = access_scxtnum,
190
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[2]) },
191
+ { .name = "SCXTNUM_EL3", .state = ARM_CP_STATE_AA64,
192
+ .opc0 = 3, .opc1 = 6, .crn = 13, .crm = 0, .opc2 = 7,
193
+ .access = PL3_RW,
194
+ .fieldoffset = offsetof(CPUARMState, scxtnum_el[3]) },
195
+};
196
+#endif /* TARGET_AARCH64 */
197
198
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
199
bool isread)
200
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
201
define_arm_cp_regs(cpu, mte_tco_ro_reginfo);
202
define_arm_cp_regs(cpu, mte_el0_cacheop_reginfo);
203
}
204
+
205
+ if (cpu_isar_feature(aa64_scxtnum, cpu)) {
206
+ define_arm_cp_regs(cpu, scxtnum_reginfo);
207
+ }
104
#endif
208
#endif
105
209
106
-static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
210
if (cpu_isar_feature(any_predinv, cpu)) {
107
- ARMMMUIdx mmu_idx, uint32_t flags)
108
+static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
109
+ ARMMMUIdx mmu_idx,
110
+ CPUARMTBFlags flags)
111
{
112
DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
113
DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
114
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
115
return flags;
116
}
117
118
-static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
119
- ARMMMUIdx mmu_idx, uint32_t flags)
120
+static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el,
121
+ ARMMMUIdx mmu_idx,
122
+ CPUARMTBFlags flags)
123
{
124
bool sctlr_b = arm_sctlr_b(env);
125
126
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
127
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
128
}
129
130
-static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
131
- ARMMMUIdx mmu_idx)
132
+static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
133
+ ARMMMUIdx mmu_idx)
134
{
135
- uint32_t flags = 0;
136
+ CPUARMTBFlags flags = {};
137
138
if (arm_v7m_is_handler_mode(env)) {
139
DP_TBFLAG_M32(flags, HANDLER, 1);
140
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
141
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
142
}
143
144
-static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
145
+static CPUARMTBFlags rebuild_hflags_aprofile(CPUARMState *env)
146
{
147
- int flags = 0;
148
+ CPUARMTBFlags flags = {};
149
150
DP_TBFLAG_ANY(flags, DEBUG_TARGET_EL, arm_debug_target_el(env));
151
return flags;
152
}
153
154
-static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
155
- ARMMMUIdx mmu_idx)
156
+static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
157
+ ARMMMUIdx mmu_idx)
158
{
159
- uint32_t flags = rebuild_hflags_aprofile(env);
160
+ CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
161
162
if (arm_el_is_aa64(env, 1)) {
163
DP_TBFLAG_A32(flags, VFPEN, 1);
164
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
165
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
166
}
167
168
-static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
169
- ARMMMUIdx mmu_idx)
170
+static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
171
+ ARMMMUIdx mmu_idx)
172
{
173
- uint32_t flags = rebuild_hflags_aprofile(env);
174
+ CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
175
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
176
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
177
uint64_t sctlr;
178
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
179
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
180
}
181
182
-static uint32_t rebuild_hflags_internal(CPUARMState *env)
183
+static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env)
184
{
185
int el = arm_current_el(env);
186
int fp_el = fp_exception_el(env, el);
187
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env)
188
int el = arm_current_el(env);
189
int fp_el = fp_exception_el(env, el);
190
ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
191
+
192
env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
193
}
194
195
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
196
static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
197
{
198
#ifdef CONFIG_DEBUG_TCG
199
- uint32_t env_flags_current = env->hflags;
200
- uint32_t env_flags_rebuilt = rebuild_hflags_internal(env);
201
+ CPUARMTBFlags c = env->hflags;
202
+ CPUARMTBFlags r = rebuild_hflags_internal(env);
203
204
- if (unlikely(env_flags_current != env_flags_rebuilt)) {
205
+ if (unlikely(c.flags != r.flags)) {
206
fprintf(stderr, "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
207
- env_flags_current, env_flags_rebuilt);
208
+ c.flags, r.flags);
209
abort();
210
}
211
#endif
212
@@ -XXX,XX +XXX,XX @@ static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
213
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
214
target_ulong *cs_base, uint32_t *pflags)
215
{
216
- uint32_t flags = env->hflags;
217
+ CPUARMTBFlags flags;
218
219
*cs_base = 0;
220
assert_hflags_rebuild_correctly(env);
221
+ flags = env->hflags;
222
223
if (EX_TBFLAG_ANY(flags, AARCH64_STATE)) {
224
*pc = env->pc;
225
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
226
DP_TBFLAG_ANY(flags, PSTATE__SS, 1);
227
}
228
229
- *pflags = flags;
230
+ *pflags = flags.flags;
231
}
232
233
#ifdef TARGET_AARCH64
234
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
235
index XXXXXXX..XXXXXXX 100644
236
--- a/target/arm/translate-a64.c
237
+++ b/target/arm/translate-a64.c
238
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
239
DisasContext *dc = container_of(dcbase, DisasContext, base);
240
CPUARMState *env = cpu->env_ptr;
241
ARMCPU *arm_cpu = env_archcpu(env);
242
- uint32_t tb_flags = dc->base.tb->flags;
243
+ CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
244
int bound, core_mmu_idx;
245
246
dc->isar = &arm_cpu->isar;
247
diff --git a/target/arm/translate.c b/target/arm/translate.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/target/arm/translate.c
250
+++ b/target/arm/translate.c
251
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
252
DisasContext *dc = container_of(dcbase, DisasContext, base);
253
CPUARMState *env = cs->env_ptr;
254
ARMCPU *cpu = env_archcpu(env);
255
- uint32_t tb_flags = dc->base.tb->flags;
256
+ CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
257
uint32_t condexec, core_mmu_idx;
258
259
dc->isar = &cpu->isar;
260
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
261
{
262
DisasContext dc = { };
263
const TranslatorOps *ops = &arm_translator_ops;
264
+ CPUARMTBFlags tb_flags = arm_tbflags_from_tb(tb);
265
266
- if (EX_TBFLAG_AM32(tb->flags, THUMB)) {
267
+ if (EX_TBFLAG_AM32(tb_flags, THUMB)) {
268
ops = &thumb_translator_ops;
269
}
270
#ifdef TARGET_AARCH64
271
- if (EX_TBFLAG_ANY(tb->flags, AARCH64_STATE)) {
272
+ if (EX_TBFLAG_ANY(tb_flags, AARCH64_STATE)) {
273
ops = &aarch64_translator_ops;
274
}
275
#endif
276
--
211
--
277
2.20.1
212
2.25.1
278
279
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For 128-bit load/store, use 16-byte alignment. This
3
This extension concerns cache speculation, which TCG does
4
requires that we perform the two operations in the
4
not implement. Thus we can trivially enable this feature.
5
correct order so that we generate the alignment fault
6
before modifying memory.
7
5
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210419202257.161730-27-richard.henderson@linaro.org
8
Message-id: 20220506180242.216785-22-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/translate-a64.c | 42 +++++++++++++++++++++++---------------
11
docs/system/arm/emulation.rst | 1 +
14
1 file changed, 26 insertions(+), 16 deletions(-)
12
target/arm/cpu64.c | 1 +
13
target/arm/cpu_tcg.c | 1 +
14
3 files changed, 3 insertions(+)
15
15
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
18
--- a/docs/system/arm/emulation.rst
19
+++ b/target/arm/translate-a64.c
19
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size)
21
- FEAT_CSV2_1p1 (Cache speculation variant 2, version 1.1)
22
{
22
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
23
/* This writes the bottom N bits of a 128 bit wide vector to memory */
23
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
24
- TCGv_i64 tmp = tcg_temp_new_i64();
24
+- FEAT_CSV3 (Cache speculation variant 3)
25
- tcg_gen_ld_i64(tmp, cpu_env, fp_reg_offset(s, srcidx, MO_64));
25
- FEAT_DIT (Data Independent Timing instructions)
26
+ TCGv_i64 tmplo = tcg_temp_new_i64();
26
- FEAT_DPB (DC CVAP instruction)
27
+ MemOp mop;
27
- FEAT_Debugv8p2 (Debug changes for v8.2)
28
+
28
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
29
+ tcg_gen_ld_i64(tmplo, cpu_env, fp_reg_offset(s, srcidx, MO_64));
29
index XXXXXXX..XXXXXXX 100644
30
+
30
--- a/target/arm/cpu64.c
31
if (size < 4) {
31
+++ b/target/arm/cpu64.c
32
- tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s),
32
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
33
- s->be_data + size);
33
t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1); /* FEAT_SEL2 */
34
+ mop = finalize_memop(s, size);
34
t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1); /* FEAT_DIT */
35
+ tcg_gen_qemu_st_i64(tmplo, tcg_addr, get_mem_index(s), mop);
35
t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2); /* FEAT_CSV2_2 */
36
} else {
36
+ t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1); /* FEAT_CSV3 */
37
bool be = s->be_data == MO_BE;
37
cpu->isar.id_aa64pfr0 = t;
38
TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
38
39
+ TCGv_i64 tmphi = tcg_temp_new_i64();
39
t = cpu->isar.id_aa64pfr1;
40
40
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
41
+ tcg_gen_ld_i64(tmphi, cpu_env, fp_reg_hi_offset(s, srcidx));
41
index XXXXXXX..XXXXXXX 100644
42
+
42
--- a/target/arm/cpu_tcg.c
43
+ mop = s->be_data | MO_Q;
43
+++ b/target/arm/cpu_tcg.c
44
+ tcg_gen_qemu_st_i64(be ? tmphi : tmplo, tcg_addr, get_mem_index(s),
44
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
45
+ mop | (s->align_mem ? MO_ALIGN_16 : 0));
45
cpu->isar.id_pfr0 = t;
46
tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
46
47
- tcg_gen_qemu_st_i64(tmp, be ? tcg_hiaddr : tcg_addr, get_mem_index(s),
47
t = cpu->isar.id_pfr2;
48
- s->be_data | MO_Q);
48
+ t = FIELD_DP32(t, ID_PFR2, CSV3, 1); /* FEAT_CSV3 */
49
- tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(s, srcidx));
49
t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */
50
- tcg_gen_qemu_st_i64(tmp, be ? tcg_addr : tcg_hiaddr, get_mem_index(s),
50
cpu->isar.id_pfr2 = t;
51
- s->be_data | MO_Q);
52
+ tcg_gen_qemu_st_i64(be ? tmplo : tmphi, tcg_hiaddr,
53
+ get_mem_index(s), mop);
54
+
55
tcg_temp_free_i64(tcg_hiaddr);
56
+ tcg_temp_free_i64(tmphi);
57
}
58
59
- tcg_temp_free_i64(tmp);
60
+ tcg_temp_free_i64(tmplo);
61
}
62
63
/*
64
@@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
65
/* This always zero-extends and writes to a full 128 bit wide vector */
66
TCGv_i64 tmplo = tcg_temp_new_i64();
67
TCGv_i64 tmphi = NULL;
68
+ MemOp mop;
69
70
if (size < 4) {
71
- MemOp memop = s->be_data + size;
72
- tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
73
+ mop = finalize_memop(s, size);
74
+ tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), mop);
75
} else {
76
bool be = s->be_data == MO_BE;
77
TCGv_i64 tcg_hiaddr;
78
@@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
79
tmphi = tcg_temp_new_i64();
80
tcg_hiaddr = tcg_temp_new_i64();
81
82
+ mop = s->be_data | MO_Q;
83
+ tcg_gen_qemu_ld_i64(be ? tmphi : tmplo, tcg_addr, get_mem_index(s),
84
+ mop | (s->align_mem ? MO_ALIGN_16 : 0));
85
tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
86
- tcg_gen_qemu_ld_i64(tmplo, be ? tcg_hiaddr : tcg_addr, get_mem_index(s),
87
- s->be_data | MO_Q);
88
- tcg_gen_qemu_ld_i64(tmphi, be ? tcg_addr : tcg_hiaddr, get_mem_index(s),
89
- s->be_data | MO_Q);
90
+ tcg_gen_qemu_ld_i64(be ? tmplo : tmphi, tcg_hiaddr,
91
+ get_mem_index(s), mop);
92
tcg_temp_free_i64(tcg_hiaddr);
93
}
94
51
95
--
52
--
96
2.20.1
53
2.25.1
97
98
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 the case of gpr load, merge the size and is_signed arguments;
3
This extension concerns not merging memory access, which TCG does
4
otherwise, simply convert size to memop.
4
not implement. Thus we can trivially enable this feature.
5
Add a comment to handle_hint for the DGH instruction, but no code.
5
6
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210419202257.161730-26-richard.henderson@linaro.org
9
Message-id: 20220506180242.216785-23-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/translate-a64.c | 78 ++++++++++++++++----------------------
12
docs/system/arm/emulation.rst | 1 +
12
1 file changed, 33 insertions(+), 45 deletions(-)
13
target/arm/cpu64.c | 1 +
14
target/arm/translate-a64.c | 1 +
15
3 files changed, 3 insertions(+)
13
16
17
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
18
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/system/arm/emulation.rst
20
+++ b/docs/system/arm/emulation.rst
21
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
22
- FEAT_CSV2_1p2 (Cache speculation variant 2, version 1.2)
23
- FEAT_CSV2_2 (Cache speculation variant 2, version 2)
24
- FEAT_CSV3 (Cache speculation variant 3)
25
+- FEAT_DGH (Data gathering hint)
26
- FEAT_DIT (Data Independent Timing instructions)
27
- FEAT_DPB (DC CVAP instruction)
28
- FEAT_Debugv8p2 (Debug changes for v8.2)
29
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu64.c
32
+++ b/target/arm/cpu64.c
33
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
34
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1); /* FEAT_SB */
35
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1); /* FEAT_SPECRES */
36
t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1); /* FEAT_BF16 */
37
+ t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1); /* FEAT_DGH */
38
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1); /* FEAT_I8MM */
39
cpu->isar.id_aa64isar1 = t;
40
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
41
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
43
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
44
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
45
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
19
* Store from GPR register to memory.
46
break;
20
*/
47
case 0b00100: /* SEV */
21
static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
48
case 0b00101: /* SEVL */
22
- TCGv_i64 tcg_addr, int size, int memidx,
49
+ case 0b00110: /* DGH */
23
+ TCGv_i64 tcg_addr, MemOp memop, int memidx,
50
/* we treat all as NOP at least for now */
24
bool iss_valid,
51
break;
25
unsigned int iss_srt,
52
case 0b00111: /* XPACLRI */
26
bool iss_sf, bool iss_ar)
27
{
28
- g_assert(size <= 3);
29
- tcg_gen_qemu_st_i64(source, tcg_addr, memidx, s->be_data + size);
30
+ memop = finalize_memop(s, memop);
31
+ tcg_gen_qemu_st_i64(source, tcg_addr, memidx, memop);
32
33
if (iss_valid) {
34
uint32_t syn;
35
36
syn = syn_data_abort_with_iss(0,
37
- size,
38
+ (memop & MO_SIZE),
39
false,
40
iss_srt,
41
iss_sf,
42
@@ -XXX,XX +XXX,XX @@ static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
43
}
44
45
static void do_gpr_st(DisasContext *s, TCGv_i64 source,
46
- TCGv_i64 tcg_addr, int size,
47
+ TCGv_i64 tcg_addr, MemOp memop,
48
bool iss_valid,
49
unsigned int iss_srt,
50
bool iss_sf, bool iss_ar)
51
{
52
- do_gpr_st_memidx(s, source, tcg_addr, size, get_mem_index(s),
53
+ do_gpr_st_memidx(s, source, tcg_addr, memop, get_mem_index(s),
54
iss_valid, iss_srt, iss_sf, iss_ar);
55
}
56
57
/*
58
* Load from memory to GPR register
59
*/
60
-static void do_gpr_ld_memidx(DisasContext *s,
61
- TCGv_i64 dest, TCGv_i64 tcg_addr,
62
- int size, bool is_signed,
63
- bool extend, int memidx,
64
+static void do_gpr_ld_memidx(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
65
+ MemOp memop, bool extend, int memidx,
66
bool iss_valid, unsigned int iss_srt,
67
bool iss_sf, bool iss_ar)
68
{
69
- MemOp memop = s->be_data + size;
70
-
71
- g_assert(size <= 3);
72
-
73
- if (is_signed) {
74
- memop += MO_SIGN;
75
- }
76
-
77
+ memop = finalize_memop(s, memop);
78
tcg_gen_qemu_ld_i64(dest, tcg_addr, memidx, memop);
79
80
- if (extend && is_signed) {
81
- g_assert(size < 3);
82
+ if (extend && (memop & MO_SIGN)) {
83
+ g_assert((memop & MO_SIZE) <= MO_32);
84
tcg_gen_ext32u_i64(dest, dest);
85
}
86
87
@@ -XXX,XX +XXX,XX @@ static void do_gpr_ld_memidx(DisasContext *s,
88
uint32_t syn;
89
90
syn = syn_data_abort_with_iss(0,
91
- size,
92
- is_signed,
93
+ (memop & MO_SIZE),
94
+ (memop & MO_SIGN) != 0,
95
iss_srt,
96
iss_sf,
97
iss_ar,
98
@@ -XXX,XX +XXX,XX @@ static void do_gpr_ld_memidx(DisasContext *s,
99
}
100
}
101
102
-static void do_gpr_ld(DisasContext *s,
103
- TCGv_i64 dest, TCGv_i64 tcg_addr,
104
- int size, bool is_signed, bool extend,
105
+static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
106
+ MemOp memop, bool extend,
107
bool iss_valid, unsigned int iss_srt,
108
bool iss_sf, bool iss_ar)
109
{
110
- do_gpr_ld_memidx(s, dest, tcg_addr, size, is_signed, extend,
111
- get_mem_index(s),
112
+ do_gpr_ld_memidx(s, dest, tcg_addr, memop, extend, get_mem_index(s),
113
iss_valid, iss_srt, iss_sf, iss_ar);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
117
}
118
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn),
119
false, rn != 31, size);
120
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, false, true, rt,
121
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, true, rt,
122
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
123
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
124
return;
125
@@ -XXX,XX +XXX,XX @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
126
/* Only unsigned 32bit loads target 32bit registers. */
127
bool iss_sf = opc != 0;
128
129
- do_gpr_ld(s, tcg_rt, clean_addr, size, is_signed, false,
130
- true, rt, iss_sf, false);
131
+ do_gpr_ld(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
132
+ false, true, rt, iss_sf, false);
133
}
134
tcg_temp_free_i64(clean_addr);
135
}
136
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
137
/* Do not modify tcg_rt before recognizing any exception
138
* from the second load.
139
*/
140
- do_gpr_ld(s, tmp, clean_addr, size, is_signed, false,
141
- false, 0, false, false);
142
+ do_gpr_ld(s, tmp, clean_addr, size + is_signed * MO_SIGN,
143
+ false, false, 0, false, false);
144
tcg_gen_addi_i64(clean_addr, clean_addr, 1 << size);
145
- do_gpr_ld(s, tcg_rt2, clean_addr, size, is_signed, false,
146
- false, 0, false, false);
147
+ do_gpr_ld(s, tcg_rt2, clean_addr, size + is_signed * MO_SIGN,
148
+ false, false, 0, false, false);
149
150
tcg_gen_mov_i64(tcg_rt, tmp);
151
tcg_temp_free_i64(tmp);
152
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
153
do_gpr_st_memidx(s, tcg_rt, clean_addr, size, memidx,
154
iss_valid, rt, iss_sf, false);
155
} else {
156
- do_gpr_ld_memidx(s, tcg_rt, clean_addr, size,
157
- is_signed, is_extended, memidx,
158
+ do_gpr_ld_memidx(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
159
+ is_extended, memidx,
160
iss_valid, rt, iss_sf, false);
161
}
162
}
163
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn,
164
do_gpr_st(s, tcg_rt, clean_addr, size,
165
true, rt, iss_sf, false);
166
} else {
167
- do_gpr_ld(s, tcg_rt, clean_addr, size,
168
- is_signed, is_extended,
169
- true, rt, iss_sf, false);
170
+ do_gpr_ld(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
171
+ is_extended, true, rt, iss_sf, false);
172
}
173
}
174
}
175
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn,
176
do_gpr_st(s, tcg_rt, clean_addr, size,
177
true, rt, iss_sf, false);
178
} else {
179
- do_gpr_ld(s, tcg_rt, clean_addr, size, is_signed, is_extended,
180
- true, rt, iss_sf, false);
181
+ do_gpr_ld(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
182
+ is_extended, true, rt, iss_sf, false);
183
}
184
}
185
}
186
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
187
* full load-acquire (we only need "load-acquire processor consistent"),
188
* but we choose to implement them as full LDAQ.
189
*/
190
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, false,
191
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false,
192
true, rt, disas_ldst_compute_iss_sf(size, false, 0), true);
193
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
194
return;
195
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pac(DisasContext *s, uint32_t insn,
196
is_wback || rn != 31, size);
197
198
tcg_rt = cpu_reg(s, rt);
199
- do_gpr_ld(s, tcg_rt, clean_addr, size, /* is_signed */ false,
200
+ do_gpr_ld(s, tcg_rt, clean_addr, size,
201
/* extend */ false, /* iss_valid */ !is_wback,
202
/* iss_srt */ rt, /* iss_sf */ true, /* iss_ar */ false);
203
204
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
205
* Load-AcquirePC semantics; we implement as the slightly more
206
* restrictive Load-Acquire.
207
*/
208
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, is_signed, extend,
209
- true, rt, iss_sf, true);
210
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size + is_signed * MO_SIGN,
211
+ extend, true, rt, iss_sf, true);
212
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
213
}
214
}
215
--
53
--
216
2.20.1
54
2.25.1
217
218
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Adjust the interface to match what has been done to the
3
Enable the a76 for virt and sbsa board use.
4
TCGv_i32 load/store functions.
5
6
This is less obvious, because at present the only user of
7
these functions, trans_VLDST_multiple, also wants to manipulate
8
the endianness to speed up loading multiple bytes. Thus we
9
retain an "internal" interface which is identical to the
10
current gen_aa32_{ld,st}_i64 interface.
11
12
The "new" interface will gain users as we remove the legacy
13
interfaces, gen_aa32_ld64 and gen_aa32_st64.
14
4
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210419202257.161730-15-richard.henderson@linaro.org
7
Message-id: 20220506180242.216785-24-richard.henderson@linaro.org
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
9
---
20
target/arm/translate.c | 78 +++++++++++++++++++--------------
10
docs/system/arm/virt.rst | 1 +
21
target/arm/translate-neon.c.inc | 6 ++-
11
hw/arm/sbsa-ref.c | 1 +
22
2 files changed, 49 insertions(+), 35 deletions(-)
12
hw/arm/virt.c | 1 +
13
target/arm/cpu64.c | 66 ++++++++++++++++++++++++++++++++++++++++
14
4 files changed, 69 insertions(+)
23
15
24
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate.c
18
--- a/docs/system/arm/virt.rst
27
+++ b/target/arm/translate.c
19
+++ b/docs/system/arm/virt.rst
28
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
29
tcg_temp_free(addr);
21
- ``cortex-a53`` (64-bit)
22
- ``cortex-a57`` (64-bit)
23
- ``cortex-a72`` (64-bit)
24
+- ``cortex-a76`` (64-bit)
25
- ``a64fx`` (64-bit)
26
- ``host`` (with KVM only)
27
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
28
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/sbsa-ref.c
31
+++ b/hw/arm/sbsa-ref.c
32
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
33
static const char * const valid_cpus[] = {
34
ARM_CPU_TYPE_NAME("cortex-a57"),
35
ARM_CPU_TYPE_NAME("cortex-a72"),
36
+ ARM_CPU_TYPE_NAME("cortex-a76"),
37
ARM_CPU_TYPE_NAME("max"),
38
};
39
40
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/virt.c
43
+++ b/hw/arm/virt.c
44
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
45
ARM_CPU_TYPE_NAME("cortex-a53"),
46
ARM_CPU_TYPE_NAME("cortex-a57"),
47
ARM_CPU_TYPE_NAME("cortex-a72"),
48
+ ARM_CPU_TYPE_NAME("cortex-a76"),
49
ARM_CPU_TYPE_NAME("a64fx"),
50
ARM_CPU_TYPE_NAME("host"),
51
ARM_CPU_TYPE_NAME("max"),
52
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu64.c
55
+++ b/target/arm/cpu64.c
56
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
57
define_cortex_a72_a57_a53_cp_reginfo(cpu);
30
}
58
}
31
59
32
+static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
60
+static void aarch64_a76_initfn(Object *obj)
33
+ TCGv_i32 a32, int index, MemOp opc)
34
+{
61
+{
35
+ TCGv addr = gen_aa32_addr(s, a32, opc);
62
+ ARMCPU *cpu = ARM_CPU(obj);
36
+
63
+
37
+ tcg_gen_qemu_ld_i64(val, addr, index, opc);
64
+ cpu->dtb_compatible = "arm,cortex-a76";
65
+ set_feature(&cpu->env, ARM_FEATURE_V8);
66
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
67
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
68
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
69
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
70
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
71
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
72
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
38
+
73
+
39
+ /* Not needed for user-mode BE32, where we use MO_BE instead. */
74
+ /* Ordered by B2.4 AArch64 registers by functional group */
40
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
75
+ cpu->clidr = 0x82000023;
41
+ tcg_gen_rotri_i64(val, val, 32);
76
+ cpu->ctr = 0x8444C004;
42
+ }
77
+ cpu->dcz_blocksize = 4;
43
+ tcg_temp_free(addr);
78
+ cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
79
+ cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
80
+ cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
81
+ cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
82
+ cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
83
+ cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
84
+ cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
85
+ cpu->isar.id_aa64pfr1 = 0x0000000000000010ull;
86
+ cpu->id_afr0 = 0x00000000;
87
+ cpu->isar.id_dfr0 = 0x04010088;
88
+ cpu->isar.id_isar0 = 0x02101110;
89
+ cpu->isar.id_isar1 = 0x13112111;
90
+ cpu->isar.id_isar2 = 0x21232042;
91
+ cpu->isar.id_isar3 = 0x01112131;
92
+ cpu->isar.id_isar4 = 0x00010142;
93
+ cpu->isar.id_isar5 = 0x01011121;
94
+ cpu->isar.id_isar6 = 0x00000010;
95
+ cpu->isar.id_mmfr0 = 0x10201105;
96
+ cpu->isar.id_mmfr1 = 0x40000000;
97
+ cpu->isar.id_mmfr2 = 0x01260000;
98
+ cpu->isar.id_mmfr3 = 0x02122211;
99
+ cpu->isar.id_mmfr4 = 0x00021110;
100
+ cpu->isar.id_pfr0 = 0x10010131;
101
+ cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
102
+ cpu->isar.id_pfr2 = 0x00000011;
103
+ cpu->midr = 0x414fd0b1; /* r4p1 */
104
+ cpu->revidr = 0;
105
+
106
+ /* From B2.18 CCSIDR_EL1 */
107
+ cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */
108
+ cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */
109
+ cpu->ccsidr[2] = 0x707fe03a; /* 512KB L2 cache */
110
+
111
+ /* From B2.93 SCTLR_EL3 */
112
+ cpu->reset_sctlr = 0x30c50838;
113
+
114
+ /* From B4.23 ICH_VTR_EL2 */
115
+ cpu->gic_num_lrs = 4;
116
+ cpu->gic_vpribits = 5;
117
+ cpu->gic_vprebits = 5;
118
+
119
+ /* From B5.1 AdvSIMD AArch64 register summary */
120
+ cpu->isar.mvfr0 = 0x10110222;
121
+ cpu->isar.mvfr1 = 0x13211111;
122
+ cpu->isar.mvfr2 = 0x00000043;
44
+}
123
+}
45
+
124
+
46
+static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
125
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
47
+ TCGv_i32 a32, int index, MemOp opc)
48
+{
49
+ TCGv addr = gen_aa32_addr(s, a32, opc);
50
+
51
+ /* Not needed for user-mode BE32, where we use MO_BE instead. */
52
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
53
+ TCGv_i64 tmp = tcg_temp_new_i64();
54
+ tcg_gen_rotri_i64(tmp, val, 32);
55
+ tcg_gen_qemu_st_i64(tmp, addr, index, opc);
56
+ tcg_temp_free_i64(tmp);
57
+ } else {
58
+ tcg_gen_qemu_st_i64(val, addr, index, opc);
59
+ }
60
+ tcg_temp_free(addr);
61
+}
62
+
63
static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
64
int index, MemOp opc)
65
{
126
{
66
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
127
/*
67
gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
68
}
129
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
69
130
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
70
+static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
131
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
71
+ int index, MemOp opc)
132
+ { .name = "cortex-a76", .initfn = aarch64_a76_initfn },
72
+{
133
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
73
+ gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
134
{ .name = "max", .initfn = aarch64_max_initfn },
74
+}
135
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
75
+
76
+static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
77
+ int index, MemOp opc)
78
+{
79
+ gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
80
+}
81
+
82
#define DO_GEN_LD(SUFF, OPC) \
83
static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
84
TCGv_i32 a32, int index) \
85
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
86
gen_aa32_st_i32(s, val, a32, index, OPC); \
87
}
88
89
-static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
90
- int index, MemOp opc)
91
-{
92
- TCGv addr = gen_aa32_addr(s, a32, opc);
93
- tcg_gen_qemu_ld_i64(val, addr, index, opc);
94
-
95
- /* Not needed for user-mode BE32, where we use MO_BE instead. */
96
- if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
97
- tcg_gen_rotri_i64(val, val, 32);
98
- }
99
-
100
- tcg_temp_free(addr);
101
-}
102
-
103
static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
104
TCGv_i32 a32, int index)
105
{
106
- gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
107
-}
108
-
109
-static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
110
- int index, MemOp opc)
111
-{
112
- TCGv addr = gen_aa32_addr(s, a32, opc);
113
-
114
- /* Not needed for user-mode BE32, where we use MO_BE instead. */
115
- if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
116
- TCGv_i64 tmp = tcg_temp_new_i64();
117
- tcg_gen_rotri_i64(tmp, val, 32);
118
- tcg_gen_qemu_st_i64(tmp, addr, index, opc);
119
- tcg_temp_free_i64(tmp);
120
- } else {
121
- tcg_gen_qemu_st_i64(val, addr, index, opc);
122
- }
123
- tcg_temp_free(addr);
124
+ gen_aa32_ld_i64(s, val, a32, index, MO_Q);
125
}
126
127
static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
128
TCGv_i32 a32, int index)
129
{
130
- gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
131
+ gen_aa32_st_i64(s, val, a32, index, MO_Q);
132
}
133
134
DO_GEN_LD(8u, MO_UB)
135
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
136
index XXXXXXX..XXXXXXX 100644
137
--- a/target/arm/translate-neon.c.inc
138
+++ b/target/arm/translate-neon.c.inc
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
140
int tt = a->vd + reg + spacing * xs;
141
142
if (a->l) {
143
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
144
+ gen_aa32_ld_internal_i64(s, tmp64, addr, mmu_idx,
145
+ endian | size);
146
neon_store_element64(tt, n, size, tmp64);
147
} else {
148
neon_load_element64(tmp64, tt, n, size);
149
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
150
+ gen_aa32_st_internal_i64(s, tmp64, addr, mmu_idx,
151
+ endian | size);
152
}
153
tcg_gen_add_i32(addr, addr, tmp);
154
}
155
--
136
--
156
2.20.1
137
2.25.1
157
158
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Create a finalize_memop function that computes alignment and
3
Enable the n1 for virt and sbsa board use.
4
endianness and returns the final MemOp for the operation.
5
6
Split out gen_aa32_{ld,st}_internal_i32 which bypasses any special
7
handling of endianness or alignment. Adjust gen_aa32_{ld,st}_i32
8
so that s->be_data is not added by the callers.
9
4
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210419202257.161730-12-richard.henderson@linaro.org
7
Message-id: 20220506180242.216785-25-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
9
---
15
target/arm/translate.h | 24 ++++++++
10
docs/system/arm/virt.rst | 1 +
16
target/arm/translate.c | 100 +++++++++++++++++---------------
11
hw/arm/sbsa-ref.c | 1 +
17
target/arm/translate-neon.c.inc | 9 +--
12
hw/arm/virt.c | 1 +
18
3 files changed, 79 insertions(+), 54 deletions(-)
13
target/arm/cpu64.c | 66 ++++++++++++++++++++++++++++++++++++++++
14
4 files changed, 69 insertions(+)
19
15
20
diff --git a/target/arm/translate.h b/target/arm/translate.h
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/translate.h
18
--- a/docs/system/arm/virt.rst
23
+++ b/target/arm/translate.h
19
+++ b/docs/system/arm/virt.rst
24
@@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour)
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
25
return statusptr;
21
- ``cortex-a76`` (64-bit)
22
- ``a64fx`` (64-bit)
23
- ``host`` (with KVM only)
24
+- ``neoverse-n1`` (64-bit)
25
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
26
27
Note that the default is ``cortex-a15``, so for an AArch64 guest you must
28
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/sbsa-ref.c
31
+++ b/hw/arm/sbsa-ref.c
32
@@ -XXX,XX +XXX,XX @@ static const char * const valid_cpus[] = {
33
ARM_CPU_TYPE_NAME("cortex-a57"),
34
ARM_CPU_TYPE_NAME("cortex-a72"),
35
ARM_CPU_TYPE_NAME("cortex-a76"),
36
+ ARM_CPU_TYPE_NAME("neoverse-n1"),
37
ARM_CPU_TYPE_NAME("max"),
38
};
39
40
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/virt.c
43
+++ b/hw/arm/virt.c
44
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
45
ARM_CPU_TYPE_NAME("cortex-a72"),
46
ARM_CPU_TYPE_NAME("cortex-a76"),
47
ARM_CPU_TYPE_NAME("a64fx"),
48
+ ARM_CPU_TYPE_NAME("neoverse-n1"),
49
ARM_CPU_TYPE_NAME("host"),
50
ARM_CPU_TYPE_NAME("max"),
51
};
52
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu64.c
55
+++ b/target/arm/cpu64.c
56
@@ -XXX,XX +XXX,XX @@ static void aarch64_a76_initfn(Object *obj)
57
cpu->isar.mvfr2 = 0x00000043;
26
}
58
}
27
59
28
+/**
60
+static void aarch64_neoverse_n1_initfn(Object *obj)
29
+ * finalize_memop:
30
+ * @s: DisasContext
31
+ * @opc: size+sign+align of the memory operation
32
+ *
33
+ * Build the complete MemOp for a memory operation, including alignment
34
+ * and endianness.
35
+ *
36
+ * If (op & MO_AMASK) then the operation already contains the required
37
+ * alignment, e.g. for AccType_ATOMIC. Otherwise, this an optionally
38
+ * unaligned operation, e.g. for AccType_NORMAL.
39
+ *
40
+ * In the latter case, there are configuration bits that require alignment,
41
+ * and this is applied here. Note that there is no way to indicate that
42
+ * no alignment should ever be enforced; this must be handled manually.
43
+ */
44
+static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
45
+{
61
+{
46
+ if (s->align_mem && !(opc & MO_AMASK)) {
62
+ ARMCPU *cpu = ARM_CPU(obj);
47
+ opc |= MO_ALIGN;
63
+
48
+ }
64
+ cpu->dtb_compatible = "arm,neoverse-n1";
49
+ return opc | s->be_data;
65
+ set_feature(&cpu->env, ARM_FEATURE_V8);
66
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
67
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
68
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
69
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
70
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
71
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
72
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
73
+
74
+ /* Ordered by B2.4 AArch64 registers by functional group */
75
+ cpu->clidr = 0x82000023;
76
+ cpu->ctr = 0x8444c004;
77
+ cpu->dcz_blocksize = 4;
78
+ cpu->isar.id_aa64dfr0 = 0x0000000110305408ull;
79
+ cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
80
+ cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
81
+ cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
82
+ cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
83
+ cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
84
+ cpu->isar.id_aa64pfr0 = 0x1100000010111112ull; /* GIC filled in later */
85
+ cpu->isar.id_aa64pfr1 = 0x0000000000000020ull;
86
+ cpu->id_afr0 = 0x00000000;
87
+ cpu->isar.id_dfr0 = 0x04010088;
88
+ cpu->isar.id_isar0 = 0x02101110;
89
+ cpu->isar.id_isar1 = 0x13112111;
90
+ cpu->isar.id_isar2 = 0x21232042;
91
+ cpu->isar.id_isar3 = 0x01112131;
92
+ cpu->isar.id_isar4 = 0x00010142;
93
+ cpu->isar.id_isar5 = 0x01011121;
94
+ cpu->isar.id_isar6 = 0x00000010;
95
+ cpu->isar.id_mmfr0 = 0x10201105;
96
+ cpu->isar.id_mmfr1 = 0x40000000;
97
+ cpu->isar.id_mmfr2 = 0x01260000;
98
+ cpu->isar.id_mmfr3 = 0x02122211;
99
+ cpu->isar.id_mmfr4 = 0x00021110;
100
+ cpu->isar.id_pfr0 = 0x10010131;
101
+ cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
102
+ cpu->isar.id_pfr2 = 0x00000011;
103
+ cpu->midr = 0x414fd0c1; /* r4p1 */
104
+ cpu->revidr = 0;
105
+
106
+ /* From B2.23 CCSIDR_EL1 */
107
+ cpu->ccsidr[0] = 0x701fe01a; /* 64KB L1 dcache */
108
+ cpu->ccsidr[1] = 0x201fe01a; /* 64KB L1 icache */
109
+ cpu->ccsidr[2] = 0x70ffe03a; /* 1MB L2 cache */
110
+
111
+ /* From B2.98 SCTLR_EL3 */
112
+ cpu->reset_sctlr = 0x30c50838;
113
+
114
+ /* From B4.23 ICH_VTR_EL2 */
115
+ cpu->gic_num_lrs = 4;
116
+ cpu->gic_vpribits = 5;
117
+ cpu->gic_vprebits = 5;
118
+
119
+ /* From B5.1 AdvSIMD AArch64 register summary */
120
+ cpu->isar.mvfr0 = 0x10110222;
121
+ cpu->isar.mvfr1 = 0x13211111;
122
+ cpu->isar.mvfr2 = 0x00000043;
50
+}
123
+}
51
+
124
+
52
#endif /* TARGET_ARM_TRANSLATE_H */
125
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
53
diff --git a/target/arm/translate.c b/target/arm/translate.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.c
56
+++ b/target/arm/translate.c
57
@@ -XXX,XX +XXX,XX @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
58
#define IS_USER_ONLY 0
59
#endif
60
61
-/* Abstractions of "generate code to do a guest load/store for
62
+/*
63
+ * Abstractions of "generate code to do a guest load/store for
64
* AArch32", where a vaddr is always 32 bits (and is zero
65
* extended if we're a 64 bit core) and data is also
66
* 32 bits unless specifically doing a 64 bit access.
67
@@ -XXX,XX +XXX,XX @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
68
* that the address argument is TCGv_i32 rather than TCGv.
69
*/
70
71
-static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
72
+static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
73
{
126
{
74
TCGv addr = tcg_temp_new();
75
tcg_gen_extu_i32_tl(addr, a32);
76
@@ -XXX,XX +XXX,XX @@ static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
77
return addr;
78
}
79
80
+/*
81
+ * Internal routines are used for NEON cases where the endianness
82
+ * and/or alignment has already been taken into account and manipulated.
83
+ */
84
+static void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
85
+ TCGv_i32 a32, int index, MemOp opc)
86
+{
87
+ TCGv addr = gen_aa32_addr(s, a32, opc);
88
+ tcg_gen_qemu_ld_i32(val, addr, index, opc);
89
+ tcg_temp_free(addr);
90
+}
91
+
92
+static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
93
+ TCGv_i32 a32, int index, MemOp opc)
94
+{
95
+ TCGv addr = gen_aa32_addr(s, a32, opc);
96
+ tcg_gen_qemu_st_i32(val, addr, index, opc);
97
+ tcg_temp_free(addr);
98
+}
99
+
100
static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
101
int index, MemOp opc)
102
{
103
- TCGv addr;
104
-
105
- if (s->align_mem) {
106
- opc |= MO_ALIGN;
107
- }
108
-
109
- addr = gen_aa32_addr(s, a32, opc);
110
- tcg_gen_qemu_ld_i32(val, addr, index, opc);
111
- tcg_temp_free(addr);
112
+ gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
113
}
114
115
static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
116
int index, MemOp opc)
117
{
118
- TCGv addr;
119
+ gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
120
+}
121
122
- if (s->align_mem) {
123
- opc |= MO_ALIGN;
124
+#define DO_GEN_LD(SUFF, OPC) \
125
+ static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
126
+ TCGv_i32 a32, int index) \
127
+ { \
128
+ gen_aa32_ld_i32(s, val, a32, index, OPC); \
129
}
130
131
- addr = gen_aa32_addr(s, a32, opc);
132
- tcg_gen_qemu_st_i32(val, addr, index, opc);
133
- tcg_temp_free(addr);
134
-}
135
-
136
-#define DO_GEN_LD(SUFF, OPC) \
137
-static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
138
- TCGv_i32 a32, int index) \
139
-{ \
140
- gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
141
-}
142
-
143
-#define DO_GEN_ST(SUFF, OPC) \
144
-static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
145
- TCGv_i32 a32, int index) \
146
-{ \
147
- gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
148
-}
149
+#define DO_GEN_ST(SUFF, OPC) \
150
+ static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
151
+ TCGv_i32 a32, int index) \
152
+ { \
153
+ gen_aa32_st_i32(s, val, a32, index, OPC); \
154
+ }
155
156
static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
157
{
158
@@ -XXX,XX +XXX,XX @@ static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
159
addr = op_addr_rr_pre(s, a);
160
161
tmp = tcg_temp_new_i32();
162
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
163
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
164
disas_set_da_iss(s, mop, issinfo);
165
166
/*
127
/*
167
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
128
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
168
addr = op_addr_rr_pre(s, a);
129
{ .name = "cortex-a72", .initfn = aarch64_a72_initfn },
169
130
{ .name = "cortex-a76", .initfn = aarch64_a76_initfn },
170
tmp = load_reg(s, a->rt);
131
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
171
- gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
132
+ { .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
172
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
133
{ .name = "max", .initfn = aarch64_max_initfn },
173
disas_set_da_iss(s, mop, issinfo);
134
#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
174
tcg_temp_free_i32(tmp);
135
{ .name = "host", .initfn = aarch64_host_initfn },
175
176
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
177
addr = op_addr_rr_pre(s, a);
178
179
tmp = tcg_temp_new_i32();
180
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
181
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
182
store_reg(s, a->rt, tmp);
183
184
tcg_gen_addi_i32(addr, addr, 4);
185
186
tmp = tcg_temp_new_i32();
187
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
188
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
189
store_reg(s, a->rt + 1, tmp);
190
191
/* LDRD w/ base writeback is undefined if the registers overlap. */
192
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
193
addr = op_addr_rr_pre(s, a);
194
195
tmp = load_reg(s, a->rt);
196
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
197
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
198
tcg_temp_free_i32(tmp);
199
200
tcg_gen_addi_i32(addr, addr, 4);
201
202
tmp = load_reg(s, a->rt + 1);
203
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
204
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
205
tcg_temp_free_i32(tmp);
206
207
op_addr_rr_post(s, a, addr, -4);
208
@@ -XXX,XX +XXX,XX @@ static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
209
addr = op_addr_ri_pre(s, a);
210
211
tmp = tcg_temp_new_i32();
212
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
213
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
214
disas_set_da_iss(s, mop, issinfo);
215
216
/*
217
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
218
addr = op_addr_ri_pre(s, a);
219
220
tmp = load_reg(s, a->rt);
221
- gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
222
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
223
disas_set_da_iss(s, mop, issinfo);
224
tcg_temp_free_i32(tmp);
225
226
@@ -XXX,XX +XXX,XX @@ static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
227
addr = op_addr_ri_pre(s, a);
228
229
tmp = tcg_temp_new_i32();
230
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
231
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
232
store_reg(s, a->rt, tmp);
233
234
tcg_gen_addi_i32(addr, addr, 4);
235
236
tmp = tcg_temp_new_i32();
237
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
238
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
239
store_reg(s, rt2, tmp);
240
241
/* LDRD w/ base writeback is undefined if the registers overlap. */
242
@@ -XXX,XX +XXX,XX @@ static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
243
addr = op_addr_ri_pre(s, a);
244
245
tmp = load_reg(s, a->rt);
246
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
247
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
248
tcg_temp_free_i32(tmp);
249
250
tcg_gen_addi_i32(addr, addr, 4);
251
252
tmp = load_reg(s, rt2);
253
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
254
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
255
tcg_temp_free_i32(tmp);
256
257
op_addr_ri_post(s, a, addr, -4);
258
@@ -XXX,XX +XXX,XX @@ static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
259
addr = load_reg(s, a->rn);
260
tmp = load_reg(s, a->rt);
261
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
262
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
263
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop);
264
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
265
266
tcg_temp_free_i32(tmp);
267
@@ -XXX,XX +XXX,XX @@ static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
268
269
addr = load_reg(s, a->rn);
270
tmp = tcg_temp_new_i32();
271
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
272
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop);
273
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
274
tcg_temp_free_i32(addr);
275
276
@@ -XXX,XX +XXX,XX @@ static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
277
addr = load_reg(s, a->rn);
278
tcg_gen_add_i32(addr, addr, tmp);
279
280
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
281
- half ? MO_UW | s->be_data : MO_UB);
282
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), half ? MO_UW : MO_UB);
283
tcg_temp_free_i32(addr);
284
285
tcg_gen_add_i32(tmp, tmp, tmp);
286
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
287
index XXXXXXX..XXXXXXX 100644
288
--- a/target/arm/translate-neon.c.inc
289
+++ b/target/arm/translate-neon.c.inc
290
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
291
addr = tcg_temp_new_i32();
292
load_reg_var(s, addr, a->rn);
293
for (reg = 0; reg < nregs; reg++) {
294
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
295
- s->be_data | size);
296
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), size);
297
if ((vd & 1) && vec_size == 16) {
298
/*
299
* We cannot write 16 bytes at once because the
300
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
301
*/
302
for (reg = 0; reg < nregs; reg++) {
303
if (a->l) {
304
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
305
- s->be_data | a->size);
306
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), a->size);
307
neon_store_element(vd, a->reg_idx, a->size, tmp);
308
} else { /* Store */
309
neon_load_element(tmp, vd, a->reg_idx, a->size);
310
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
311
- s->be_data | a->size);
312
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), a->size);
313
}
314
vd += a->stride;
315
tcg_gen_addi_i32(addr, addr, 1 << a->size);
316
--
136
--
317
2.20.1
137
2.25.1
318
319
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
The sbsa-ref machine is continuously evolving. Some of the changes we
4
want to make in the near future, to align with real components (e.g.
5
the GIC-700), will break compatibility for existing firmware.
6
7
Introduce two new properties to the DT generated on machine generation:
8
- machine-version-major
9
To be incremented when a platform change makes the machine
10
incompatible with existing firmware.
11
- machine-version-minor
12
To be incremented when functionality is added to the machine
13
without causing incompatibility with existing firmware.
14
to be reset to 0 when machine-version-major is incremented.
15
16
This versioning scheme is *neither*:
17
- A QEMU versioned machine type; a given version of QEMU will emulate
18
a given version of the platform.
19
- A reflection of level of SBSA (now SystemReady SR) support provided.
20
21
The version will increment on guest-visible functional changes only,
22
akin to a revision ID register found on a physical platform.
23
24
These properties are both introduced with the value 0.
25
(Hence, a machine where the DT is lacking these nodes is equivalent
26
to version 0.0.)
27
28
Signed-off-by: Leif Lindholm <quic_llindhol@quicinc.com>
29
Message-id: 20220505113947.75714-1-quic_llindhol@quicinc.com
30
Cc: Peter Maydell <peter.maydell@linaro.org>
31
Cc: Radoslaw Biernacki <rad@semihalf.com>
32
Cc: Cédric Le Goater <clg@kaod.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-25-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
35
---
8
target/arm/translate-neon.c.inc | 48 ++++++++++++++++++++++++++++-----
36
hw/arm/sbsa-ref.c | 14 ++++++++++++++
9
1 file changed, 42 insertions(+), 6 deletions(-)
37
1 file changed, 14 insertions(+)
10
38
11
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
39
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
12
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-neon.c.inc
41
--- a/hw/arm/sbsa-ref.c
14
+++ b/target/arm/translate-neon.c.inc
42
+++ b/hw/arm/sbsa-ref.c
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
43
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
16
int nregs = a->n + 1;
44
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
17
int vd = a->vd;
45
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
18
TCGv_i32 addr, tmp;
46
19
+ MemOp mop;
47
+ /*
20
48
+ * This versioning scheme is for informing platform fw only. It is neither:
21
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
49
+ * - A QEMU versioned machine type; a given version of QEMU will emulate
22
return false;
50
+ * a given version of the platform.
23
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
51
+ * - A reflection of level of SBSA (now SystemReady SR) support provided.
24
return true;
52
+ *
25
}
53
+ * machine-version-major: updated when changes breaking fw compatibility
26
54
+ * are introduced.
27
+ /* Pick up SCTLR settings */
55
+ * machine-version-minor: updated when features are added that don't break
28
+ mop = finalize_memop(s, a->size);
56
+ * fw compatibility.
57
+ */
58
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
59
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 0);
29
+
60
+
30
+ if (a->align) {
61
if (ms->numa_state->have_numa_distance) {
31
+ MemOp align_op;
62
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
32
+
63
uint32_t *matrix = g_malloc0(size);
33
+ switch (nregs) {
34
+ case 1:
35
+ /* For VLD1, use natural alignment. */
36
+ align_op = MO_ALIGN;
37
+ break;
38
+ case 2:
39
+ /* For VLD2, use double alignment. */
40
+ align_op = pow2_align(a->size + 1);
41
+ break;
42
+ case 4:
43
+ if (a->size == MO_32) {
44
+ /*
45
+ * For VLD4.32, align = 1 is double alignment, align = 2 is
46
+ * quad alignment; align = 3 is rejected above.
47
+ */
48
+ align_op = pow2_align(a->size + a->align);
49
+ } else {
50
+ /* For VLD4.8 and VLD.16, we want quad alignment. */
51
+ align_op = pow2_align(a->size + 2);
52
+ }
53
+ break;
54
+ default:
55
+ /* For VLD3, the alignment field is zero and rejected above. */
56
+ g_assert_not_reached();
57
+ }
58
+
59
+ mop = (mop & ~MO_AMASK) | align_op;
60
+ }
61
+
62
tmp = tcg_temp_new_i32();
63
addr = tcg_temp_new_i32();
64
load_reg_var(s, addr, a->rn);
65
- /*
66
- * TODO: if we implemented alignment exceptions, we should check
67
- * addr against the alignment encoded in a->align here.
68
- */
69
+
70
for (reg = 0; reg < nregs; reg++) {
71
if (a->l) {
72
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), a->size);
73
+ gen_aa32_ld_internal_i32(s, tmp, addr, get_mem_index(s), mop);
74
neon_store_element(vd, a->reg_idx, a->size, tmp);
75
} else { /* Store */
76
neon_load_element(tmp, vd, a->reg_idx, a->size);
77
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), a->size);
78
+ gen_aa32_st_internal_i32(s, tmp, addr, get_mem_index(s), mop);
79
}
80
vd += a->stride;
81
tcg_gen_addi_i32(addr, addr, 1 << a->size);
82
+
83
+ /* Subsequent memory operations inherit alignment */
84
+ mop &= ~MO_AMASK;
85
}
86
tcg_temp_free_i32(addr);
87
tcg_temp_free_i32(tmp);
88
--
64
--
89
2.20.1
65
2.25.1
90
66
91
67
diff view generated by jsdifflib
1
Currently the gpex PCI controller implements no special behaviour for
1
From: Gavin Shan <gshan@redhat.com>
2
guest accesses to areas of the PIO and MMIO where it has not mapped
3
any PCI devices, which means that for Arm you end up with a CPU
4
exception due to a data abort.
5
2
6
Most host OSes expect "like an x86 PC" behaviour, where bad accesses
3
This adds cluster-id in CPU instance properties, which will be used
7
like this return -1 for reads and ignore writes. In the interests of
4
by arm/virt machine. Besides, the cluster-id is also verified or
8
not being surprising, make host CPU accesses to these windows behave
5
dumped in various spots:
9
as -1/discard where there's no mapped PCI device.
10
6
11
The old behaviour generally didn't cause any problems, because
7
* hw/core/machine.c::machine_set_cpu_numa_node() to associate
12
almost always the guest OS will map the PCI devices and then only
8
CPU with its NUMA node.
13
access where it has mapped them. One corner case where you will see
14
this kind of access is if Linux attempts to probe legacy ISA
15
devices via a PIO window access. So far the only case where we've
16
seen this has been via the syzkaller fuzzer.
17
9
18
Reported-by: Dmitry Vyukov <dvyukov@google.com>
10
* hw/core/machine.c::machine_numa_finish_cpu_init() to record
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
CPU slots with no NUMA mapping set.
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
21
Acked-by: Michael S. Tsirkin <mst@redhat.com>
13
* hw/core/machine-hmp-cmds.c::hmp_hotpluggable_cpus() to dump
22
Message-id: 20210325163315.27724-1-peter.maydell@linaro.org
14
cluster-id.
23
Fixes: https://bugs.launchpad.net/qemu/+bug/1918917
15
16
Signed-off-by: Gavin Shan <gshan@redhat.com>
17
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
18
Acked-by: Igor Mammedov <imammedo@redhat.com>
19
Message-id: 20220503140304.855514-2-gshan@redhat.com
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
21
---
26
include/hw/pci-host/gpex.h | 4 +++
22
qapi/machine.json | 6 ++++--
27
hw/core/machine.c | 4 ++-
23
hw/core/machine-hmp-cmds.c | 4 ++++
28
hw/pci-host/gpex.c | 56 ++++++++++++++++++++++++++++++++++++--
24
hw/core/machine.c | 16 ++++++++++++++++
29
3 files changed, 60 insertions(+), 4 deletions(-)
25
3 files changed, 24 insertions(+), 2 deletions(-)
30
26
31
diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h
27
diff --git a/qapi/machine.json b/qapi/machine.json
32
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/pci-host/gpex.h
29
--- a/qapi/machine.json
34
+++ b/include/hw/pci-host/gpex.h
30
+++ b/qapi/machine.json
35
@@ -XXX,XX +XXX,XX @@ struct GPEXHost {
31
@@ -XXX,XX +XXX,XX @@
36
32
# @node-id: NUMA node ID the CPU belongs to
37
MemoryRegion io_ioport;
33
# @socket-id: socket number within node/board the CPU belongs to
38
MemoryRegion io_mmio;
34
# @die-id: die number within socket the CPU belongs to (since 4.1)
39
+ MemoryRegion io_ioport_window;
35
-# @core-id: core number within die the CPU belongs to
40
+ MemoryRegion io_mmio_window;
36
+# @cluster-id: cluster number within die the CPU belongs to (since 7.1)
41
qemu_irq irq[GPEX_NUM_IRQS];
37
+# @core-id: core number within cluster the CPU belongs to
42
int irq_num[GPEX_NUM_IRQS];
38
# @thread-id: thread number within core the CPU belongs to
43
+
39
#
44
+ bool allow_unmapped_accesses;
40
-# Note: currently there are 5 properties that could be present
45
};
41
+# Note: currently there are 6 properties that could be present
46
42
# but management should be prepared to pass through other
47
struct GPEXConfig {
43
# properties with device_add command to allow for future
44
# interface extension. This also requires the filed names to be kept in
45
@@ -XXX,XX +XXX,XX @@
46
'data': { '*node-id': 'int',
47
'*socket-id': 'int',
48
'*die-id': 'int',
49
+ '*cluster-id': 'int',
50
'*core-id': 'int',
51
'*thread-id': 'int'
52
}
53
diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/core/machine-hmp-cmds.c
56
+++ b/hw/core/machine-hmp-cmds.c
57
@@ -XXX,XX +XXX,XX @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict)
58
if (c->has_die_id) {
59
monitor_printf(mon, " die-id: \"%" PRIu64 "\"\n", c->die_id);
60
}
61
+ if (c->has_cluster_id) {
62
+ monitor_printf(mon, " cluster-id: \"%" PRIu64 "\"\n",
63
+ c->cluster_id);
64
+ }
65
if (c->has_core_id) {
66
monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id);
67
}
48
diff --git a/hw/core/machine.c b/hw/core/machine.c
68
diff --git a/hw/core/machine.c b/hw/core/machine.c
49
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/core/machine.c
70
--- a/hw/core/machine.c
51
+++ b/hw/core/machine.c
71
+++ b/hw/core/machine.c
52
@@ -XXX,XX +XXX,XX @@
72
@@ -XXX,XX +XXX,XX @@ void machine_set_cpu_numa_node(MachineState *machine,
53
#include "hw/virtio/virtio.h"
73
return;
54
#include "hw/virtio/virtio-pci.h"
74
}
55
75
56
-GlobalProperty hw_compat_6_0[] = {};
76
+ if (props->has_cluster_id && !slot->props.has_cluster_id) {
57
+GlobalProperty hw_compat_6_0[] = {
77
+ error_setg(errp, "cluster-id is not supported");
58
+ { "gpex-pcihost", "allow-unmapped-accesses", "false" },
78
+ return;
59
+};
79
+ }
60
const size_t hw_compat_6_0_len = G_N_ELEMENTS(hw_compat_6_0);
61
62
GlobalProperty hw_compat_5_2[] = {
63
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/pci-host/gpex.c
66
+++ b/hw/pci-host/gpex.c
67
@@ -XXX,XX +XXX,XX @@ static void gpex_host_realize(DeviceState *dev, Error **errp)
68
int i;
69
70
pcie_host_mmcfg_init(pex, PCIE_MMCFG_SIZE_MAX);
71
+ sysbus_init_mmio(sbd, &pex->mmio);
72
+
80
+
73
+ /*
81
if (props->has_socket_id && !slot->props.has_socket_id) {
74
+ * Note that the MemoryRegions io_mmio and io_ioport that we pass
82
error_setg(errp, "socket-id is not supported");
75
+ * to pci_register_root_bus() are not the same as the
83
return;
76
+ * MemoryRegions io_mmio_window and io_ioport_window that we
84
@@ -XXX,XX +XXX,XX @@ void machine_set_cpu_numa_node(MachineState *machine,
77
+ * expose as SysBus MRs. The difference is in the behaviour of
85
continue;
78
+ * accesses to addresses where no PCI device has been mapped.
86
}
79
+ *
87
80
+ * io_mmio and io_ioport are the underlying PCI view of the PCI
88
+ if (props->has_cluster_id &&
81
+ * address space, and when a PCI device does a bus master access
89
+ props->cluster_id != slot->props.cluster_id) {
82
+ * to a bad address this is reported back to it as a transaction
90
+ continue;
83
+ * failure.
91
+ }
84
+ *
85
+ * io_mmio_window and io_ioport_window implement "unmapped
86
+ * addresses read as -1 and ignore writes"; this is traditional
87
+ * x86 PC behaviour, which is not mandated by the PCI spec proper
88
+ * but expected by much PCI-using guest software, including Linux.
89
+ *
90
+ * In the interests of not being unnecessarily surprising, we
91
+ * implement it in the gpex PCI host controller, by providing the
92
+ * _window MRs, which are containers with io ops that implement
93
+ * the 'background' behaviour and which hold the real PCI MRs as
94
+ * subregions.
95
+ */
96
memory_region_init(&s->io_mmio, OBJECT(s), "gpex_mmio", UINT64_MAX);
97
memory_region_init(&s->io_ioport, OBJECT(s), "gpex_ioport", 64 * 1024);
98
99
- sysbus_init_mmio(sbd, &pex->mmio);
100
- sysbus_init_mmio(sbd, &s->io_mmio);
101
- sysbus_init_mmio(sbd, &s->io_ioport);
102
+ if (s->allow_unmapped_accesses) {
103
+ memory_region_init_io(&s->io_mmio_window, OBJECT(s),
104
+ &unassigned_io_ops, OBJECT(s),
105
+ "gpex_mmio_window", UINT64_MAX);
106
+ memory_region_init_io(&s->io_ioport_window, OBJECT(s),
107
+ &unassigned_io_ops, OBJECT(s),
108
+ "gpex_ioport_window", 64 * 1024);
109
+
92
+
110
+ memory_region_add_subregion(&s->io_mmio_window, 0, &s->io_mmio);
93
if (props->has_die_id && props->die_id != slot->props.die_id) {
111
+ memory_region_add_subregion(&s->io_ioport_window, 0, &s->io_ioport);
94
continue;
112
+ sysbus_init_mmio(sbd, &s->io_mmio_window);
95
}
113
+ sysbus_init_mmio(sbd, &s->io_ioport_window);
96
@@ -XXX,XX +XXX,XX @@ static char *cpu_slot_to_string(const CPUArchId *cpu)
114
+ } else {
97
}
115
+ sysbus_init_mmio(sbd, &s->io_mmio);
98
g_string_append_printf(s, "die-id: %"PRId64, cpu->props.die_id);
116
+ sysbus_init_mmio(sbd, &s->io_ioport);
99
}
100
+ if (cpu->props.has_cluster_id) {
101
+ if (s->len) {
102
+ g_string_append_printf(s, ", ");
103
+ }
104
+ g_string_append_printf(s, "cluster-id: %"PRId64, cpu->props.cluster_id);
117
+ }
105
+ }
118
+
106
if (cpu->props.has_core_id) {
119
for (i = 0; i < GPEX_NUM_IRQS; i++) {
107
if (s->len) {
120
sysbus_init_irq(sbd, &s->irq[i]);
108
g_string_append_printf(s, ", ");
121
s->irq_num[i] = -1;
122
@@ -XXX,XX +XXX,XX @@ static const char *gpex_host_root_bus_path(PCIHostState *host_bridge,
123
return "0000:00";
124
}
125
126
+static Property gpex_host_properties[] = {
127
+ /*
128
+ * Permit CPU accesses to unmapped areas of the PIO and MMIO windows
129
+ * (discarding writes and returning -1 for reads) rather than aborting.
130
+ */
131
+ DEFINE_PROP_BOOL("allow-unmapped-accesses", GPEXHost,
132
+ allow_unmapped_accesses, true),
133
+ DEFINE_PROP_END_OF_LIST(),
134
+};
135
+
136
static void gpex_host_class_init(ObjectClass *klass, void *data)
137
{
138
DeviceClass *dc = DEVICE_CLASS(klass);
139
@@ -XXX,XX +XXX,XX @@ static void gpex_host_class_init(ObjectClass *klass, void *data)
140
dc->realize = gpex_host_realize;
141
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
142
dc->fw_name = "pci";
143
+ device_class_set_props(dc, gpex_host_properties);
144
}
145
146
static void gpex_host_initfn(Object *obj)
147
--
109
--
148
2.20.1
110
2.25.1
149
150
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
The CPU topology isn't enabled on arm/virt machine yet, but we're
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
going to do it in next patch. After the CPU topology is enabled by
5
Message-id: 20210419202257.161730-22-richard.henderson@linaro.org
5
next patch, "thread-id=1" becomes invalid because the CPU core is
6
preferred on arm/virt machine. It means these two CPUs have 0/1
7
as their core IDs, but their thread IDs are all 0. It will trigger
8
test failure as the following message indicates:
9
10
[14/21 qemu:qtest+qtest-aarch64 / qtest-aarch64/numa-test ERROR
11
1.48s killed by signal 6 SIGABRT
12
>>> G_TEST_DBUS_DAEMON=/home/gavin/sandbox/qemu.main/tests/dbus-vmstate-daemon.sh \
13
QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
14
QTEST_QEMU_BINARY=./qemu-system-aarch64 \
15
QTEST_QEMU_IMG=./qemu-img MALLOC_PERTURB_=83 \
16
/home/gavin/sandbox/qemu.main/build/tests/qtest/numa-test --tap -k
17
――――――――――――――――――――――――――――――――――――――――――――――
18
stderr:
19
qemu-system-aarch64: -numa cpu,node-id=0,thread-id=1: no match found
20
21
This fixes the issue by providing comprehensive SMP configurations
22
in aarch64_numa_cpu(). The SMP configurations aren't used before
23
the CPU topology is enabled in next patch.
24
25
Signed-off-by: Gavin Shan <gshan@redhat.com>
26
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
27
Message-id: 20220503140304.855514-3-gshan@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
29
---
8
target/arm/translate-vfp.c.inc | 12 ++++++------
30
tests/qtest/numa-test.c | 3 ++-
9
1 file changed, 6 insertions(+), 6 deletions(-)
31
1 file changed, 2 insertions(+), 1 deletion(-)
10
32
11
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
33
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
12
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-vfp.c.inc
35
--- a/tests/qtest/numa-test.c
14
+++ b/target/arm/translate-vfp.c.inc
36
+++ b/tests/qtest/numa-test.c
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
16
addr = add_reg_for_lit(s, a->rn, offset);
38
QTestState *qts;
17
tmp = tcg_temp_new_i32();
39
g_autofree char *cli = NULL;
18
if (a->l) {
40
19
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
41
- cli = make_cli(data, "-machine smp.cpus=2 "
20
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), MO_UW | MO_ALIGN);
42
+ cli = make_cli(data, "-machine "
21
vfp_store_reg32(tmp, a->vd);
43
+ "smp.cpus=2,smp.sockets=1,smp.clusters=1,smp.cores=1,smp.threads=2 "
22
} else {
44
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
23
vfp_load_reg32(tmp, a->vd);
45
"-numa cpu,node-id=1,thread-id=0 "
24
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
46
"-numa cpu,node-id=0,thread-id=1");
25
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UW | MO_ALIGN);
26
}
27
tcg_temp_free_i32(tmp);
28
tcg_temp_free_i32(addr);
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
30
addr = add_reg_for_lit(s, a->rn, offset);
31
tmp = tcg_temp_new_i32();
32
if (a->l) {
33
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
34
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
35
vfp_store_reg32(tmp, a->vd);
36
} else {
37
vfp_load_reg32(tmp, a->vd);
38
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
39
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
40
}
41
tcg_temp_free_i32(tmp);
42
tcg_temp_free_i32(addr);
43
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
44
addr = add_reg_for_lit(s, a->rn, offset);
45
tmp = tcg_temp_new_i64();
46
if (a->l) {
47
- gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
48
+ gen_aa32_ld_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
49
vfp_store_reg64(tmp, a->vd);
50
} else {
51
vfp_load_reg64(tmp, a->vd);
52
- gen_aa32_st64(s, tmp, addr, get_mem_index(s));
53
+ gen_aa32_st_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
54
}
55
tcg_temp_free_i64(tmp);
56
tcg_temp_free_i32(addr);
57
--
47
--
58
2.20.1
48
2.25.1
59
49
60
50
diff view generated by jsdifflib
1
From: Cornelia Huck <cohuck@redhat.com>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
Add 6.1 machine types for arm/i440fx/q35/s390x/spapr.
3
Currently, the SMP configuration isn't considered when the CPU
4
topology is populated. In this case, it's impossible to provide
5
the default CPU-to-NUMA mapping or association based on the socket
6
ID of the given CPU.
4
7
5
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
8
This takes account of SMP configuration when the CPU topology
6
Acked-by: Greg Kurz <groug@kaod.org>
9
is populated. The die ID for the given CPU isn't assigned since
7
Message-id: 20210331111900.118274-1-cohuck@redhat.com
10
it's not supported on arm/virt machine. Besides, the used SMP
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
configuration in qtest/numa-test/aarch64_numa_cpu() is corrcted
12
to avoid testing failure
13
14
Signed-off-by: Gavin Shan <gshan@redhat.com>
15
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
16
Acked-by: Igor Mammedov <imammedo@redhat.com>
17
Message-id: 20220503140304.855514-4-gshan@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
19
---
11
include/hw/boards.h | 3 +++
20
hw/arm/virt.c | 15 ++++++++++++++-
12
include/hw/i386/pc.h | 3 +++
21
1 file changed, 14 insertions(+), 1 deletion(-)
13
hw/arm/virt.c | 7 ++++++-
14
hw/core/machine.c | 3 +++
15
hw/i386/pc.c | 3 +++
16
hw/i386/pc_piix.c | 14 +++++++++++++-
17
hw/i386/pc_q35.c | 13 ++++++++++++-
18
hw/ppc/spapr.c | 17 ++++++++++++++---
19
hw/s390x/s390-virtio-ccw.c | 14 +++++++++++++-
20
9 files changed, 70 insertions(+), 7 deletions(-)
21
22
22
diff --git a/include/hw/boards.h b/include/hw/boards.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/boards.h
25
+++ b/include/hw/boards.h
26
@@ -XXX,XX +XXX,XX @@ struct MachineState {
27
} \
28
type_init(machine_initfn##_register_types)
29
30
+extern GlobalProperty hw_compat_6_0[];
31
+extern const size_t hw_compat_6_0_len;
32
+
33
extern GlobalProperty hw_compat_5_2[];
34
extern const size_t hw_compat_5_2_len;
35
36
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/i386/pc.h
39
+++ b/include/hw/i386/pc.h
40
@@ -XXX,XX +XXX,XX @@ bool pc_system_ovmf_table_find(const char *entry, uint8_t **data,
41
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
42
const CPUArchIdList *apic_ids, GArray *entry);
43
44
+extern GlobalProperty pc_compat_6_0[];
45
+extern const size_t pc_compat_6_0_len;
46
+
47
extern GlobalProperty pc_compat_5_2[];
48
extern const size_t pc_compat_5_2_len;
49
50
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
23
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
51
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/virt.c
25
--- a/hw/arm/virt.c
53
+++ b/hw/arm/virt.c
26
+++ b/hw/arm/virt.c
54
@@ -XXX,XX +XXX,XX @@ static void machvirt_machine_init(void)
27
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
28
int n;
29
unsigned int max_cpus = ms->smp.max_cpus;
30
VirtMachineState *vms = VIRT_MACHINE(ms);
31
+ MachineClass *mc = MACHINE_GET_CLASS(vms);
32
33
if (ms->possible_cpus) {
34
assert(ms->possible_cpus->len == max_cpus);
35
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
36
ms->possible_cpus->cpus[n].type = ms->cpu_type;
37
ms->possible_cpus->cpus[n].arch_id =
38
virt_cpu_mp_affinity(vms, n);
39
+
40
+ assert(!mc->smp_props.dies_supported);
41
+ ms->possible_cpus->cpus[n].props.has_socket_id = true;
42
+ ms->possible_cpus->cpus[n].props.socket_id =
43
+ n / (ms->smp.clusters * ms->smp.cores * ms->smp.threads);
44
+ ms->possible_cpus->cpus[n].props.has_cluster_id = true;
45
+ ms->possible_cpus->cpus[n].props.cluster_id =
46
+ (n / (ms->smp.cores * ms->smp.threads)) % ms->smp.clusters;
47
+ ms->possible_cpus->cpus[n].props.has_core_id = true;
48
+ ms->possible_cpus->cpus[n].props.core_id =
49
+ (n / ms->smp.threads) % ms->smp.cores;
50
ms->possible_cpus->cpus[n].props.has_thread_id = true;
51
- ms->possible_cpus->cpus[n].props.thread_id = n;
52
+ ms->possible_cpus->cpus[n].props.thread_id =
53
+ n % ms->smp.threads;
54
}
55
return ms->possible_cpus;
55
}
56
}
56
type_init(machvirt_machine_init);
57
58
+static void virt_machine_6_1_options(MachineClass *mc)
59
+{
60
+}
61
+DEFINE_VIRT_MACHINE_AS_LATEST(6, 1)
62
+
63
static void virt_machine_6_0_options(MachineClass *mc)
64
{
65
}
66
-DEFINE_VIRT_MACHINE_AS_LATEST(6, 0)
67
+DEFINE_VIRT_MACHINE(6, 0)
68
69
static void virt_machine_5_2_options(MachineClass *mc)
70
{
71
diff --git a/hw/core/machine.c b/hw/core/machine.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/core/machine.c
74
+++ b/hw/core/machine.c
75
@@ -XXX,XX +XXX,XX @@
76
#include "hw/virtio/virtio.h"
77
#include "hw/virtio/virtio-pci.h"
78
79
+GlobalProperty hw_compat_6_0[] = {};
80
+const size_t hw_compat_6_0_len = G_N_ELEMENTS(hw_compat_6_0);
81
+
82
GlobalProperty hw_compat_5_2[] = {
83
{ "ICH9-LPC", "smm-compat", "on"},
84
{ "PIIX4_PM", "smm-compat", "on"},
85
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/i386/pc.c
88
+++ b/hw/i386/pc.c
89
@@ -XXX,XX +XXX,XX @@
90
#include "trace.h"
91
#include CONFIG_DEVICES
92
93
+GlobalProperty pc_compat_6_0[] = {};
94
+const size_t pc_compat_6_0_len = G_N_ELEMENTS(pc_compat_6_0);
95
+
96
GlobalProperty pc_compat_5_2[] = {
97
{ "ICH9-LPC", "x-smi-cpu-hotunplug", "off" },
98
};
99
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/i386/pc_piix.c
102
+++ b/hw/i386/pc_piix.c
103
@@ -XXX,XX +XXX,XX @@ static void pc_i440fx_machine_options(MachineClass *m)
104
machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
105
}
106
107
-static void pc_i440fx_6_0_machine_options(MachineClass *m)
108
+static void pc_i440fx_6_1_machine_options(MachineClass *m)
109
{
110
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
111
pc_i440fx_machine_options(m);
112
@@ -XXX,XX +XXX,XX @@ static void pc_i440fx_6_0_machine_options(MachineClass *m)
113
pcmc->default_cpu_version = 1;
114
}
115
116
+DEFINE_I440FX_MACHINE(v6_1, "pc-i440fx-6.1", NULL,
117
+ pc_i440fx_6_1_machine_options);
118
+
119
+static void pc_i440fx_6_0_machine_options(MachineClass *m)
120
+{
121
+ pc_i440fx_6_1_machine_options(m);
122
+ m->alias = NULL;
123
+ m->is_default = false;
124
+ compat_props_add(m->compat_props, hw_compat_6_0, hw_compat_6_0_len);
125
+ compat_props_add(m->compat_props, pc_compat_6_0, pc_compat_6_0_len);
126
+}
127
+
128
DEFINE_I440FX_MACHINE(v6_0, "pc-i440fx-6.0", NULL,
129
pc_i440fx_6_0_machine_options);
130
131
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/i386/pc_q35.c
134
+++ b/hw/i386/pc_q35.c
135
@@ -XXX,XX +XXX,XX @@ static void pc_q35_machine_options(MachineClass *m)
136
m->max_cpus = 288;
137
}
138
139
-static void pc_q35_6_0_machine_options(MachineClass *m)
140
+static void pc_q35_6_1_machine_options(MachineClass *m)
141
{
142
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
143
pc_q35_machine_options(m);
144
@@ -XXX,XX +XXX,XX @@ static void pc_q35_6_0_machine_options(MachineClass *m)
145
pcmc->default_cpu_version = 1;
146
}
147
148
+DEFINE_Q35_MACHINE(v6_1, "pc-q35-6.1", NULL,
149
+ pc_q35_6_1_machine_options);
150
+
151
+static void pc_q35_6_0_machine_options(MachineClass *m)
152
+{
153
+ pc_q35_6_1_machine_options(m);
154
+ m->alias = NULL;
155
+ compat_props_add(m->compat_props, hw_compat_6_0, hw_compat_6_0_len);
156
+ compat_props_add(m->compat_props, pc_compat_6_0, pc_compat_6_0_len);
157
+}
158
+
159
DEFINE_Q35_MACHINE(v6_0, "pc-q35-6.0", NULL,
160
pc_q35_6_0_machine_options);
161
162
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/hw/ppc/spapr.c
165
+++ b/hw/ppc/spapr.c
166
@@ -XXX,XX +XXX,XX @@ static void spapr_machine_latest_class_options(MachineClass *mc)
167
type_init(spapr_machine_register_##suffix)
168
169
/*
170
- * pseries-6.0
171
+ * pseries-6.1
172
*/
173
-static void spapr_machine_6_0_class_options(MachineClass *mc)
174
+static void spapr_machine_6_1_class_options(MachineClass *mc)
175
{
176
/* Defaults for the latest behaviour inherited from the base class */
177
}
178
179
-DEFINE_SPAPR_MACHINE(6_0, "6.0", true);
180
+DEFINE_SPAPR_MACHINE(6_1, "6.1", true);
181
+
182
+/*
183
+ * pseries-6.0
184
+ */
185
+static void spapr_machine_6_0_class_options(MachineClass *mc)
186
+{
187
+ spapr_machine_6_1_class_options(mc);
188
+ compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
189
+}
190
+
191
+DEFINE_SPAPR_MACHINE(6_0, "6.0", false);
192
193
/*
194
* pseries-5.2
195
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/s390x/s390-virtio-ccw.c
198
+++ b/hw/s390x/s390-virtio-ccw.c
199
@@ -XXX,XX +XXX,XX @@ bool css_migration_enabled(void)
200
} \
201
type_init(ccw_machine_register_##suffix)
202
203
+static void ccw_machine_6_1_instance_options(MachineState *machine)
204
+{
205
+}
206
+
207
+static void ccw_machine_6_1_class_options(MachineClass *mc)
208
+{
209
+}
210
+DEFINE_CCW_MACHINE(6_1, "6.1", true);
211
+
212
static void ccw_machine_6_0_instance_options(MachineState *machine)
213
{
214
+ ccw_machine_6_1_instance_options(machine);
215
}
216
217
static void ccw_machine_6_0_class_options(MachineClass *mc)
218
{
219
+ ccw_machine_6_1_class_options(mc);
220
+ compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
221
}
222
-DEFINE_CCW_MACHINE(6_0, "6.0", true);
223
+DEFINE_CCW_MACHINE(6_0, "6.0", false);
224
225
static void ccw_machine_5_2_instance_options(MachineState *machine)
226
{
227
--
57
--
228
2.20.1
58
2.25.1
229
230
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
In aarch64_numa_cpu(), the CPU and NUMA association is something
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
like below. Two threads in the same core/cluster/socket are
5
Message-id: 20210419202257.161730-21-richard.henderson@linaro.org
5
associated with two individual NUMA nodes, which is unreal as
6
Igor Mammedov mentioned. We don't expect the association to break
7
NUMA-to-socket boundary, which matches with the real world.
8
9
NUMA-node socket cluster core thread
10
------------------------------------------
11
0 0 0 0 0
12
1 0 0 0 1
13
14
This corrects the topology for CPUs and their association with
15
NUMA nodes. After this patch is applied, the CPU and NUMA
16
association becomes something like below, which looks real.
17
Besides, socket/cluster/core/thread IDs are all checked when
18
the NUMA node IDs are verified. It helps to check if the CPU
19
topology is properly populated or not.
20
21
NUMA-node socket cluster core thread
22
------------------------------------------
23
0 1 0 0 0
24
1 0 0 0 0
25
26
Suggested-by: Igor Mammedov <imammedo@redhat.com>
27
Signed-off-by: Gavin Shan <gshan@redhat.com>
28
Acked-by: Igor Mammedov <imammedo@redhat.com>
29
Message-id: 20220503140304.855514-5-gshan@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
31
---
8
target/arm/translate-vfp.c.inc | 8 ++++----
32
tests/qtest/numa-test.c | 18 ++++++++++++------
9
1 file changed, 4 insertions(+), 4 deletions(-)
33
1 file changed, 12 insertions(+), 6 deletions(-)
10
34
11
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
35
diff --git a/tests/qtest/numa-test.c b/tests/qtest/numa-test.c
12
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-vfp.c.inc
37
--- a/tests/qtest/numa-test.c
14
+++ b/target/arm/translate-vfp.c.inc
38
+++ b/tests/qtest/numa-test.c
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
39
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
16
for (i = 0; i < n; i++) {
40
g_autofree char *cli = NULL;
17
if (a->l) {
41
18
/* load */
42
cli = make_cli(data, "-machine "
19
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
43
- "smp.cpus=2,smp.sockets=1,smp.clusters=1,smp.cores=1,smp.threads=2 "
20
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
44
+ "smp.cpus=2,smp.sockets=2,smp.clusters=1,smp.cores=1,smp.threads=1 "
21
vfp_store_reg32(tmp, a->vd + i);
45
"-numa node,nodeid=0,memdev=ram -numa node,nodeid=1 "
46
- "-numa cpu,node-id=1,thread-id=0 "
47
- "-numa cpu,node-id=0,thread-id=1");
48
+ "-numa cpu,node-id=0,socket-id=1,cluster-id=0,core-id=0,thread-id=0 "
49
+ "-numa cpu,node-id=1,socket-id=0,cluster-id=0,core-id=0,thread-id=0");
50
qts = qtest_init(cli);
51
cpus = get_cpus(qts, &resp);
52
g_assert(cpus);
53
54
while ((e = qlist_pop(cpus))) {
55
QDict *cpu, *props;
56
- int64_t thread, node;
57
+ int64_t socket, cluster, core, thread, node;
58
59
cpu = qobject_to(QDict, e);
60
g_assert(qdict_haskey(cpu, "props"));
61
@@ -XXX,XX +XXX,XX @@ static void aarch64_numa_cpu(const void *data)
62
63
g_assert(qdict_haskey(props, "node-id"));
64
node = qdict_get_int(props, "node-id");
65
+ g_assert(qdict_haskey(props, "socket-id"));
66
+ socket = qdict_get_int(props, "socket-id");
67
+ g_assert(qdict_haskey(props, "cluster-id"));
68
+ cluster = qdict_get_int(props, "cluster-id");
69
+ g_assert(qdict_haskey(props, "core-id"));
70
+ core = qdict_get_int(props, "core-id");
71
g_assert(qdict_haskey(props, "thread-id"));
72
thread = qdict_get_int(props, "thread-id");
73
74
- if (thread == 0) {
75
+ if (socket == 0 && cluster == 0 && core == 0 && thread == 0) {
76
g_assert_cmpint(node, ==, 1);
77
- } else if (thread == 1) {
78
+ } else if (socket == 1 && cluster == 0 && core == 0 && thread == 0) {
79
g_assert_cmpint(node, ==, 0);
22
} else {
80
} else {
23
/* store */
81
g_assert(false);
24
vfp_load_reg32(tmp, a->vd + i);
25
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
26
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
27
}
28
tcg_gen_addi_i32(addr, addr, offset);
29
}
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
31
for (i = 0; i < n; i++) {
32
if (a->l) {
33
/* load */
34
- gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
35
+ gen_aa32_ld_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
36
vfp_store_reg64(tmp, a->vd + i);
37
} else {
38
/* store */
39
vfp_load_reg64(tmp, a->vd + i);
40
- gen_aa32_st64(s, tmp, addr, get_mem_index(s));
41
+ gen_aa32_st_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
42
}
43
tcg_gen_addi_i32(addr, addr, offset);
44
}
45
--
82
--
46
2.20.1
83
2.25.1
47
48
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
We were incorrectly assuming that only the first byte of an MTE access
3
When CPU-to-NUMA association isn't explicitly provided by users,
4
is checked against the tags. But per the ARM, unaligned accesses are
4
the default one is given by mc->get_default_cpu_node_id(). However,
5
pre-decomposed into single-byte accesses. So by the time we reach the
5
the CPU topology isn't fully considered in the default association
6
actual MTE check in the ARM pseudocode, all accesses are aligned.
6
and this causes CPU topology broken warnings on booting Linux guest.
7
7
8
We cannot tell a priori whether or not a given scalar access is aligned,
8
For example, the following warning messages are observed when the
9
therefore we must at least check. Use mte_probe_int, which is already
9
Linux guest is booted with the following command lines.
10
set up for checking multiple granules.
11
10
12
Buglink: https://bugs.launchpad.net/bugs/1921948
11
/home/gavin/sandbox/qemu.main/build/qemu-system-aarch64 \
13
Tested-by: Alex Bennée <alex.bennee@linaro.org>
12
-accel kvm -machine virt,gic-version=host \
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
-cpu host \
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
-smp 6,sockets=2,cores=3,threads=1 \
16
Message-id: 20210416183106.1516563-4-richard.henderson@linaro.org
15
-m 1024M,slots=16,maxmem=64G \
16
-object memory-backend-ram,id=mem0,size=128M \
17
-object memory-backend-ram,id=mem1,size=128M \
18
-object memory-backend-ram,id=mem2,size=128M \
19
-object memory-backend-ram,id=mem3,size=128M \
20
-object memory-backend-ram,id=mem4,size=128M \
21
-object memory-backend-ram,id=mem4,size=384M \
22
-numa node,nodeid=0,memdev=mem0 \
23
-numa node,nodeid=1,memdev=mem1 \
24
-numa node,nodeid=2,memdev=mem2 \
25
-numa node,nodeid=3,memdev=mem3 \
26
-numa node,nodeid=4,memdev=mem4 \
27
-numa node,nodeid=5,memdev=mem5
28
:
29
alternatives: patching kernel code
30
BUG: arch topology borken
31
the CLS domain not a subset of the MC domain
32
<the above error log repeats>
33
BUG: arch topology borken
34
the DIE domain not a subset of the NODE domain
35
36
With current implementation of mc->get_default_cpu_node_id(),
37
CPU#0 to CPU#5 are associated with NODE#0 to NODE#5 separately.
38
That's incorrect because CPU#0/1/2 should be associated with same
39
NUMA node because they're seated in same socket.
40
41
This fixes the issue by considering the socket ID when the default
42
CPU-to-NUMA association is provided in virt_possible_cpu_arch_ids().
43
With this applied, no more CPU topology broken warnings are seen
44
from the Linux guest. The 6 CPUs are associated with NODE#0/1, but
45
there are no CPUs associated with NODE#2/3/4/5.
46
47
Signed-off-by: Gavin Shan <gshan@redhat.com>
48
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
49
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
50
Message-id: 20220503140304.855514-6-gshan@redhat.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
51
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
52
---
19
target/arm/mte_helper.c | 109 +++++++++++++---------------------------
53
hw/arm/virt.c | 4 +++-
20
1 file changed, 35 insertions(+), 74 deletions(-)
54
1 file changed, 3 insertions(+), 1 deletion(-)
21
55
22
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
56
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
23
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/mte_helper.c
58
--- a/hw/arm/virt.c
25
+++ b/target/arm/mte_helper.c
59
+++ b/hw/arm/virt.c
26
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
60
@@ -XXX,XX +XXX,XX @@ virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
27
}
61
62
static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
63
{
64
- return idx % ms->numa_state->num_nodes;
65
+ int64_t socket_id = ms->possible_cpus->cpus[idx].props.socket_id;
66
+
67
+ return socket_id % ms->numa_state->num_nodes;
28
}
68
}
29
69
30
-/*
70
static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
31
- * Perform an MTE checked access for a single logical or atomic access.
32
- */
33
-static bool mte_probe1_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
34
- uintptr_t ra, int bit55)
35
-{
36
- int mem_tag, mmu_idx, ptr_tag, size;
37
- MMUAccessType type;
38
- uint8_t *mem;
39
-
40
- ptr_tag = allocation_tag_from_addr(ptr);
41
-
42
- if (tcma_check(desc, bit55, ptr_tag)) {
43
- return true;
44
- }
45
-
46
- mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
47
- type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
48
- size = FIELD_EX32(desc, MTEDESC, ESIZE);
49
-
50
- mem = allocation_tag_mem(env, mmu_idx, ptr, type, size,
51
- MMU_DATA_LOAD, 1, ra);
52
- if (!mem) {
53
- return true;
54
- }
55
-
56
- mem_tag = load_tag1(ptr, mem);
57
- return ptr_tag == mem_tag;
58
-}
59
-
60
-/*
61
- * No-fault version of mte_check1, to be used by SVE for MemSingleNF.
62
- * Returns false if the access is Checked and the check failed. This
63
- * is only intended to probe the tag -- the validity of the page must
64
- * be checked beforehand.
65
- */
66
-bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
67
-{
68
- int bit55 = extract64(ptr, 55, 1);
69
-
70
- /* If TBI is disabled, the access is unchecked. */
71
- if (unlikely(!tbi_check(desc, bit55))) {
72
- return true;
73
- }
74
-
75
- return mte_probe1_int(env, desc, ptr, 0, bit55);
76
-}
77
-
78
-uint64_t mte_check1(CPUARMState *env, uint32_t desc,
79
- uint64_t ptr, uintptr_t ra)
80
-{
81
- int bit55 = extract64(ptr, 55, 1);
82
-
83
- /* If TBI is disabled, the access is unchecked, and ptr is not dirty. */
84
- if (unlikely(!tbi_check(desc, bit55))) {
85
- return ptr;
86
- }
87
-
88
- if (unlikely(!mte_probe1_int(env, desc, ptr, ra, bit55))) {
89
- mte_check_fail(env, desc, ptr, ra);
90
- }
91
-
92
- return useronly_clean_ptr(ptr);
93
-}
94
-
95
-uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
96
-{
97
- return mte_check1(env, desc, ptr, GETPC());
98
-}
99
-
100
-/*
101
- * Perform an MTE checked access for multiple logical accesses.
102
- */
103
-
104
/**
105
* checkN:
106
* @tag: tag memory to test
107
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mte_checkN)(CPUARMState *env, uint32_t desc, uint64_t ptr)
108
return mte_checkN(env, desc, ptr, GETPC());
109
}
110
111
+uint64_t mte_check1(CPUARMState *env, uint32_t desc,
112
+ uint64_t ptr, uintptr_t ra)
113
+{
114
+ uint64_t fault;
115
+ uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
116
+ int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
117
+
118
+ if (unlikely(ret == 0)) {
119
+ mte_check_fail(env, desc, fault, ra);
120
+ } else if (ret < 0) {
121
+ return ptr;
122
+ }
123
+ return useronly_clean_ptr(ptr);
124
+}
125
+
126
+uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
127
+{
128
+ return mte_check1(env, desc, ptr, GETPC());
129
+}
130
+
131
+/*
132
+ * No-fault version of mte_check1, to be used by SVE for MemSingleNF.
133
+ * Returns false if the access is Checked and the check failed. This
134
+ * is only intended to probe the tag -- the validity of the page must
135
+ * be checked beforehand.
136
+ */
137
+bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
138
+{
139
+ uint64_t fault;
140
+ uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
141
+ int ret = mte_probe_int(env, desc, ptr, 0, total, &fault);
142
+
143
+ return ret != 0;
144
+}
145
+
146
/*
147
* Perform an MTE checked access for DC_ZVA.
148
*/
149
--
71
--
150
2.20.1
72
2.25.1
151
152
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Gavin Shan <gshan@redhat.com>
2
2
3
Split out a helper function from mte_checkN to perform
3
When the PPTT table is built, the CPU topology is re-calculated, but
4
all of the checking and address manpulation. So far,
4
it's unecessary because the CPU topology has been populated in
5
just use this in mte_checkN itself.
5
virt_possible_cpu_arch_ids() on arm/virt machine.
6
6
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
This reworks build_pptt() to avoid by reusing the existing IDs in
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
ms->possible_cpus. Currently, the only user of build_pptt() is
9
Message-id: 20210416183106.1516563-3-richard.henderson@linaro.org
9
arm/virt machine.
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
11
Signed-off-by: Gavin Shan <gshan@redhat.com>
12
Tested-by: Yanan Wang <wangyanan55@huawei.com>
13
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
14
Acked-by: Igor Mammedov <imammedo@redhat.com>
15
Acked-by: Michael S. Tsirkin <mst@redhat.com>
16
Message-id: 20220503140304.855514-7-gshan@redhat.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
18
---
13
target/arm/mte_helper.c | 52 +++++++++++++++++++++++++++++++----------
19
hw/acpi/aml-build.c | 111 +++++++++++++++++++-------------------------
14
1 file changed, 40 insertions(+), 12 deletions(-)
20
1 file changed, 48 insertions(+), 63 deletions(-)
15
21
16
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
22
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/mte_helper.c
24
--- a/hw/acpi/aml-build.c
19
+++ b/target/arm/mte_helper.c
25
+++ b/hw/acpi/aml-build.c
20
@@ -XXX,XX +XXX,XX @@ static int checkN(uint8_t *mem, int odd, int cmp, int count)
26
@@ -XXX,XX +XXX,XX @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
21
return n;
27
const char *oem_id, const char *oem_table_id)
22
}
23
24
-uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
25
- uint64_t ptr, uintptr_t ra)
26
+/**
27
+ * mte_probe_int() - helper for mte_probe and mte_check
28
+ * @env: CPU environment
29
+ * @desc: MTEDESC descriptor
30
+ * @ptr: virtual address of the base of the access
31
+ * @fault: return virtual address of the first check failure
32
+ *
33
+ * Internal routine for both mte_probe and mte_check.
34
+ * Return zero on failure, filling in *fault.
35
+ * Return negative on trivial success for tbi disabled.
36
+ * Return positive on success with tbi enabled.
37
+ */
38
+static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
39
+ uintptr_t ra, uint32_t total, uint64_t *fault)
40
{
28
{
41
int mmu_idx, ptr_tag, bit55;
29
MachineClass *mc = MACHINE_GET_CLASS(ms);
42
uint64_t ptr_last, prev_page, next_page;
30
- GQueue *list = g_queue_new();
43
uint64_t tag_first, tag_last;
31
- guint pptt_start = table_data->len;
44
uint64_t tag_byte_first, tag_byte_last;
32
- guint parent_offset;
45
- uint32_t total, tag_count, tag_size, n, c;
33
- guint length, i;
46
+ uint32_t tag_count, tag_size, n, c;
34
- int uid = 0;
47
uint8_t *mem1, *mem2;
35
- int socket;
48
MMUAccessType type;
36
+ CPUArchIdList *cpus = ms->possible_cpus;
49
37
+ int64_t socket_id = -1, cluster_id = -1, core_id = -1;
50
bit55 = extract64(ptr, 55, 1);
38
+ uint32_t socket_offset = 0, cluster_offset = 0, core_offset = 0;
51
+ *fault = ptr;
39
+ uint32_t pptt_start = table_data->len;
52
40
+ int n;
53
/* If TBI is disabled, the access is unchecked, and ptr is not dirty. */
41
AcpiTable table = { .sig = "PPTT", .rev = 2,
54
if (unlikely(!tbi_check(desc, bit55))) {
42
.oem_id = oem_id, .oem_table_id = oem_table_id };
55
- return ptr;
43
56
+ return -1;
44
acpi_table_begin(&table, table_data);
57
}
45
58
46
- for (socket = 0; socket < ms->smp.sockets; socket++) {
59
ptr_tag = allocation_tag_from_addr(ptr);
47
- g_queue_push_tail(list,
60
48
- GUINT_TO_POINTER(table_data->len - pptt_start));
61
if (tcma_check(desc, bit55, ptr_tag)) {
49
- build_processor_hierarchy_node(
62
- goto done;
50
- table_data,
63
+ return 1;
51
- /*
64
}
52
- * Physical package - represents the boundary
65
53
- * of a physical package
66
mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
54
- */
67
type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
55
- (1 << 0),
68
- total = FIELD_EX32(desc, MTEDESC, TSIZE);
56
- 0, socket, NULL, 0);
69
57
- }
70
/* Find the addr of the end of the access */
58
-
71
ptr_last = ptr + total - 1;
59
- if (mc->smp_props.clusters_supported) {
72
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
60
- length = g_queue_get_length(list);
73
mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, total,
61
- for (i = 0; i < length; i++) {
74
MMU_DATA_LOAD, tag_size, ra);
62
- int cluster;
75
if (!mem1) {
63
-
76
- goto done;
64
- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
77
+ return 1;
65
- for (cluster = 0; cluster < ms->smp.clusters; cluster++) {
66
- g_queue_push_tail(list,
67
- GUINT_TO_POINTER(table_data->len - pptt_start));
68
- build_processor_hierarchy_node(
69
- table_data,
70
- (0 << 0), /* not a physical package */
71
- parent_offset, cluster, NULL, 0);
72
- }
73
+ /*
74
+ * This works with the assumption that cpus[n].props.*_id has been
75
+ * sorted from top to down levels in mc->possible_cpu_arch_ids().
76
+ * Otherwise, the unexpected and duplicated containers will be
77
+ * created.
78
+ */
79
+ for (n = 0; n < cpus->len; n++) {
80
+ if (cpus->cpus[n].props.socket_id != socket_id) {
81
+ assert(cpus->cpus[n].props.socket_id > socket_id);
82
+ socket_id = cpus->cpus[n].props.socket_id;
83
+ cluster_id = -1;
84
+ core_id = -1;
85
+ socket_offset = table_data->len - pptt_start;
86
+ build_processor_hierarchy_node(table_data,
87
+ (1 << 0), /* Physical package */
88
+ 0, socket_id, NULL, 0);
78
}
89
}
79
/* Perform all of the comparisons. */
90
- }
80
n = checkN(mem1, ptr & TAG_GRANULE, ptr_tag, tag_count);
91
81
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
92
- length = g_queue_get_length(list);
93
- for (i = 0; i < length; i++) {
94
- int core;
95
-
96
- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
97
- for (core = 0; core < ms->smp.cores; core++) {
98
- if (ms->smp.threads > 1) {
99
- g_queue_push_tail(list,
100
- GUINT_TO_POINTER(table_data->len - pptt_start));
101
- build_processor_hierarchy_node(
102
- table_data,
103
- (0 << 0), /* not a physical package */
104
- parent_offset, core, NULL, 0);
105
- } else {
106
- build_processor_hierarchy_node(
107
- table_data,
108
- (1 << 1) | /* ACPI Processor ID valid */
109
- (1 << 3), /* Node is a Leaf */
110
- parent_offset, uid++, NULL, 0);
111
+ if (mc->smp_props.clusters_supported) {
112
+ if (cpus->cpus[n].props.cluster_id != cluster_id) {
113
+ assert(cpus->cpus[n].props.cluster_id > cluster_id);
114
+ cluster_id = cpus->cpus[n].props.cluster_id;
115
+ core_id = -1;
116
+ cluster_offset = table_data->len - pptt_start;
117
+ build_processor_hierarchy_node(table_data,
118
+ (0 << 0), /* Not a physical package */
119
+ socket_offset, cluster_id, NULL, 0);
120
}
121
+ } else {
122
+ cluster_offset = socket_offset;
82
}
123
}
83
if (n == c) {
124
- }
84
if (!mem2) {
125
85
- goto done;
126
- length = g_queue_get_length(list);
86
+ return 1;
127
- for (i = 0; i < length; i++) {
87
}
128
- int thread;
88
n += checkN(mem2, 0, ptr_tag, tag_count - c);
129
+ if (ms->smp.threads == 1) {
130
+ build_processor_hierarchy_node(table_data,
131
+ (1 << 1) | /* ACPI Processor ID valid */
132
+ (1 << 3), /* Node is a Leaf */
133
+ cluster_offset, n, NULL, 0);
134
+ } else {
135
+ if (cpus->cpus[n].props.core_id != core_id) {
136
+ assert(cpus->cpus[n].props.core_id > core_id);
137
+ core_id = cpus->cpus[n].props.core_id;
138
+ core_offset = table_data->len - pptt_start;
139
+ build_processor_hierarchy_node(table_data,
140
+ (0 << 0), /* Not a physical package */
141
+ cluster_offset, core_id, NULL, 0);
142
+ }
143
144
- parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
145
- for (thread = 0; thread < ms->smp.threads; thread++) {
146
- build_processor_hierarchy_node(
147
- table_data,
148
+ build_processor_hierarchy_node(table_data,
149
(1 << 1) | /* ACPI Processor ID valid */
150
(1 << 2) | /* Processor is a Thread */
151
(1 << 3), /* Node is a Leaf */
152
- parent_offset, uid++, NULL, 0);
153
+ core_offset, n, NULL, 0);
89
}
154
}
90
}
155
}
91
156
92
+ if (likely(n == tag_count)) {
157
- g_queue_free(list);
93
+ return 1;
158
acpi_table_end(linker, &table);
94
+ }
95
+
96
/*
97
* If we failed, we know which granule. For the first granule, the
98
* failure address is @ptr, the first byte accessed. Otherwise the
99
* failure address is the first byte of the nth granule.
100
*/
101
- if (unlikely(n < tag_count)) {
102
- uint64_t fault = (n == 0 ? ptr : tag_first + n * TAG_GRANULE);
103
- mte_check_fail(env, desc, fault, ra);
104
+ if (n > 0) {
105
+ *fault = tag_first + n * TAG_GRANULE;
106
}
107
+ return 0;
108
+}
109
110
- done:
111
+uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
112
+ uint64_t ptr, uintptr_t ra)
113
+{
114
+ uint64_t fault;
115
+ uint32_t total = FIELD_EX32(desc, MTEDESC, TSIZE);
116
+ int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
117
+
118
+ if (unlikely(ret == 0)) {
119
+ mte_check_fail(env, desc, fault, ra);
120
+ } else if (ret < 0) {
121
+ return ptr;
122
+ }
123
return useronly_clean_ptr(ptr);
124
}
159
}
125
160
126
--
161
--
127
2.20.1
162
2.25.1
128
129
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Buglink: https://bugs.launchpad.net/bugs/1921948
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210416183106.1516563-5-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
tests/tcg/aarch64/mte-5.c | 44 +++++++++++++++++++++++++++++++
10
tests/tcg/aarch64/Makefile.target | 2 +-
11
2 files changed, 45 insertions(+), 1 deletion(-)
12
create mode 100644 tests/tcg/aarch64/mte-5.c
13
14
diff --git a/tests/tcg/aarch64/mte-5.c b/tests/tcg/aarch64/mte-5.c
15
new file mode 100644
16
index XXXXXXX..XXXXXXX
17
--- /dev/null
18
+++ b/tests/tcg/aarch64/mte-5.c
19
@@ -XXX,XX +XXX,XX @@
20
+/*
21
+ * Memory tagging, faulting unaligned access.
22
+ *
23
+ * Copyright (c) 2021 Linaro Ltd
24
+ * SPDX-License-Identifier: GPL-2.0-or-later
25
+ */
26
+
27
+#include "mte.h"
28
+
29
+void pass(int sig, siginfo_t *info, void *uc)
30
+{
31
+ assert(info->si_code == SEGV_MTESERR);
32
+ exit(0);
33
+}
34
+
35
+int main(int ac, char **av)
36
+{
37
+ struct sigaction sa;
38
+ void *p0, *p1, *p2;
39
+ long excl = 1;
40
+
41
+ enable_mte(PR_MTE_TCF_SYNC);
42
+ p0 = alloc_mte_mem(sizeof(*p0));
43
+
44
+ /* Create two differently tagged pointers. */
45
+ asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
46
+ asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
47
+ assert(excl != 1);
48
+ asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
49
+ assert(p1 != p2);
50
+
51
+ memset(&sa, 0, sizeof(sa));
52
+ sa.sa_sigaction = pass;
53
+ sa.sa_flags = SA_SIGINFO;
54
+ sigaction(SIGSEGV, &sa, NULL);
55
+
56
+ /* Store store two different tags in sequential granules. */
57
+ asm("stg %0, [%0]" : : "r"(p1));
58
+ asm("stg %0, [%0]" : : "r"(p2 + 16));
59
+
60
+ /* Perform an unaligned load crossing the granules. */
61
+ asm volatile("ldr %0, [%1]" : "=r"(p0) : "r"(p1 + 12));
62
+ abort();
63
+}
64
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
65
index XXXXXXX..XXXXXXX 100644
66
--- a/tests/tcg/aarch64/Makefile.target
67
+++ b/tests/tcg/aarch64/Makefile.target
68
@@ -XXX,XX +XXX,XX @@ AARCH64_TESTS += bti-2
69
70
# MTE Tests
71
ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_MTE),)
72
-AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-6
73
+AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6
74
mte-%: CFLAGS += -march=armv8.5-a+memtag
75
endif
76
77
--
78
2.20.1
79
80
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The mte_check1 and mte_checkN functions are now identical.
4
Drop mte_check1 and rename mte_checkN to mte_check.
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210416183106.1516563-7-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper-a64.h | 3 +--
12
target/arm/internals.h | 5 +----
13
target/arm/mte_helper.c | 26 +++-----------------------
14
target/arm/sve_helper.c | 14 +++++++-------
15
target/arm/translate-a64.c | 4 ++--
16
5 files changed, 14 insertions(+), 38 deletions(-)
17
18
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-a64.h
21
+++ b/target/arm/helper-a64.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64)
23
DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
24
DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
25
26
-DEF_HELPER_FLAGS_3(mte_check1, TCG_CALL_NO_WG, i64, env, i32, i64)
27
-DEF_HELPER_FLAGS_3(mte_checkN, TCG_CALL_NO_WG, i64, env, i32, i64)
28
+DEF_HELPER_FLAGS_3(mte_check, TCG_CALL_NO_WG, i64, env, i32, i64)
29
DEF_HELPER_FLAGS_3(mte_check_zva, TCG_CALL_NO_WG, i64, env, i32, i64)
30
DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
31
DEF_HELPER_FLAGS_4(addsubg, TCG_CALL_NO_RWG_SE, i64, env, i64, s32, i32)
32
diff --git a/target/arm/internals.h b/target/arm/internals.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/internals.h
35
+++ b/target/arm/internals.h
36
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, WRITE, 8, 1)
37
FIELD(MTEDESC, SIZEM1, 9, SIMD_DATA_BITS - 9) /* size - 1 */
38
39
bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr);
40
-uint64_t mte_check1(CPUARMState *env, uint32_t desc,
41
- uint64_t ptr, uintptr_t ra);
42
-uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
43
- uint64_t ptr, uintptr_t ra);
44
+uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
45
46
static inline int allocation_tag_from_addr(uint64_t ptr)
47
{
48
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/mte_helper.c
51
+++ b/target/arm/mte_helper.c
52
@@ -XXX,XX +XXX,XX @@ static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
53
return 0;
54
}
55
56
-uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
57
- uint64_t ptr, uintptr_t ra)
58
+uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra)
59
{
60
uint64_t fault;
61
int ret = mte_probe_int(env, desc, ptr, ra, &fault);
62
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
63
return useronly_clean_ptr(ptr);
64
}
65
66
-uint64_t HELPER(mte_checkN)(CPUARMState *env, uint32_t desc, uint64_t ptr)
67
+uint64_t HELPER(mte_check)(CPUARMState *env, uint32_t desc, uint64_t ptr)
68
{
69
- return mte_checkN(env, desc, ptr, GETPC());
70
-}
71
-
72
-uint64_t mte_check1(CPUARMState *env, uint32_t desc,
73
- uint64_t ptr, uintptr_t ra)
74
-{
75
- uint64_t fault;
76
- int ret = mte_probe_int(env, desc, ptr, ra, &fault);
77
-
78
- if (unlikely(ret == 0)) {
79
- mte_check_fail(env, desc, fault, ra);
80
- } else if (ret < 0) {
81
- return ptr;
82
- }
83
- return useronly_clean_ptr(ptr);
84
-}
85
-
86
-uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
87
-{
88
- return mte_check1(env, desc, ptr, GETPC());
89
+ return mte_check(env, desc, ptr, GETPC());
90
}
91
92
/*
93
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/sve_helper.c
96
+++ b/target/arm/sve_helper.c
97
@@ -XXX,XX +XXX,XX @@ static void sve_cont_ldst_mte_check1(SVEContLdSt *info, CPUARMState *env,
98
uintptr_t ra)
99
{
100
sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
101
- mtedesc, ra, mte_check1);
102
+ mtedesc, ra, mte_check);
103
}
104
105
static void sve_cont_ldst_mte_checkN(SVEContLdSt *info, CPUARMState *env,
106
@@ -XXX,XX +XXX,XX @@ static void sve_cont_ldst_mte_checkN(SVEContLdSt *info, CPUARMState *env,
107
uintptr_t ra)
108
{
109
sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
110
- mtedesc, ra, mte_checkN);
111
+ mtedesc, ra, mte_check);
112
}
113
114
115
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
116
if (fault == FAULT_FIRST) {
117
/* Trapping mte check for the first-fault element. */
118
if (mtedesc) {
119
- mte_check1(env, mtedesc, addr + mem_off, retaddr);
120
+ mte_check(env, mtedesc, addr + mem_off, retaddr);
121
}
122
123
/*
124
@@ -XXX,XX +XXX,XX @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
125
info.attrs, BP_MEM_READ, retaddr);
126
}
127
if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
128
- mte_check1(env, mtedesc, addr, retaddr);
129
+ mte_check(env, mtedesc, addr, retaddr);
130
}
131
host_fn(&scratch, reg_off, info.host);
132
} else {
133
@@ -XXX,XX +XXX,XX @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
134
BP_MEM_READ, retaddr);
135
}
136
if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
137
- mte_check1(env, mtedesc, addr, retaddr);
138
+ mte_check(env, mtedesc, addr, retaddr);
139
}
140
tlb_fn(env, &scratch, reg_off, addr, retaddr);
141
}
142
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
143
*/
144
addr = base + (off_fn(vm, reg_off) << scale);
145
if (mtedesc) {
146
- mte_check1(env, mtedesc, addr, retaddr);
147
+ mte_check(env, mtedesc, addr, retaddr);
148
}
149
tlb_fn(env, vd, reg_off, addr, retaddr);
150
151
@@ -XXX,XX +XXX,XX @@ void sve_st1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
152
}
153
154
if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
155
- mte_check1(env, mtedesc, addr, retaddr);
156
+ mte_check(env, mtedesc, addr, retaddr);
157
}
158
}
159
i += 1;
160
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
161
index XXXXXXX..XXXXXXX 100644
162
--- a/target/arm/translate-a64.c
163
+++ b/target/arm/translate-a64.c
164
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr,
165
tcg_desc = tcg_const_i32(desc);
166
167
ret = new_tmp_a64(s);
168
- gen_helper_mte_check1(ret, cpu_env, tcg_desc, addr);
169
+ gen_helper_mte_check(ret, cpu_env, tcg_desc, addr);
170
tcg_temp_free_i32(tcg_desc);
171
172
return ret;
173
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
174
tcg_desc = tcg_const_i32(desc);
175
176
ret = new_tmp_a64(s);
177
- gen_helper_mte_checkN(ret, cpu_env, tcg_desc, addr);
178
+ gen_helper_mte_check(ret, cpu_env, tcg_desc, addr);
179
tcg_temp_free_i32(tcg_desc);
180
181
return ret;
182
--
183
2.20.1
184
185
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Now that mte_check1 and mte_checkN have been merged, we can
4
merge sve_cont_ldst_mte_check1 and sve_cont_ldst_mte_checkN.
5
6
Which means that we can eliminate the function pointer into
7
sve_ldN_r and sve_stN_r, calling sve_cont_ldst_mte_check directly.
8
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210416183106.1516563-9-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/sve_helper.c | 84 +++++++++++++----------------------------
15
1 file changed, 26 insertions(+), 58 deletions(-)
16
17
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/sve_helper.c
20
+++ b/target/arm/sve_helper.c
21
@@ -XXX,XX +XXX,XX @@ static void sve_cont_ldst_watchpoints(SVEContLdSt *info, CPUARMState *env,
22
#endif
23
}
24
25
-typedef uint64_t mte_check_fn(CPUARMState *, uint32_t, uint64_t, uintptr_t);
26
-
27
-static inline QEMU_ALWAYS_INLINE
28
-void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
29
- uint64_t *vg, target_ulong addr, int esize,
30
- int msize, uint32_t mtedesc, uintptr_t ra,
31
- mte_check_fn *check)
32
+static void sve_cont_ldst_mte_check(SVEContLdSt *info, CPUARMState *env,
33
+ uint64_t *vg, target_ulong addr, int esize,
34
+ int msize, uint32_t mtedesc, uintptr_t ra)
35
{
36
intptr_t mem_off, reg_off, reg_last;
37
38
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
39
uint64_t pg = vg[reg_off >> 6];
40
do {
41
if ((pg >> (reg_off & 63)) & 1) {
42
- check(env, mtedesc, addr, ra);
43
+ mte_check(env, mtedesc, addr, ra);
44
}
45
reg_off += esize;
46
mem_off += msize;
47
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
48
uint64_t pg = vg[reg_off >> 6];
49
do {
50
if ((pg >> (reg_off & 63)) & 1) {
51
- check(env, mtedesc, addr, ra);
52
+ mte_check(env, mtedesc, addr, ra);
53
}
54
reg_off += esize;
55
mem_off += msize;
56
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
57
}
58
}
59
60
-typedef void sve_cont_ldst_mte_check_fn(SVEContLdSt *info, CPUARMState *env,
61
- uint64_t *vg, target_ulong addr,
62
- int esize, int msize, uint32_t mtedesc,
63
- uintptr_t ra);
64
-
65
-static void sve_cont_ldst_mte_check1(SVEContLdSt *info, CPUARMState *env,
66
- uint64_t *vg, target_ulong addr,
67
- int esize, int msize, uint32_t mtedesc,
68
- uintptr_t ra)
69
-{
70
- sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
71
- mtedesc, ra, mte_check);
72
-}
73
-
74
-static void sve_cont_ldst_mte_checkN(SVEContLdSt *info, CPUARMState *env,
75
- uint64_t *vg, target_ulong addr,
76
- int esize, int msize, uint32_t mtedesc,
77
- uintptr_t ra)
78
-{
79
- sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
80
- mtedesc, ra, mte_check);
81
-}
82
-
83
-
84
/*
85
* Common helper for all contiguous 1,2,3,4-register predicated stores.
86
*/
87
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r(CPUARMState *env, uint64_t *vg, const target_ulong addr,
88
uint32_t desc, const uintptr_t retaddr,
89
const int esz, const int msz, const int N, uint32_t mtedesc,
90
sve_ldst1_host_fn *host_fn,
91
- sve_ldst1_tlb_fn *tlb_fn,
92
- sve_cont_ldst_mte_check_fn *mte_check_fn)
93
+ sve_ldst1_tlb_fn *tlb_fn)
94
{
95
const unsigned rd = simd_data(desc);
96
const intptr_t reg_max = simd_oprsz(desc);
97
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r(CPUARMState *env, uint64_t *vg, const target_ulong addr,
98
* Handle mte checks for all active elements.
99
* Since TBI must be set for MTE, !mtedesc => !mte_active.
100
*/
101
- if (mte_check_fn && mtedesc) {
102
- mte_check_fn(&info, env, vg, addr, 1 << esz, N << msz,
103
- mtedesc, retaddr);
104
+ if (mtedesc) {
105
+ sve_cont_ldst_mte_check(&info, env, vg, addr, 1 << esz, N << msz,
106
+ mtedesc, retaddr);
107
}
108
109
flags = info.page[0].flags | info.page[1].flags;
110
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
111
mtedesc = 0;
112
}
113
114
- sve_ldN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn,
115
- N == 1 ? sve_cont_ldst_mte_check1 : sve_cont_ldst_mte_checkN);
116
+ sve_ldN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn);
117
}
118
119
#define DO_LD1_1(NAME, ESZ) \
120
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_##NAME##_r)(CPUARMState *env, void *vg, \
121
target_ulong addr, uint32_t desc) \
122
{ \
123
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MO_8, 1, 0, \
124
- sve_##NAME##_host, sve_##NAME##_tlb, NULL); \
125
+ sve_##NAME##_host, sve_##NAME##_tlb); \
126
} \
127
void HELPER(sve_##NAME##_r_mte)(CPUARMState *env, void *vg, \
128
target_ulong addr, uint32_t desc) \
129
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_##NAME##_le_r)(CPUARMState *env, void *vg, \
130
target_ulong addr, uint32_t desc) \
131
{ \
132
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, 0, \
133
- sve_##NAME##_le_host, sve_##NAME##_le_tlb, NULL); \
134
+ sve_##NAME##_le_host, sve_##NAME##_le_tlb); \
135
} \
136
void HELPER(sve_##NAME##_be_r)(CPUARMState *env, void *vg, \
137
target_ulong addr, uint32_t desc) \
138
{ \
139
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, 0, \
140
- sve_##NAME##_be_host, sve_##NAME##_be_tlb, NULL); \
141
+ sve_##NAME##_be_host, sve_##NAME##_be_tlb); \
142
} \
143
void HELPER(sve_##NAME##_le_r_mte)(CPUARMState *env, void *vg, \
144
- target_ulong addr, uint32_t desc) \
145
+ target_ulong addr, uint32_t desc) \
146
{ \
147
sve_ldN_r_mte(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, \
148
sve_##NAME##_le_host, sve_##NAME##_le_tlb); \
149
} \
150
void HELPER(sve_##NAME##_be_r_mte)(CPUARMState *env, void *vg, \
151
- target_ulong addr, uint32_t desc) \
152
+ target_ulong addr, uint32_t desc) \
153
{ \
154
sve_ldN_r_mte(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, \
155
sve_##NAME##_be_host, sve_##NAME##_be_tlb); \
156
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_ld##N##bb_r)(CPUARMState *env, void *vg, \
157
target_ulong addr, uint32_t desc) \
158
{ \
159
sve_ldN_r(env, vg, addr, desc, GETPC(), MO_8, MO_8, N, 0, \
160
- sve_ld1bb_host, sve_ld1bb_tlb, NULL); \
161
+ sve_ld1bb_host, sve_ld1bb_tlb); \
162
} \
163
void HELPER(sve_ld##N##bb_r_mte)(CPUARMState *env, void *vg, \
164
target_ulong addr, uint32_t desc) \
165
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_ld##N##SUFF##_le_r)(CPUARMState *env, void *vg, \
166
target_ulong addr, uint32_t desc) \
167
{ \
168
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, ESZ, N, 0, \
169
- sve_ld1##SUFF##_le_host, sve_ld1##SUFF##_le_tlb, NULL); \
170
+ sve_ld1##SUFF##_le_host, sve_ld1##SUFF##_le_tlb); \
171
} \
172
void HELPER(sve_ld##N##SUFF##_be_r)(CPUARMState *env, void *vg, \
173
target_ulong addr, uint32_t desc) \
174
{ \
175
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, ESZ, N, 0, \
176
- sve_ld1##SUFF##_be_host, sve_ld1##SUFF##_be_tlb, NULL); \
177
+ sve_ld1##SUFF##_be_host, sve_ld1##SUFF##_be_tlb); \
178
} \
179
void HELPER(sve_ld##N##SUFF##_le_r_mte)(CPUARMState *env, void *vg, \
180
target_ulong addr, uint32_t desc) \
181
@@ -XXX,XX +XXX,XX @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr,
182
uint32_t desc, const uintptr_t retaddr,
183
const int esz, const int msz, const int N, uint32_t mtedesc,
184
sve_ldst1_host_fn *host_fn,
185
- sve_ldst1_tlb_fn *tlb_fn,
186
- sve_cont_ldst_mte_check_fn *mte_check_fn)
187
+ sve_ldst1_tlb_fn *tlb_fn)
188
{
189
const unsigned rd = simd_data(desc);
190
const intptr_t reg_max = simd_oprsz(desc);
191
@@ -XXX,XX +XXX,XX @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr,
192
* Handle mte checks for all active elements.
193
* Since TBI must be set for MTE, !mtedesc => !mte_active.
194
*/
195
- if (mte_check_fn && mtedesc) {
196
- mte_check_fn(&info, env, vg, addr, 1 << esz, N << msz,
197
- mtedesc, retaddr);
198
+ if (mtedesc) {
199
+ sve_cont_ldst_mte_check(&info, env, vg, addr, 1 << esz, N << msz,
200
+ mtedesc, retaddr);
201
}
202
203
flags = info.page[0].flags | info.page[1].flags;
204
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
205
mtedesc = 0;
206
}
207
208
- sve_stN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn,
209
- N == 1 ? sve_cont_ldst_mte_check1 : sve_cont_ldst_mte_checkN);
210
+ sve_stN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn);
211
}
212
213
#define DO_STN_1(N, NAME, ESZ) \
214
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st##N##NAME##_r)(CPUARMState *env, void *vg, \
215
target_ulong addr, uint32_t desc) \
216
{ \
217
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MO_8, N, 0, \
218
- sve_st1##NAME##_host, sve_st1##NAME##_tlb, NULL); \
219
+ sve_st1##NAME##_host, sve_st1##NAME##_tlb); \
220
} \
221
void HELPER(sve_st##N##NAME##_r_mte)(CPUARMState *env, void *vg, \
222
target_ulong addr, uint32_t desc) \
223
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st##N##NAME##_le_r)(CPUARMState *env, void *vg, \
224
target_ulong addr, uint32_t desc) \
225
{ \
226
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, N, 0, \
227
- sve_st1##NAME##_le_host, sve_st1##NAME##_le_tlb, NULL); \
228
+ sve_st1##NAME##_le_host, sve_st1##NAME##_le_tlb); \
229
} \
230
void HELPER(sve_st##N##NAME##_be_r)(CPUARMState *env, void *vg, \
231
target_ulong addr, uint32_t desc) \
232
{ \
233
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, N, 0, \
234
- sve_st1##NAME##_be_host, sve_st1##NAME##_be_tlb, NULL); \
235
+ sve_st1##NAME##_be_host, sve_st1##NAME##_be_tlb); \
236
} \
237
void HELPER(sve_st##N##NAME##_le_r_mte)(CPUARMState *env, void *vg, \
238
target_ulong addr, uint32_t desc) \
239
--
240
2.20.1
241
242
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The log2_esize parameter is not used except trivially.
4
Drop the parameter and the deferral to gen_mte_check1.
5
6
This fixes a bug in that the parameters as documented
7
in the header file were the reverse from those in the
8
implementation. Which meant that translate-sve.c was
9
passing the parameters in the wrong order.
10
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210416183106.1516563-10-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/translate-a64.h | 2 +-
17
target/arm/translate-a64.c | 15 +++++++--------
18
target/arm/translate-sve.c | 4 ++--
19
3 files changed, 10 insertions(+), 11 deletions(-)
20
21
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate-a64.h
24
+++ b/target/arm/translate-a64.h
25
@@ -XXX,XX +XXX,XX @@ TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr);
26
TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
27
bool tag_checked, int log2_size);
28
TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
29
- bool tag_checked, int count, int log2_esize);
30
+ bool tag_checked, int size);
31
32
/* We should have at some point before trying to access an FP register
33
* done the necessary access check, so assert that
34
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-a64.c
37
+++ b/target/arm/translate-a64.c
38
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
39
* For MTE, check multiple logical sequential accesses.
40
*/
41
TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
42
- bool tag_checked, int log2_esize, int total_size)
43
+ bool tag_checked, int size)
44
{
45
- if (tag_checked && s->mte_active[0] && total_size != (1 << log2_esize)) {
46
+ if (tag_checked && s->mte_active[0]) {
47
TCGv_i32 tcg_desc;
48
TCGv_i64 ret;
49
int desc = 0;
50
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
51
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
52
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
53
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
54
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, total_size - 1);
55
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, size - 1);
56
tcg_desc = tcg_const_i32(desc);
57
58
ret = new_tmp_a64(s);
59
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
60
61
return ret;
62
}
63
- return gen_mte_check1(s, addr, is_write, tag_checked, log2_esize);
64
+ return clean_data_tbi(s, addr);
65
}
66
67
typedef struct DisasCompare64 {
68
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
69
}
70
71
clean_addr = gen_mte_checkN(s, dirty_addr, !is_load,
72
- (wback || rn != 31) && !set_tag,
73
- size, 2 << size);
74
+ (wback || rn != 31) && !set_tag, 2 << size);
75
76
if (is_vector) {
77
if (is_load) {
78
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
79
* promote consecutive little-endian elements below.
80
*/
81
clean_addr = gen_mte_checkN(s, tcg_rn, is_store, is_postidx || rn != 31,
82
- size, total);
83
+ total);
84
85
/*
86
* Consecutive little-endian elements from a single register
87
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
88
tcg_rn = cpu_reg_sp(s, rn);
89
90
clean_addr = gen_mte_checkN(s, tcg_rn, !is_load, is_postidx || rn != 31,
91
- scale, total);
92
+ total);
93
94
tcg_ebytes = tcg_const_i64(1 << scale);
95
for (xs = 0; xs < selem; xs++) {
96
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate-sve.c
99
+++ b/target/arm/translate-sve.c
100
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
101
102
dirty_addr = tcg_temp_new_i64();
103
tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm);
104
- clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len, MO_8);
105
+ clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len);
106
tcg_temp_free_i64(dirty_addr);
107
108
/*
109
@@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
110
111
dirty_addr = tcg_temp_new_i64();
112
tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm);
113
- clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len, MO_8);
114
+ clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len);
115
tcg_temp_free_i64(dirty_addr);
116
117
/* Note that unpredicated load/store of vector/predicate registers
118
--
119
2.20.1
120
121
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Buglink: https://bugs.launchpad.net/qemu/+bug/1905356
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210419202257.161730-16-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/translate.c | 16 ++++++++--------
10
1 file changed, 8 insertions(+), 8 deletions(-)
11
12
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate.c
15
+++ b/target/arm/translate.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
17
addr = op_addr_rr_pre(s, a);
18
19
tmp = tcg_temp_new_i32();
20
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
21
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
22
store_reg(s, a->rt, tmp);
23
24
tcg_gen_addi_i32(addr, addr, 4);
25
26
tmp = tcg_temp_new_i32();
27
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
28
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
29
store_reg(s, a->rt + 1, tmp);
30
31
/* LDRD w/ base writeback is undefined if the registers overlap. */
32
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
33
addr = op_addr_rr_pre(s, a);
34
35
tmp = load_reg(s, a->rt);
36
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
37
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
38
tcg_temp_free_i32(tmp);
39
40
tcg_gen_addi_i32(addr, addr, 4);
41
42
tmp = load_reg(s, a->rt + 1);
43
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
44
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
45
tcg_temp_free_i32(tmp);
46
47
op_addr_rr_post(s, a, addr, -4);
48
@@ -XXX,XX +XXX,XX @@ static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
49
addr = op_addr_ri_pre(s, a);
50
51
tmp = tcg_temp_new_i32();
52
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
53
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
54
store_reg(s, a->rt, tmp);
55
56
tcg_gen_addi_i32(addr, addr, 4);
57
58
tmp = tcg_temp_new_i32();
59
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
60
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
61
store_reg(s, rt2, tmp);
62
63
/* LDRD w/ base writeback is undefined if the registers overlap. */
64
@@ -XXX,XX +XXX,XX @@ static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
65
addr = op_addr_ri_pre(s, a);
66
67
tmp = load_reg(s, a->rt);
68
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
69
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
70
tcg_temp_free_i32(tmp);
71
72
tcg_gen_addi_i32(addr, addr, 4);
73
74
tmp = load_reg(s, rt2);
75
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
76
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
77
tcg_temp_free_i32(tmp);
78
79
op_addr_ri_post(s, a, addr, -4);
80
--
81
2.20.1
82
83
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-18-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate.c | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
10
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
16
} else {
17
tmp = load_reg(s, i);
18
}
19
- gen_aa32_st32(s, tmp, addr, mem_idx);
20
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
21
tcg_temp_free_i32(tmp);
22
23
/* No need to add after the last transfer. */
24
@@ -XXX,XX +XXX,XX @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
25
}
26
27
tmp = tcg_temp_new_i32();
28
- gen_aa32_ld32u(s, tmp, addr, mem_idx);
29
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
30
if (user) {
31
tmp2 = tcg_const_i32(i);
32
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-19-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate.c | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
10
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static bool trans_RFE(DisasContext *s, arg_RFE *a)
16
17
/* Load PC into tmp and CPSR into tmp2. */
18
t1 = tcg_temp_new_i32();
19
- gen_aa32_ld32u(s, t1, addr, get_mem_index(s));
20
+ gen_aa32_ld_i32(s, t1, addr, get_mem_index(s), MO_UL | MO_ALIGN);
21
tcg_gen_addi_i32(addr, addr, 4);
22
t2 = tcg_temp_new_i32();
23
- gen_aa32_ld32u(s, t2, addr, get_mem_index(s));
24
+ gen_aa32_ld_i32(s, t2, addr, get_mem_index(s), MO_UL | MO_ALIGN);
25
26
if (a->w) {
27
/* Base writeback. */
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-20-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate.c | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
10
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
16
}
17
tcg_gen_addi_i32(addr, addr, offset);
18
tmp = load_reg(s, 14);
19
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
20
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
21
tcg_temp_free_i32(tmp);
22
tmp = load_cpu_field(spsr);
23
tcg_gen_addi_i32(addr, addr, 4);
24
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
25
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
26
tcg_temp_free_i32(tmp);
27
if (writeback) {
28
switch (amode) {
29
--
30
2.20.1
31
32
diff view generated by jsdifflib