1
Small pile of bug fixes for rc1. I've included my patches to get
1
Hi; here's a target-arm pullreq. Mostly this is RTH's FEAT_RME
2
our docs building with Sphinx 3, just for convenience...
2
series; there are also a handful of bug fixes including some
3
which aren't arm-specific but which it's convenient to include
4
here.
3
5
6
thanks
4
-- PMM
7
-- PMM
5
8
6
The following changes since commit b149dea55cce97cb226683d06af61984a1c11e96:
9
The following changes since commit b455ce4c2f300c8ba47cba7232dd03261368a4cb:
7
10
8
Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20201102' into staging (2020-11-02 10:57:48 +0000)
11
Merge tag 'q800-for-8.1-pull-request' of https://github.com/vivier/qemu-m68k into staging (2023-06-22 10:18:32 +0200)
9
12
10
are available in the Git repository at:
13
are available in the Git repository at:
11
14
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201102
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230623
13
16
14
for you to fetch changes up to ffb4fbf90a2f63c9cb33e4bb9f854c79bf04ca4a:
17
for you to fetch changes up to 497fad38979c16b6412388927401e577eba43d26:
15
18
16
tests/qtest/npcm7xx_rng-test: Disable randomness tests (2020-11-02 16:52:18 +0000)
19
pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym (2023-06-23 11:46:02 +0100)
17
20
18
----------------------------------------------------------------
21
----------------------------------------------------------------
19
target-arm queue:
22
target-arm queue:
20
* target/arm: Fix Neon emulation bugs on big-endian hosts
23
* Add (experimental) support for FEAT_RME
21
* target/arm: fix handling of HCR.FB
24
* host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
22
* target/arm: fix LORID_EL1 access check
25
* target/arm: Restructure has_vfp_d32 test
23
* disas/capstone: Fix monitor disassembly of >32 bytes
26
* hw/arm/sbsa-ref: add ITS support in SBSA GIC
24
* hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
27
* target/arm: Fix sve predicate store, 8 <= VQ <= 15
25
* hw/arm/boot: fix SVE for EL3 direct kernel boot
28
* pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
26
* hw/display/omap_lcdc: Fix potential NULL pointer dereference
27
* hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
28
* target/arm: Get correct MMU index for other-security-state
29
* configure: Test that gio libs from pkg-config work
30
* hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
31
* docs: Fix building with Sphinx 3
32
* tests/qtest/npcm7xx_rng-test: Disable randomness tests
33
29
34
----------------------------------------------------------------
30
----------------------------------------------------------------
35
AlexChen (2):
31
Peter Maydell (2):
36
hw/display/omap_lcdc: Fix potential NULL pointer dereference
32
host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
37
hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
33
pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
38
34
39
Peter Maydell (9):
35
Richard Henderson (23):
40
target/arm: Fix float16 pairwise Neon ops on big-endian hosts
36
target/arm: Add isar_feature_aa64_rme
41
target/arm: Fix VUDOT/VSDOT (scalar) on big-endian hosts
37
target/arm: Update SCR and HCR for RME
42
disas/capstone: Fix monitor disassembly of >32 bytes
38
target/arm: SCR_EL3.NS may be RES1
43
target/arm: Get correct MMU index for other-security-state
39
target/arm: Add RME cpregs
44
configure: Test that gio libs from pkg-config work
40
target/arm: Introduce ARMSecuritySpace
45
hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
41
include/exec/memattrs: Add two bits of space to MemTxAttrs
46
scripts/kerneldoc: For Sphinx 3 use c:macro for macros with arguments
42
target/arm: Adjust the order of Phys and Stage2 ARMMMUIdx
47
qemu-option-trace.rst.inc: Don't use option:: markup
43
target/arm: Introduce ARMMMUIdx_Phys_{Realm,Root}
48
tests/qtest/npcm7xx_rng-test: Disable randomness tests
44
target/arm: Remove __attribute__((nonnull)) from ptw.c
45
target/arm: Pipe ARMSecuritySpace through ptw.c
46
target/arm: NSTable is RES0 for the RME EL3 regime
47
target/arm: Handle Block and Page bits for security space
48
target/arm: Handle no-execute for Realm and Root regimes
49
target/arm: Use get_phys_addr_with_struct in S1_ptw_translate
50
target/arm: Move s1_is_el0 into S1Translate
51
target/arm: Use get_phys_addr_with_struct for stage2
52
target/arm: Add GPC syndrome
53
target/arm: Implement GPC exceptions
54
target/arm: Implement the granule protection check
55
target/arm: Add cpu properties for enabling FEAT_RME
56
docs/system/arm: Document FEAT_RME
57
target/arm: Restructure has_vfp_d32 test
58
target/arm: Fix sve predicate store, 8 <= VQ <= 15
49
59
50
Philippe Mathieu-Daudé (1):
60
Shashi Mallela (1):
51
hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
61
hw/arm/sbsa-ref: add ITS support in SBSA GIC
52
62
53
Richard Henderson (11):
63
docs/system/arm/cpu-features.rst | 23 ++
54
target/arm: Introduce neon_full_reg_offset
64
docs/system/arm/emulation.rst | 1 +
55
target/arm: Move neon_element_offset to translate.c
65
docs/system/arm/sbsa.rst | 14 +
56
target/arm: Use neon_element_offset in neon_load/store_reg
66
include/exec/memattrs.h | 9 +-
57
target/arm: Use neon_element_offset in vfp_reg_offset
67
include/qemu/compiler.h | 13 +
58
target/arm: Add read/write_neon_element32
68
include/qemu/host-utils.h | 2 +-
59
target/arm: Expand read/write_neon_element32 to all MemOp
69
target/arm/cpu.h | 151 ++++++++---
60
target/arm: Rename neon_load_reg32 to vfp_load_reg32
70
target/arm/internals.h | 27 ++
61
target/arm: Add read/write_neon_element64
71
target/arm/syndrome.h | 10 +
62
target/arm: Rename neon_load_reg64 to vfp_load_reg64
72
hw/arm/sbsa-ref.c | 33 ++-
63
target/arm: Simplify do_long_3d and do_2scalar_long
73
target/arm/cpu.c | 32 ++-
64
target/arm: Improve do_prewiden_3d
74
target/arm/helper.c | 162 ++++++++++-
65
75
target/arm/ptw.c | 570 +++++++++++++++++++++++++++++++--------
66
Rémi Denis-Courmont (3):
76
target/arm/tcg/cpu64.c | 53 ++++
67
target/arm: fix handling of HCR.FB
77
target/arm/tcg/tlb_helper.c | 96 ++++++-
68
target/arm: fix LORID_EL1 access check
78
target/arm/tcg/translate-sve.c | 2 +-
69
hw/arm/boot: fix SVE for EL3 direct kernel boot
79
pc-bios/keymaps/meson.build | 2 +-
70
80
17 files changed, 1034 insertions(+), 166 deletions(-)
71
docs/qemu-option-trace.rst.inc | 6 +-
72
configure | 10 +-
73
include/hw/intc/arm_gicv3_common.h | 1 -
74
disas/capstone.c | 2 +-
75
hw/arm/boot.c | 3 +
76
hw/arm/smmuv3.c | 3 +-
77
hw/display/exynos4210_fimd.c | 4 +-
78
hw/display/omap_lcdc.c | 10 +-
79
hw/intc/arm_gicv3_cpuif.c | 5 +-
80
target/arm/helper.c | 24 +-
81
target/arm/m_helper.c | 3 +-
82
target/arm/translate.c | 153 +++++++++---
83
target/arm/vec_helper.c | 12 +-
84
tests/qtest/npcm7xx_rng-test.c | 14 +-
85
scripts/kernel-doc | 18 +-
86
target/arm/translate-neon.c.inc | 472 ++++++++++++++++++++-----------------
87
target/arm/translate-vfp.c.inc | 341 +++++++++++----------------
88
17 files changed, 588 insertions(+), 493 deletions(-)
89
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 function makes it clear that we're talking about the whole
3
Add the missing field for ID_AA64PFR0, and the predicate.
4
register, and not the 32-bit piece at index 0. This fixes a bug
4
Disable it if EL3 is forced off by the board or command-line.
5
when running on a big-endian host.
6
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@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: 20201030022618.785675-2-richard.henderson@linaro.org
9
Message-id: 20230620124418.805717-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@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/translate.c | 8 ++++++
12
target/arm/cpu.h | 6 ++++++
13
target/arm/translate-neon.c.inc | 44 ++++++++++++++++-----------------
13
target/arm/cpu.c | 4 ++++
14
target/arm/translate-vfp.c.inc | 2 +-
14
2 files changed, 10 insertions(+)
15
3 files changed, 31 insertions(+), 23 deletions(-)
16
15
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.c
18
--- a/target/arm/cpu.h
20
+++ b/target/arm/translate.c
19
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
20
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64PFR0, SEL2, 36, 4)
22
unallocated_encoding(s);
21
FIELD(ID_AA64PFR0, MPAM, 40, 4)
22
FIELD(ID_AA64PFR0, AMU, 44, 4)
23
FIELD(ID_AA64PFR0, DIT, 48, 4)
24
+FIELD(ID_AA64PFR0, RME, 52, 4)
25
FIELD(ID_AA64PFR0, CSV2, 56, 4)
26
FIELD(ID_AA64PFR0, CSV3, 60, 4)
27
28
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
29
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0;
23
}
30
}
24
31
25
+/*
32
+static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
26
+ * Return the offset of a "full" NEON Dreg.
27
+ */
28
+static long neon_full_reg_offset(unsigned reg)
29
+{
33
+{
30
+ return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
34
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
31
+}
35
+}
32
+
36
+
33
static inline long vfp_reg_offset(bool dp, unsigned reg)
37
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
34
{
38
{
35
if (dp) {
39
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
36
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
40
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
37
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.c.inc
42
--- a/target/arm/cpu.c
39
+++ b/target/arm/translate-neon.c.inc
43
+++ b/target/arm/cpu.c
40
@@ -XXX,XX +XXX,XX @@ neon_element_offset(int reg, int element, MemOp size)
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
41
ofs ^= 8 - element_size;
45
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
46
cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
47
ID_AA64PFR0, EL3, 0);
48
+
49
+ /* Disable the realm management extension, which requires EL3. */
50
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
51
+ ID_AA64PFR0, RME, 0);
42
}
52
}
43
#endif
53
44
- return neon_reg_offset(reg, 0) + ofs;
54
if (!cpu->has_el2) {
45
+ return neon_full_reg_offset(reg) + ofs;
46
}
47
48
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
50
* We cannot write 16 bytes at once because the
51
* destination is unaligned.
52
*/
53
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
54
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
55
8, 8, tmp);
56
- tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
57
- neon_reg_offset(vd, 0), 8, 8);
58
+ tcg_gen_gvec_mov(0, neon_full_reg_offset(vd + 1),
59
+ neon_full_reg_offset(vd), 8, 8);
60
} else {
61
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
62
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
63
vec_size, vec_size, tmp);
64
}
65
tcg_gen_addi_i32(addr, addr, 1 << size);
66
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
67
static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
68
{
69
int vec_size = a->q ? 16 : 8;
70
- int rd_ofs = neon_reg_offset(a->vd, 0);
71
- int rn_ofs = neon_reg_offset(a->vn, 0);
72
- int rm_ofs = neon_reg_offset(a->vm, 0);
73
+ int rd_ofs = neon_full_reg_offset(a->vd);
74
+ int rn_ofs = neon_full_reg_offset(a->vn);
75
+ int rm_ofs = neon_full_reg_offset(a->vm);
76
77
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
78
return false;
79
@@ -XXX,XX +XXX,XX @@ static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
80
{
81
/* Handle a 2-reg-shift insn which can be vectorized. */
82
int vec_size = a->q ? 16 : 8;
83
- int rd_ofs = neon_reg_offset(a->vd, 0);
84
- int rm_ofs = neon_reg_offset(a->vm, 0);
85
+ int rd_ofs = neon_full_reg_offset(a->vd);
86
+ int rm_ofs = neon_full_reg_offset(a->vm);
87
88
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
89
return false;
90
@@ -XXX,XX +XXX,XX @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
91
{
92
/* FP operations in 2-reg-and-shift group */
93
int vec_size = a->q ? 16 : 8;
94
- int rd_ofs = neon_reg_offset(a->vd, 0);
95
- int rm_ofs = neon_reg_offset(a->vm, 0);
96
+ int rd_ofs = neon_full_reg_offset(a->vd);
97
+ int rm_ofs = neon_full_reg_offset(a->vm);
98
TCGv_ptr fpst;
99
100
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
101
@@ -XXX,XX +XXX,XX @@ static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
102
return true;
103
}
104
105
- reg_ofs = neon_reg_offset(a->vd, 0);
106
+ reg_ofs = neon_full_reg_offset(a->vd);
107
vec_size = a->q ? 16 : 8;
108
imm = asimd_imm_const(a->imm, a->cmode, a->op);
109
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMULL_P_3d(DisasContext *s, arg_3diff *a)
111
return true;
112
}
113
114
- tcg_gen_gvec_3_ool(neon_reg_offset(a->vd, 0),
115
- neon_reg_offset(a->vn, 0),
116
- neon_reg_offset(a->vm, 0),
117
+ tcg_gen_gvec_3_ool(neon_full_reg_offset(a->vd),
118
+ neon_full_reg_offset(a->vn),
119
+ neon_full_reg_offset(a->vm),
120
16, 16, 0, fn_gvec);
121
return true;
122
}
123
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
124
{
125
/* Two registers and a scalar, using gvec */
126
int vec_size = a->q ? 16 : 8;
127
- int rd_ofs = neon_reg_offset(a->vd, 0);
128
- int rn_ofs = neon_reg_offset(a->vn, 0);
129
+ int rd_ofs = neon_full_reg_offset(a->vd);
130
+ int rn_ofs = neon_full_reg_offset(a->vn);
131
int rm_ofs;
132
int idx;
133
TCGv_ptr fpstatus;
134
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
135
/* a->vm is M:Vm, which encodes both register and index */
136
idx = extract32(a->vm, a->size + 2, 2);
137
a->vm = extract32(a->vm, 0, a->size + 2);
138
- rm_ofs = neon_reg_offset(a->vm, 0);
139
+ rm_ofs = neon_full_reg_offset(a->vm);
140
141
fpstatus = fpstatus_ptr(a->size == 1 ? FPST_STD_F16 : FPST_STD);
142
tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpstatus,
143
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
144
return true;
145
}
146
147
- tcg_gen_gvec_dup_mem(a->size, neon_reg_offset(a->vd, 0),
148
+ tcg_gen_gvec_dup_mem(a->size, neon_full_reg_offset(a->vd),
149
neon_element_offset(a->vm, a->index, a->size),
150
a->q ? 16 : 8, a->q ? 16 : 8);
151
return true;
152
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
153
static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
154
{
155
int vec_size = a->q ? 16 : 8;
156
- int rd_ofs = neon_reg_offset(a->vd, 0);
157
- int rm_ofs = neon_reg_offset(a->vm, 0);
158
+ int rd_ofs = neon_full_reg_offset(a->vd);
159
+ int rm_ofs = neon_full_reg_offset(a->vm);
160
161
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
return false;
163
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/translate-vfp.c.inc
166
+++ b/target/arm/translate-vfp.c.inc
167
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
168
}
169
170
tmp = load_reg(s, a->rt);
171
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(a->vn, 0),
172
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(a->vn),
173
vec_size, vec_size, tmp);
174
tcg_temp_free_i32(tmp);
175
176
--
55
--
177
2.20.1
56
2.34.1
178
57
179
58
diff view generated by jsdifflib
1
The kerneldoc script currently emits Sphinx markup for a macro with
1
From: Richard Henderson <richard.henderson@linaro.org>
2
arguments that uses the c:function directive. This is correct for
3
Sphinx versions earlier than Sphinx 3, where c:macro doesn't allow
4
documentation of macros with arguments and c:function is not picky
5
about the syntax of what it is passed. However, in Sphinx 3 the
6
c:macro directive was enhanced to support macros with arguments,
7
and c:function was made more picky about what syntax it accepted.
8
2
9
When kerneldoc is told that it needs to produce output for Sphinx
3
Define the missing SCR and HCR bits, allow SCR_NSE and {SCR,HCR}_GPF
10
3 or later, make it emit c:function only for functions and c:macro
4
to be set, and invalidate TLBs when NSE changes.
11
for macros with arguments. We assume that anything with a return
12
type is a function and anything without is a macro.
13
5
14
This fixes the Sphinx error:
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-3-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 5 +++--
12
target/arm/helper.c | 10 ++++++++--
13
2 files changed, 11 insertions(+), 4 deletions(-)
15
14
16
/home/petmay01/linaro/qemu-from-laptop/qemu/docs/../include/qom/object.h:155:Error in declarator
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
If declarator-id with parameters (e.g., 'void f(int arg)'):
16
index XXXXXXX..XXXXXXX 100644
18
Invalid C declaration: Expected identifier in nested name. [error at 25]
17
--- a/target/arm/cpu.h
19
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
18
+++ b/target/arm/cpu.h
20
-------------------------^
19
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
21
If parenthesis in noptr-declarator (e.g., 'void (*f(int arg))(double)'):
20
#define HCR_TERR (1ULL << 36)
22
Error in declarator or parameters
21
#define HCR_TEA (1ULL << 37)
23
Invalid C declaration: Expecting "(" in parameters. [error at 39]
22
#define HCR_MIOCNCE (1ULL << 38)
24
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
23
-/* RES0 bit 39 */
25
---------------------------------------^
24
+#define HCR_TME (1ULL << 39)
26
25
#define HCR_APK (1ULL << 40)
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
#define HCR_API (1ULL << 41)
28
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
27
#define HCR_NV (1ULL << 42)
29
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
28
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
30
Message-id: 20201030174700.7204-2-peter.maydell@linaro.org
29
#define HCR_NV2 (1ULL << 45)
31
---
30
#define HCR_FWB (1ULL << 46)
32
scripts/kernel-doc | 18 +++++++++++++++++-
31
#define HCR_FIEN (1ULL << 47)
33
1 file changed, 17 insertions(+), 1 deletion(-)
32
-/* RES0 bit 48 */
34
33
+#define HCR_GPF (1ULL << 48)
35
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
34
#define HCR_TID4 (1ULL << 49)
36
index XXXXXXX..XXXXXXX 100755
35
#define HCR_TICAB (1ULL << 50)
37
--- a/scripts/kernel-doc
36
#define HCR_AMVOFFEN (1ULL << 51)
38
+++ b/scripts/kernel-doc
37
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
39
@@ -XXX,XX +XXX,XX @@ sub output_function_rst(%) {
38
#define SCR_TRNDR (1ULL << 40)
40
    output_highlight_rst($args{'purpose'});
39
#define SCR_ENTP2 (1ULL << 41)
41
    $start = "\n\n**Syntax**\n\n ``";
40
#define SCR_GPF (1ULL << 48)
41
+#define SCR_NSE (1ULL << 62)
42
43
#define HSTR_TTEE (1 << 16)
44
#define HSTR_TJDBX (1 << 17)
45
diff --git a/target/arm/helper.c b/target/arm/helper.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/helper.c
48
+++ b/target/arm/helper.c
49
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
50
if (cpu_isar_feature(aa64_fgt, cpu)) {
51
valid_mask |= SCR_FGTEN;
52
}
53
+ if (cpu_isar_feature(aa64_rme, cpu)) {
54
+ valid_mask |= SCR_NSE | SCR_GPF;
55
+ }
42
} else {
56
} else {
43
-    print ".. c:function:: ";
57
valid_mask &= ~(SCR_RW | SCR_ST);
44
+ if ((split(/\./, $sphinx_version))[0] >= 3) {
58
if (cpu_isar_feature(aa32_ras, cpu)) {
45
+ # Sphinx 3 and later distinguish macros and functions and
59
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
46
+ # complain if you use c:function with something that's not
60
env->cp15.scr_el3 = value;
47
+ # syntactically valid as a function declaration.
61
48
+ # We assume that anything with a return type is a function
62
/*
49
+ # and anything without is a macro.
63
- * If SCR_EL3.NS changes, i.e. arm_is_secure_below_el3, then
50
+ if ($args{'functiontype'} ne "") {
64
+ * If SCR_EL3.{NS,NSE} changes, i.e. change of security state,
51
+ print ".. c:function:: ";
65
* we must invalidate all TLBs below EL3.
52
+ } else {
66
*/
53
+ print ".. c:macro:: ";
67
- if (changed & SCR_NS) {
54
+ }
68
+ if (changed & (SCR_NS | SCR_NSE)) {
55
+ } else {
69
tlb_flush_by_mmuidx(env_cpu(env), (ARMMMUIdxBit_E10_0 |
56
+ # Older Sphinx don't support documenting macros that take
70
ARMMMUIdxBit_E20_0 |
57
+ # arguments with c:macro, and don't complain about the use
71
ARMMMUIdxBit_E10_1 |
58
+ # of c:function for this.
72
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
59
+ print ".. c:function:: ";
73
if (cpu_isar_feature(aa64_fwb, cpu)) {
74
valid_mask |= HCR_FWB;
75
}
76
+ if (cpu_isar_feature(aa64_rme, cpu)) {
77
+ valid_mask |= HCR_GPF;
60
+ }
78
+ }
61
}
79
}
62
if ($args{'functiontype'} ne "") {
80
63
    $start .= $args{'functiontype'} . " " . $args{'function'} . " (";
81
if (cpu_isar_feature(any_evt, cpu)) {
64
--
82
--
65
2.20.1
83
2.34.1
66
67
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
HCR should be applied when NS is set, not when it is cleared.
3
With RME, SEL2 must also be present to support secure state.
4
The NS bit is RES1 if SEL2 is not present.
4
5
5
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
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>
8
Message-id: 20230620124418.805717-4-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
target/arm/helper.c | 5 ++---
11
target/arm/helper.c | 3 +++
10
1 file changed, 2 insertions(+), 3 deletions(-)
12
1 file changed, 3 insertions(+)
11
13
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
18
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
17
19
}
18
/*
20
if (cpu_isar_feature(aa64_sel2, cpu)) {
19
* Non-IS variants of TLB operations are upgraded to
21
valid_mask |= SCR_EEL2;
20
- * IS versions if we are at NS EL1 and HCR_EL2.FB is set to
22
+ } else if (cpu_isar_feature(aa64_rme, cpu)) {
21
+ * IS versions if we are at EL1 and HCR_EL2.FB is effectively set to
23
+ /* With RME and without SEL2, NS is RES1 (R_GSWWH, I_DJJQJ). */
22
* force broadcast of these operations.
24
+ value |= SCR_NS;
23
*/
25
}
24
static bool tlb_force_broadcast(CPUARMState *env)
26
if (cpu_isar_feature(aa64_mte, cpu)) {
25
{
27
valid_mask |= SCR_ATA;
26
- return (env->cp15.hcr_el2 & HCR_FB) &&
27
- arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
28
+ return arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_FB);
29
}
30
31
static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
32
--
28
--
33
2.20.1
29
2.34.1
34
35
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Secure mode is not exempted from checking SCR_EL3.TLOR, and in the
3
This includes GPCCR, GPTBR, MFAR, the TLB flush insns PAALL, PAALLOS,
4
future HCR_EL2.TLOR when S-EL2 is enabled.
4
RPALOS, RPAOS, and the cache flush insns CIPAPA and CIGDPAPA.
5
5
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
7
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>
8
Message-id: 20230620124418.805717-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/helper.c | 19 +++++--------------
11
target/arm/cpu.h | 19 ++++++++++
11
1 file changed, 5 insertions(+), 14 deletions(-)
12
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
13
2 files changed, 103 insertions(+)
12
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
20
uint64_t fgt_read[2]; /* HFGRTR, HDFGRTR */
21
uint64_t fgt_write[2]; /* HFGWTR, HDFGWTR */
22
uint64_t fgt_exec[1]; /* HFGITR */
23
+
24
+ /* RME registers */
25
+ uint64_t gpccr_el3;
26
+ uint64_t gptbr_el3;
27
+ uint64_t mfar_el3;
28
} cp15;
29
30
struct {
31
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
32
uint64_t reset_cbar;
33
uint32_t reset_auxcr;
34
bool reset_hivecs;
35
+ uint8_t reset_l0gptsz;
36
37
/*
38
* Intermediate values used during property parsing.
39
@@ -XXX,XX +XXX,XX @@ FIELD(MVFR1, SIMDFMAC, 28, 4)
40
FIELD(MVFR2, SIMDMISC, 0, 4)
41
FIELD(MVFR2, FPMISC, 4, 4)
42
43
+FIELD(GPCCR, PPS, 0, 3)
44
+FIELD(GPCCR, IRGN, 8, 2)
45
+FIELD(GPCCR, ORGN, 10, 2)
46
+FIELD(GPCCR, SH, 12, 2)
47
+FIELD(GPCCR, PGS, 14, 2)
48
+FIELD(GPCCR, GPC, 16, 1)
49
+FIELD(GPCCR, GPCP, 17, 1)
50
+FIELD(GPCCR, L0GPTSZ, 20, 4)
51
+
52
+FIELD(MFAR, FPA, 12, 40)
53
+FIELD(MFAR, NSE, 62, 1)
54
+FIELD(MFAR, NS, 63, 1)
55
+
56
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
57
58
/* If adding a feature bit which corresponds to a Linux ELF
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
61
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
62
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
64
.access = PL2_RW, .accessfn = access_esm,
65
.type = ARM_CP_CONST, .resetvalue = 0 },
66
};
67
+
68
+static void tlbi_aa64_paall_write(CPUARMState *env, const ARMCPRegInfo *ri,
69
+ uint64_t value)
70
+{
71
+ CPUState *cs = env_cpu(env);
72
+
73
+ tlb_flush(cs);
74
+}
75
+
76
+static void gpccr_write(CPUARMState *env, const ARMCPRegInfo *ri,
77
+ uint64_t value)
78
+{
79
+ /* L0GPTSZ is RO; other bits not mentioned are RES0. */
80
+ uint64_t rw_mask = R_GPCCR_PPS_MASK | R_GPCCR_IRGN_MASK |
81
+ R_GPCCR_ORGN_MASK | R_GPCCR_SH_MASK | R_GPCCR_PGS_MASK |
82
+ R_GPCCR_GPC_MASK | R_GPCCR_GPCP_MASK;
83
+
84
+ env->cp15.gpccr_el3 = (value & rw_mask) | (env->cp15.gpccr_el3 & ~rw_mask);
85
+}
86
+
87
+static void gpccr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
88
+{
89
+ env->cp15.gpccr_el3 = FIELD_DP64(0, GPCCR, L0GPTSZ,
90
+ env_archcpu(env)->reset_l0gptsz);
91
+}
92
+
93
+static void tlbi_aa64_paallos_write(CPUARMState *env, const ARMCPRegInfo *ri,
94
+ uint64_t value)
95
+{
96
+ CPUState *cs = env_cpu(env);
97
+
98
+ tlb_flush_all_cpus_synced(cs);
99
+}
100
+
101
+static const ARMCPRegInfo rme_reginfo[] = {
102
+ { .name = "GPCCR_EL3", .state = ARM_CP_STATE_AA64,
103
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 1, .opc2 = 6,
104
+ .access = PL3_RW, .writefn = gpccr_write, .resetfn = gpccr_reset,
105
+ .fieldoffset = offsetof(CPUARMState, cp15.gpccr_el3) },
106
+ { .name = "GPTBR_EL3", .state = ARM_CP_STATE_AA64,
107
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 1, .opc2 = 4,
108
+ .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.gptbr_el3) },
109
+ { .name = "MFAR_EL3", .state = ARM_CP_STATE_AA64,
110
+ .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 5,
111
+ .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mfar_el3) },
112
+ { .name = "TLBI_PAALL", .state = ARM_CP_STATE_AA64,
113
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 4,
114
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
115
+ .writefn = tlbi_aa64_paall_write },
116
+ { .name = "TLBI_PAALLOS", .state = ARM_CP_STATE_AA64,
117
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 4,
118
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
119
+ .writefn = tlbi_aa64_paallos_write },
120
+ /*
121
+ * QEMU does not have a way to invalidate by physical address, thus
122
+ * invalidating a range of physical addresses is accomplished by
123
+ * flushing all tlb entries in the outer sharable domain,
124
+ * just like PAALLOS.
125
+ */
126
+ { .name = "TLBI_RPALOS", .state = ARM_CP_STATE_AA64,
127
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 4, .opc2 = 7,
128
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
129
+ .writefn = tlbi_aa64_paallos_write },
130
+ { .name = "TLBI_RPAOS", .state = ARM_CP_STATE_AA64,
131
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 4, .opc2 = 3,
132
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
133
+ .writefn = tlbi_aa64_paallos_write },
134
+ { .name = "DC_CIPAPA", .state = ARM_CP_STATE_AA64,
135
+ .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 14, .opc2 = 1,
136
+ .access = PL3_W, .type = ARM_CP_NOP },
137
+};
138
+
139
+static const ARMCPRegInfo rme_mte_reginfo[] = {
140
+ { .name = "DC_CIGDPAPA", .state = ARM_CP_STATE_AA64,
141
+ .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 14, .opc2 = 5,
142
+ .access = PL3_W, .type = ARM_CP_NOP },
143
+};
144
#endif /* TARGET_AARCH64 */
145
146
static void define_pmu_regs(ARMCPU *cpu)
147
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
148
if (cpu_isar_feature(aa64_fgt, cpu)) {
149
define_arm_cp_regs(cpu, fgt_reginfo);
150
}
151
+
152
+ if (cpu_isar_feature(aa64_rme, cpu)) {
153
+ define_arm_cp_regs(cpu, rme_reginfo);
154
+ if (cpu_isar_feature(aa64_mte, cpu)) {
155
+ define_arm_cp_regs(cpu, rme_mte_reginfo);
156
+ }
157
+ }
18
#endif
158
#endif
19
159
20
/* Shared logic between LORID and the rest of the LOR* registers.
160
if (cpu_isar_feature(any_predinv, cpu)) {
21
- * Secure state has already been delt with.
22
+ * Secure state exclusion has already been dealt with.
23
*/
24
-static CPAccessResult access_lor_ns(CPUARMState *env)
25
+static CPAccessResult access_lor_ns(CPUARMState *env,
26
+ const ARMCPRegInfo *ri, bool isread)
27
{
28
int el = arm_current_el(env);
29
30
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_ns(CPUARMState *env)
31
return CP_ACCESS_OK;
32
}
33
34
-static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
35
- bool isread)
36
-{
37
- if (arm_is_secure_below_el3(env)) {
38
- /* Access ok in secure mode. */
39
- return CP_ACCESS_OK;
40
- }
41
- return access_lor_ns(env);
42
-}
43
-
44
static CPAccessResult access_lor_other(CPUARMState *env,
45
const ARMCPRegInfo *ri, bool isread)
46
{
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_other(CPUARMState *env,
48
/* Access denied in secure mode. */
49
return CP_ACCESS_TRAP;
50
}
51
- return access_lor_ns(env);
52
+ return access_lor_ns(env, ri, isread);
53
}
54
55
/*
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
57
.type = ARM_CP_CONST, .resetvalue = 0 },
58
{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
59
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
60
- .access = PL1_R, .accessfn = access_lorid,
61
+ .access = PL1_R, .accessfn = access_lor_ns,
62
.type = ARM_CP_CONST, .resetvalue = 0 },
63
REGINFO_SENTINEL
64
};
65
--
161
--
66
2.20.1
162
2.34.1
67
68
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 can then use this to improve VMOV (scalar to gp) and
3
Introduce both the enumeration and functions to retrieve
4
VMOV (gp to scalar) so that we simply perform the memory
4
the current state, and state outside of EL3.
5
operation that we wanted, rather than inserting or
6
extracting from a 32-bit quantity.
7
5
8
These were the last uses of neon_load/store_reg, so remove them.
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20201030022618.785675-7-richard.henderson@linaro.org
8
Message-id: 20230620124418.805717-6-richard.henderson@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
target/arm/translate.c | 50 +++++++++++++-----------
11
target/arm/cpu.h | 89 ++++++++++++++++++++++++++++++++++-----------
16
target/arm/translate-vfp.c.inc | 71 +++++-----------------------------
12
target/arm/helper.c | 60 ++++++++++++++++++++++++++++++
17
2 files changed, 37 insertions(+), 84 deletions(-)
13
2 files changed, 127 insertions(+), 22 deletions(-)
18
14
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate.c
17
--- a/target/arm/cpu.h
22
+++ b/target/arm/translate.c
18
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
19
@@ -XXX,XX +XXX,XX @@ static inline int arm_feature(CPUARMState *env, int feature)
24
* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
20
25
* where 0 is the least significant end of the register.
21
void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp);
22
23
-#if !defined(CONFIG_USER_ONLY)
24
/*
25
+ * ARM v9 security states.
26
+ * The ordering of the enumeration corresponds to the low 2 bits
27
+ * of the GPI value, and (except for Root) the concat of NSE:NS.
28
+ */
29
+
30
+typedef enum ARMSecuritySpace {
31
+ ARMSS_Secure = 0,
32
+ ARMSS_NonSecure = 1,
33
+ ARMSS_Root = 2,
34
+ ARMSS_Realm = 3,
35
+} ARMSecuritySpace;
36
+
37
+/* Return true if @space is secure, in the pre-v9 sense. */
38
+static inline bool arm_space_is_secure(ARMSecuritySpace space)
39
+{
40
+ return space == ARMSS_Secure || space == ARMSS_Root;
41
+}
42
+
43
+/* Return the ARMSecuritySpace for @secure, assuming !RME or EL[0-2]. */
44
+static inline ARMSecuritySpace arm_secure_to_space(bool secure)
45
+{
46
+ return secure ? ARMSS_Secure : ARMSS_NonSecure;
47
+}
48
+
49
+#if !defined(CONFIG_USER_ONLY)
50
+/**
51
+ * arm_security_space_below_el3:
52
+ * @env: cpu context
53
+ *
54
+ * Return the security space of exception levels below EL3, following
55
+ * an exception return to those levels. Unlike arm_security_space,
56
+ * this doesn't care about the current EL.
57
+ */
58
+ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env);
59
+
60
+/**
61
+ * arm_is_secure_below_el3:
62
+ * @env: cpu context
63
+ *
64
* Return true if exception levels below EL3 are in secure state,
65
- * or would be following an exception return to that level.
66
- * Unlike arm_is_secure() (which is always a question about the
67
- * _current_ state of the CPU) this doesn't care about the current
68
- * EL or mode.
69
+ * or would be following an exception return to those levels.
26
*/
70
*/
27
-static long neon_element_offset(int reg, int element, MemOp size)
71
static inline bool arm_is_secure_below_el3(CPUARMState *env)
28
+static long neon_element_offset(int reg, int element, MemOp memop)
72
{
29
{
73
- assert(!arm_feature(env, ARM_FEATURE_M));
30
- int element_size = 1 << size;
74
- if (arm_feature(env, ARM_FEATURE_EL3)) {
31
+ int element_size = 1 << (memop & MO_SIZE);
75
- return !(env->cp15.scr_el3 & SCR_NS);
32
int ofs = element * element_size;
76
- } else {
33
#ifdef HOST_WORDS_BIGENDIAN
77
- /* If EL3 is not supported then the secure state is implementation
34
/*
78
- * defined, in which case QEMU defaults to non-secure.
35
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
79
- */
80
- return false;
81
- }
82
+ ARMSecuritySpace ss = arm_security_space_below_el3(env);
83
+ return ss == ARMSS_Secure;
84
}
85
86
/* Return true if the CPU is AArch64 EL3 or AArch32 Mon */
87
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el3_or_mon(CPUARMState *env)
88
return false;
89
}
90
91
-/* Return true if the processor is in secure state */
92
+/**
93
+ * arm_security_space:
94
+ * @env: cpu context
95
+ *
96
+ * Return the current security space of the cpu.
97
+ */
98
+ARMSecuritySpace arm_security_space(CPUARMState *env);
99
+
100
+/**
101
+ * arm_is_secure:
102
+ * @env: cpu context
103
+ *
104
+ * Return true if the processor is in secure state.
105
+ */
106
static inline bool arm_is_secure(CPUARMState *env)
107
{
108
- if (arm_feature(env, ARM_FEATURE_M)) {
109
- return env->v7m.secure;
110
- }
111
- if (arm_is_el3_or_mon(env)) {
112
- return true;
113
- }
114
- return arm_is_secure_below_el3(env);
115
+ return arm_space_is_secure(arm_security_space(env));
116
}
117
118
/*
119
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
120
}
121
122
#else
123
+static inline ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
124
+{
125
+ return ARMSS_NonSecure;
126
+}
127
+
128
static inline bool arm_is_secure_below_el3(CPUARMState *env)
129
{
130
return false;
131
}
132
133
+static inline ARMSecuritySpace arm_security_space(CPUARMState *env)
134
+{
135
+ return ARMSS_NonSecure;
136
+}
137
+
138
static inline bool arm_is_secure(CPUARMState *env)
139
{
140
return false;
141
diff --git a/target/arm/helper.c b/target/arm/helper.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/target/arm/helper.c
144
+++ b/target/arm/helper.c
145
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
36
}
146
}
37
}
147
}
38
148
#endif
39
-static TCGv_i32 neon_load_reg(int reg, int pass)
149
+
40
-{
150
+#ifndef CONFIG_USER_ONLY
41
- TCGv_i32 tmp = tcg_temp_new_i32();
151
+ARMSecuritySpace arm_security_space(CPUARMState *env)
42
- tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
152
+{
43
- return tmp;
153
+ if (arm_feature(env, ARM_FEATURE_M)) {
44
-}
154
+ return arm_secure_to_space(env->v7m.secure);
45
-
155
+ }
46
-static void neon_store_reg(int reg, int pass, TCGv_i32 var)
156
+
47
-{
157
+ /*
48
- tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
158
+ * If EL3 is not supported then the secure state is implementation
49
- tcg_temp_free_i32(var);
159
+ * defined, in which case QEMU defaults to non-secure.
50
-}
160
+ */
51
-
161
+ if (!arm_feature(env, ARM_FEATURE_EL3)) {
52
static inline void neon_load_reg64(TCGv_i64 var, int reg)
162
+ return ARMSS_NonSecure;
53
{
163
+ }
54
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
164
+
55
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
165
+ /* Check for AArch64 EL3 or AArch32 Mon. */
56
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
166
+ if (is_a64(env)) {
57
}
167
+ if (extract32(env->pstate, 2, 2) == 3) {
58
168
+ if (cpu_isar_feature(aa64_rme, env_archcpu(env))) {
59
-static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
169
+ return ARMSS_Root;
60
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
170
+ } else {
61
{
171
+ return ARMSS_Secure;
62
- long off = neon_element_offset(reg, ele, size);
172
+ }
63
+ long off = neon_element_offset(reg, ele, memop);
173
+ }
64
174
+ } else {
65
- switch (size) {
175
+ if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
66
- case MO_32:
176
+ return ARMSS_Secure;
67
+ switch (memop) {
177
+ }
68
+ case MO_SB:
178
+ }
69
+ tcg_gen_ld8s_i32(dest, cpu_env, off);
179
+
70
+ break;
180
+ return arm_security_space_below_el3(env);
71
+ case MO_UB:
181
+}
72
+ tcg_gen_ld8u_i32(dest, cpu_env, off);
182
+
73
+ break;
183
+ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
74
+ case MO_SW:
184
+{
75
+ tcg_gen_ld16s_i32(dest, cpu_env, off);
185
+ assert(!arm_feature(env, ARM_FEATURE_M));
76
+ break;
186
+
77
+ case MO_UW:
187
+ /*
78
+ tcg_gen_ld16u_i32(dest, cpu_env, off);
188
+ * If EL3 is not supported then the secure state is implementation
79
+ break;
189
+ * defined, in which case QEMU defaults to non-secure.
80
+ case MO_UL:
190
+ */
81
+ case MO_SL:
191
+ if (!arm_feature(env, ARM_FEATURE_EL3)) {
82
tcg_gen_ld_i32(dest, cpu_env, off);
192
+ return ARMSS_NonSecure;
83
break;
193
+ }
84
default:
194
+
85
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
195
+ /*
86
}
196
+ * Note NSE cannot be set without RME, and NSE & !NS is Reserved.
87
}
197
+ * Ignoring NSE when !NS retains consistency without having to
88
198
+ * modify other predicates.
89
-static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
199
+ */
90
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
200
+ if (!(env->cp15.scr_el3 & SCR_NS)) {
91
{
201
+ return ARMSS_Secure;
92
- long off = neon_element_offset(reg, ele, size);
202
+ } else if (env->cp15.scr_el3 & SCR_NSE) {
93
+ long off = neon_element_offset(reg, ele, memop);
203
+ return ARMSS_Realm;
94
204
+ } else {
95
- switch (size) {
205
+ return ARMSS_NonSecure;
96
+ switch (memop) {
206
+ }
97
+ case MO_8:
207
+}
98
+ tcg_gen_st8_i32(src, cpu_env, off);
208
+#endif /* !CONFIG_USER_ONLY */
99
+ break;
100
+ case MO_16:
101
+ tcg_gen_st16_i32(src, cpu_env, off);
102
+ break;
103
case MO_32:
104
tcg_gen_st_i32(src, cpu_env, off);
105
break;
106
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-vfp.c.inc
109
+++ b/target/arm/translate-vfp.c.inc
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
111
{
112
/* VMOV scalar to general purpose register */
113
TCGv_i32 tmp;
114
- int pass;
115
- uint32_t offset;
116
117
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
118
- if (a->size == 2
119
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
120
+ if (a->size == MO_32
121
? !dc_isar_feature(aa32_fpsp_v2, s)
122
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
123
return false;
124
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
125
return false;
126
}
127
128
- offset = a->index << a->size;
129
- pass = extract32(offset, 2, 1);
130
- offset = extract32(offset, 0, 2) * 8;
131
-
132
if (!vfp_access_check(s)) {
133
return true;
134
}
135
136
- tmp = neon_load_reg(a->vn, pass);
137
- switch (a->size) {
138
- case 0:
139
- if (offset) {
140
- tcg_gen_shri_i32(tmp, tmp, offset);
141
- }
142
- if (a->u) {
143
- gen_uxtb(tmp);
144
- } else {
145
- gen_sxtb(tmp);
146
- }
147
- break;
148
- case 1:
149
- if (a->u) {
150
- if (offset) {
151
- tcg_gen_shri_i32(tmp, tmp, 16);
152
- } else {
153
- gen_uxth(tmp);
154
- }
155
- } else {
156
- if (offset) {
157
- tcg_gen_sari_i32(tmp, tmp, 16);
158
- } else {
159
- gen_sxth(tmp);
160
- }
161
- }
162
- break;
163
- case 2:
164
- break;
165
- }
166
+ tmp = tcg_temp_new_i32();
167
+ read_neon_element32(tmp, a->vn, a->index, a->size | (a->u ? 0 : MO_SIGN));
168
store_reg(s, a->rt, tmp);
169
170
return true;
171
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
172
static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
173
{
174
/* VMOV general purpose register to scalar */
175
- TCGv_i32 tmp, tmp2;
176
- int pass;
177
- uint32_t offset;
178
+ TCGv_i32 tmp;
179
180
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
181
- if (a->size == 2
182
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
183
+ if (a->size == MO_32
184
? !dc_isar_feature(aa32_fpsp_v2, s)
185
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
186
return false;
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
188
return false;
189
}
190
191
- offset = a->index << a->size;
192
- pass = extract32(offset, 2, 1);
193
- offset = extract32(offset, 0, 2) * 8;
194
-
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
199
tmp = load_reg(s, a->rt);
200
- switch (a->size) {
201
- case 0:
202
- tmp2 = neon_load_reg(a->vn, pass);
203
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
204
- tcg_temp_free_i32(tmp2);
205
- break;
206
- case 1:
207
- tmp2 = neon_load_reg(a->vn, pass);
208
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
209
- tcg_temp_free_i32(tmp2);
210
- break;
211
- case 2:
212
- break;
213
- }
214
- neon_store_reg(a->vn, pass, tmp);
215
+ write_neon_element32(tmp, a->vn, a->index, a->size);
216
+ tcg_temp_free_i32(tmp);
217
218
return true;
219
}
220
--
209
--
221
2.20.1
210
2.34.1
222
223
diff view generated by jsdifflib
1
The randomness tests in the NPCM7xx RNG test fail intermittently
1
From: Richard Henderson <richard.henderson@linaro.org>
2
but fairly frequently. On my machine running the test in a loop:
3
while QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/npcm7xx_rng-test; do true; done
4
2
5
will fail in less than a minute with an error like:
3
We will need 2 bits to represent ARMSecurityState.
6
ERROR:../../tests/qtest/npcm7xx_rng-test.c:256:test_first_byte_runs:
7
assertion failed (calc_runs_p(buf.l, sizeof(buf) * BITS_PER_BYTE) > 0.01): (0.00286205989 > 0.01)
8
4
9
(Failures have been observed on all 4 of the randomness tests,
5
Do not attempt to replace or widen secure, even though it
10
not just first_byte_runs.)
6
logically overlaps the new field -- there are uses within
7
e.g. hw/block/pflash_cfi01.c, which don't know anything
8
specific about ARM.
11
9
12
It's not clear why these tests are failing like this, but intermittent
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
failures make CI and merge testing awkward, so disable running them
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
unless a developer specifically sets QEMU_TEST_FLAKY_RNG_TESTS when
12
Message-id: 20230620124418.805717-7-richard.henderson@linaro.org
15
running the test suite, until we work out the cause.
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/exec/memattrs.h | 9 ++++++++-
16
1 file changed, 8 insertions(+), 1 deletion(-)
16
17
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Message-id: 20201102152454.8287-1-peter.maydell@linaro.org
20
Reviewed-by: Havard Skinnemoen <hskinnemoen@google.com>
21
---
22
tests/qtest/npcm7xx_rng-test.c | 14 ++++++++++----
23
1 file changed, 10 insertions(+), 4 deletions(-)
24
25
diff --git a/tests/qtest/npcm7xx_rng-test.c b/tests/qtest/npcm7xx_rng-test.c
26
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/qtest/npcm7xx_rng-test.c
20
--- a/include/exec/memattrs.h
28
+++ b/tests/qtest/npcm7xx_rng-test.c
21
+++ b/include/exec/memattrs.h
29
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
22
@@ -XXX,XX +XXX,XX @@ typedef struct MemTxAttrs {
30
23
* "didn't specify" if necessary.
31
qtest_add_func("npcm7xx_rng/enable_disable", test_enable_disable);
24
*/
32
qtest_add_func("npcm7xx_rng/rosel", test_rosel);
25
unsigned int unspecified:1;
33
- qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
26
- /* ARM/AMBA: TrustZone Secure access
34
- qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
35
- qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
36
- qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
37
+ /*
27
+ /*
38
+ * These tests fail intermittently; only run them on explicit
28
+ * ARM/AMBA: TrustZone Secure access
39
+ * request until we figure out why.
29
* x86: System Management Mode access
30
*/
31
unsigned int secure:1;
32
+ /*
33
+ * ARM: ArmSecuritySpace. This partially overlaps secure, but it is
34
+ * easier to have both fields to assist code that does not understand
35
+ * ARMv9 RME, or no specific knowledge of ARM at all (e.g. pflash).
40
+ */
36
+ */
41
+ if (getenv("QEMU_TEST_FLAKY_RNG_TESTS")) {
37
+ unsigned int space:2;
42
+ qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
38
/* Memory access is usermode (unprivileged) */
43
+ qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
39
unsigned int user:1;
44
+ qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
40
/*
45
+ qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
46
+ }
47
48
qtest_start("-machine npcm750-evb");
49
ret = g_test_run();
50
--
41
--
51
2.20.1
42
2.34.1
52
53
diff view generated by jsdifflib
1
Sphinx 3.2 is pickier than earlier versions about the option:: markup,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and complains about our usage in qemu-option-trace.rst:
3
2
4
../../docs/qemu-option-trace.rst.inc:4:Malformed option description
3
It will be helpful to have ARMMMUIdx_Phys_* to be in the same
5
'[enable=]PATTERN', should look like "opt", "-opt args", "--opt args",
4
relative order as ARMSecuritySpace enumerators. This requires
6
"/opt args" or "+opt args"
5
the adjustment to the nstable check. While there, check for being
6
in secure state rather than rely on clearing the low bit making
7
no change to non-secure state.
7
8
8
In this file, we're really trying to document the different parts of
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
the top-level --trace option, which qemu-nbd.rst and qemu-img.rst
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
have already introduced with an option:: markup. So it's not right
11
Message-id: 20230620124418.805717-8-richard.henderson@linaro.org
11
to use option:: here anyway. Switch to a different markup
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
(definition lists) which gives about the same formatted output.
13
---
14
target/arm/cpu.h | 12 ++++++------
15
target/arm/ptw.c | 12 +++++-------
16
2 files changed, 11 insertions(+), 13 deletions(-)
13
17
14
(Unlike option::, this markup doesn't produce index entries; but
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
at the moment we don't do anything much with indexes anyway, and
16
in any case I think it doesn't make much sense to have individual
17
index entries for the sub-parts of the --trace option.)
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
21
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Message-id: 20201030174700.7204-3-peter.maydell@linaro.org
23
---
24
docs/qemu-option-trace.rst.inc | 6 +++---
25
1 file changed, 3 insertions(+), 3 deletions(-)
26
27
diff --git a/docs/qemu-option-trace.rst.inc b/docs/qemu-option-trace.rst.inc
28
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
29
--- a/docs/qemu-option-trace.rst.inc
20
--- a/target/arm/cpu.h
30
+++ b/docs/qemu-option-trace.rst.inc
21
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
32
23
ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A,
33
Specify tracing options.
24
ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A,
34
25
35
-.. option:: [enable=]PATTERN
26
- /* TLBs with 1-1 mapping to the physical address spaces. */
36
+``[enable=]PATTERN``
27
- ARMMMUIdx_Phys_NS = 8 | ARM_MMU_IDX_A,
37
28
- ARMMMUIdx_Phys_S = 9 | ARM_MMU_IDX_A,
38
Immediately enable events matching *PATTERN*
29
-
39
(either event name or a globbing pattern). This option is only
30
/*
40
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
31
* Used for second stage of an S12 page table walk, or for descriptor
41
32
* loads during first stage of an S1 page table walk. Note that both
42
Use :option:`-trace help` to print a list of names of trace points.
33
* are in use simultaneously for SecureEL2: the security state for
43
34
* the S2 ptw is selected by the NS bit from the S1 ptw.
44
-.. option:: events=FILE
35
*/
45
+``events=FILE``
36
- ARMMMUIdx_Stage2 = 10 | ARM_MMU_IDX_A,
46
37
- ARMMMUIdx_Stage2_S = 11 | ARM_MMU_IDX_A,
47
Immediately enable events listed in *FILE*.
38
+ ARMMMUIdx_Stage2_S = 8 | ARM_MMU_IDX_A,
48
The file must contain one event name (as listed in the ``trace-events-all``
39
+ ARMMMUIdx_Stage2 = 9 | ARM_MMU_IDX_A,
49
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
40
+
50
available if QEMU has been compiled with the ``simple``, ``log`` or
41
+ /* TLBs with 1-1 mapping to the physical address spaces. */
51
``ftrace`` tracing backend.
42
+ ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
52
43
+ ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
53
-.. option:: file=FILE
44
54
+``file=FILE``
45
/*
55
46
* These are not allocated TLBs and are used only for AT system
56
Log output traces to *FILE*.
47
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
57
This option is only available if QEMU has been compiled with
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/ptw.c
50
+++ b/target/arm/ptw.c
51
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
52
descaddr |= (address >> (stride * (4 - level))) & indexmask;
53
descaddr &= ~7ULL;
54
nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
55
- if (nstable) {
56
+ if (nstable && ptw->in_secure) {
57
/*
58
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
59
- * Assert that the non-secure idx are even, and relative order.
60
+ * Assert the relative order of the secure/non-secure indexes.
61
*/
62
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
63
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
64
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
65
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
66
- ptw->in_ptw_idx &= ~1;
67
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_S + 1 != ARMMMUIdx_Phys_NS);
68
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2);
69
+ ptw->in_ptw_idx += 1;
70
ptw->in_secure = false;
71
}
72
if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
58
--
73
--
59
2.20.1
74
2.34.1
60
61
diff view generated by jsdifflib
1
In gicv3_init_cpuif() we copy the ARMCPU gicv3_maintenance_interrupt
1
From: Richard Henderson <richard.henderson@linaro.org>
2
into the GICv3CPUState struct's maintenance_irq field. This will
3
only work if the board happens to have already wired up the CPU
4
maintenance IRQ before the GIC was realized. Unfortunately this is
5
not the case for the 'virt' board, and so the value that gets copied
6
is NULL (since a qemu_irq is really a pointer to an IRQState struct
7
under the hood). The effect is that the CPU interface code never
8
actually raises the maintenance interrupt line.
9
2
10
Instead, since the GICv3CPUState has a pointer to the CPUState, make
3
With FEAT_RME, there are four physical address spaces.
11
the dereference at the point where we want to raise the interrupt, to
4
For now, just define the symbols, and mention them in
12
avoid an implicit requirement on board code to wire things up in a
5
the same spots as the other Phys indexes in ptw.c.
13
particular order.
14
6
15
Reported-by: Jose Martins <josemartins90@gmail.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620124418.805717-9-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20201009153904.28529-1-peter.maydell@linaro.org
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
19
---
12
---
20
include/hw/intc/arm_gicv3_common.h | 1 -
13
target/arm/cpu.h | 23 +++++++++++++++++++++--
21
hw/intc/arm_gicv3_cpuif.c | 5 ++---
14
target/arm/ptw.c | 10 ++++++++--
22
2 files changed, 2 insertions(+), 4 deletions(-)
15
2 files changed, 29 insertions(+), 4 deletions(-)
23
16
24
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/intc/arm_gicv3_common.h
19
--- a/target/arm/cpu.h
27
+++ b/include/hw/intc/arm_gicv3_common.h
20
+++ b/target/arm/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
21
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
29
qemu_irq parent_fiq;
22
ARMMMUIdx_Stage2 = 9 | ARM_MMU_IDX_A,
30
qemu_irq parent_virq;
23
31
qemu_irq parent_vfiq;
24
/* TLBs with 1-1 mapping to the physical address spaces. */
32
- qemu_irq maintenance_irq;
25
- ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
33
26
- ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
34
/* Redistributor */
27
+ ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
35
uint32_t level; /* Current IRQ level */
28
+ ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
36
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
29
+ ARMMMUIdx_Phys_Root = 12 | ARM_MMU_IDX_A,
30
+ ARMMMUIdx_Phys_Realm = 13 | ARM_MMU_IDX_A,
31
32
/*
33
* These are not allocated TLBs and are used only for AT system
34
@@ -XXX,XX +XXX,XX @@ typedef enum ARMASIdx {
35
ARMASIdx_TagS = 3,
36
} ARMASIdx;
37
38
+static inline ARMMMUIdx arm_space_to_phys(ARMSecuritySpace space)
39
+{
40
+ /* Assert the relative order of the physical mmu indexes. */
41
+ QEMU_BUILD_BUG_ON(ARMSS_Secure != 0);
42
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS != ARMMMUIdx_Phys_S + ARMSS_NonSecure);
43
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_Root != ARMMMUIdx_Phys_S + ARMSS_Root);
44
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_Realm != ARMMMUIdx_Phys_S + ARMSS_Realm);
45
+
46
+ return ARMMMUIdx_Phys_S + space;
47
+}
48
+
49
+static inline ARMSecuritySpace arm_phys_to_space(ARMMMUIdx idx)
50
+{
51
+ assert(idx >= ARMMMUIdx_Phys_S && idx <= ARMMMUIdx_Phys_Realm);
52
+ return idx - ARMMMUIdx_Phys_S;
53
+}
54
+
55
static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
56
{
57
/* If all the CLIDR.Ctypem bits are 0 there are no caches, and
58
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
37
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/arm_gicv3_cpuif.c
60
--- a/target/arm/ptw.c
39
+++ b/hw/intc/arm_gicv3_cpuif.c
61
+++ b/target/arm/ptw.c
40
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
62
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
41
int irqlevel = 0;
63
case ARMMMUIdx_E3:
42
int fiqlevel = 0;
64
break;
43
int maintlevel = 0;
65
44
+ ARMCPU *cpu = ARM_CPU(cs->cpu);
66
- case ARMMMUIdx_Phys_NS:
45
67
case ARMMMUIdx_Phys_S:
46
idx = hppvi_index(cs);
68
+ case ARMMMUIdx_Phys_NS:
47
trace_gicv3_cpuif_virt_update(gicv3_redist_affid(cs), idx);
69
+ case ARMMMUIdx_Phys_Root:
48
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
70
+ case ARMMMUIdx_Phys_Realm:
49
71
/* No translation for physical address spaces. */
50
qemu_set_irq(cs->parent_vfiq, fiqlevel);
72
return true;
51
qemu_set_irq(cs->parent_virq, irqlevel);
73
52
- qemu_set_irq(cs->maintenance_irq, maintlevel);
74
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
53
+ qemu_set_irq(cpu->gicv3_maintenance_interrupt, maintlevel);
75
switch (mmu_idx) {
54
}
76
case ARMMMUIdx_Stage2:
55
77
case ARMMMUIdx_Stage2_S:
56
static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
78
- case ARMMMUIdx_Phys_NS:
57
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
79
case ARMMMUIdx_Phys_S:
58
&& cpu->gic_num_lrs) {
80
+ case ARMMMUIdx_Phys_NS:
59
int j;
81
+ case ARMMMUIdx_Phys_Root:
60
82
+ case ARMMMUIdx_Phys_Realm:
61
- cs->maintenance_irq = cpu->gicv3_maintenance_interrupt;
83
break;
62
-
84
63
cs->num_list_regs = cpu->gic_num_lrs;
85
default:
64
cs->vpribits = cpu->gic_vpribits;
86
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
65
cs->vprebits = cpu->gic_vprebits;
87
switch (mmu_idx) {
88
case ARMMMUIdx_Phys_S:
89
case ARMMMUIdx_Phys_NS:
90
+ case ARMMMUIdx_Phys_Root:
91
+ case ARMMMUIdx_Phys_Realm:
92
/* Checking Phys early avoids special casing later vs regime_el. */
93
return get_phys_addr_disabled(env, address, access_type, mmu_idx,
94
is_secure, result, fi);
66
--
95
--
67
2.20.1
96
2.34.1
68
97
69
98
diff view generated by jsdifflib
1
On some hosts (eg Ubuntu Bionic) pkg-config returns a set of
1
From: Richard Henderson <richard.henderson@linaro.org>
2
libraries for gio-2.0 which don't actually work when compiling
3
statically. (Specifically, the returned library string includes
4
-lmount, but not -lblkid which -lmount depends upon, so linking
5
fails due to missing symbols.)
6
2
7
Check that the libraries work, and don't enable gio if they don't,
3
This was added in 7e98e21c098 as part of a reorg in which
8
in the same way we do for gnutls.
4
one of the argument had been legally NULL, and this caught
5
actual instances. Now that the reorg is complete, this
6
serves little purpose.
9
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20230620124418.805717-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20200928160402.7961-1-peter.maydell@linaro.org
14
---
13
---
15
configure | 10 +++++++++-
14
target/arm/ptw.c | 6 ++----
16
1 file changed, 9 insertions(+), 1 deletion(-)
15
1 file changed, 2 insertions(+), 4 deletions(-)
17
16
18
diff --git a/configure b/configure
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
19
index XXXXXXX..XXXXXXX 100755
18
index XXXXXXX..XXXXXXX 100644
20
--- a/configure
19
--- a/target/arm/ptw.c
21
+++ b/configure
20
+++ b/target/arm/ptw.c
22
@@ -XXX,XX +XXX,XX @@ if test "$static" = yes && test "$mingw32" = yes; then
21
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
23
fi
22
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
24
23
uint64_t address,
25
if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
24
MMUAccessType access_type, bool s1_is_el0,
26
- gio=yes
25
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
27
gio_cflags=$($pkg_config --cflags gio-2.0)
26
- __attribute__((nonnull));
28
gio_libs=$($pkg_config --libs gio-2.0)
27
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
29
gdbus_codegen=$($pkg_config --variable=gdbus_codegen gio-2.0)
28
30
if [ ! -x "$gdbus_codegen" ]; then
29
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
31
gdbus_codegen=
30
target_ulong address,
32
fi
31
MMUAccessType access_type,
33
+ # Check that the libraries actually work -- Ubuntu 18.04 ships
32
GetPhysAddrResult *result,
34
+ # with pkg-config --static --libs data for gio-2.0 that is missing
33
- ARMMMUFaultInfo *fi)
35
+ # -lblkid and will give a link error.
34
- __attribute__((nonnull));
36
+ write_c_skeleton
35
+ ARMMMUFaultInfo *fi);
37
+ if compile_prog "" "gio_libs" ; then
36
38
+ gio=yes
37
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
39
+ else
38
static const uint8_t pamax_map[] = {
40
+ gio=no
41
+ fi
42
else
43
gio=no
44
fi
45
--
39
--
46
2.20.1
40
2.34.1
47
41
48
42
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 can use proper widening loads to extend 32-bit inputs,
3
Add input and output space members to S1Translate. Set and adjust
4
and skip the "widenfn" step.
4
them in S1_ptw_translate, and the various points at which we drop
5
secure state. Initialize the space in get_phys_addr; for now leave
6
get_phys_addr_with_secure considering only secure vs non-secure spaces.
5
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-12-richard.henderson@linaro.org
10
Message-id: 20230620124418.805717-11-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/translate.c | 6 +++
13
target/arm/ptw.c | 86 +++++++++++++++++++++++++++++++++++++++---------
12
target/arm/translate-neon.c.inc | 66 ++++++++++++++++++---------------
14
1 file changed, 71 insertions(+), 15 deletions(-)
13
2 files changed, 43 insertions(+), 29 deletions(-)
14
15
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
18
--- a/target/arm/ptw.c
18
+++ b/target/arm/translate.c
19
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@ static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
20
@@ -XXX,XX +XXX,XX @@
20
long off = neon_element_offset(reg, ele, memop);
21
typedef struct S1Translate {
21
22
ARMMMUIdx in_mmu_idx;
22
switch (memop) {
23
ARMMMUIdx in_ptw_idx;
23
+ case MO_SL:
24
+ ARMSecuritySpace in_space;
24
+ tcg_gen_ld32s_i64(dest, cpu_env, off);
25
bool in_secure;
25
+ break;
26
bool in_debug;
26
+ case MO_UL:
27
bool out_secure;
27
+ tcg_gen_ld32u_i64(dest, cpu_env, off);
28
bool out_rw;
28
+ break;
29
bool out_be;
29
case MO_Q:
30
+ ARMSecuritySpace out_space;
30
tcg_gen_ld_i64(dest, cpu_env, off);
31
hwaddr out_virt;
31
break;
32
hwaddr out_phys;
32
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
33
void *out_host;
33
index XXXXXXX..XXXXXXX 100644
34
@@ -XXX,XX +XXX,XX @@ static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
34
--- a/target/arm/translate-neon.c.inc
35
static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
35
+++ b/target/arm/translate-neon.c.inc
36
hwaddr addr, ARMMMUFaultInfo *fi)
36
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1reg_imm *a)
37
static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
38
NeonGenWidenFn *widenfn,
39
NeonGenTwo64OpFn *opfn,
40
- bool src1_wide)
41
+ int src1_mop, int src2_mop)
42
{
37
{
43
/* 3-regs different lengths, prewidening case (VADDL/VSUBL/VAADW/VSUBW) */
38
+ ARMSecuritySpace space = ptw->in_space;
44
TCGv_i64 rn0_64, rn1_64, rm_64;
39
bool is_secure = ptw->in_secure;
45
- TCGv_i32 rm;
40
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
46
41
ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
47
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
42
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
48
return false;
43
.in_mmu_idx = s2_mmu_idx,
49
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
44
.in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
50
return false;
45
.in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
51
}
46
+ .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
52
47
+ : space == ARMSS_Realm ? ARMSS_Realm
53
- if (!widenfn || !opfn) {
48
+ : ARMSS_NonSecure),
54
+ if (!opfn) {
49
.in_debug = true,
55
/* size == 3 case, which is an entirely different insn group */
50
};
56
return false;
51
GetPhysAddrResult s2 = { };
57
}
52
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
58
53
ptw->out_phys = s2.f.phys_addr;
59
- if ((a->vd & 1) || (src1_wide && (a->vn & 1))) {
54
pte_attrs = s2.cacheattrs.attrs;
60
+ if ((a->vd & 1) || (src1_mop == MO_Q && (a->vn & 1))) {
55
ptw->out_secure = s2.f.attrs.secure;
61
return false;
56
+ ptw->out_space = s2.f.attrs.space;
62
}
57
} else {
63
58
/* Regime is physical. */
64
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
59
ptw->out_phys = addr;
65
rn1_64 = tcg_temp_new_i64();
60
pte_attrs = 0;
66
rm_64 = tcg_temp_new_i64();
61
ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
67
62
+ ptw->out_space = (s2_mmu_idx == ARMMMUIdx_Phys_S ? ARMSS_Secure
68
- if (src1_wide) {
63
+ : space == ARMSS_Realm ? ARMSS_Realm
69
- read_neon_element64(rn0_64, a->vn, 0, MO_64);
64
+ : ARMSS_NonSecure);
70
+ if (src1_mop >= 0) {
65
}
71
+ read_neon_element64(rn0_64, a->vn, 0, src1_mop);
66
ptw->out_host = NULL;
67
ptw->out_rw = false;
68
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
69
ptw->out_rw = full->prot & PAGE_WRITE;
70
pte_attrs = full->pte_attrs;
71
ptw->out_secure = full->attrs.secure;
72
+ ptw->out_space = full->attrs.space;
73
#else
74
g_assert_not_reached();
75
#endif
76
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw,
77
}
72
} else {
78
} else {
73
TCGv_i32 tmp = tcg_temp_new_i32();
79
/* Page tables are in MMIO. */
74
read_neon_element32(tmp, a->vn, 0, MO_32);
80
- MemTxAttrs attrs = { .secure = ptw->out_secure };
75
widenfn(rn0_64, tmp);
81
+ MemTxAttrs attrs = {
76
tcg_temp_free_i32(tmp);
82
+ .secure = ptw->out_secure,
77
}
83
+ .space = ptw->out_space,
78
- rm = tcg_temp_new_i32();
84
+ };
79
- read_neon_element32(rm, a->vm, 0, MO_32);
85
AddressSpace *as = arm_addressspace(cs, attrs);
80
+ if (src2_mop >= 0) {
86
MemTxResult result = MEMTX_OK;
81
+ read_neon_element64(rm_64, a->vm, 0, src2_mop);
87
82
+ } else {
88
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
83
+ TCGv_i32 tmp = tcg_temp_new_i32();
89
#endif
84
+ read_neon_element32(tmp, a->vm, 0, MO_32);
90
} else {
85
+ widenfn(rm_64, tmp);
91
/* Page tables are in MMIO. */
86
+ tcg_temp_free_i32(tmp);
92
- MemTxAttrs attrs = { .secure = ptw->out_secure };
87
+ }
93
+ MemTxAttrs attrs = {
88
94
+ .secure = ptw->out_secure,
89
- widenfn(rm_64, rm);
95
+ .space = ptw->out_space,
90
- tcg_temp_free_i32(rm);
96
+ };
91
opfn(rn0_64, rn0_64, rm_64);
97
AddressSpace *as = arm_addressspace(cs, attrs);
98
MemTxResult result = MEMTX_OK;
99
100
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
101
* regime, because the attribute will already be non-secure.
102
*/
103
result->f.attrs.secure = false;
104
+ result->f.attrs.space = ARMSS_NonSecure;
105
}
106
result->f.phys_addr = phys_addr;
107
return false;
108
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
109
* regime, because the attribute will already be non-secure.
110
*/
111
result->f.attrs.secure = false;
112
+ result->f.attrs.space = ARMSS_NonSecure;
113
}
114
115
if (regime_is_stage2(mmu_idx)) {
116
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
117
*/
118
if (sattrs.ns) {
119
result->f.attrs.secure = false;
120
+ result->f.attrs.space = ARMSS_NonSecure;
121
} else if (!secure) {
122
/*
123
* NS access to S memory must fault.
124
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
125
bool is_secure = ptw->in_secure;
126
bool ret, ipa_secure;
127
ARMCacheAttrs cacheattrs1;
128
+ ARMSecuritySpace ipa_space;
129
bool is_el0;
130
uint64_t hcr;
131
132
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
133
134
ipa = result->f.phys_addr;
135
ipa_secure = result->f.attrs.secure;
136
+ ipa_space = result->f.attrs.space;
137
138
is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
139
ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
140
ptw->in_secure = ipa_secure;
141
+ ptw->in_space = ipa_space;
142
ptw->in_ptw_idx = ptw_idx_for_stage_2(env, ptw->in_mmu_idx);
92
143
93
/*
144
/*
94
* Load second pass inputs before storing the first pass result, to
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
95
* avoid incorrect results if a narrow input overlaps with the result.
146
ARMMMUIdx s1_mmu_idx;
147
148
/*
149
- * The page table entries may downgrade secure to non-secure, but
150
- * cannot upgrade an non-secure translation regime's attributes
151
- * to secure.
152
+ * The page table entries may downgrade Secure to NonSecure, but
153
+ * cannot upgrade a NonSecure translation regime's attributes
154
+ * to Secure or Realm.
96
*/
155
*/
97
- if (src1_wide) {
156
result->f.attrs.secure = is_secure;
98
- read_neon_element64(rn1_64, a->vn, 1, MO_64);
157
+ result->f.attrs.space = ptw->in_space;
99
+ if (src1_mop >= 0) {
158
100
+ read_neon_element64(rn1_64, a->vn, 1, src1_mop);
159
switch (mmu_idx) {
101
} else {
160
case ARMMMUIdx_Phys_S:
102
TCGv_i32 tmp = tcg_temp_new_i32();
161
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
103
read_neon_element32(tmp, a->vn, 1, MO_32);
162
104
widenfn(rn1_64, tmp);
163
default:
105
tcg_temp_free_i32(tmp);
164
/* Single stage uses physical for ptw. */
106
}
165
- ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
107
- rm = tcg_temp_new_i32();
166
+ ptw->in_ptw_idx = arm_space_to_phys(ptw->in_space);
108
- read_neon_element32(rm, a->vm, 1, MO_32);
167
break;
109
+ if (src2_mop >= 0) {
168
}
110
+ read_neon_element64(rm_64, a->vm, 1, src2_mop);
169
111
+ } else {
170
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
112
+ TCGv_i32 tmp = tcg_temp_new_i32();
171
S1Translate ptw = {
113
+ read_neon_element32(tmp, a->vm, 1, MO_32);
172
.in_mmu_idx = mmu_idx,
114
+ widenfn(rm_64, tmp);
173
.in_secure = is_secure,
115
+ tcg_temp_free_i32(tmp);
174
+ .in_space = arm_secure_to_space(is_secure),
116
+ }
175
};
117
176
return get_phys_addr_with_struct(env, &ptw, address, access_type,
118
write_neon_element64(rn0_64, a->vd, 0, MO_64);
177
result, fi);
119
178
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
120
- widenfn(rm_64, rm);
179
MMUAccessType access_type, ARMMMUIdx mmu_idx,
121
- tcg_temp_free_i32(rm);
180
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
122
opfn(rn1_64, rn1_64, rm_64);
181
{
123
write_neon_element64(rn1_64, a->vd, 1, MO_64);
182
- bool is_secure;
124
183
+ S1Translate ptw = {
125
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
184
+ .in_mmu_idx = mmu_idx,
126
return true;
185
+ };
186
+ ARMSecuritySpace ss;
187
188
switch (mmu_idx) {
189
case ARMMMUIdx_E10_0:
190
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
191
case ARMMMUIdx_Stage1_E1:
192
case ARMMMUIdx_Stage1_E1_PAN:
193
case ARMMMUIdx_E2:
194
- is_secure = arm_is_secure_below_el3(env);
195
+ ss = arm_security_space_below_el3(env);
196
break;
197
case ARMMMUIdx_Stage2:
198
+ /*
199
+ * For Secure EL2, we need this index to be NonSecure;
200
+ * otherwise this will already be NonSecure or Realm.
201
+ */
202
+ ss = arm_security_space_below_el3(env);
203
+ if (ss == ARMSS_Secure) {
204
+ ss = ARMSS_NonSecure;
205
+ }
206
+ break;
207
case ARMMMUIdx_Phys_NS:
208
case ARMMMUIdx_MPrivNegPri:
209
case ARMMMUIdx_MUserNegPri:
210
case ARMMMUIdx_MPriv:
211
case ARMMMUIdx_MUser:
212
- is_secure = false;
213
+ ss = ARMSS_NonSecure;
214
break;
215
- case ARMMMUIdx_E3:
216
case ARMMMUIdx_Stage2_S:
217
case ARMMMUIdx_Phys_S:
218
case ARMMMUIdx_MSPrivNegPri:
219
case ARMMMUIdx_MSUserNegPri:
220
case ARMMMUIdx_MSPriv:
221
case ARMMMUIdx_MSUser:
222
- is_secure = true;
223
+ ss = ARMSS_Secure;
224
+ break;
225
+ case ARMMMUIdx_E3:
226
+ if (arm_feature(env, ARM_FEATURE_AARCH64) &&
227
+ cpu_isar_feature(aa64_rme, env_archcpu(env))) {
228
+ ss = ARMSS_Root;
229
+ } else {
230
+ ss = ARMSS_Secure;
231
+ }
232
+ break;
233
+ case ARMMMUIdx_Phys_Root:
234
+ ss = ARMSS_Root;
235
+ break;
236
+ case ARMMMUIdx_Phys_Realm:
237
+ ss = ARMSS_Realm;
238
break;
239
default:
240
g_assert_not_reached();
241
}
242
- return get_phys_addr_with_secure(env, address, access_type, mmu_idx,
243
- is_secure, result, fi);
244
+
245
+ ptw.in_space = ss;
246
+ ptw.in_secure = arm_space_is_secure(ss);
247
+ return get_phys_addr_with_struct(env, &ptw, address, access_type,
248
+ result, fi);
127
}
249
}
128
250
129
-#define DO_PREWIDEN(INSN, S, EXT, OP, SRC1WIDE) \
251
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
130
+#define DO_PREWIDEN(INSN, S, OP, SRC1WIDE, SIGN) \
252
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
131
static bool trans_##INSN##_3d(DisasContext *s, arg_3diff *a) \
253
{
132
{ \
254
ARMCPU *cpu = ARM_CPU(cs);
133
static NeonGenWidenFn * const widenfn[] = { \
255
CPUARMState *env = &cpu->env;
134
gen_helper_neon_widen_##S##8, \
256
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
135
gen_helper_neon_widen_##S##16, \
257
+ ARMSecuritySpace ss = arm_security_space(env);
136
- tcg_gen_##EXT##_i32_i64, \
258
S1Translate ptw = {
137
- NULL, \
259
- .in_mmu_idx = arm_mmu_idx(env),
138
+ NULL, NULL, \
260
- .in_secure = arm_is_secure(env),
139
}; \
261
+ .in_mmu_idx = mmu_idx,
140
static NeonGenTwo64OpFn * const addfn[] = { \
262
+ .in_space = ss,
141
gen_helper_neon_##OP##l_u16, \
263
+ .in_secure = arm_space_is_secure(ss),
142
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
264
.in_debug = true,
143
tcg_gen_##OP##_i64, \
265
};
144
NULL, \
266
GetPhysAddrResult res = {};
145
}; \
146
- return do_prewiden_3d(s, a, widenfn[a->size], \
147
- addfn[a->size], SRC1WIDE); \
148
+ int narrow_mop = a->size == MO_32 ? MO_32 | SIGN : -1; \
149
+ return do_prewiden_3d(s, a, widenfn[a->size], addfn[a->size], \
150
+ SRC1WIDE ? MO_Q : narrow_mop, \
151
+ narrow_mop); \
152
}
153
154
-DO_PREWIDEN(VADDL_S, s, ext, add, false)
155
-DO_PREWIDEN(VADDL_U, u, extu, add, false)
156
-DO_PREWIDEN(VSUBL_S, s, ext, sub, false)
157
-DO_PREWIDEN(VSUBL_U, u, extu, sub, false)
158
-DO_PREWIDEN(VADDW_S, s, ext, add, true)
159
-DO_PREWIDEN(VADDW_U, u, extu, add, true)
160
-DO_PREWIDEN(VSUBW_S, s, ext, sub, true)
161
-DO_PREWIDEN(VSUBW_U, u, extu, sub, true)
162
+DO_PREWIDEN(VADDL_S, s, add, false, MO_SIGN)
163
+DO_PREWIDEN(VADDL_U, u, add, false, 0)
164
+DO_PREWIDEN(VSUBL_S, s, sub, false, MO_SIGN)
165
+DO_PREWIDEN(VSUBL_U, u, sub, false, 0)
166
+DO_PREWIDEN(VADDW_S, s, add, true, MO_SIGN)
167
+DO_PREWIDEN(VADDW_U, u, add, true, 0)
168
+DO_PREWIDEN(VSUBW_S, s, sub, true, MO_SIGN)
169
+DO_PREWIDEN(VSUBW_U, u, sub, true, 0)
170
171
static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
172
NeonGenTwo64OpFn *opfn, NeonGenNarrowFn *narrowfn)
173
--
267
--
174
2.20.1
268
2.34.1
175
176
diff view generated by jsdifflib
1
From: AlexChen <alex.chen@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In exynos4210_fimd_update(), the pointer s is dereferinced before
3
Test in_space instead of in_secure so that we don't
4
being check if it is valid, which may lead to NULL pointer dereference.
4
switch out of Root space.
5
So move the assignment to global_width after checking that the s is valid.
6
5
7
Reported-by: Euler Robot <euler.robot@huawei.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Alex Chen <alex.chen@huawei.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20230620124418.805717-12-richard.henderson@linaro.org
10
Message-id: 5F9F8D88.9030102@huawei.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
hw/display/exynos4210_fimd.c | 4 +++-
11
target/arm/ptw.c | 28 ++++++++++++++--------------
14
1 file changed, 3 insertions(+), 1 deletion(-)
12
1 file changed, 14 insertions(+), 14 deletions(-)
15
13
16
diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/display/exynos4210_fimd.c
16
--- a/target/arm/ptw.c
19
+++ b/hw/display/exynos4210_fimd.c
17
+++ b/target/arm/ptw.c
20
@@ -XXX,XX +XXX,XX @@ static void exynos4210_fimd_update(void *opaque)
18
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
21
bool blend = false;
19
{
22
uint8_t *host_fb_addr;
20
ARMCPU *cpu = env_archcpu(env);
23
bool is_dirty = false;
21
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
24
- const int global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
22
- bool is_secure = ptw->in_secure;
25
+ int global_width;
23
int32_t level;
26
24
ARMVAParameters param;
27
if (!s || !s->console || !s->enabled ||
25
uint64_t ttbr;
28
surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) {
26
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
29
return;
27
uint64_t descaddrmask;
28
bool aarch64 = arm_el_is_aa64(env, el);
29
uint64_t descriptor, new_descriptor;
30
- bool nstable;
31
32
/* TODO: This code does not support shareability levels. */
33
if (aarch64) {
34
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
35
descaddrmask = MAKE_64BIT_MASK(0, 40);
36
}
37
descaddrmask &= ~indexmask_grainsize;
38
-
39
- /*
40
- * Secure stage 1 accesses start with the page table in secure memory and
41
- * can be downgraded to non-secure at any step. Non-secure accesses
42
- * remain non-secure. We implement this by just ORing in the NSTable/NS
43
- * bits at each step.
44
- * Stage 2 never gets this kind of downgrade.
45
- */
46
- tableattrs = is_secure ? 0 : (1 << 4);
47
+ tableattrs = 0;
48
49
next_level:
50
descaddr |= (address >> (stride * (4 - level))) & indexmask;
51
descaddr &= ~7ULL;
52
- nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
53
- if (nstable && ptw->in_secure) {
54
+
55
+ /*
56
+ * Process the NSTable bit from the previous level. This changes
57
+ * the table address space and the output space from Secure to
58
+ * NonSecure. With RME, the EL3 translation regime does not change
59
+ * from Root to NonSecure.
60
+ */
61
+ if (ptw->in_space == ARMSS_Secure
62
+ && !regime_is_stage2(mmu_idx)
63
+ && extract32(tableattrs, 4, 1)) {
64
/*
65
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
66
* Assert the relative order of the secure/non-secure indexes.
67
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
68
QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2);
69
ptw->in_ptw_idx += 1;
70
ptw->in_secure = false;
71
+ ptw->in_space = ARMSS_NonSecure;
30
}
72
}
31
+
73
+
32
+ global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
74
if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
33
exynos4210_update_resolution(s);
75
goto do_fault;
34
surface = qemu_console_surface(s->console);
76
}
35
77
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
78
*/
79
attrs = new_descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
80
if (!regime_is_stage2(mmu_idx)) {
81
- attrs |= nstable << 5; /* NS */
82
+ attrs |= !ptw->in_secure << 5; /* NS */
83
if (!param.hpd) {
84
attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
85
/*
36
--
86
--
37
2.20.1
87
2.34.1
38
39
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 only uses of this function are for loading VFP
3
With Realm security state, bit 55 of a block or page descriptor during
4
single-precision values, and nothing to do with NEON.
4
the stage2 walk becomes the NS bit; during the stage1 walk the bit 5
5
NS bit is RES0. With Root security state, bit 11 of the block or page
6
descriptor during the stage1 walk becomes the NSE bit.
5
7
8
Rather than collecting an NS bit and applying it later, compute the
9
output pa space from the input pa space and unconditionally assign.
10
This means that we no longer need to adjust the output space earlier
11
for the NSTable bit.
12
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-8-richard.henderson@linaro.org
15
Message-id: 20230620124418.805717-13-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
17
---
11
target/arm/translate.c | 4 +-
18
target/arm/ptw.c | 89 +++++++++++++++++++++++++++++++++++++++---------
12
target/arm/translate-vfp.c.inc | 184 ++++++++++++++++-----------------
19
1 file changed, 73 insertions(+), 16 deletions(-)
13
2 files changed, 94 insertions(+), 94 deletions(-)
14
20
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
21
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
23
--- a/target/arm/ptw.c
18
+++ b/target/arm/translate.c
24
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg64(TCGv_i64 var, int reg)
25
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
20
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
26
* @mmu_idx: MMU index indicating required translation regime
21
}
27
* @is_aa64: TRUE if AArch64
22
28
* @ap: The 2-bit simple AP (AP[2:1])
23
-static inline void neon_load_reg32(TCGv_i32 var, int reg)
29
- * @ns: NS (non-secure) bit
24
+static inline void vfp_load_reg32(TCGv_i32 var, int reg)
30
* @xn: XN (execute-never) bit
31
* @pxn: PXN (privileged execute-never) bit
32
+ * @in_pa: The original input pa space
33
+ * @out_pa: The output pa space, modified by NSTable, NS, and NSE
34
*/
35
static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
36
- int ap, int ns, int xn, int pxn)
37
+ int ap, int xn, int pxn,
38
+ ARMSecuritySpace in_pa, ARMSecuritySpace out_pa)
25
{
39
{
26
tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
40
ARMCPU *cpu = env_archcpu(env);
27
}
41
bool is_user = regime_is_user(env, mmu_idx);
28
42
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
29
-static inline void neon_store_reg32(TCGv_i32 var, int reg)
30
+static inline void vfp_store_reg32(TCGv_i32 var, int reg)
31
{
32
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
33
}
34
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-vfp.c.inc
37
+++ b/target/arm/translate-vfp.c.inc
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
39
frn = tcg_temp_new_i32();
40
frm = tcg_temp_new_i32();
41
dest = tcg_temp_new_i32();
42
- neon_load_reg32(frn, rn);
43
- neon_load_reg32(frm, rm);
44
+ vfp_load_reg32(frn, rn);
45
+ vfp_load_reg32(frm, rm);
46
switch (a->cc) {
47
case 0: /* eq: Z */
48
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
50
if (sz == 1) {
51
tcg_gen_andi_i32(dest, dest, 0xffff);
52
}
53
- neon_store_reg32(dest, rd);
54
+ vfp_store_reg32(dest, rd);
55
tcg_temp_free_i32(frn);
56
tcg_temp_free_i32(frm);
57
tcg_temp_free_i32(dest);
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
59
TCGv_i32 tcg_res;
60
tcg_op = tcg_temp_new_i32();
61
tcg_res = tcg_temp_new_i32();
62
- neon_load_reg32(tcg_op, rm);
63
+ vfp_load_reg32(tcg_op, rm);
64
if (sz == 1) {
65
gen_helper_rinth(tcg_res, tcg_op, fpst);
66
} else {
67
gen_helper_rints(tcg_res, tcg_op, fpst);
68
}
69
- neon_store_reg32(tcg_res, rd);
70
+ vfp_store_reg32(tcg_res, rd);
71
tcg_temp_free_i32(tcg_op);
72
tcg_temp_free_i32(tcg_res);
73
}
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
75
gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
76
}
77
tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
78
- neon_store_reg32(tcg_tmp, rd);
79
+ vfp_store_reg32(tcg_tmp, rd);
80
tcg_temp_free_i32(tcg_tmp);
81
tcg_temp_free_i64(tcg_res);
82
tcg_temp_free_i64(tcg_double);
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
84
TCGv_i32 tcg_single, tcg_res;
85
tcg_single = tcg_temp_new_i32();
86
tcg_res = tcg_temp_new_i32();
87
- neon_load_reg32(tcg_single, rm);
88
+ vfp_load_reg32(tcg_single, rm);
89
if (sz == 1) {
90
if (is_signed) {
91
gen_helper_vfp_toslh(tcg_res, tcg_single, tcg_shift, fpst);
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
93
gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
94
}
95
}
96
- neon_store_reg32(tcg_res, rd);
97
+ vfp_store_reg32(tcg_res, rd);
98
tcg_temp_free_i32(tcg_res);
99
tcg_temp_free_i32(tcg_single);
100
}
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a)
102
if (a->l) {
103
/* VFP to general purpose register */
104
tmp = tcg_temp_new_i32();
105
- neon_load_reg32(tmp, a->vn);
106
+ vfp_load_reg32(tmp, a->vn);
107
tcg_gen_andi_i32(tmp, tmp, 0xffff);
108
store_reg(s, a->rt, tmp);
109
} else {
110
/* general purpose register to VFP */
111
tmp = load_reg(s, a->rt);
112
tcg_gen_andi_i32(tmp, tmp, 0xffff);
113
- neon_store_reg32(tmp, a->vn);
114
+ vfp_store_reg32(tmp, a->vn);
115
tcg_temp_free_i32(tmp);
116
}
117
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
119
if (a->l) {
120
/* VFP to general purpose register */
121
tmp = tcg_temp_new_i32();
122
- neon_load_reg32(tmp, a->vn);
123
+ vfp_load_reg32(tmp, a->vn);
124
if (a->rt == 15) {
125
/* Set the 4 flag bits in the CPSR. */
126
gen_set_nzcv(tmp);
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
128
} else {
129
/* general purpose register to VFP */
130
tmp = load_reg(s, a->rt);
131
- neon_store_reg32(tmp, a->vn);
132
+ vfp_store_reg32(tmp, a->vn);
133
tcg_temp_free_i32(tmp);
134
}
135
136
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
137
if (a->op) {
138
/* fpreg to gpreg */
139
tmp = tcg_temp_new_i32();
140
- neon_load_reg32(tmp, a->vm);
141
+ vfp_load_reg32(tmp, a->vm);
142
store_reg(s, a->rt, tmp);
143
tmp = tcg_temp_new_i32();
144
- neon_load_reg32(tmp, a->vm + 1);
145
+ vfp_load_reg32(tmp, a->vm + 1);
146
store_reg(s, a->rt2, tmp);
147
} else {
148
/* gpreg to fpreg */
149
tmp = load_reg(s, a->rt);
150
- neon_store_reg32(tmp, a->vm);
151
+ vfp_store_reg32(tmp, a->vm);
152
tcg_temp_free_i32(tmp);
153
tmp = load_reg(s, a->rt2);
154
- neon_store_reg32(tmp, a->vm + 1);
155
+ vfp_store_reg32(tmp, a->vm + 1);
156
tcg_temp_free_i32(tmp);
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
160
if (a->op) {
161
/* fpreg to gpreg */
162
tmp = tcg_temp_new_i32();
163
- neon_load_reg32(tmp, a->vm * 2);
164
+ vfp_load_reg32(tmp, a->vm * 2);
165
store_reg(s, a->rt, tmp);
166
tmp = tcg_temp_new_i32();
167
- neon_load_reg32(tmp, a->vm * 2 + 1);
168
+ vfp_load_reg32(tmp, a->vm * 2 + 1);
169
store_reg(s, a->rt2, tmp);
170
} else {
171
/* gpreg to fpreg */
172
tmp = load_reg(s, a->rt);
173
- neon_store_reg32(tmp, a->vm * 2);
174
+ vfp_store_reg32(tmp, a->vm * 2);
175
tcg_temp_free_i32(tmp);
176
tmp = load_reg(s, a->rt2);
177
- neon_store_reg32(tmp, a->vm * 2 + 1);
178
+ vfp_store_reg32(tmp, a->vm * 2 + 1);
179
tcg_temp_free_i32(tmp);
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
183
tmp = tcg_temp_new_i32();
184
if (a->l) {
185
gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
186
- neon_store_reg32(tmp, a->vd);
187
+ vfp_store_reg32(tmp, a->vd);
188
} else {
189
- neon_load_reg32(tmp, a->vd);
190
+ vfp_load_reg32(tmp, a->vd);
191
gen_aa32_st16(s, tmp, addr, get_mem_index(s));
192
}
193
tcg_temp_free_i32(tmp);
194
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
195
tmp = tcg_temp_new_i32();
196
if (a->l) {
197
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
198
- neon_store_reg32(tmp, a->vd);
199
+ vfp_store_reg32(tmp, a->vd);
200
} else {
201
- neon_load_reg32(tmp, a->vd);
202
+ vfp_load_reg32(tmp, a->vd);
203
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
204
}
205
tcg_temp_free_i32(tmp);
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
207
if (a->l) {
208
/* load */
209
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
210
- neon_store_reg32(tmp, a->vd + i);
211
+ vfp_store_reg32(tmp, a->vd + i);
212
} else {
213
/* store */
214
- neon_load_reg32(tmp, a->vd + i);
215
+ vfp_load_reg32(tmp, a->vd + i);
216
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
217
}
218
tcg_gen_addi_i32(addr, addr, offset);
219
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
220
fd = tcg_temp_new_i32();
221
fpst = fpstatus_ptr(FPST_FPCR);
222
223
- neon_load_reg32(f0, vn);
224
- neon_load_reg32(f1, vm);
225
+ vfp_load_reg32(f0, vn);
226
+ vfp_load_reg32(f1, vm);
227
228
for (;;) {
229
if (reads_vd) {
230
- neon_load_reg32(fd, vd);
231
+ vfp_load_reg32(fd, vd);
232
}
233
fn(fd, f0, f1, fpst);
234
- neon_store_reg32(fd, vd);
235
+ vfp_store_reg32(fd, vd);
236
237
if (veclen == 0) {
238
break;
239
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
240
veclen--;
241
vd = vfp_advance_sreg(vd, delta_d);
242
vn = vfp_advance_sreg(vn, delta_d);
243
- neon_load_reg32(f0, vn);
244
+ vfp_load_reg32(f0, vn);
245
if (delta_m) {
246
vm = vfp_advance_sreg(vm, delta_m);
247
- neon_load_reg32(f1, vm);
248
+ vfp_load_reg32(f1, vm);
249
}
43
}
250
}
44
}
251
45
252
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn,
46
- if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) {
253
fd = tcg_temp_new_i32();
47
+ if (out_pa == ARMSS_NonSecure && in_pa == ARMSS_Secure &&
254
fpst = fpstatus_ptr(FPST_FPCR_F16);
48
+ (env->cp15.scr_el3 & SCR_SIF)) {
255
49
return prot_rw;
256
- neon_load_reg32(f0, vn);
257
- neon_load_reg32(f1, vm);
258
+ vfp_load_reg32(f0, vn);
259
+ vfp_load_reg32(f1, vm);
260
261
if (reads_vd) {
262
- neon_load_reg32(fd, vd);
263
+ vfp_load_reg32(fd, vd);
264
}
50
}
265
fn(fd, f0, f1, fpst);
51
266
- neon_store_reg32(fd, vd);
52
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
267
+ vfp_store_reg32(fd, vd);
53
int32_t stride;
268
54
int addrsize, inputsize, outputsize;
269
tcg_temp_free_i32(f0);
55
uint64_t tcr = regime_tcr(env, mmu_idx);
270
tcg_temp_free_i32(f1);
56
- int ap, ns, xn, pxn;
271
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
57
+ int ap, xn, pxn;
272
f0 = tcg_temp_new_i32();
58
uint32_t el = regime_el(env, mmu_idx);
273
fd = tcg_temp_new_i32();
59
uint64_t descaddrmask;
274
60
bool aarch64 = arm_el_is_aa64(env, el);
275
- neon_load_reg32(f0, vm);
61
uint64_t descriptor, new_descriptor;
276
+ vfp_load_reg32(f0, vm);
62
+ ARMSecuritySpace out_space;
277
63
278
for (;;) {
64
/* TODO: This code does not support shareability levels. */
279
fn(fd, f0);
65
if (aarch64) {
280
- neon_store_reg32(fd, vd);
66
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
281
+ vfp_store_reg32(fd, vd);
282
283
if (veclen == 0) {
284
break;
285
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
286
/* single source one-many */
287
while (veclen--) {
288
vd = vfp_advance_sreg(vd, delta_d);
289
- neon_store_reg32(fd, vd);
290
+ vfp_store_reg32(fd, vd);
291
}
292
break;
293
}
294
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
295
veclen--;
296
vd = vfp_advance_sreg(vd, delta_d);
297
vm = vfp_advance_sreg(vm, delta_m);
298
- neon_load_reg32(f0, vm);
299
+ vfp_load_reg32(f0, vm);
300
}
67
}
301
68
302
tcg_temp_free_i32(f0);
69
ap = extract32(attrs, 6, 2);
303
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_hp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
70
+ out_space = ptw->in_space;
71
if (regime_is_stage2(mmu_idx)) {
72
- ns = mmu_idx == ARMMMUIdx_Stage2;
73
+ /*
74
+ * R_GYNXY: For stage2 in Realm security state, bit 55 is NS.
75
+ * The bit remains ignored for other security states.
76
+ */
77
+ if (out_space == ARMSS_Realm && extract64(attrs, 55, 1)) {
78
+ out_space = ARMSS_NonSecure;
79
+ }
80
xn = extract64(attrs, 53, 2);
81
result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
82
} else {
83
- ns = extract32(attrs, 5, 1);
84
+ int nse, ns = extract32(attrs, 5, 1);
85
+ switch (out_space) {
86
+ case ARMSS_Root:
87
+ /*
88
+ * R_GVZML: Bit 11 becomes the NSE field in the EL3 regime.
89
+ * R_XTYPW: NSE and NS together select the output pa space.
90
+ */
91
+ nse = extract32(attrs, 11, 1);
92
+ out_space = (nse << 1) | ns;
93
+ if (out_space == ARMSS_Secure &&
94
+ !cpu_isar_feature(aa64_sel2, cpu)) {
95
+ out_space = ARMSS_NonSecure;
96
+ }
97
+ break;
98
+ case ARMSS_Secure:
99
+ if (ns) {
100
+ out_space = ARMSS_NonSecure;
101
+ }
102
+ break;
103
+ case ARMSS_Realm:
104
+ switch (mmu_idx) {
105
+ case ARMMMUIdx_Stage1_E0:
106
+ case ARMMMUIdx_Stage1_E1:
107
+ case ARMMMUIdx_Stage1_E1_PAN:
108
+ /* I_CZPRF: For Realm EL1&0 stage1, NS bit is RES0. */
109
+ break;
110
+ case ARMMMUIdx_E2:
111
+ case ARMMMUIdx_E20_0:
112
+ case ARMMMUIdx_E20_2:
113
+ case ARMMMUIdx_E20_2_PAN:
114
+ /*
115
+ * R_LYKFZ, R_WGRZN: For Realm EL2 and EL2&1,
116
+ * NS changes the output to non-secure space.
117
+ */
118
+ if (ns) {
119
+ out_space = ARMSS_NonSecure;
120
+ }
121
+ break;
122
+ default:
123
+ g_assert_not_reached();
124
+ }
125
+ break;
126
+ case ARMSS_NonSecure:
127
+ /* R_QRMFF: For NonSecure state, the NS bit is RES0. */
128
+ break;
129
+ default:
130
+ g_assert_not_reached();
131
+ }
132
xn = extract64(attrs, 54, 1);
133
pxn = extract64(attrs, 53, 1);
134
- result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
135
+
136
+ /*
137
+ * Note that we modified ptw->in_space earlier for NSTable, but
138
+ * result->f.attrs retains a copy of the original security space.
139
+ */
140
+ result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, xn, pxn,
141
+ result->f.attrs.space, out_space);
304
}
142
}
305
143
306
f0 = tcg_temp_new_i32();
144
if (!(result->f.prot & (1 << access_type))) {
307
- neon_load_reg32(f0, vm);
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
308
+ vfp_load_reg32(f0, vm);
309
fn(f0, f0);
310
- neon_store_reg32(f0, vd);
311
+ vfp_store_reg32(f0, vd);
312
tcg_temp_free_i32(f0);
313
314
return true;
315
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_hp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
316
vm = tcg_temp_new_i32();
317
vd = tcg_temp_new_i32();
318
319
- neon_load_reg32(vn, a->vn);
320
- neon_load_reg32(vm, a->vm);
321
+ vfp_load_reg32(vn, a->vn);
322
+ vfp_load_reg32(vm, a->vm);
323
if (neg_n) {
324
/* VFNMS, VFMS */
325
gen_helper_vfp_negh(vn, vn);
326
}
327
- neon_load_reg32(vd, a->vd);
328
+ vfp_load_reg32(vd, a->vd);
329
if (neg_d) {
330
/* VFNMA, VFNMS */
331
gen_helper_vfp_negh(vd, vd);
332
}
333
fpst = fpstatus_ptr(FPST_FPCR_F16);
334
gen_helper_vfp_muladdh(vd, vn, vm, vd, fpst);
335
- neon_store_reg32(vd, a->vd);
336
+ vfp_store_reg32(vd, a->vd);
337
338
tcg_temp_free_ptr(fpst);
339
tcg_temp_free_i32(vn);
340
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
341
vm = tcg_temp_new_i32();
342
vd = tcg_temp_new_i32();
343
344
- neon_load_reg32(vn, a->vn);
345
- neon_load_reg32(vm, a->vm);
346
+ vfp_load_reg32(vn, a->vn);
347
+ vfp_load_reg32(vm, a->vm);
348
if (neg_n) {
349
/* VFNMS, VFMS */
350
gen_helper_vfp_negs(vn, vn);
351
}
352
- neon_load_reg32(vd, a->vd);
353
+ vfp_load_reg32(vd, a->vd);
354
if (neg_d) {
355
/* VFNMA, VFNMS */
356
gen_helper_vfp_negs(vd, vd);
357
}
358
fpst = fpstatus_ptr(FPST_FPCR);
359
gen_helper_vfp_muladds(vd, vn, vm, vd, fpst);
360
- neon_store_reg32(vd, a->vd);
361
+ vfp_store_reg32(vd, a->vd);
362
363
tcg_temp_free_ptr(fpst);
364
tcg_temp_free_i32(vn);
365
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_hp(DisasContext *s, arg_VMOV_imm_sp *a)
366
}
367
368
fd = tcg_const_i32(vfp_expand_imm(MO_16, a->imm));
369
- neon_store_reg32(fd, a->vd);
370
+ vfp_store_reg32(fd, a->vd);
371
tcg_temp_free_i32(fd);
372
return true;
373
}
374
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
375
fd = tcg_const_i32(vfp_expand_imm(MO_32, a->imm));
376
377
for (;;) {
378
- neon_store_reg32(fd, vd);
379
+ vfp_store_reg32(fd, vd);
380
381
if (veclen == 0) {
382
break;
383
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
384
vd = tcg_temp_new_i32();
385
vm = tcg_temp_new_i32();
386
387
- neon_load_reg32(vd, a->vd);
388
+ vfp_load_reg32(vd, a->vd);
389
if (a->z) {
390
tcg_gen_movi_i32(vm, 0);
391
} else {
392
- neon_load_reg32(vm, a->vm);
393
+ vfp_load_reg32(vm, a->vm);
394
}
395
396
if (a->e) {
397
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
398
vd = tcg_temp_new_i32();
399
vm = tcg_temp_new_i32();
400
401
- neon_load_reg32(vd, a->vd);
402
+ vfp_load_reg32(vd, a->vd);
403
if (a->z) {
404
tcg_gen_movi_i32(vm, 0);
405
} else {
406
- neon_load_reg32(vm, a->vm);
407
+ vfp_load_reg32(vm, a->vm);
408
}
409
410
if (a->e) {
411
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f32_f16(DisasContext *s, arg_VCVT_f32_f16 *a)
412
/* The T bit tells us if we want the low or high 16 bits of Vm */
413
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
414
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp_mode);
415
- neon_store_reg32(tmp, a->vd);
416
+ vfp_store_reg32(tmp, a->vd);
417
tcg_temp_free_i32(ahp_mode);
418
tcg_temp_free_ptr(fpst);
419
tcg_temp_free_i32(tmp);
420
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a)
421
ahp_mode = get_ahp_flag();
422
tmp = tcg_temp_new_i32();
423
424
- neon_load_reg32(tmp, a->vm);
425
+ vfp_load_reg32(tmp, a->vm);
426
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp_mode);
427
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
428
tcg_temp_free_i32(ahp_mode);
429
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_hp(DisasContext *s, arg_VRINTR_sp *a)
430
}
431
432
tmp = tcg_temp_new_i32();
433
- neon_load_reg32(tmp, a->vm);
434
+ vfp_load_reg32(tmp, a->vm);
435
fpst = fpstatus_ptr(FPST_FPCR_F16);
436
gen_helper_rinth(tmp, tmp, fpst);
437
- neon_store_reg32(tmp, a->vd);
438
+ vfp_store_reg32(tmp, a->vd);
439
tcg_temp_free_ptr(fpst);
440
tcg_temp_free_i32(tmp);
441
return true;
442
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
443
}
444
445
tmp = tcg_temp_new_i32();
446
- neon_load_reg32(tmp, a->vm);
447
+ vfp_load_reg32(tmp, a->vm);
448
fpst = fpstatus_ptr(FPST_FPCR);
449
gen_helper_rints(tmp, tmp, fpst);
450
- neon_store_reg32(tmp, a->vd);
451
+ vfp_store_reg32(tmp, a->vd);
452
tcg_temp_free_ptr(fpst);
453
tcg_temp_free_i32(tmp);
454
return true;
455
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_hp(DisasContext *s, arg_VRINTZ_sp *a)
456
}
457
458
tmp = tcg_temp_new_i32();
459
- neon_load_reg32(tmp, a->vm);
460
+ vfp_load_reg32(tmp, a->vm);
461
fpst = fpstatus_ptr(FPST_FPCR_F16);
462
tcg_rmode = tcg_const_i32(float_round_to_zero);
463
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
464
gen_helper_rinth(tmp, tmp, fpst);
465
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
466
- neon_store_reg32(tmp, a->vd);
467
+ vfp_store_reg32(tmp, a->vd);
468
tcg_temp_free_ptr(fpst);
469
tcg_temp_free_i32(tcg_rmode);
470
tcg_temp_free_i32(tmp);
471
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
472
}
473
474
tmp = tcg_temp_new_i32();
475
- neon_load_reg32(tmp, a->vm);
476
+ vfp_load_reg32(tmp, a->vm);
477
fpst = fpstatus_ptr(FPST_FPCR);
478
tcg_rmode = tcg_const_i32(float_round_to_zero);
479
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
480
gen_helper_rints(tmp, tmp, fpst);
481
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
482
- neon_store_reg32(tmp, a->vd);
483
+ vfp_store_reg32(tmp, a->vd);
484
tcg_temp_free_ptr(fpst);
485
tcg_temp_free_i32(tcg_rmode);
486
tcg_temp_free_i32(tmp);
487
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_hp(DisasContext *s, arg_VRINTX_sp *a)
488
}
489
490
tmp = tcg_temp_new_i32();
491
- neon_load_reg32(tmp, a->vm);
492
+ vfp_load_reg32(tmp, a->vm);
493
fpst = fpstatus_ptr(FPST_FPCR_F16);
494
gen_helper_rinth_exact(tmp, tmp, fpst);
495
- neon_store_reg32(tmp, a->vd);
496
+ vfp_store_reg32(tmp, a->vd);
497
tcg_temp_free_ptr(fpst);
498
tcg_temp_free_i32(tmp);
499
return true;
500
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_sp(DisasContext *s, arg_VRINTX_sp *a)
501
}
502
503
tmp = tcg_temp_new_i32();
504
- neon_load_reg32(tmp, a->vm);
505
+ vfp_load_reg32(tmp, a->vm);
506
fpst = fpstatus_ptr(FPST_FPCR);
507
gen_helper_rints_exact(tmp, tmp, fpst);
508
- neon_store_reg32(tmp, a->vd);
509
+ vfp_store_reg32(tmp, a->vd);
510
tcg_temp_free_ptr(fpst);
511
tcg_temp_free_i32(tmp);
512
return true;
513
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
514
515
vm = tcg_temp_new_i32();
516
vd = tcg_temp_new_i64();
517
- neon_load_reg32(vm, a->vm);
518
+ vfp_load_reg32(vm, a->vm);
519
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
520
neon_store_reg64(vd, a->vd);
521
tcg_temp_free_i32(vm);
522
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
523
vm = tcg_temp_new_i64();
524
neon_load_reg64(vm, a->vm);
525
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
526
- neon_store_reg32(vd, a->vd);
527
+ vfp_store_reg32(vd, a->vd);
528
tcg_temp_free_i32(vd);
529
tcg_temp_free_i64(vm);
530
return true;
531
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
532
}
533
534
vm = tcg_temp_new_i32();
535
- neon_load_reg32(vm, a->vm);
536
+ vfp_load_reg32(vm, a->vm);
537
fpst = fpstatus_ptr(FPST_FPCR_F16);
538
if (a->s) {
539
/* i32 -> f16 */
540
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
541
/* u32 -> f16 */
542
gen_helper_vfp_uitoh(vm, vm, fpst);
543
}
544
- neon_store_reg32(vm, a->vd);
545
+ vfp_store_reg32(vm, a->vd);
546
tcg_temp_free_i32(vm);
547
tcg_temp_free_ptr(fpst);
548
return true;
549
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
550
}
551
552
vm = tcg_temp_new_i32();
553
- neon_load_reg32(vm, a->vm);
554
+ vfp_load_reg32(vm, a->vm);
555
fpst = fpstatus_ptr(FPST_FPCR);
556
if (a->s) {
557
/* i32 -> f32 */
558
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
559
/* u32 -> f32 */
560
gen_helper_vfp_uitos(vm, vm, fpst);
561
}
562
- neon_store_reg32(vm, a->vd);
563
+ vfp_store_reg32(vm, a->vd);
564
tcg_temp_free_i32(vm);
565
tcg_temp_free_ptr(fpst);
566
return true;
567
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
568
569
vm = tcg_temp_new_i32();
570
vd = tcg_temp_new_i64();
571
- neon_load_reg32(vm, a->vm);
572
+ vfp_load_reg32(vm, a->vm);
573
fpst = fpstatus_ptr(FPST_FPCR);
574
if (a->s) {
575
/* i32 -> f64 */
576
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
577
vd = tcg_temp_new_i32();
578
neon_load_reg64(vm, a->vm);
579
gen_helper_vjcvt(vd, vm, cpu_env);
580
- neon_store_reg32(vd, a->vd);
581
+ vfp_store_reg32(vd, a->vd);
582
tcg_temp_free_i64(vm);
583
tcg_temp_free_i32(vd);
584
return true;
585
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
586
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
587
588
vd = tcg_temp_new_i32();
589
- neon_load_reg32(vd, a->vd);
590
+ vfp_load_reg32(vd, a->vd);
591
592
fpst = fpstatus_ptr(FPST_FPCR_F16);
593
shift = tcg_const_i32(frac_bits);
594
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
595
g_assert_not_reached();
596
}
597
598
- neon_store_reg32(vd, a->vd);
599
+ vfp_store_reg32(vd, a->vd);
600
tcg_temp_free_i32(vd);
601
tcg_temp_free_i32(shift);
602
tcg_temp_free_ptr(fpst);
603
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
604
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
605
606
vd = tcg_temp_new_i32();
607
- neon_load_reg32(vd, a->vd);
608
+ vfp_load_reg32(vd, a->vd);
609
610
fpst = fpstatus_ptr(FPST_FPCR);
611
shift = tcg_const_i32(frac_bits);
612
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
613
g_assert_not_reached();
614
}
615
616
- neon_store_reg32(vd, a->vd);
617
+ vfp_store_reg32(vd, a->vd);
618
tcg_temp_free_i32(vd);
619
tcg_temp_free_i32(shift);
620
tcg_temp_free_ptr(fpst);
621
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
622
623
fpst = fpstatus_ptr(FPST_FPCR_F16);
624
vm = tcg_temp_new_i32();
625
- neon_load_reg32(vm, a->vm);
626
+ vfp_load_reg32(vm, a->vm);
627
628
if (a->s) {
629
if (a->rz) {
630
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
631
gen_helper_vfp_touih(vm, vm, fpst);
632
}
146
}
633
}
147
}
634
- neon_store_reg32(vm, a->vd);
148
635
+ vfp_store_reg32(vm, a->vd);
149
- if (ns) {
636
tcg_temp_free_i32(vm);
150
- /*
637
tcg_temp_free_ptr(fpst);
151
- * The NS bit will (as required by the architecture) have no effect if
638
return true;
152
- * the CPU doesn't support TZ or this is a non-secure translation
639
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
153
- * regime, because the attribute will already be non-secure.
640
154
- */
641
fpst = fpstatus_ptr(FPST_FPCR);
155
- result->f.attrs.secure = false;
642
vm = tcg_temp_new_i32();
156
- result->f.attrs.space = ARMSS_NonSecure;
643
- neon_load_reg32(vm, a->vm);
157
- }
644
+ vfp_load_reg32(vm, a->vm);
158
+ result->f.attrs.space = out_space;
645
159
+ result->f.attrs.secure = arm_space_is_secure(out_space);
646
if (a->s) {
160
647
if (a->rz) {
161
if (regime_is_stage2(mmu_idx)) {
648
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
162
result->cacheattrs.is_s2_format = true;
649
gen_helper_vfp_touis(vm, vm, fpst);
650
}
651
}
652
- neon_store_reg32(vm, a->vd);
653
+ vfp_store_reg32(vm, a->vd);
654
tcg_temp_free_i32(vm);
655
tcg_temp_free_ptr(fpst);
656
return true;
657
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
658
gen_helper_vfp_touid(vd, vm, fpst);
659
}
660
}
661
- neon_store_reg32(vd, a->vd);
662
+ vfp_store_reg32(vd, a->vd);
663
tcg_temp_free_i32(vd);
664
tcg_temp_free_i64(vm);
665
tcg_temp_free_ptr(fpst);
666
@@ -XXX,XX +XXX,XX @@ static bool trans_VINS(DisasContext *s, arg_VINS *a)
667
/* Insert low half of Vm into high half of Vd */
668
rm = tcg_temp_new_i32();
669
rd = tcg_temp_new_i32();
670
- neon_load_reg32(rm, a->vm);
671
- neon_load_reg32(rd, a->vd);
672
+ vfp_load_reg32(rm, a->vm);
673
+ vfp_load_reg32(rd, a->vd);
674
tcg_gen_deposit_i32(rd, rd, rm, 16, 16);
675
- neon_store_reg32(rd, a->vd);
676
+ vfp_store_reg32(rd, a->vd);
677
tcg_temp_free_i32(rm);
678
tcg_temp_free_i32(rd);
679
return true;
680
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOVX(DisasContext *s, arg_VINS *a)
681
682
/* Set Vd to high half of Vm */
683
rm = tcg_temp_new_i32();
684
- neon_load_reg32(rm, a->vm);
685
+ vfp_load_reg32(rm, a->vm);
686
tcg_gen_shri_i32(rm, rm, 16);
687
- neon_store_reg32(rm, a->vd);
688
+ vfp_store_reg32(rm, a->vd);
689
tcg_temp_free_i32(rm);
690
return true;
691
}
692
--
163
--
693
2.20.1
164
2.34.1
694
695
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 only uses of this function are for loading VFP
3
While Root and Realm may read and write data from other spaces,
4
double-precision values, and nothing to do with NEON.
4
neither may execute from other pa spaces.
5
5
6
This happens for Stage1 EL3, EL2, EL2&0, and Stage2 EL1&0.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-10-richard.henderson@linaro.org
10
Message-id: 20230620124418.805717-14-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/translate.c | 8 ++--
13
target/arm/ptw.c | 52 ++++++++++++++++++++++++++++++++++++++++++------
12
target/arm/translate-vfp.c.inc | 84 +++++++++++++++++-----------------
14
1 file changed, 46 insertions(+), 6 deletions(-)
13
2 files changed, 46 insertions(+), 46 deletions(-)
14
15
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
18
--- a/target/arm/ptw.c
18
+++ b/target/arm/translate.c
19
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
20
@@ -XXX,XX +XXX,XX @@ do_fault:
21
* @xn: XN (execute-never) bits
22
* @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
23
*/
24
-static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
25
+static int get_S2prot_noexecute(int s2ap)
26
{
27
int prot = 0;
28
29
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
30
if (s2ap & 2) {
31
prot |= PAGE_WRITE;
20
}
32
}
21
}
33
+ return prot;
22
34
+}
23
-static inline void neon_load_reg64(TCGv_i64 var, int reg)
35
+
24
+static inline void vfp_load_reg64(TCGv_i64 var, int reg)
36
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
25
{
37
+{
26
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
38
+ int prot = get_S2prot_noexecute(s2ap);
27
+ tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
39
28
}
40
if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
29
41
switch (xn) {
30
-static inline void neon_store_reg64(TCGv_i64 var, int reg)
42
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
31
+static inline void vfp_store_reg64(TCGv_i64 var, int reg)
32
{
33
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
34
+ tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
35
}
36
37
static inline void vfp_load_reg32(TCGv_i32 var, int reg)
38
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate-vfp.c.inc
41
+++ b/target/arm/translate-vfp.c.inc
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
43
tcg_gen_ext_i32_i64(nf, cpu_NF);
44
tcg_gen_ext_i32_i64(vf, cpu_VF);
45
46
- neon_load_reg64(frn, rn);
47
- neon_load_reg64(frm, rm);
48
+ vfp_load_reg64(frn, rn);
49
+ vfp_load_reg64(frm, rm);
50
switch (a->cc) {
51
case 0: /* eq: Z */
52
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
53
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
54
tcg_temp_free_i64(tmp);
55
break;
56
}
57
- neon_store_reg64(dest, rd);
58
+ vfp_store_reg64(dest, rd);
59
tcg_temp_free_i64(frn);
60
tcg_temp_free_i64(frm);
61
tcg_temp_free_i64(dest);
62
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
63
TCGv_i64 tcg_res;
64
tcg_op = tcg_temp_new_i64();
65
tcg_res = tcg_temp_new_i64();
66
- neon_load_reg64(tcg_op, rm);
67
+ vfp_load_reg64(tcg_op, rm);
68
gen_helper_rintd(tcg_res, tcg_op, fpst);
69
- neon_store_reg64(tcg_res, rd);
70
+ vfp_store_reg64(tcg_res, rd);
71
tcg_temp_free_i64(tcg_op);
72
tcg_temp_free_i64(tcg_res);
73
} else {
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
75
tcg_double = tcg_temp_new_i64();
76
tcg_res = tcg_temp_new_i64();
77
tcg_tmp = tcg_temp_new_i32();
78
- neon_load_reg64(tcg_double, rm);
79
+ vfp_load_reg64(tcg_double, rm);
80
if (is_signed) {
81
gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
82
} else {
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
84
tmp = tcg_temp_new_i64();
85
if (a->l) {
86
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
87
- neon_store_reg64(tmp, a->vd);
88
+ vfp_store_reg64(tmp, a->vd);
89
} else {
90
- neon_load_reg64(tmp, a->vd);
91
+ vfp_load_reg64(tmp, a->vd);
92
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
93
}
94
tcg_temp_free_i64(tmp);
95
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
96
if (a->l) {
97
/* load */
98
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
99
- neon_store_reg64(tmp, a->vd + i);
100
+ vfp_store_reg64(tmp, a->vd + i);
101
} else {
102
/* store */
103
- neon_load_reg64(tmp, a->vd + i);
104
+ vfp_load_reg64(tmp, a->vd + i);
105
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
106
}
107
tcg_gen_addi_i32(addr, addr, offset);
108
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
109
fd = tcg_temp_new_i64();
110
fpst = fpstatus_ptr(FPST_FPCR);
111
112
- neon_load_reg64(f0, vn);
113
- neon_load_reg64(f1, vm);
114
+ vfp_load_reg64(f0, vn);
115
+ vfp_load_reg64(f1, vm);
116
117
for (;;) {
118
if (reads_vd) {
119
- neon_load_reg64(fd, vd);
120
+ vfp_load_reg64(fd, vd);
121
}
122
fn(fd, f0, f1, fpst);
123
- neon_store_reg64(fd, vd);
124
+ vfp_store_reg64(fd, vd);
125
126
if (veclen == 0) {
127
break;
128
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
129
veclen--;
130
vd = vfp_advance_dreg(vd, delta_d);
131
vn = vfp_advance_dreg(vn, delta_d);
132
- neon_load_reg64(f0, vn);
133
+ vfp_load_reg64(f0, vn);
134
if (delta_m) {
135
vm = vfp_advance_dreg(vm, delta_m);
136
- neon_load_reg64(f1, vm);
137
+ vfp_load_reg64(f1, vm);
138
}
43
}
139
}
44
}
140
45
141
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
46
- if (out_pa == ARMSS_NonSecure && in_pa == ARMSS_Secure &&
142
f0 = tcg_temp_new_i64();
47
- (env->cp15.scr_el3 & SCR_SIF)) {
143
fd = tcg_temp_new_i64();
48
- return prot_rw;
144
49
+ if (in_pa != out_pa) {
145
- neon_load_reg64(f0, vm);
50
+ switch (in_pa) {
146
+ vfp_load_reg64(f0, vm);
51
+ case ARMSS_Root:
147
52
+ /*
148
for (;;) {
53
+ * R_ZWRVD: permission fault for insn fetched from non-Root,
149
fn(fd, f0);
54
+ * I_WWBFB: SIF has no effect in EL3.
150
- neon_store_reg64(fd, vd);
55
+ */
151
+ vfp_store_reg64(fd, vd);
56
+ return prot_rw;
152
57
+ case ARMSS_Realm:
153
if (veclen == 0) {
58
+ /*
154
break;
59
+ * R_PKTDS: permission fault for insn fetched from non-Realm,
155
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
60
+ * for Realm EL2 or EL2&0. The corresponding fault for EL1&0
156
/* single source one-many */
61
+ * happens during any stage2 translation.
157
while (veclen--) {
62
+ */
158
vd = vfp_advance_dreg(vd, delta_d);
63
+ switch (mmu_idx) {
159
- neon_store_reg64(fd, vd);
64
+ case ARMMMUIdx_E2:
160
+ vfp_store_reg64(fd, vd);
65
+ case ARMMMUIdx_E20_0:
161
}
66
+ case ARMMMUIdx_E20_2:
162
break;
67
+ case ARMMMUIdx_E20_2_PAN:
68
+ return prot_rw;
69
+ default:
70
+ break;
71
+ }
72
+ break;
73
+ case ARMSS_Secure:
74
+ if (env->cp15.scr_el3 & SCR_SIF) {
75
+ return prot_rw;
76
+ }
77
+ break;
78
+ default:
79
+ /* Input NonSecure must have output NonSecure. */
80
+ g_assert_not_reached();
81
+ }
82
}
83
84
/* TODO have_wxn should be replaced with
85
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
86
/*
87
* R_GYNXY: For stage2 in Realm security state, bit 55 is NS.
88
* The bit remains ignored for other security states.
89
+ * R_YMCSL: Executing an insn fetched from non-Realm causes
90
+ * a stage2 permission fault.
91
*/
92
if (out_space == ARMSS_Realm && extract64(attrs, 55, 1)) {
93
out_space = ARMSS_NonSecure;
94
+ result->f.prot = get_S2prot_noexecute(ap);
95
+ } else {
96
+ xn = extract64(attrs, 53, 2);
97
+ result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
163
}
98
}
164
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
99
- xn = extract64(attrs, 53, 2);
165
veclen--;
100
- result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
166
vd = vfp_advance_dreg(vd, delta_d);
167
vd = vfp_advance_dreg(vm, delta_m);
168
- neon_load_reg64(f0, vm);
169
+ vfp_load_reg64(f0, vm);
170
}
171
172
tcg_temp_free_i64(f0);
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
174
vm = tcg_temp_new_i64();
175
vd = tcg_temp_new_i64();
176
177
- neon_load_reg64(vn, a->vn);
178
- neon_load_reg64(vm, a->vm);
179
+ vfp_load_reg64(vn, a->vn);
180
+ vfp_load_reg64(vm, a->vm);
181
if (neg_n) {
182
/* VFNMS, VFMS */
183
gen_helper_vfp_negd(vn, vn);
184
}
185
- neon_load_reg64(vd, a->vd);
186
+ vfp_load_reg64(vd, a->vd);
187
if (neg_d) {
188
/* VFNMA, VFNMS */
189
gen_helper_vfp_negd(vd, vd);
190
}
191
fpst = fpstatus_ptr(FPST_FPCR);
192
gen_helper_vfp_muladdd(vd, vn, vm, vd, fpst);
193
- neon_store_reg64(vd, a->vd);
194
+ vfp_store_reg64(vd, a->vd);
195
196
tcg_temp_free_ptr(fpst);
197
tcg_temp_free_i64(vn);
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
199
fd = tcg_const_i64(vfp_expand_imm(MO_64, a->imm));
200
201
for (;;) {
202
- neon_store_reg64(fd, vd);
203
+ vfp_store_reg64(fd, vd);
204
205
if (veclen == 0) {
206
break;
207
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
208
vd = tcg_temp_new_i64();
209
vm = tcg_temp_new_i64();
210
211
- neon_load_reg64(vd, a->vd);
212
+ vfp_load_reg64(vd, a->vd);
213
if (a->z) {
214
tcg_gen_movi_i64(vm, 0);
215
} else {
101
} else {
216
- neon_load_reg64(vm, a->vm);
102
int nse, ns = extract32(attrs, 5, 1);
217
+ vfp_load_reg64(vm, a->vm);
103
switch (out_space) {
218
}
219
220
if (a->e) {
221
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
222
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
223
vd = tcg_temp_new_i64();
224
gen_helper_vfp_fcvt_f16_to_f64(vd, tmp, fpst, ahp_mode);
225
- neon_store_reg64(vd, a->vd);
226
+ vfp_store_reg64(vd, a->vd);
227
tcg_temp_free_i32(ahp_mode);
228
tcg_temp_free_ptr(fpst);
229
tcg_temp_free_i32(tmp);
230
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
231
tmp = tcg_temp_new_i32();
232
vm = tcg_temp_new_i64();
233
234
- neon_load_reg64(vm, a->vm);
235
+ vfp_load_reg64(vm, a->vm);
236
gen_helper_vfp_fcvt_f64_to_f16(tmp, vm, fpst, ahp_mode);
237
tcg_temp_free_i64(vm);
238
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
239
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
240
}
241
242
tmp = tcg_temp_new_i64();
243
- neon_load_reg64(tmp, a->vm);
244
+ vfp_load_reg64(tmp, a->vm);
245
fpst = fpstatus_ptr(FPST_FPCR);
246
gen_helper_rintd(tmp, tmp, fpst);
247
- neon_store_reg64(tmp, a->vd);
248
+ vfp_store_reg64(tmp, a->vd);
249
tcg_temp_free_ptr(fpst);
250
tcg_temp_free_i64(tmp);
251
return true;
252
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
253
}
254
255
tmp = tcg_temp_new_i64();
256
- neon_load_reg64(tmp, a->vm);
257
+ vfp_load_reg64(tmp, a->vm);
258
fpst = fpstatus_ptr(FPST_FPCR);
259
tcg_rmode = tcg_const_i32(float_round_to_zero);
260
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
261
gen_helper_rintd(tmp, tmp, fpst);
262
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
263
- neon_store_reg64(tmp, a->vd);
264
+ vfp_store_reg64(tmp, a->vd);
265
tcg_temp_free_ptr(fpst);
266
tcg_temp_free_i64(tmp);
267
tcg_temp_free_i32(tcg_rmode);
268
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
269
}
270
271
tmp = tcg_temp_new_i64();
272
- neon_load_reg64(tmp, a->vm);
273
+ vfp_load_reg64(tmp, a->vm);
274
fpst = fpstatus_ptr(FPST_FPCR);
275
gen_helper_rintd_exact(tmp, tmp, fpst);
276
- neon_store_reg64(tmp, a->vd);
277
+ vfp_store_reg64(tmp, a->vd);
278
tcg_temp_free_ptr(fpst);
279
tcg_temp_free_i64(tmp);
280
return true;
281
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
282
vd = tcg_temp_new_i64();
283
vfp_load_reg32(vm, a->vm);
284
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
285
- neon_store_reg64(vd, a->vd);
286
+ vfp_store_reg64(vd, a->vd);
287
tcg_temp_free_i32(vm);
288
tcg_temp_free_i64(vd);
289
return true;
290
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
291
292
vd = tcg_temp_new_i32();
293
vm = tcg_temp_new_i64();
294
- neon_load_reg64(vm, a->vm);
295
+ vfp_load_reg64(vm, a->vm);
296
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
297
vfp_store_reg32(vd, a->vd);
298
tcg_temp_free_i32(vd);
299
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
300
/* u32 -> f64 */
301
gen_helper_vfp_uitod(vd, vm, fpst);
302
}
303
- neon_store_reg64(vd, a->vd);
304
+ vfp_store_reg64(vd, a->vd);
305
tcg_temp_free_i32(vm);
306
tcg_temp_free_i64(vd);
307
tcg_temp_free_ptr(fpst);
308
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
309
310
vm = tcg_temp_new_i64();
311
vd = tcg_temp_new_i32();
312
- neon_load_reg64(vm, a->vm);
313
+ vfp_load_reg64(vm, a->vm);
314
gen_helper_vjcvt(vd, vm, cpu_env);
315
vfp_store_reg32(vd, a->vd);
316
tcg_temp_free_i64(vm);
317
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
318
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
319
320
vd = tcg_temp_new_i64();
321
- neon_load_reg64(vd, a->vd);
322
+ vfp_load_reg64(vd, a->vd);
323
324
fpst = fpstatus_ptr(FPST_FPCR);
325
shift = tcg_const_i32(frac_bits);
326
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
327
g_assert_not_reached();
328
}
329
330
- neon_store_reg64(vd, a->vd);
331
+ vfp_store_reg64(vd, a->vd);
332
tcg_temp_free_i64(vd);
333
tcg_temp_free_i32(shift);
334
tcg_temp_free_ptr(fpst);
335
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
336
fpst = fpstatus_ptr(FPST_FPCR);
337
vm = tcg_temp_new_i64();
338
vd = tcg_temp_new_i32();
339
- neon_load_reg64(vm, a->vm);
340
+ vfp_load_reg64(vm, a->vm);
341
342
if (a->s) {
343
if (a->rz) {
344
--
104
--
345
2.20.1
105
2.34.1
346
347
diff view generated by jsdifflib
1
In arm_v7m_mmu_idx_for_secstate() we get the 'priv' level to pass to
1
From: Richard Henderson <richard.henderson@linaro.org>
2
armv7m_mmu_idx_for_secstate_and_priv() by calling arm_current_el().
3
This is incorrect when the security state being queried is not the
4
current one, because arm_current_el() uses the current security state
5
to determine which of the banked CONTROL.nPRIV bits to look at.
6
The effect was that if (for instance) Secure state was in privileged
7
mode but Non-Secure was not then we would return the wrong MMU index.
8
2
9
The only places where we are using this function in a way that could
3
Do not provide a fast-path for physical addresses,
10
trigger this bug are for the stack loads during a v8M function-return
4
as those will need to be validated for GPC.
11
and for the instruction fetch of a v8M SG insn.
12
5
13
Fix the bug by expanding out the M-profile version of the
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
arm_current_el() logic inline so it can use the passed in secstate
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
rather than env->v7m.secure.
8
Message-id: 20230620124418.805717-15-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/ptw.c | 44 +++++++++++++++++---------------------------
12
1 file changed, 17 insertions(+), 27 deletions(-)
16
13
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20201022164408.13214-1-peter.maydell@linaro.org
20
---
21
target/arm/m_helper.c | 3 ++-
22
1 file changed, 2 insertions(+), 1 deletion(-)
23
24
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/m_helper.c
16
--- a/target/arm/ptw.c
27
+++ b/target/arm/m_helper.c
17
+++ b/target/arm/ptw.c
28
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
18
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
29
/* Return the MMU index for a v7M CPU in the specified security state */
19
* From gdbstub, do not use softmmu so that we don't modify the
30
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
20
* state of the cpu at all, including softmmu tlb contents.
31
{
21
*/
32
- bool priv = arm_current_el(env) != 0;
22
- if (regime_is_stage2(s2_mmu_idx)) {
33
+ bool priv = arm_v7m_is_handler_mode(env) ||
23
- S1Translate s2ptw = {
34
+ !(env->v7m.control[secstate] & 1);
24
- .in_mmu_idx = s2_mmu_idx,
35
25
- .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
36
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
26
- .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
37
}
27
- .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
28
- : space == ARMSS_Realm ? ARMSS_Realm
29
- : ARMSS_NonSecure),
30
- .in_debug = true,
31
- };
32
- GetPhysAddrResult s2 = { };
33
+ S1Translate s2ptw = {
34
+ .in_mmu_idx = s2_mmu_idx,
35
+ .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
36
+ .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
37
+ .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
38
+ : space == ARMSS_Realm ? ARMSS_Realm
39
+ : ARMSS_NonSecure),
40
+ .in_debug = true,
41
+ };
42
+ GetPhysAddrResult s2 = { };
43
44
- if (get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
45
- false, &s2, fi)) {
46
- goto fail;
47
- }
48
- ptw->out_phys = s2.f.phys_addr;
49
- pte_attrs = s2.cacheattrs.attrs;
50
- ptw->out_secure = s2.f.attrs.secure;
51
- ptw->out_space = s2.f.attrs.space;
52
- } else {
53
- /* Regime is physical. */
54
- ptw->out_phys = addr;
55
- pte_attrs = 0;
56
- ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
57
- ptw->out_space = (s2_mmu_idx == ARMMMUIdx_Phys_S ? ARMSS_Secure
58
- : space == ARMSS_Realm ? ARMSS_Realm
59
- : ARMSS_NonSecure);
60
+ if (get_phys_addr_with_struct(env, &s2ptw, addr,
61
+ MMU_DATA_LOAD, &s2, fi)) {
62
+ goto fail;
63
}
64
+ ptw->out_phys = s2.f.phys_addr;
65
+ pte_attrs = s2.cacheattrs.attrs;
66
ptw->out_host = NULL;
67
ptw->out_rw = false;
68
+ ptw->out_secure = s2.f.attrs.secure;
69
+ ptw->out_space = s2.f.attrs.space;
70
} else {
71
#ifdef CONFIG_TCG
72
CPUTLBEntryFull *full;
38
--
73
--
39
2.20.1
74
2.34.1
40
41
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
When booting a CPU with EL3 using the -kernel flag, set up CPTR_EL3 so
3
Instead of passing this to get_phys_addr_lpae, stash it
4
that SVE will not trap to EL3.
4
in the S1Translate structure.
5
5
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20201030151541.11976-1-remi@remlab.net
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-16-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
hw/arm/boot.c | 3 +++
12
target/arm/ptw.c | 27 ++++++++++++---------------
12
1 file changed, 3 insertions(+)
13
1 file changed, 12 insertions(+), 15 deletions(-)
13
14
14
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/boot.c
17
--- a/target/arm/ptw.c
17
+++ b/hw/arm/boot.c
18
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
19
if (cpu_isar_feature(aa64_mte, cpu)) {
20
ARMSecuritySpace in_space;
20
env->cp15.scr_el3 |= SCR_ATA;
21
bool in_secure;
21
}
22
bool in_debug;
22
+ if (cpu_isar_feature(aa64_sve, cpu)) {
23
+ /*
23
+ env->cp15.cptr_el[3] |= CPTR_EZ;
24
+ * If this is stage 2 of a stage 1+2 page table walk, then this must
24
+ }
25
+ * be true if stage 1 is an EL0 access; otherwise this is ignored.
25
/* AArch64 kernels never boot in secure mode */
26
+ * Stage 2 is indicated by in_mmu_idx set to ARMMMUIdx_Stage2{,_S}.
26
assert(!info->secure_boot);
27
+ */
27
/* This hook is only supported for AArch32 currently:
28
+ bool in_s1_is_el0;
29
bool out_secure;
30
bool out_rw;
31
bool out_be;
32
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
33
} S1Translate;
34
35
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
36
- uint64_t address,
37
- MMUAccessType access_type, bool s1_is_el0,
38
+ uint64_t address, MMUAccessType access_type,
39
GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
40
41
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
42
@@ -XXX,XX +XXX,XX @@ static int check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, uint64_t tcr,
43
* @ptw: Current and next stage parameters for the walk.
44
* @address: virtual address to get physical address for
45
* @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
46
- * @s1_is_el0: if @ptw->in_mmu_idx is ARMMMUIdx_Stage2
47
- * (so this is a stage 2 page table walk),
48
- * must be true if this is stage 2 of a stage 1+2
49
- * walk for an EL0 access. If @mmu_idx is anything else,
50
- * @s1_is_el0 is ignored.
51
* @result: set on translation success,
52
* @fi: set to fault info if the translation fails
53
*/
54
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
55
uint64_t address,
56
- MMUAccessType access_type, bool s1_is_el0,
57
+ MMUAccessType access_type,
58
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
59
{
60
ARMCPU *cpu = env_archcpu(env);
61
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
62
result->f.prot = get_S2prot_noexecute(ap);
63
} else {
64
xn = extract64(attrs, 53, 2);
65
- result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
66
+ result->f.prot = get_S2prot(env, ap, xn, ptw->in_s1_is_el0);
67
}
68
} else {
69
int nse, ns = extract32(attrs, 5, 1);
70
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
71
bool ret, ipa_secure;
72
ARMCacheAttrs cacheattrs1;
73
ARMSecuritySpace ipa_space;
74
- bool is_el0;
75
uint64_t hcr;
76
77
ret = get_phys_addr_with_struct(env, ptw, address, access_type, result, fi);
78
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
79
ipa_secure = result->f.attrs.secure;
80
ipa_space = result->f.attrs.space;
81
82
- is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
83
+ ptw->in_s1_is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
84
ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
85
ptw->in_secure = ipa_secure;
86
ptw->in_space = ipa_space;
87
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
88
ret = get_phys_addr_pmsav8(env, ipa, access_type,
89
ptw->in_mmu_idx, is_secure, result, fi);
90
} else {
91
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type,
92
- is_el0, result, fi);
93
+ ret = get_phys_addr_lpae(env, ptw, ipa, access_type, result, fi);
94
}
95
fi->s2addr = ipa;
96
97
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
98
}
99
100
if (regime_using_lpae_format(env, mmu_idx)) {
101
- return get_phys_addr_lpae(env, ptw, address, access_type, false,
102
- result, fi);
103
+ return get_phys_addr_lpae(env, ptw, address, access_type, result, fi);
104
} else if (arm_feature(env, ARM_FEATURE_V7) ||
105
regime_sctlr(env, mmu_idx) & SCTLR_XP) {
106
return get_phys_addr_v6(env, ptw, address, access_type, result, fi);
28
--
107
--
29
2.20.1
108
2.34.1
30
109
31
110
diff view generated by jsdifflib
1
From: AlexChen <alex.chen@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In omap_lcd_interrupts(), the pointer omap_lcd is dereferinced before
3
This fixes a bug in which we failed to initialize
4
being check if it is valid, which may lead to NULL pointer dereference.
4
the result attributes properly after the memset.
5
So move the assignment to surface after checking that the omap_lcd is valid
6
and move surface_bits_per_pixel(surface) to after the surface assignment.
7
5
8
Reported-by: Euler Robot <euler.robot@huawei.com>
9
Signed-off-by: AlexChen <alex.chen@huawei.com>
10
Message-id: 5F9CDB8A.9000001@huawei.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-17-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/display/omap_lcdc.c | 10 +++++++---
12
target/arm/ptw.c | 11 +----------
15
1 file changed, 7 insertions(+), 3 deletions(-)
13
1 file changed, 1 insertion(+), 10 deletions(-)
16
14
17
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/display/omap_lcdc.c
17
--- a/target/arm/ptw.c
20
+++ b/hw/display/omap_lcdc.c
18
+++ b/target/arm/ptw.c
21
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
22
static void omap_update_display(void *opaque)
20
void *out_host;
23
{
21
} S1Translate;
24
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
22
25
- DisplaySurface *surface = qemu_console_surface(omap_lcd->con);
23
-static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
26
+ DisplaySurface *surface;
24
- uint64_t address, MMUAccessType access_type,
27
draw_line_func draw_line;
25
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
28
int size, height, first, last;
26
-
29
int width, linesize, step, bpp, frame_offset;
27
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
30
hwaddr frame_base;
28
target_ulong address,
31
29
MMUAccessType access_type,
32
- if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable ||
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
33
- !surface_bits_per_pixel(surface)) {
31
cacheattrs1 = result->cacheattrs;
34
+ if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable) {
32
memset(result, 0, sizeof(*result));
35
+ return;
33
36
+ }
34
- if (arm_feature(env, ARM_FEATURE_PMSA)) {
37
+
35
- ret = get_phys_addr_pmsav8(env, ipa, access_type,
38
+ surface = qemu_console_surface(omap_lcd->con);
36
- ptw->in_mmu_idx, is_secure, result, fi);
39
+ if (!surface_bits_per_pixel(surface)) {
37
- } else {
40
return;
38
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type, result, fi);
41
}
39
- }
42
40
+ ret = get_phys_addr_with_struct(env, ptw, ipa, access_type, result, fi);
41
fi->s2addr = ipa;
42
43
/* Combine the S1 and S2 perms. */
43
--
44
--
44
2.20.1
45
2.34.1
45
46
46
47
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 will shortly have users outside of translate-neon.c.inc.
3
The function takes the fields as filled in by
4
the Arm ARM pseudocode for TakeGPCException.
4
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-3-richard.henderson@linaro.org
8
Message-id: 20230620124418.805717-18-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/translate.c | 20 ++++++++++++++++++++
11
target/arm/syndrome.h | 10 ++++++++++
11
target/arm/translate-neon.c.inc | 19 -------------------
12
1 file changed, 10 insertions(+)
12
2 files changed, 20 insertions(+), 19 deletions(-)
13
13
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
16
--- a/target/arm/syndrome.h
17
+++ b/target/arm/translate.c
17
+++ b/target/arm/syndrome.h
18
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
18
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
19
return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
19
EC_SVEACCESSTRAP = 0x19,
20
EC_ERETTRAP = 0x1a,
21
EC_SMETRAP = 0x1d,
22
+ EC_GPC = 0x1e,
23
EC_INSNABORT = 0x20,
24
EC_INSNABORT_SAME_EL = 0x21,
25
EC_PCALIGNMENT = 0x22,
26
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
27
(cv << 24) | (cond << 20) | rm;
20
}
28
}
21
29
22
+/*
30
+static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc,
23
+ * Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
31
+ int cm, int s1ptw, int wnr, int fsc)
24
+ * where 0 is the least significant end of the register.
25
+ */
26
+static long neon_element_offset(int reg, int element, MemOp size)
27
+{
32
+{
28
+ int element_size = 1 << size;
33
+ /* TODO: FEAT_NV2 adds VNCR */
29
+ int ofs = element * element_size;
34
+ return (EC_GPC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (s2ptw << 21)
30
+#ifdef HOST_WORDS_BIGENDIAN
35
+ | (ind << 20) | (gpcsc << 14) | (cm << 8) | (s1ptw << 7)
31
+ /*
36
+ | (wnr << 6) | fsc;
32
+ * Calculate the offset assuming fully little-endian,
33
+ * then XOR to account for the order of the 8-byte units.
34
+ */
35
+ if (element_size < 8) {
36
+ ofs ^= 8 - element_size;
37
+ }
38
+#endif
39
+ return neon_full_reg_offset(reg) + ofs;
40
+}
37
+}
41
+
38
+
42
static inline long vfp_reg_offset(bool dp, unsigned reg)
39
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
43
{
40
{
44
if (dp) {
41
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
45
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate-neon.c.inc
48
+++ b/target/arm/translate-neon.c.inc
49
@@ -XXX,XX +XXX,XX @@ static inline int neon_3same_fp_size(DisasContext *s, int x)
50
#include "decode-neon-ls.c.inc"
51
#include "decode-neon-shared.c.inc"
52
53
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
54
- * where 0 is the least significant end of the register.
55
- */
56
-static inline long
57
-neon_element_offset(int reg, int element, MemOp size)
58
-{
59
- int element_size = 1 << size;
60
- int ofs = element * element_size;
61
-#ifdef HOST_WORDS_BIGENDIAN
62
- /* Calculate the offset assuming fully little-endian,
63
- * then XOR to account for the order of the 8-byte units.
64
- */
65
- if (element_size < 8) {
66
- ofs ^= 8 - element_size;
67
- }
68
-#endif
69
- return neon_full_reg_offset(reg) + ofs;
70
-}
71
-
72
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
73
{
74
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
75
--
42
--
76
2.20.1
43
2.34.1
77
78
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Model these off the aa64 read/write_vec_element functions.
3
Handle GPC Fault types in arm_deliver_fault, reporting as
4
Use it within translate-neon.c.inc. The new functions do
4
either a GPC exception at EL3, or falling through to insn
5
not allocate or free temps, so this rearranges the calling
5
or data aborts at various exception levels.
6
code a bit.
7
6
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: 20201030022618.785675-6-richard.henderson@linaro.org
9
Message-id: 20230620124418.805717-19-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@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/translate.c | 26 ++++
12
target/arm/cpu.h | 1 +
14
target/arm/translate-neon.c.inc | 256 ++++++++++++++++++++------------
13
target/arm/internals.h | 27 +++++++++++
15
2 files changed, 183 insertions(+), 99 deletions(-)
14
target/arm/helper.c | 5 ++
15
target/arm/tcg/tlb_helper.c | 96 +++++++++++++++++++++++++++++++++++--
16
4 files changed, 126 insertions(+), 3 deletions(-)
16
17
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.c
20
--- a/target/arm/cpu.h
20
+++ b/target/arm/translate.c
21
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
22
@@ -XXX,XX +XXX,XX @@
22
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
23
#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
24
#define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */
25
#define EXCP_VSERR 24
26
+#define EXCP_GPC 25 /* v9 Granule Protection Check Fault */
27
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
28
29
#define ARMV7M_EXCP_RESET 1
30
diff --git a/target/arm/internals.h b/target/arm/internals.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/internals.h
33
+++ b/target/arm/internals.h
34
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
35
ARMFault_ICacheMaint,
36
ARMFault_QEMU_NSCExec, /* v8M: NS executing in S&NSC memory */
37
ARMFault_QEMU_SFault, /* v8M: SecureFault INVTRAN, INVEP or AUVIOL */
38
+ ARMFault_GPCFOnWalk,
39
+ ARMFault_GPCFOnOutput,
40
} ARMFaultType;
41
42
+typedef enum ARMGPCF {
43
+ GPCF_None,
44
+ GPCF_AddressSize,
45
+ GPCF_Walk,
46
+ GPCF_EABT,
47
+ GPCF_Fail,
48
+} ARMGPCF;
49
+
50
/**
51
* ARMMMUFaultInfo: Information describing an ARM MMU Fault
52
* @type: Type of fault
53
+ * @gpcf: Subtype of ARMFault_GPCFOn{Walk,Output}.
54
* @level: Table walk level (for translation, access flag and permission faults)
55
* @domain: Domain of the fault address (for non-LPAE CPUs only)
56
* @s2addr: Address that caused a fault at stage 2
57
+ * @paddr: physical address that caused a fault for gpc
58
+ * @paddr_space: physical address space that caused a fault for gpc
59
* @stage2: True if we faulted at stage 2
60
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
61
* @s1ns: True if we faulted on a non-secure IPA while in secure state
62
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
63
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
64
struct ARMMMUFaultInfo {
65
ARMFaultType type;
66
+ ARMGPCF gpcf;
67
target_ulong s2addr;
68
+ target_ulong paddr;
69
+ ARMSecuritySpace paddr_space;
70
int level;
71
int domain;
72
bool stage2;
73
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
74
case ARMFault_Exclusive:
75
fsc = 0x35;
76
break;
77
+ case ARMFault_GPCFOnWalk:
78
+ assert(fi->level >= -1 && fi->level <= 3);
79
+ if (fi->level < 0) {
80
+ fsc = 0b100011;
81
+ } else {
82
+ fsc = 0b100100 | fi->level;
83
+ }
84
+ break;
85
+ case ARMFault_GPCFOnOutput:
86
+ fsc = 0b101000;
87
+ break;
88
default:
89
/* Other faults can't occur in a context that requires a
90
* long-format status code.
91
diff --git a/target/arm/helper.c b/target/arm/helper.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/helper.c
94
+++ b/target/arm/helper.c
95
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(CPUState *cs)
96
[EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
97
[EXCP_DIVBYZERO] = "v7M DIVBYZERO UsageFault",
98
[EXCP_VSERR] = "Virtual SERR",
99
+ [EXCP_GPC] = "Granule Protection Check",
100
};
101
102
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
103
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
104
}
105
106
switch (cs->exception_index) {
107
+ case EXCP_GPC:
108
+ qemu_log_mask(CPU_LOG_INT, "...with MFAR 0x%" PRIx64 "\n",
109
+ env->cp15.mfar_el3);
110
+ /* fall through */
111
case EXCP_PREFETCH_ABORT:
112
case EXCP_DATA_ABORT:
113
/*
114
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/tcg/tlb_helper.c
117
+++ b/target/arm/tcg/tlb_helper.c
118
@@ -XXX,XX +XXX,XX @@ static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
119
return fsr;
23
}
120
}
24
121
25
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
122
+static bool report_as_gpc_exception(ARMCPU *cpu, int current_el,
123
+ ARMMMUFaultInfo *fi)
26
+{
124
+{
27
+ long off = neon_element_offset(reg, ele, size);
125
+ bool ret;
28
+
126
+
29
+ switch (size) {
127
+ switch (fi->gpcf) {
30
+ case MO_32:
128
+ case GPCF_None:
31
+ tcg_gen_ld_i32(dest, cpu_env, off);
129
+ return false;
130
+ case GPCF_AddressSize:
131
+ case GPCF_Walk:
132
+ case GPCF_EABT:
133
+ /* R_PYTGX: GPT faults are reported as GPC. */
134
+ ret = true;
135
+ break;
136
+ case GPCF_Fail:
137
+ /*
138
+ * R_BLYPM: A GPF at EL3 is reported as insn or data abort.
139
+ * R_VBZMW, R_LXHQR: A GPF at EL[0-2] is reported as a GPC
140
+ * if SCR_EL3.GPF is set, otherwise an insn or data abort.
141
+ */
142
+ ret = (cpu->env.cp15.scr_el3 & SCR_GPF) && current_el != 3;
32
+ break;
143
+ break;
33
+ default:
144
+ default:
34
+ g_assert_not_reached();
145
+ g_assert_not_reached();
35
+ }
146
+ }
147
+
148
+ assert(cpu_isar_feature(aa64_rme, cpu));
149
+ assert(fi->type == ARMFault_GPCFOnWalk ||
150
+ fi->type == ARMFault_GPCFOnOutput);
151
+ if (fi->gpcf == GPCF_AddressSize) {
152
+ assert(fi->level == 0);
153
+ } else {
154
+ assert(fi->level >= 0 && fi->level <= 1);
155
+ }
156
+
157
+ return ret;
36
+}
158
+}
37
+
159
+
38
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
160
+static unsigned encode_gpcsc(ARMMMUFaultInfo *fi)
39
+{
161
+{
40
+ long off = neon_element_offset(reg, ele, size);
162
+ static uint8_t const gpcsc[] = {
41
+
163
+ [GPCF_AddressSize] = 0b000000,
42
+ switch (size) {
164
+ [GPCF_Walk] = 0b000100,
43
+ case MO_32:
165
+ [GPCF_Fail] = 0b001100,
44
+ tcg_gen_st_i32(src, cpu_env, off);
166
+ [GPCF_EABT] = 0b010100,
45
+ break;
167
+ };
46
+ default:
168
+
47
+ g_assert_not_reached();
169
+ /* Note that we've validated fi->gpcf and fi->level above. */
48
+ }
170
+ return gpcsc[fi->gpcf] | fi->level;
49
+}
171
+}
50
+
172
+
51
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
173
static G_NORETURN
174
void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
175
MMUAccessType access_type,
176
int mmu_idx, ARMMMUFaultInfo *fi)
52
{
177
{
53
TCGv_ptr ret = tcg_temp_new_ptr();
178
CPUARMState *env = &cpu->env;
54
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
179
- int target_el;
55
index XXXXXXX..XXXXXXX 100644
180
+ int target_el = exception_target_el(env);
56
--- a/target/arm/translate-neon.c.inc
181
+ int current_el = arm_current_el(env);
57
+++ b/target/arm/translate-neon.c.inc
182
bool same_el;
58
@@ -XXX,XX +XXX,XX @@ static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
183
uint32_t syn, exc, fsr, fsc;
59
* early. Since Q is 0 there are always just two passes, so instead
184
60
* of a complicated loop over each pass we just unroll.
185
- target_el = exception_target_el(env);
61
*/
186
+ if (report_as_gpc_exception(cpu, current_el, fi)) {
62
- tmp = neon_load_reg(a->vn, 0);
187
+ target_el = 3;
63
- tmp2 = neon_load_reg(a->vn, 1);
188
+
64
+ tmp = tcg_temp_new_i32();
189
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
65
+ tmp2 = tcg_temp_new_i32();
190
+
66
+ tmp3 = tcg_temp_new_i32();
191
+ syn = syn_gpc(fi->stage2 && fi->type == ARMFault_GPCFOnWalk,
67
+
192
+ access_type == MMU_INST_FETCH,
68
+ read_neon_element32(tmp, a->vn, 0, MO_32);
193
+ encode_gpcsc(fi), 0, fi->s1ptw,
69
+ read_neon_element32(tmp2, a->vn, 1, MO_32);
194
+ access_type == MMU_DATA_STORE, fsc);
70
fn(tmp, tmp, tmp2);
195
+
71
- tcg_temp_free_i32(tmp2);
196
+ env->cp15.mfar_el3 = fi->paddr;
72
197
+ switch (fi->paddr_space) {
73
- tmp3 = neon_load_reg(a->vm, 0);
198
+ case ARMSS_Secure:
74
- tmp2 = neon_load_reg(a->vm, 1);
199
+ break;
75
+ read_neon_element32(tmp3, a->vm, 0, MO_32);
200
+ case ARMSS_NonSecure:
76
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
201
+ env->cp15.mfar_el3 |= R_MFAR_NS_MASK;
77
fn(tmp3, tmp3, tmp2);
202
+ break;
78
- tcg_temp_free_i32(tmp2);
203
+ case ARMSS_Root:
79
204
+ env->cp15.mfar_el3 |= R_MFAR_NSE_MASK;
80
- neon_store_reg(a->vd, 0, tmp);
205
+ break;
81
- neon_store_reg(a->vd, 1, tmp3);
206
+ case ARMSS_Realm:
82
+ write_neon_element32(tmp, a->vd, 0, MO_32);
207
+ env->cp15.mfar_el3 |= R_MFAR_NSE_MASK | R_MFAR_NS_MASK;
83
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
208
+ break;
84
+
209
+ default:
85
+ tcg_temp_free_i32(tmp);
210
+ g_assert_not_reached();
86
+ tcg_temp_free_i32(tmp2);
211
+ }
87
+ tcg_temp_free_i32(tmp3);
212
+
88
return true;
213
+ exc = EXCP_GPC;
89
}
214
+ goto do_raise;
90
215
+ }
91
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
216
+
92
* 2-reg-and-shift operations, size < 3 case, where the
217
+ /* If SCR_EL3.GPF is unset, GPF may still be routed to EL2. */
93
* helper needs to be passed cpu_env.
218
+ if (fi->gpcf == GPCF_Fail && target_el < 2) {
94
*/
219
+ if (arm_hcr_el2_eff(env) & HCR_GPF) {
95
- TCGv_i32 constimm;
220
+ target_el = 2;
96
+ TCGv_i32 constimm, tmp;
221
+ }
97
int pass;
222
+ }
98
223
+
99
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
224
if (fi->stage2) {
100
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
225
target_el = 2;
101
* by immediate using the variable shift operations.
226
env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
102
*/
227
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
103
constimm = tcg_const_i32(dup_const(a->size, a->shift));
228
env->cp15.hpfar_el2 |= HPFAR_NS;
104
+ tmp = tcg_temp_new_i32();
105
106
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
107
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
108
+ read_neon_element32(tmp, a->vm, pass, MO_32);
109
fn(tmp, cpu_env, tmp, constimm);
110
- neon_store_reg(a->vd, pass, tmp);
111
+ write_neon_element32(tmp, a->vd, pass, MO_32);
112
}
113
+ tcg_temp_free_i32(tmp);
114
tcg_temp_free_i32(constimm);
115
return true;
116
}
117
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
118
constimm = tcg_const_i64(-a->shift);
119
rm1 = tcg_temp_new_i64();
120
rm2 = tcg_temp_new_i64();
121
+ rd = tcg_temp_new_i32();
122
123
/* Load both inputs first to avoid potential overwrite if rm == rd */
124
neon_load_reg64(rm1, a->vm);
125
neon_load_reg64(rm2, a->vm + 1);
126
127
shiftfn(rm1, rm1, constimm);
128
- rd = tcg_temp_new_i32();
129
narrowfn(rd, cpu_env, rm1);
130
- neon_store_reg(a->vd, 0, rd);
131
+ write_neon_element32(rd, a->vd, 0, MO_32);
132
133
shiftfn(rm2, rm2, constimm);
134
- rd = tcg_temp_new_i32();
135
narrowfn(rd, cpu_env, rm2);
136
- neon_store_reg(a->vd, 1, rd);
137
+ write_neon_element32(rd, a->vd, 1, MO_32);
138
139
+ tcg_temp_free_i32(rd);
140
tcg_temp_free_i64(rm1);
141
tcg_temp_free_i64(rm2);
142
tcg_temp_free_i64(constimm);
143
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
144
constimm = tcg_const_i32(imm);
145
146
/* Load all inputs first to avoid potential overwrite */
147
- rm1 = neon_load_reg(a->vm, 0);
148
- rm2 = neon_load_reg(a->vm, 1);
149
- rm3 = neon_load_reg(a->vm + 1, 0);
150
- rm4 = neon_load_reg(a->vm + 1, 1);
151
+ rm1 = tcg_temp_new_i32();
152
+ rm2 = tcg_temp_new_i32();
153
+ rm3 = tcg_temp_new_i32();
154
+ rm4 = tcg_temp_new_i32();
155
+ read_neon_element32(rm1, a->vm, 0, MO_32);
156
+ read_neon_element32(rm2, a->vm, 1, MO_32);
157
+ read_neon_element32(rm3, a->vm, 2, MO_32);
158
+ read_neon_element32(rm4, a->vm, 3, MO_32);
159
rtmp = tcg_temp_new_i64();
160
161
shiftfn(rm1, rm1, constimm);
162
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
163
tcg_temp_free_i32(rm2);
164
165
narrowfn(rm1, cpu_env, rtmp);
166
- neon_store_reg(a->vd, 0, rm1);
167
+ write_neon_element32(rm1, a->vd, 0, MO_32);
168
+ tcg_temp_free_i32(rm1);
169
170
shiftfn(rm3, rm3, constimm);
171
shiftfn(rm4, rm4, constimm);
172
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
173
174
narrowfn(rm3, cpu_env, rtmp);
175
tcg_temp_free_i64(rtmp);
176
- neon_store_reg(a->vd, 1, rm3);
177
+ write_neon_element32(rm3, a->vd, 1, MO_32);
178
+ tcg_temp_free_i32(rm3);
179
return true;
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
183
widen_mask = dup_const(a->size + 1, widen_mask);
184
}
185
186
- rm0 = neon_load_reg(a->vm, 0);
187
- rm1 = neon_load_reg(a->vm, 1);
188
+ rm0 = tcg_temp_new_i32();
189
+ rm1 = tcg_temp_new_i32();
190
+ read_neon_element32(rm0, a->vm, 0, MO_32);
191
+ read_neon_element32(rm1, a->vm, 1, MO_32);
192
tmp = tcg_temp_new_i64();
193
194
widenfn(tmp, rm0);
195
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
196
if (src1_wide) {
197
neon_load_reg64(rn0_64, a->vn);
198
} else {
199
- TCGv_i32 tmp = neon_load_reg(a->vn, 0);
200
+ TCGv_i32 tmp = tcg_temp_new_i32();
201
+ read_neon_element32(tmp, a->vn, 0, MO_32);
202
widenfn(rn0_64, tmp);
203
tcg_temp_free_i32(tmp);
204
}
205
- rm = neon_load_reg(a->vm, 0);
206
+ rm = tcg_temp_new_i32();
207
+ read_neon_element32(rm, a->vm, 0, MO_32);
208
209
widenfn(rm_64, rm);
210
tcg_temp_free_i32(rm);
211
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
212
if (src1_wide) {
213
neon_load_reg64(rn1_64, a->vn + 1);
214
} else {
215
- TCGv_i32 tmp = neon_load_reg(a->vn, 1);
216
+ TCGv_i32 tmp = tcg_temp_new_i32();
217
+ read_neon_element32(tmp, a->vn, 1, MO_32);
218
widenfn(rn1_64, tmp);
219
tcg_temp_free_i32(tmp);
220
}
221
- rm = neon_load_reg(a->vm, 1);
222
+ rm = tcg_temp_new_i32();
223
+ read_neon_element32(rm, a->vm, 1, MO_32);
224
225
neon_store_reg64(rn0_64, a->vd);
226
227
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
228
229
narrowfn(rd1, rn_64);
230
231
- neon_store_reg(a->vd, 0, rd0);
232
- neon_store_reg(a->vd, 1, rd1);
233
+ write_neon_element32(rd0, a->vd, 0, MO_32);
234
+ write_neon_element32(rd1, a->vd, 1, MO_32);
235
236
+ tcg_temp_free_i32(rd0);
237
+ tcg_temp_free_i32(rd1);
238
tcg_temp_free_i64(rn_64);
239
tcg_temp_free_i64(rm_64);
240
241
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
242
rd0 = tcg_temp_new_i64();
243
rd1 = tcg_temp_new_i64();
244
245
- rn = neon_load_reg(a->vn, 0);
246
- rm = neon_load_reg(a->vm, 0);
247
+ rn = tcg_temp_new_i32();
248
+ rm = tcg_temp_new_i32();
249
+ read_neon_element32(rn, a->vn, 0, MO_32);
250
+ read_neon_element32(rm, a->vm, 0, MO_32);
251
opfn(rd0, rn, rm);
252
- tcg_temp_free_i32(rn);
253
- tcg_temp_free_i32(rm);
254
255
- rn = neon_load_reg(a->vn, 1);
256
- rm = neon_load_reg(a->vm, 1);
257
+ read_neon_element32(rn, a->vn, 1, MO_32);
258
+ read_neon_element32(rm, a->vm, 1, MO_32);
259
opfn(rd1, rn, rm);
260
tcg_temp_free_i32(rn);
261
tcg_temp_free_i32(rm);
262
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
263
264
static inline TCGv_i32 neon_get_scalar(int size, int reg)
265
{
266
- TCGv_i32 tmp;
267
- if (size == 1) {
268
- tmp = neon_load_reg(reg & 7, reg >> 4);
269
+ TCGv_i32 tmp = tcg_temp_new_i32();
270
+ if (size == MO_16) {
271
+ read_neon_element32(tmp, reg & 7, reg >> 4, MO_32);
272
if (reg & 8) {
273
gen_neon_dup_high16(tmp);
274
} else {
275
gen_neon_dup_low16(tmp);
276
}
277
} else {
278
- tmp = neon_load_reg(reg & 15, reg >> 4);
279
+ read_neon_element32(tmp, reg & 15, reg >> 4, MO_32);
280
}
281
return tmp;
282
}
283
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
284
* perform an accumulation operation of that result into the
285
* destination.
286
*/
287
- TCGv_i32 scalar;
288
+ TCGv_i32 scalar, tmp;
289
int pass;
290
291
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
292
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
293
}
294
295
scalar = neon_get_scalar(a->size, a->vm);
296
+ tmp = tcg_temp_new_i32();
297
298
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
299
- TCGv_i32 tmp = neon_load_reg(a->vn, pass);
300
+ read_neon_element32(tmp, a->vn, pass, MO_32);
301
opfn(tmp, tmp, scalar);
302
if (accfn) {
303
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
304
+ TCGv_i32 rd = tcg_temp_new_i32();
305
+ read_neon_element32(rd, a->vd, pass, MO_32);
306
accfn(tmp, rd, tmp);
307
tcg_temp_free_i32(rd);
308
}
309
- neon_store_reg(a->vd, pass, tmp);
310
+ write_neon_element32(tmp, a->vd, pass, MO_32);
311
}
312
+ tcg_temp_free_i32(tmp);
313
tcg_temp_free_i32(scalar);
314
return true;
315
}
316
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
317
* performs a kind of fused op-then-accumulate using a helper
318
* function that takes all of rd, rn and the scalar at once.
319
*/
320
- TCGv_i32 scalar;
321
+ TCGv_i32 scalar, rn, rd;
322
int pass;
323
324
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
325
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
326
}
327
328
scalar = neon_get_scalar(a->size, a->vm);
329
+ rn = tcg_temp_new_i32();
330
+ rd = tcg_temp_new_i32();
331
332
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
333
- TCGv_i32 rn = neon_load_reg(a->vn, pass);
334
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
335
+ read_neon_element32(rn, a->vn, pass, MO_32);
336
+ read_neon_element32(rd, a->vd, pass, MO_32);
337
opfn(rd, cpu_env, rn, scalar, rd);
338
- tcg_temp_free_i32(rn);
339
- neon_store_reg(a->vd, pass, rd);
340
+ write_neon_element32(rd, a->vd, pass, MO_32);
341
}
342
+ tcg_temp_free_i32(rn);
343
+ tcg_temp_free_i32(rd);
344
tcg_temp_free_i32(scalar);
345
346
return true;
347
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
348
scalar = neon_get_scalar(a->size, a->vm);
349
350
/* Load all inputs before writing any outputs, in case of overlap */
351
- rn = neon_load_reg(a->vn, 0);
352
+ rn = tcg_temp_new_i32();
353
+ read_neon_element32(rn, a->vn, 0, MO_32);
354
rn0_64 = tcg_temp_new_i64();
355
opfn(rn0_64, rn, scalar);
356
- tcg_temp_free_i32(rn);
357
358
- rn = neon_load_reg(a->vn, 1);
359
+ read_neon_element32(rn, a->vn, 1, MO_32);
360
rn1_64 = tcg_temp_new_i64();
361
opfn(rn1_64, rn, scalar);
362
tcg_temp_free_i32(rn);
363
@@ -XXX,XX +XXX,XX @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
364
return false;
365
}
366
n <<= 3;
367
+ tmp = tcg_temp_new_i32();
368
if (a->op) {
369
- tmp = neon_load_reg(a->vd, 0);
370
+ read_neon_element32(tmp, a->vd, 0, MO_32);
371
} else {
372
- tmp = tcg_temp_new_i32();
373
tcg_gen_movi_i32(tmp, 0);
374
}
375
- tmp2 = neon_load_reg(a->vm, 0);
376
+ tmp2 = tcg_temp_new_i32();
377
+ read_neon_element32(tmp2, a->vm, 0, MO_32);
378
ptr1 = vfp_reg_ptr(true, a->vn);
379
tmp4 = tcg_const_i32(n);
380
gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp4);
381
- tcg_temp_free_i32(tmp);
382
+
383
if (a->op) {
384
- tmp = neon_load_reg(a->vd, 1);
385
+ read_neon_element32(tmp, a->vd, 1, MO_32);
386
} else {
387
- tmp = tcg_temp_new_i32();
388
tcg_gen_movi_i32(tmp, 0);
389
}
390
- tmp3 = neon_load_reg(a->vm, 1);
391
+ tmp3 = tcg_temp_new_i32();
392
+ read_neon_element32(tmp3, a->vm, 1, MO_32);
393
gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp4);
394
+ tcg_temp_free_i32(tmp);
395
tcg_temp_free_i32(tmp4);
396
tcg_temp_free_ptr(ptr1);
397
- neon_store_reg(a->vd, 0, tmp2);
398
- neon_store_reg(a->vd, 1, tmp3);
399
- tcg_temp_free_i32(tmp);
400
+
401
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
402
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
403
+ tcg_temp_free_i32(tmp2);
404
+ tcg_temp_free_i32(tmp3);
405
return true;
406
}
407
408
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
409
static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
410
{
411
int pass, half;
412
+ TCGv_i32 tmp[2];
413
414
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
415
return false;
416
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
417
return true;
418
}
419
420
- for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
421
- TCGv_i32 tmp[2];
422
+ tmp[0] = tcg_temp_new_i32();
423
+ tmp[1] = tcg_temp_new_i32();
424
425
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
426
for (half = 0; half < 2; half++) {
427
- tmp[half] = neon_load_reg(a->vm, pass * 2 + half);
428
+ read_neon_element32(tmp[half], a->vm, pass * 2 + half, MO_32);
429
switch (a->size) {
430
case 0:
431
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
432
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
433
g_assert_not_reached();
434
}
435
}
436
- neon_store_reg(a->vd, pass * 2, tmp[1]);
437
- neon_store_reg(a->vd, pass * 2 + 1, tmp[0]);
438
+ write_neon_element32(tmp[1], a->vd, pass * 2, MO_32);
439
+ write_neon_element32(tmp[0], a->vd, pass * 2 + 1, MO_32);
440
}
441
+
442
+ tcg_temp_free_i32(tmp[0]);
443
+ tcg_temp_free_i32(tmp[1]);
444
return true;
445
}
446
447
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
448
rm0_64 = tcg_temp_new_i64();
449
rm1_64 = tcg_temp_new_i64();
450
rd_64 = tcg_temp_new_i64();
451
- tmp = neon_load_reg(a->vm, pass * 2);
452
+
453
+ tmp = tcg_temp_new_i32();
454
+ read_neon_element32(tmp, a->vm, pass * 2, MO_32);
455
widenfn(rm0_64, tmp);
456
- tcg_temp_free_i32(tmp);
457
- tmp = neon_load_reg(a->vm, pass * 2 + 1);
458
+ read_neon_element32(tmp, a->vm, pass * 2 + 1, MO_32);
459
widenfn(rm1_64, tmp);
460
tcg_temp_free_i32(tmp);
461
+
462
opfn(rd_64, rm0_64, rm1_64);
463
tcg_temp_free_i64(rm0_64);
464
tcg_temp_free_i64(rm1_64);
465
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
466
narrowfn(rd0, cpu_env, rm);
467
neon_load_reg64(rm, a->vm + 1);
468
narrowfn(rd1, cpu_env, rm);
469
- neon_store_reg(a->vd, 0, rd0);
470
- neon_store_reg(a->vd, 1, rd1);
471
+ write_neon_element32(rd0, a->vd, 0, MO_32);
472
+ write_neon_element32(rd1, a->vd, 1, MO_32);
473
+ tcg_temp_free_i32(rd0);
474
+ tcg_temp_free_i32(rd1);
475
tcg_temp_free_i64(rm);
476
return true;
477
}
478
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
479
}
480
481
rd = tcg_temp_new_i64();
482
+ rm0 = tcg_temp_new_i32();
483
+ rm1 = tcg_temp_new_i32();
484
485
- rm0 = neon_load_reg(a->vm, 0);
486
- rm1 = neon_load_reg(a->vm, 1);
487
+ read_neon_element32(rm0, a->vm, 0, MO_32);
488
+ read_neon_element32(rm1, a->vm, 1, MO_32);
489
490
widenfn(rd, rm0);
491
tcg_gen_shli_i64(rd, rd, 8 << a->size);
492
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
493
494
fpst = fpstatus_ptr(FPST_STD);
495
ahp = get_ahp_flag();
496
- tmp = neon_load_reg(a->vm, 0);
497
+ tmp = tcg_temp_new_i32();
498
+ read_neon_element32(tmp, a->vm, 0, MO_32);
499
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
500
- tmp2 = neon_load_reg(a->vm, 1);
501
+ tmp2 = tcg_temp_new_i32();
502
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
503
gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
504
tcg_gen_shli_i32(tmp2, tmp2, 16);
505
tcg_gen_or_i32(tmp2, tmp2, tmp);
506
- tcg_temp_free_i32(tmp);
507
- tmp = neon_load_reg(a->vm, 2);
508
+ read_neon_element32(tmp, a->vm, 2, MO_32);
509
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
510
- tmp3 = neon_load_reg(a->vm, 3);
511
- neon_store_reg(a->vd, 0, tmp2);
512
+ tmp3 = tcg_temp_new_i32();
513
+ read_neon_element32(tmp3, a->vm, 3, MO_32);
514
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
515
+ tcg_temp_free_i32(tmp2);
516
gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
517
tcg_gen_shli_i32(tmp3, tmp3, 16);
518
tcg_gen_or_i32(tmp3, tmp3, tmp);
519
- neon_store_reg(a->vd, 1, tmp3);
520
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
521
+ tcg_temp_free_i32(tmp3);
522
tcg_temp_free_i32(tmp);
523
tcg_temp_free_i32(ahp);
524
tcg_temp_free_ptr(fpst);
525
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
526
fpst = fpstatus_ptr(FPST_STD);
527
ahp = get_ahp_flag();
528
tmp3 = tcg_temp_new_i32();
529
- tmp = neon_load_reg(a->vm, 0);
530
- tmp2 = neon_load_reg(a->vm, 1);
531
+ tmp2 = tcg_temp_new_i32();
532
+ tmp = tcg_temp_new_i32();
533
+ read_neon_element32(tmp, a->vm, 0, MO_32);
534
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
535
tcg_gen_ext16u_i32(tmp3, tmp);
536
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
537
- neon_store_reg(a->vd, 0, tmp3);
538
+ write_neon_element32(tmp3, a->vd, 0, MO_32);
539
tcg_gen_shri_i32(tmp, tmp, 16);
540
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
541
- neon_store_reg(a->vd, 1, tmp);
542
- tmp3 = tcg_temp_new_i32();
543
+ write_neon_element32(tmp, a->vd, 1, MO_32);
544
+ tcg_temp_free_i32(tmp);
545
tcg_gen_ext16u_i32(tmp3, tmp2);
546
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
547
- neon_store_reg(a->vd, 2, tmp3);
548
+ write_neon_element32(tmp3, a->vd, 2, MO_32);
549
+ tcg_temp_free_i32(tmp3);
550
tcg_gen_shri_i32(tmp2, tmp2, 16);
551
gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
552
- neon_store_reg(a->vd, 3, tmp2);
553
+ write_neon_element32(tmp2, a->vd, 3, MO_32);
554
+ tcg_temp_free_i32(tmp2);
555
tcg_temp_free_i32(ahp);
556
tcg_temp_free_ptr(fpst);
557
558
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
559
560
static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
561
{
562
+ TCGv_i32 tmp;
563
int pass;
564
565
/* Handle a 2-reg-misc operation by iterating 32 bits at a time */
566
@@ -XXX,XX +XXX,XX @@ static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
567
return true;
568
}
569
570
+ tmp = tcg_temp_new_i32();
571
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
572
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
573
+ read_neon_element32(tmp, a->vm, pass, MO_32);
574
fn(tmp, tmp);
575
- neon_store_reg(a->vd, pass, tmp);
576
+ write_neon_element32(tmp, a->vd, pass, MO_32);
577
}
578
+ tcg_temp_free_i32(tmp);
579
580
return true;
581
}
582
@@ -XXX,XX +XXX,XX @@ static bool trans_VTRN(DisasContext *s, arg_2misc *a)
583
return true;
584
}
585
586
- if (a->size == 2) {
587
+ tmp = tcg_temp_new_i32();
588
+ tmp2 = tcg_temp_new_i32();
589
+ if (a->size == MO_32) {
590
for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) {
591
- tmp = neon_load_reg(a->vm, pass);
592
- tmp2 = neon_load_reg(a->vd, pass + 1);
593
- neon_store_reg(a->vm, pass, tmp2);
594
- neon_store_reg(a->vd, pass + 1, tmp);
595
+ read_neon_element32(tmp, a->vm, pass, MO_32);
596
+ read_neon_element32(tmp2, a->vd, pass + 1, MO_32);
597
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
598
+ write_neon_element32(tmp, a->vd, pass + 1, MO_32);
599
}
600
} else {
601
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
602
- tmp = neon_load_reg(a->vm, pass);
603
- tmp2 = neon_load_reg(a->vd, pass);
604
- if (a->size == 0) {
605
+ read_neon_element32(tmp, a->vm, pass, MO_32);
606
+ read_neon_element32(tmp2, a->vd, pass, MO_32);
607
+ if (a->size == MO_8) {
608
gen_neon_trn_u8(tmp, tmp2);
609
} else {
610
gen_neon_trn_u16(tmp, tmp2);
611
}
612
- neon_store_reg(a->vm, pass, tmp2);
613
- neon_store_reg(a->vd, pass, tmp);
614
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
615
+ write_neon_element32(tmp, a->vd, pass, MO_32);
616
}
229
}
617
}
230
}
618
+ tcg_temp_free_i32(tmp);
231
- same_el = (arm_current_el(env) == target_el);
619
+ tcg_temp_free_i32(tmp2);
232
620
return true;
233
+ same_el = current_el == target_el;
621
}
234
fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
235
236
if (access_type == MMU_INST_FETCH) {
237
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
238
exc = EXCP_DATA_ABORT;
239
}
240
241
+ do_raise:
242
env->exception.vaddress = addr;
243
env->exception.fsr = fsr;
244
raise_exception(env, exc, syn, target_el);
622
--
245
--
623
2.20.1
246
2.34.1
624
625
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 seems a bit more readable than using offsetof CPU_DoubleU.
3
Place the check at the end of get_phys_addr_with_struct,
4
so that we check all physical results.
4
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-5-richard.henderson@linaro.org
8
Message-id: 20230620124418.805717-20-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/translate.c | 13 ++++---------
11
target/arm/ptw.c | 249 +++++++++++++++++++++++++++++++++++++++++++----
11
1 file changed, 4 insertions(+), 9 deletions(-)
12
1 file changed, 232 insertions(+), 17 deletions(-)
12
13
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
16
--- a/target/arm/ptw.c
16
+++ b/target/arm/translate.c
17
+++ b/target/arm/ptw.c
17
@@ -XXX,XX +XXX,XX @@ static long neon_element_offset(int reg, int element, MemOp size)
18
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
18
return neon_full_reg_offset(reg) + ofs;
19
void *out_host;
19
}
20
} S1Translate;
20
21
21
-static inline long vfp_reg_offset(bool dp, unsigned reg)
22
-static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
22
+/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
23
- target_ulong address,
23
+static long vfp_reg_offset(bool dp, unsigned reg)
24
- MMUAccessType access_type,
25
- GetPhysAddrResult *result,
26
- ARMMMUFaultInfo *fi);
27
+static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
28
+ target_ulong address,
29
+ MMUAccessType access_type,
30
+ GetPhysAddrResult *result,
31
+ ARMMMUFaultInfo *fi);
32
+
33
+static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
34
+ target_ulong address,
35
+ MMUAccessType access_type,
36
+ GetPhysAddrResult *result,
37
+ ARMMMUFaultInfo *fi);
38
39
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
40
static const uint8_t pamax_map[] = {
41
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
42
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
43
}
44
45
+static bool granule_protection_check(CPUARMState *env, uint64_t paddress,
46
+ ARMSecuritySpace pspace,
47
+ ARMMMUFaultInfo *fi)
48
+{
49
+ MemTxAttrs attrs = {
50
+ .secure = true,
51
+ .space = ARMSS_Root,
52
+ };
53
+ ARMCPU *cpu = env_archcpu(env);
54
+ uint64_t gpccr = env->cp15.gpccr_el3;
55
+ unsigned pps, pgs, l0gptsz, level = 0;
56
+ uint64_t tableaddr, pps_mask, align, entry, index;
57
+ AddressSpace *as;
58
+ MemTxResult result;
59
+ int gpi;
60
+
61
+ if (!FIELD_EX64(gpccr, GPCCR, GPC)) {
62
+ return true;
63
+ }
64
+
65
+ /*
66
+ * GPC Priority 1 (R_GMGRR):
67
+ * R_JWCSM: If the configuration of GPCCR_EL3 is invalid,
68
+ * the access fails as GPT walk fault at level 0.
69
+ */
70
+
71
+ /*
72
+ * Configuration of PPS to a value exceeding the implemented
73
+ * physical address size is invalid.
74
+ */
75
+ pps = FIELD_EX64(gpccr, GPCCR, PPS);
76
+ if (pps > FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE)) {
77
+ goto fault_walk;
78
+ }
79
+ pps = pamax_map[pps];
80
+ pps_mask = MAKE_64BIT_MASK(0, pps);
81
+
82
+ switch (FIELD_EX64(gpccr, GPCCR, SH)) {
83
+ case 0b10: /* outer shareable */
84
+ break;
85
+ case 0b00: /* non-shareable */
86
+ case 0b11: /* inner shareable */
87
+ /* Inner and Outer non-cacheable requires Outer shareable. */
88
+ if (FIELD_EX64(gpccr, GPCCR, ORGN) == 0 &&
89
+ FIELD_EX64(gpccr, GPCCR, IRGN) == 0) {
90
+ goto fault_walk;
91
+ }
92
+ break;
93
+ default: /* reserved */
94
+ goto fault_walk;
95
+ }
96
+
97
+ switch (FIELD_EX64(gpccr, GPCCR, PGS)) {
98
+ case 0b00: /* 4KB */
99
+ pgs = 12;
100
+ break;
101
+ case 0b01: /* 64KB */
102
+ pgs = 16;
103
+ break;
104
+ case 0b10: /* 16KB */
105
+ pgs = 14;
106
+ break;
107
+ default: /* reserved */
108
+ goto fault_walk;
109
+ }
110
+
111
+ /* Note this field is read-only and fixed at reset. */
112
+ l0gptsz = 30 + FIELD_EX64(gpccr, GPCCR, L0GPTSZ);
113
+
114
+ /*
115
+ * GPC Priority 2: Secure, Realm or Root address exceeds PPS.
116
+ * R_CPDSB: A NonSecure physical address input exceeding PPS
117
+ * does not experience any fault.
118
+ */
119
+ if (paddress & ~pps_mask) {
120
+ if (pspace == ARMSS_NonSecure) {
121
+ return true;
122
+ }
123
+ goto fault_size;
124
+ }
125
+
126
+ /* GPC Priority 3: the base address of GPTBR_EL3 exceeds PPS. */
127
+ tableaddr = env->cp15.gptbr_el3 << 12;
128
+ if (tableaddr & ~pps_mask) {
129
+ goto fault_size;
130
+ }
131
+
132
+ /*
133
+ * BADDR is aligned per a function of PPS and L0GPTSZ.
134
+ * These bits of GPTBR_EL3 are RES0, but are not a configuration error,
135
+ * unlike the RES0 bits of the GPT entries (R_XNKFZ).
136
+ */
137
+ align = MAX(pps - l0gptsz + 3, 12);
138
+ align = MAKE_64BIT_MASK(0, align);
139
+ tableaddr &= ~align;
140
+
141
+ as = arm_addressspace(env_cpu(env), attrs);
142
+
143
+ /* Level 0 lookup. */
144
+ index = extract64(paddress, l0gptsz, pps - l0gptsz);
145
+ tableaddr += index * 8;
146
+ entry = address_space_ldq_le(as, tableaddr, attrs, &result);
147
+ if (result != MEMTX_OK) {
148
+ goto fault_eabt;
149
+ }
150
+
151
+ switch (extract32(entry, 0, 4)) {
152
+ case 1: /* block descriptor */
153
+ if (entry >> 8) {
154
+ goto fault_walk; /* RES0 bits not 0 */
155
+ }
156
+ gpi = extract32(entry, 4, 4);
157
+ goto found;
158
+ case 3: /* table descriptor */
159
+ tableaddr = entry & ~0xf;
160
+ align = MAX(l0gptsz - pgs - 1, 12);
161
+ align = MAKE_64BIT_MASK(0, align);
162
+ if (tableaddr & (~pps_mask | align)) {
163
+ goto fault_walk; /* RES0 bits not 0 */
164
+ }
165
+ break;
166
+ default: /* invalid */
167
+ goto fault_walk;
168
+ }
169
+
170
+ /* Level 1 lookup */
171
+ level = 1;
172
+ index = extract64(paddress, pgs + 4, l0gptsz - pgs - 4);
173
+ tableaddr += index * 8;
174
+ entry = address_space_ldq_le(as, tableaddr, attrs, &result);
175
+ if (result != MEMTX_OK) {
176
+ goto fault_eabt;
177
+ }
178
+
179
+ switch (extract32(entry, 0, 4)) {
180
+ case 1: /* contiguous descriptor */
181
+ if (entry >> 10) {
182
+ goto fault_walk; /* RES0 bits not 0 */
183
+ }
184
+ /*
185
+ * Because the softmmu tlb only works on units of TARGET_PAGE_SIZE,
186
+ * and because we cannot invalidate by pa, and thus will always
187
+ * flush entire tlbs, we don't actually care about the range here
188
+ * and can simply extract the GPI as the result.
189
+ */
190
+ if (extract32(entry, 8, 2) == 0) {
191
+ goto fault_walk; /* reserved contig */
192
+ }
193
+ gpi = extract32(entry, 4, 4);
194
+ break;
195
+ default:
196
+ index = extract64(paddress, pgs, 4);
197
+ gpi = extract64(entry, index * 4, 4);
198
+ break;
199
+ }
200
+
201
+ found:
202
+ switch (gpi) {
203
+ case 0b0000: /* no access */
204
+ break;
205
+ case 0b1111: /* all access */
206
+ return true;
207
+ case 0b1000:
208
+ case 0b1001:
209
+ case 0b1010:
210
+ case 0b1011:
211
+ if (pspace == (gpi & 3)) {
212
+ return true;
213
+ }
214
+ break;
215
+ default:
216
+ goto fault_walk; /* reserved */
217
+ }
218
+
219
+ fi->gpcf = GPCF_Fail;
220
+ goto fault_common;
221
+ fault_eabt:
222
+ fi->gpcf = GPCF_EABT;
223
+ goto fault_common;
224
+ fault_size:
225
+ fi->gpcf = GPCF_AddressSize;
226
+ goto fault_common;
227
+ fault_walk:
228
+ fi->gpcf = GPCF_Walk;
229
+ fault_common:
230
+ fi->level = level;
231
+ fi->paddr = paddress;
232
+ fi->paddr_space = pspace;
233
+ return false;
234
+}
235
+
236
static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
24
{
237
{
25
if (dp) {
238
/*
26
- return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
239
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
27
+ return neon_element_offset(reg, 0, MO_64);
240
};
28
} else {
241
GetPhysAddrResult s2 = { };
29
- long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
242
30
- if (reg & 1) {
243
- if (get_phys_addr_with_struct(env, &s2ptw, addr,
31
- ofs += offsetof(CPU_DoubleU, l.upper);
244
- MMU_DATA_LOAD, &s2, fi)) {
32
- } else {
245
+ if (get_phys_addr_gpc(env, &s2ptw, addr, MMU_DATA_LOAD, &s2, fi)) {
33
- ofs += offsetof(CPU_DoubleU, l.lower);
246
goto fail;
34
- }
247
}
35
- return ofs;
248
+
36
+ return neon_element_offset(reg >> 1, reg & 1, MO_32);
249
ptw->out_phys = s2.f.phys_addr;
250
pte_attrs = s2.cacheattrs.attrs;
251
ptw->out_host = NULL;
252
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
253
254
fail:
255
assert(fi->type != ARMFault_None);
256
+ if (fi->type == ARMFault_GPCFOnOutput) {
257
+ fi->type = ARMFault_GPCFOnWalk;
258
+ }
259
fi->s2addr = addr;
260
fi->stage2 = true;
261
fi->s1ptw = true;
262
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
263
ARMMMUFaultInfo *fi)
264
{
265
uint8_t memattr = 0x00; /* Device nGnRnE */
266
- uint8_t shareability = 0; /* non-sharable */
267
+ uint8_t shareability = 0; /* non-shareable */
268
int r_el;
269
270
switch (mmu_idx) {
271
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
272
} else {
273
memattr = 0x44; /* Normal, NC, No */
274
}
275
- shareability = 2; /* outer sharable */
276
+ shareability = 2; /* outer shareable */
277
}
278
result->cacheattrs.is_s2_format = false;
279
break;
280
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
281
ARMSecuritySpace ipa_space;
282
uint64_t hcr;
283
284
- ret = get_phys_addr_with_struct(env, ptw, address, access_type, result, fi);
285
+ ret = get_phys_addr_nogpc(env, ptw, address, access_type, result, fi);
286
287
/* If S1 fails, return early. */
288
if (ret) {
289
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
290
cacheattrs1 = result->cacheattrs;
291
memset(result, 0, sizeof(*result));
292
293
- ret = get_phys_addr_with_struct(env, ptw, ipa, access_type, result, fi);
294
+ ret = get_phys_addr_nogpc(env, ptw, ipa, access_type, result, fi);
295
fi->s2addr = ipa;
296
297
/* Combine the S1 and S2 perms. */
298
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
299
return false;
300
}
301
302
-static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
303
+static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
304
target_ulong address,
305
MMUAccessType access_type,
306
GetPhysAddrResult *result,
307
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
37
}
308
}
38
}
309
}
39
310
311
+static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
312
+ target_ulong address,
313
+ MMUAccessType access_type,
314
+ GetPhysAddrResult *result,
315
+ ARMMMUFaultInfo *fi)
316
+{
317
+ if (get_phys_addr_nogpc(env, ptw, address, access_type, result, fi)) {
318
+ return true;
319
+ }
320
+ if (!granule_protection_check(env, result->f.phys_addr,
321
+ result->f.attrs.space, fi)) {
322
+ fi->type = ARMFault_GPCFOnOutput;
323
+ return true;
324
+ }
325
+ return false;
326
+}
327
+
328
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
329
MMUAccessType access_type, ARMMMUIdx mmu_idx,
330
bool is_secure, GetPhysAddrResult *result,
331
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
332
.in_secure = is_secure,
333
.in_space = arm_secure_to_space(is_secure),
334
};
335
- return get_phys_addr_with_struct(env, &ptw, address, access_type,
336
- result, fi);
337
+ return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
338
}
339
340
bool get_phys_addr(CPUARMState *env, target_ulong address,
341
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
342
343
ptw.in_space = ss;
344
ptw.in_secure = arm_space_is_secure(ss);
345
- return get_phys_addr_with_struct(env, &ptw, address, access_type,
346
- result, fi);
347
+ return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
348
}
349
350
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
351
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
352
ARMMMUFaultInfo fi = {};
353
bool ret;
354
355
- ret = get_phys_addr_with_struct(env, &ptw, addr, MMU_DATA_LOAD, &res, &fi);
356
+ ret = get_phys_addr_gpc(env, &ptw, addr, MMU_DATA_LOAD, &res, &fi);
357
*attrs = res.f.attrs;
358
359
if (ret) {
40
--
360
--
41
2.20.1
361
2.34.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
Replace all uses of neon_load/store_reg64 within translate-neon.c.inc.
3
Add an x-rme cpu property to enable FEAT_RME.
4
Add an x-l0gptsz property to set GPCCR_EL3.L0GPTSZ,
5
for testing various possible configurations.
6
7
We're not currently completely sure whether FEAT_RME will
8
be OK to enable purely as a CPU-level property, or if it will
9
need board co-operation, so we're making these experimental
10
x- properties, so that the people developing the system
11
level software for RME can try to start using this and let
12
us know how it goes. The command line syntax for enabling
13
this will change in future, without backwards-compatibility.
4
14
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-9-richard.henderson@linaro.org
16
Message-id: 20230620124418.805717-21-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
19
---
10
target/arm/translate.c | 26 +++++++++
20
target/arm/tcg/cpu64.c | 53 ++++++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-neon.c.inc | 94 ++++++++++++++++-----------------
21
1 file changed, 53 insertions(+)
12
2 files changed, 73 insertions(+), 47 deletions(-)
13
22
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
23
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
25
--- a/target/arm/tcg/cpu64.c
17
+++ b/target/arm/translate.c
26
+++ b/target/arm/tcg/cpu64.c
18
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
27
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
19
}
28
cpu->sve_max_vq = max_vq;
20
}
29
}
21
30
22
+static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
31
+static bool cpu_arm_get_rme(Object *obj, Error **errp)
23
+{
32
+{
24
+ long off = neon_element_offset(reg, ele, memop);
33
+ ARMCPU *cpu = ARM_CPU(obj);
34
+ return cpu_isar_feature(aa64_rme, cpu);
35
+}
25
+
36
+
26
+ switch (memop) {
37
+static void cpu_arm_set_rme(Object *obj, bool value, Error **errp)
27
+ case MO_Q:
38
+{
28
+ tcg_gen_ld_i64(dest, cpu_env, off);
39
+ ARMCPU *cpu = ARM_CPU(obj);
40
+ uint64_t t;
41
+
42
+ t = cpu->isar.id_aa64pfr0;
43
+ t = FIELD_DP64(t, ID_AA64PFR0, RME, value);
44
+ cpu->isar.id_aa64pfr0 = t;
45
+}
46
+
47
+static void cpu_max_set_l0gptsz(Object *obj, Visitor *v, const char *name,
48
+ void *opaque, Error **errp)
49
+{
50
+ ARMCPU *cpu = ARM_CPU(obj);
51
+ uint32_t value;
52
+
53
+ if (!visit_type_uint32(v, name, &value, errp)) {
54
+ return;
55
+ }
56
+
57
+ /* Encode the value for the GPCCR_EL3 field. */
58
+ switch (value) {
59
+ case 30:
60
+ case 34:
61
+ case 36:
62
+ case 39:
63
+ cpu->reset_l0gptsz = value - 30;
29
+ break;
64
+ break;
30
+ default:
65
+ default:
31
+ g_assert_not_reached();
66
+ error_setg(errp, "invalid value for l0gptsz");
67
+ error_append_hint(errp, "valid values are 30, 34, 36, 39\n");
68
+ break;
32
+ }
69
+ }
33
+}
70
+}
34
+
71
+
35
static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
72
+static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
36
{
73
+ void *opaque, Error **errp)
37
long off = neon_element_offset(reg, ele, memop);
38
@@ -XXX,XX +XXX,XX @@ static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
39
}
40
}
41
42
+static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
43
+{
74
+{
44
+ long off = neon_element_offset(reg, ele, memop);
75
+ ARMCPU *cpu = ARM_CPU(obj);
76
+ uint32_t value = cpu->reset_l0gptsz + 30;
45
+
77
+
46
+ switch (memop) {
78
+ visit_type_uint32(v, name, &value, errp);
47
+ case MO_64:
48
+ tcg_gen_st_i64(src, cpu_env, off);
49
+ break;
50
+ default:
51
+ g_assert_not_reached();
52
+ }
53
+}
79
+}
54
+
80
+
55
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
81
static Property arm_cpu_lpa2_property =
56
{
82
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
57
TCGv_ptr ret = tcg_temp_new_ptr();
83
58
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
84
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
59
index XXXXXXX..XXXXXXX 100644
85
aarch64_add_sme_properties(obj);
60
--- a/target/arm/translate-neon.c.inc
86
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
61
+++ b/target/arm/translate-neon.c.inc
87
cpu_max_set_sve_max_vq, NULL, NULL);
62
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_64(DisasContext *s, arg_2reg_shift *a,
88
+ object_property_add_bool(obj, "x-rme", cpu_arm_get_rme, cpu_arm_set_rme);
63
for (pass = 0; pass < a->q + 1; pass++) {
89
+ object_property_add(obj, "x-l0gptsz", "uint32", cpu_max_get_l0gptsz,
64
TCGv_i64 tmp = tcg_temp_new_i64();
90
+ cpu_max_set_l0gptsz, NULL, NULL);
65
91
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
66
- neon_load_reg64(tmp, a->vm + pass);
67
+ read_neon_element64(tmp, a->vm, pass, MO_64);
68
fn(tmp, cpu_env, tmp, constimm);
69
- neon_store_reg64(tmp, a->vd + pass);
70
+ write_neon_element64(tmp, a->vd, pass, MO_64);
71
tcg_temp_free_i64(tmp);
72
}
73
tcg_temp_free_i64(constimm);
74
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
75
rd = tcg_temp_new_i32();
76
77
/* Load both inputs first to avoid potential overwrite if rm == rd */
78
- neon_load_reg64(rm1, a->vm);
79
- neon_load_reg64(rm2, a->vm + 1);
80
+ read_neon_element64(rm1, a->vm, 0, MO_64);
81
+ read_neon_element64(rm2, a->vm, 1, MO_64);
82
83
shiftfn(rm1, rm1, constimm);
84
narrowfn(rd, cpu_env, rm1);
85
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
86
tcg_gen_shli_i64(tmp, tmp, a->shift);
87
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
88
}
89
- neon_store_reg64(tmp, a->vd);
90
+ write_neon_element64(tmp, a->vd, 0, MO_64);
91
92
widenfn(tmp, rm1);
93
tcg_temp_free_i32(rm1);
94
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
95
tcg_gen_shli_i64(tmp, tmp, a->shift);
96
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
97
}
98
- neon_store_reg64(tmp, a->vd + 1);
99
+ write_neon_element64(tmp, a->vd, 1, MO_64);
100
tcg_temp_free_i64(tmp);
101
return true;
102
}
92
}
103
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
93
104
rm_64 = tcg_temp_new_i64();
105
106
if (src1_wide) {
107
- neon_load_reg64(rn0_64, a->vn);
108
+ read_neon_element64(rn0_64, a->vn, 0, MO_64);
109
} else {
110
TCGv_i32 tmp = tcg_temp_new_i32();
111
read_neon_element32(tmp, a->vn, 0, MO_32);
112
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
113
* avoid incorrect results if a narrow input overlaps with the result.
114
*/
115
if (src1_wide) {
116
- neon_load_reg64(rn1_64, a->vn + 1);
117
+ read_neon_element64(rn1_64, a->vn, 1, MO_64);
118
} else {
119
TCGv_i32 tmp = tcg_temp_new_i32();
120
read_neon_element32(tmp, a->vn, 1, MO_32);
121
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
122
rm = tcg_temp_new_i32();
123
read_neon_element32(rm, a->vm, 1, MO_32);
124
125
- neon_store_reg64(rn0_64, a->vd);
126
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
127
128
widenfn(rm_64, rm);
129
tcg_temp_free_i32(rm);
130
opfn(rn1_64, rn1_64, rm_64);
131
- neon_store_reg64(rn1_64, a->vd + 1);
132
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
133
134
tcg_temp_free_i64(rn0_64);
135
tcg_temp_free_i64(rn1_64);
136
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
137
rd0 = tcg_temp_new_i32();
138
rd1 = tcg_temp_new_i32();
139
140
- neon_load_reg64(rn_64, a->vn);
141
- neon_load_reg64(rm_64, a->vm);
142
+ read_neon_element64(rn_64, a->vn, 0, MO_64);
143
+ read_neon_element64(rm_64, a->vm, 0, MO_64);
144
145
opfn(rn_64, rn_64, rm_64);
146
147
narrowfn(rd0, rn_64);
148
149
- neon_load_reg64(rn_64, a->vn + 1);
150
- neon_load_reg64(rm_64, a->vm + 1);
151
+ read_neon_element64(rn_64, a->vn, 1, MO_64);
152
+ read_neon_element64(rm_64, a->vm, 1, MO_64);
153
154
opfn(rn_64, rn_64, rm_64);
155
156
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
157
/* Don't store results until after all loads: they might overlap */
158
if (accfn) {
159
tmp = tcg_temp_new_i64();
160
- neon_load_reg64(tmp, a->vd);
161
+ read_neon_element64(tmp, a->vd, 0, MO_64);
162
accfn(tmp, tmp, rd0);
163
- neon_store_reg64(tmp, a->vd);
164
- neon_load_reg64(tmp, a->vd + 1);
165
+ write_neon_element64(tmp, a->vd, 0, MO_64);
166
+ read_neon_element64(tmp, a->vd, 1, MO_64);
167
accfn(tmp, tmp, rd1);
168
- neon_store_reg64(tmp, a->vd + 1);
169
+ write_neon_element64(tmp, a->vd, 1, MO_64);
170
tcg_temp_free_i64(tmp);
171
} else {
172
- neon_store_reg64(rd0, a->vd);
173
- neon_store_reg64(rd1, a->vd + 1);
174
+ write_neon_element64(rd0, a->vd, 0, MO_64);
175
+ write_neon_element64(rd1, a->vd, 1, MO_64);
176
}
177
178
tcg_temp_free_i64(rd0);
179
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
180
181
if (accfn) {
182
TCGv_i64 t64 = tcg_temp_new_i64();
183
- neon_load_reg64(t64, a->vd);
184
+ read_neon_element64(t64, a->vd, 0, MO_64);
185
accfn(t64, t64, rn0_64);
186
- neon_store_reg64(t64, a->vd);
187
- neon_load_reg64(t64, a->vd + 1);
188
+ write_neon_element64(t64, a->vd, 0, MO_64);
189
+ read_neon_element64(t64, a->vd, 1, MO_64);
190
accfn(t64, t64, rn1_64);
191
- neon_store_reg64(t64, a->vd + 1);
192
+ write_neon_element64(t64, a->vd, 1, MO_64);
193
tcg_temp_free_i64(t64);
194
} else {
195
- neon_store_reg64(rn0_64, a->vd);
196
- neon_store_reg64(rn1_64, a->vd + 1);
197
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
198
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
199
}
200
tcg_temp_free_i64(rn0_64);
201
tcg_temp_free_i64(rn1_64);
202
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
203
right = tcg_temp_new_i64();
204
dest = tcg_temp_new_i64();
205
206
- neon_load_reg64(right, a->vn);
207
- neon_load_reg64(left, a->vm);
208
+ read_neon_element64(right, a->vn, 0, MO_64);
209
+ read_neon_element64(left, a->vm, 0, MO_64);
210
tcg_gen_extract2_i64(dest, right, left, a->imm * 8);
211
- neon_store_reg64(dest, a->vd);
212
+ write_neon_element64(dest, a->vd, 0, MO_64);
213
214
tcg_temp_free_i64(left);
215
tcg_temp_free_i64(right);
216
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
217
destright = tcg_temp_new_i64();
218
219
if (a->imm < 8) {
220
- neon_load_reg64(right, a->vn);
221
- neon_load_reg64(middle, a->vn + 1);
222
+ read_neon_element64(right, a->vn, 0, MO_64);
223
+ read_neon_element64(middle, a->vn, 1, MO_64);
224
tcg_gen_extract2_i64(destright, right, middle, a->imm * 8);
225
- neon_load_reg64(left, a->vm);
226
+ read_neon_element64(left, a->vm, 0, MO_64);
227
tcg_gen_extract2_i64(destleft, middle, left, a->imm * 8);
228
} else {
229
- neon_load_reg64(right, a->vn + 1);
230
- neon_load_reg64(middle, a->vm);
231
+ read_neon_element64(right, a->vn, 1, MO_64);
232
+ read_neon_element64(middle, a->vm, 0, MO_64);
233
tcg_gen_extract2_i64(destright, right, middle, (a->imm - 8) * 8);
234
- neon_load_reg64(left, a->vm + 1);
235
+ read_neon_element64(left, a->vm, 1, MO_64);
236
tcg_gen_extract2_i64(destleft, middle, left, (a->imm - 8) * 8);
237
}
238
239
- neon_store_reg64(destright, a->vd);
240
- neon_store_reg64(destleft, a->vd + 1);
241
+ write_neon_element64(destright, a->vd, 0, MO_64);
242
+ write_neon_element64(destleft, a->vd, 1, MO_64);
243
244
tcg_temp_free_i64(destright);
245
tcg_temp_free_i64(destleft);
246
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
247
248
if (accfn) {
249
TCGv_i64 tmp64 = tcg_temp_new_i64();
250
- neon_load_reg64(tmp64, a->vd + pass);
251
+ read_neon_element64(tmp64, a->vd, pass, MO_64);
252
accfn(rd_64, tmp64, rd_64);
253
tcg_temp_free_i64(tmp64);
254
}
255
- neon_store_reg64(rd_64, a->vd + pass);
256
+ write_neon_element64(rd_64, a->vd, pass, MO_64);
257
tcg_temp_free_i64(rd_64);
258
}
259
return true;
260
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
261
rd0 = tcg_temp_new_i32();
262
rd1 = tcg_temp_new_i32();
263
264
- neon_load_reg64(rm, a->vm);
265
+ read_neon_element64(rm, a->vm, 0, MO_64);
266
narrowfn(rd0, cpu_env, rm);
267
- neon_load_reg64(rm, a->vm + 1);
268
+ read_neon_element64(rm, a->vm, 1, MO_64);
269
narrowfn(rd1, cpu_env, rm);
270
write_neon_element32(rd0, a->vd, 0, MO_32);
271
write_neon_element32(rd1, a->vd, 1, MO_32);
272
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
273
274
widenfn(rd, rm0);
275
tcg_gen_shli_i64(rd, rd, 8 << a->size);
276
- neon_store_reg64(rd, a->vd);
277
+ write_neon_element64(rd, a->vd, 0, MO_64);
278
widenfn(rd, rm1);
279
tcg_gen_shli_i64(rd, rd, 8 << a->size);
280
- neon_store_reg64(rd, a->vd + 1);
281
+ write_neon_element64(rd, a->vd, 1, MO_64);
282
283
tcg_temp_free_i64(rd);
284
tcg_temp_free_i32(rm0);
285
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
286
rm = tcg_temp_new_i64();
287
rd = tcg_temp_new_i64();
288
for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
289
- neon_load_reg64(rm, a->vm + pass);
290
- neon_load_reg64(rd, a->vd + pass);
291
- neon_store_reg64(rm, a->vd + pass);
292
- neon_store_reg64(rd, a->vm + pass);
293
+ read_neon_element64(rm, a->vm, pass, MO_64);
294
+ read_neon_element64(rd, a->vd, pass, MO_64);
295
+ write_neon_element64(rm, a->vd, pass, MO_64);
296
+ write_neon_element64(rd, a->vm, pass, MO_64);
297
}
298
tcg_temp_free_i64(rm);
299
tcg_temp_free_i64(rd);
300
--
94
--
301
2.20.1
95
2.34.1
302
303
diff view generated by jsdifflib
1
The helper functions for performing the udot/sdot operations against
1
From: Richard Henderson <richard.henderson@linaro.org>
2
a scalar were not using an address-swizzling macro when converting
3
the index of the scalar element into a pointer into the vm array.
4
This had no effect on little-endian hosts but meant we generated
5
incorrect results on big-endian hosts.
6
2
7
For these insns, the index is indexing over group of 4 8-bit values,
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
so 32 bits per indexed entity, and H4() is therefore what we want.
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
(For Neon the only possible input indexes are 0 and 1.)
5
Message-id: 20230622143046.1578160-1-richard.henderson@linaro.org
6
[PMM: fixed typo; note experimental status in emulation.rst too]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
docs/system/arm/cpu-features.rst | 23 +++++++++++++++++++++++
10
docs/system/arm/emulation.rst | 1 +
11
2 files changed, 24 insertions(+)
10
12
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20201028191712.4910-3-peter.maydell@linaro.org
15
---
16
target/arm/vec_helper.c | 4 ++--
17
1 file changed, 2 insertions(+), 2 deletions(-)
18
19
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/vec_helper.c
15
--- a/docs/system/arm/cpu-features.rst
22
+++ b/target/arm/vec_helper.c
16
+++ b/docs/system/arm/cpu-features.rst
23
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
17
@@ -XXX,XX +XXX,XX @@ As with ``sve-default-vector-length``, if the default length is larger
24
intptr_t index = simd_data(desc);
18
than the maximum vector length enabled, the actual vector length will
25
uint32_t *d = vd;
19
be reduced. If this property is set to ``-1`` then the default vector
26
int8_t *n = vn;
20
length is set to the maximum possible length.
27
- int8_t *m_indexed = (int8_t *)vm + index * 4;
21
+
28
+ int8_t *m_indexed = (int8_t *)vm + H4(index) * 4;
22
+RME CPU Properties
29
23
+==================
30
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
24
+
31
* Otherwise opr_sz is a multiple of 16.
25
+The status of RME support with QEMU is experimental. At this time we
32
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
26
+only support RME within the CPU proper, not within the SMMU or GIC.
33
intptr_t index = simd_data(desc);
27
+The feature is enabled by the CPU property ``x-rme``, with the ``x-``
34
uint32_t *d = vd;
28
+prefix present as a reminder of the experimental status, and defaults off.
35
uint8_t *n = vn;
29
+
36
- uint8_t *m_indexed = (uint8_t *)vm + index * 4;
30
+The method for enabling RME will change in some future QEMU release
37
+ uint8_t *m_indexed = (uint8_t *)vm + H4(index) * 4;
31
+without notice or backward compatibility.
38
32
+
39
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
33
+RME Level 0 GPT Size Property
40
* Otherwise opr_sz is a multiple of 16.
34
+-----------------------------
35
+
36
+To aid firmware developers in testing different possible CPU
37
+configurations, ``x-l0gptsz=S`` may be used to specify the value
38
+to encode into ``GPCCR_EL3.L0GPTSZ``, a read-only field that
39
+specifies the size of the Level 0 Granule Protection Table.
40
+Legal values for ``S`` are 30, 34, 36, and 39; the default is 30.
41
+
42
+As with ``x-rme``, the ``x-l0gptsz`` property may be renamed or
43
+removed in some future QEMU release.
44
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
45
index XXXXXXX..XXXXXXX 100644
46
--- a/docs/system/arm/emulation.rst
47
+++ b/docs/system/arm/emulation.rst
48
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
49
- FEAT_RAS (Reliability, availability, and serviceability)
50
- FEAT_RASv1p1 (RAS Extension v1.1)
51
- FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
52
+- FEAT_RME (Realm Management Extension) (NB: support status in QEMU is experimental)
53
- FEAT_RNG (Random number generator)
54
- FEAT_S2FWB (Stage 2 forced Write-Back)
55
- FEAT_SB (Speculation Barrier)
41
--
56
--
42
2.20.1
57
2.34.1
43
58
44
59
diff view generated by jsdifflib
1
In the neon_padd/pmax/pmin helpers for float16, a cut-and-paste error
1
We use __builtin_subcll() to do a 64-bit subtract with borrow-in and
2
meant we were using the H4() address swizzler macro rather than the
2
borrow-out when the host compiler supports it. Unfortunately some
3
H2() which is required for 2-byte data. This had no effect on
3
versions of Apple Clang have a bug in their implementation of this
4
little-endian hosts but meant we put the result data into the
4
intrinsic which means it returns the wrong value. The effect is that
5
destination Dreg in the wrong order on big-endian hosts.
5
a QEMU built with the affected compiler will hang when emulating x86
6
or m68k float80 division.
6
7
8
The upstream LLVM issue is:
9
https://github.com/llvm/llvm-project/issues/55253
10
11
The commit that introduced the bug apparently never made it into an
12
upstream LLVM release without the subsequent fix
13
https://github.com/llvm/llvm-project/commit/fffb6e6afdbaba563189c1f715058ed401fbc88d
14
but unfortunately it did make it into Apple Clang 14.0, as shipped
15
in Xcode 14.3 (14.2 is reported to be OK). The Apple bug number is
16
FB12210478.
17
18
Add ifdefs to avoid use of __builtin_subcll() on Apple Clang version
19
14 or greater. There is not currently a version of Apple Clang which
20
has the bug fix -- when one appears we should be able to add an upper
21
bound to the ifdef condition so we can start using the builtin again.
22
We make the lower bound a conservative "any Apple clang with major
23
version 14 or greater" because the consequences of incorrectly
24
disabling the builtin when it would work are pretty small and the
25
consequences of not disabling it when we should are pretty bad.
26
27
Many thanks to those users who both reported this bug and also
28
did a lot of work in identifying the root cause; in particular
29
to Daniel Bertalan and osy.
30
31
Cc: qemu-stable@nongnu.org
32
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1631
33
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1659
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
36
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
10
Message-id: 20201028191712.4910-2-peter.maydell@linaro.org
37
Tested-by: Daniel Bertalan <dani@danielbertalan.dev>
38
Tested-by: Tested-By: Solra Bizna <solra@bizna.name>
39
Message-id: 20230622130823.1631719-1-peter.maydell@linaro.org
11
---
40
---
12
target/arm/vec_helper.c | 8 ++++----
41
include/qemu/compiler.h | 13 +++++++++++++
13
1 file changed, 4 insertions(+), 4 deletions(-)
42
include/qemu/host-utils.h | 2 +-
43
2 files changed, 14 insertions(+), 1 deletion(-)
14
44
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
45
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
16
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/vec_helper.c
47
--- a/include/qemu/compiler.h
18
+++ b/target/arm/vec_helper.c
48
+++ b/include/qemu/compiler.h
19
@@ -XXX,XX +XXX,XX @@ DO_ABA(gvec_uaba_d, uint64_t)
49
@@ -XXX,XX +XXX,XX @@
20
r2 = float16_##OP(m[H2(0)], m[H2(1)], fpst); \
50
#define QEMU_DISABLE_CFI
21
r3 = float16_##OP(m[H2(2)], m[H2(3)], fpst); \
51
#endif
22
\
52
23
- d[H4(0)] = r0; \
53
+/*
24
- d[H4(1)] = r1; \
54
+ * Apple clang version 14 has a bug in its __builtin_subcll(); define
25
- d[H4(2)] = r2; \
55
+ * BUILTIN_SUBCLL_BROKEN for the offending versions so we can avoid it.
26
- d[H4(3)] = r3; \
56
+ * When a version of Apple clang which has this bug fixed is released
27
+ d[H2(0)] = r0; \
57
+ * we can add an upper bound to this check.
28
+ d[H2(1)] = r1; \
58
+ * See https://gitlab.com/qemu-project/qemu/-/issues/1631
29
+ d[H2(2)] = r2; \
59
+ * and https://gitlab.com/qemu-project/qemu/-/issues/1659 for details.
30
+ d[H2(3)] = r3; \
60
+ * The bug never made it into any upstream LLVM releases, only Apple ones.
31
}
61
+ */
32
62
+#if defined(__apple_build_version__) && __clang_major__ >= 14
33
DO_NEON_PAIRWISE(neon_padd, add)
63
+#define BUILTIN_SUBCLL_BROKEN
64
+#endif
65
+
66
#endif /* COMPILER_H */
67
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
68
index XXXXXXX..XXXXXXX 100644
69
--- a/include/qemu/host-utils.h
70
+++ b/include/qemu/host-utils.h
71
@@ -XXX,XX +XXX,XX @@ static inline uint64_t uadd64_carry(uint64_t x, uint64_t y, bool *pcarry)
72
*/
73
static inline uint64_t usub64_borrow(uint64_t x, uint64_t y, bool *pborrow)
74
{
75
-#if __has_builtin(__builtin_subcll)
76
+#if __has_builtin(__builtin_subcll) && !defined(BUILTIN_SUBCLL_BROKEN)
77
unsigned long long b = *pborrow;
78
x = __builtin_subcll(x, y, b, &b);
79
*pborrow = b & 1;
34
--
80
--
35
2.20.1
81
2.34.1
36
82
37
83
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 both cases, we can sink the write-back and perform
3
One cannot test for feature aa32_simd_r32 without first
4
the accumulate into the normal destination temps.
4
testing if AArch32 mode is supported at all. This leads to
5
5
6
qemu-system-aarch64: ARM CPUs must have both VFP-D32 and Neon or neither
7
8
for Apple M1 cpus.
9
10
We already have a check for ARMv8-A never setting vfp-d32 true,
11
so restructure the code so that AArch64 avoids the test entirely.
12
13
Reported-by: Mads Ynddal <mads@ynddal.dk>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-11-richard.henderson@linaro.org
15
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Tested-by: Mads Ynddal <m.ynddal@samsung.com>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Reviewed-by: Cédric Le Goater <clg@kaod.org>
19
Reviewed-by: Mads Ynddal <m.ynddal@samsung.com>
20
Message-id: 20230619140216.402530-1-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
22
---
11
target/arm/translate-neon.c.inc | 23 +++++++++--------------
23
target/arm/cpu.c | 28 +++++++++++++++-------------
12
1 file changed, 9 insertions(+), 14 deletions(-)
24
1 file changed, 15 insertions(+), 13 deletions(-)
13
25
14
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-neon.c.inc
28
--- a/target/arm/cpu.c
17
+++ b/target/arm/translate-neon.c.inc
29
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
30
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
19
if (accfn) {
31
* KVM does not currently allow us to lie to the guest about its
20
tmp = tcg_temp_new_i64();
32
* ID/feature registers, so the guest always sees what the host has.
21
read_neon_element64(tmp, a->vd, 0, MO_64);
33
*/
22
- accfn(tmp, tmp, rd0);
34
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
23
- write_neon_element64(tmp, a->vd, 0, MO_64);
35
- ? cpu_isar_feature(aa64_fp_simd, cpu)
24
+ accfn(rd0, tmp, rd0);
36
- : cpu_isar_feature(aa32_vfp, cpu)) {
25
read_neon_element64(tmp, a->vd, 1, MO_64);
37
- cpu->has_vfp = true;
26
- accfn(tmp, tmp, rd1);
38
- if (!kvm_enabled()) {
27
- write_neon_element64(tmp, a->vd, 1, MO_64);
39
- qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
28
+ accfn(rd1, tmp, rd1);
40
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
29
tcg_temp_free_i64(tmp);
41
+ if (cpu_isar_feature(aa64_fp_simd, cpu)) {
30
- } else {
42
+ cpu->has_vfp = true;
31
- write_neon_element64(rd0, a->vd, 0, MO_64);
43
+ cpu->has_vfp_d32 = true;
32
- write_neon_element64(rd1, a->vd, 1, MO_64);
44
+ if (tcg_enabled() || qtest_enabled()) {
33
}
45
+ qdev_property_add_static(DEVICE(obj),
34
46
+ &arm_cpu_has_vfp_property);
35
+ write_neon_element64(rd0, a->vd, 0, MO_64);
47
+ }
36
+ write_neon_element64(rd1, a->vd, 1, MO_64);
48
}
37
tcg_temp_free_i64(rd0);
49
- }
38
tcg_temp_free_i64(rd1);
50
-
39
51
- if (cpu->has_vfp && cpu_isar_feature(aa32_simd_r32, cpu)) {
40
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
52
- cpu->has_vfp_d32 = true;
41
if (accfn) {
53
- if (!kvm_enabled()) {
42
TCGv_i64 t64 = tcg_temp_new_i64();
54
+ } else if (cpu_isar_feature(aa32_vfp, cpu)) {
43
read_neon_element64(t64, a->vd, 0, MO_64);
55
+ cpu->has_vfp = true;
44
- accfn(t64, t64, rn0_64);
56
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
45
- write_neon_element64(t64, a->vd, 0, MO_64);
57
+ cpu->has_vfp_d32 = true;
46
+ accfn(rn0_64, t64, rn0_64);
58
/*
47
read_neon_element64(t64, a->vd, 1, MO_64);
59
* The permitted values of the SIMDReg bits [3:0] on
48
- accfn(t64, t64, rn1_64);
60
* Armv8-A are either 0b0000 and 0b0010. On such CPUs,
49
- write_neon_element64(t64, a->vd, 1, MO_64);
61
* make sure that has_vfp_d32 can not be set to false.
50
+ accfn(rn1_64, t64, rn1_64);
62
*/
51
tcg_temp_free_i64(t64);
63
- if (!(arm_feature(&cpu->env, ARM_FEATURE_V8) &&
52
- } else {
64
- !arm_feature(&cpu->env, ARM_FEATURE_M))) {
53
- write_neon_element64(rn0_64, a->vd, 0, MO_64);
65
+ if ((tcg_enabled() || qtest_enabled())
54
- write_neon_element64(rn1_64, a->vd, 1, MO_64);
66
+ && !(arm_feature(&cpu->env, ARM_FEATURE_V8)
55
}
67
+ && !arm_feature(&cpu->env, ARM_FEATURE_M))) {
56
+
68
qdev_property_add_static(DEVICE(obj),
57
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
69
&arm_cpu_has_vfp_d32_property);
58
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
70
}
59
tcg_temp_free_i64(rn0_64);
60
tcg_temp_free_i64(rn1_64);
61
return true;
62
--
71
--
63
2.20.1
72
2.34.1
64
73
65
74
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Shashi Mallela <shashi.mallela@linaro.org>
2
2
3
Use the BIT_ULL() macro to ensure we use 64-bit arithmetic.
3
Create ITS as part of SBSA platform GIC initialization.
4
This fixes the following Coverity issue (OVERFLOW_BEFORE_WIDEN):
5
4
6
CID 1432363 (#1 of 1): Unintentional integer overflow:
5
GIC ITS information is in DeviceTree so TF-A can pass it to EDK2.
7
6
8
overflow_before_widen:
7
Bumping platform version to 0.2 as this is important hardware change.
9
Potentially overflowing expression 1 << scale with type int
10
(32 bits, signed) is evaluated using 32-bit arithmetic, and
11
then used in a context that expects an expression of type
12
hwaddr (64 bits, unsigned).
13
8
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
15
Acked-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
16
Message-id: 20201030144617.1535064-1-philmd@redhat.com
11
Message-id: 20230619170913.517373-2-marcin.juszkiewicz@linaro.org
12
Co-authored-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
13
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
16
---
20
hw/arm/smmuv3.c | 3 ++-
17
docs/system/arm/sbsa.rst | 14 ++++++++++++++
21
1 file changed, 2 insertions(+), 1 deletion(-)
18
hw/arm/sbsa-ref.c | 33 ++++++++++++++++++++++++++++++---
19
2 files changed, 44 insertions(+), 3 deletions(-)
22
20
23
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
21
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/smmuv3.c
23
--- a/docs/system/arm/sbsa.rst
26
+++ b/hw/arm/smmuv3.c
24
+++ b/docs/system/arm/sbsa.rst
27
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ to be a complete compliant DT. It currently reports:
28
*/
26
- platform version
29
27
- GIC addresses
30
#include "qemu/osdep.h"
28
31
+#include "qemu/bitops.h"
29
+Platform version
32
#include "hw/irq.h"
30
+''''''''''''''''
33
#include "hw/sysbus.h"
31
+
34
#include "migration/vmstate.h"
32
The platform version is only for informing platform firmware about
35
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
33
what kind of ``sbsa-ref`` board it is running on. It is neither
36
scale = CMD_SCALE(cmd);
34
a QEMU versioned machine type nor a reflection of the level of the
37
num = CMD_NUM(cmd);
35
@@ -XXX,XX +XXX,XX @@ SBSA/SystemReady SR support provided.
38
ttl = CMD_TTL(cmd);
36
The ``machine-version-major`` value is updated when changes breaking
39
- num_pages = (num + 1) * (1 << (scale));
37
fw compatibility are introduced. The ``machine-version-minor`` value
40
+ num_pages = (num + 1) * BIT_ULL(scale);
38
is updated when features are added that don't break fw compatibility.
39
+
40
+Platform version changes:
41
+
42
+0.0
43
+ Devicetree holds information about CPUs, memory and platform version.
44
+
45
+0.1
46
+ GIC information is present in devicetree.
47
+
48
+0.2
49
+ GIC ITS information is present in devicetree.
50
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/sbsa-ref.c
53
+++ b/hw/arm/sbsa-ref.c
54
@@ -XXX,XX +XXX,XX @@ enum {
55
SBSA_CPUPERIPHS,
56
SBSA_GIC_DIST,
57
SBSA_GIC_REDIST,
58
+ SBSA_GIC_ITS,
59
SBSA_SECURE_EC,
60
SBSA_GWDT_WS0,
61
SBSA_GWDT_REFRESH,
62
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
63
[SBSA_CPUPERIPHS] = { 0x40000000, 0x00040000 },
64
[SBSA_GIC_DIST] = { 0x40060000, 0x00010000 },
65
[SBSA_GIC_REDIST] = { 0x40080000, 0x04000000 },
66
+ [SBSA_GIC_ITS] = { 0x44081000, 0x00020000 },
67
[SBSA_SECURE_EC] = { 0x50000000, 0x00001000 },
68
[SBSA_GWDT_REFRESH] = { 0x50010000, 0x00001000 },
69
[SBSA_GWDT_CONTROL] = { 0x50011000, 0x00001000 },
70
@@ -XXX,XX +XXX,XX @@ static void sbsa_fdt_add_gic_node(SBSAMachineState *sms)
71
2, sbsa_ref_memmap[SBSA_GIC_REDIST].base,
72
2, sbsa_ref_memmap[SBSA_GIC_REDIST].size);
73
74
+ nodename = g_strdup_printf("/intc/its");
75
+ qemu_fdt_add_subnode(sms->fdt, nodename);
76
+ qemu_fdt_setprop_sized_cells(sms->fdt, nodename, "reg",
77
+ 2, sbsa_ref_memmap[SBSA_GIC_ITS].base,
78
+ 2, sbsa_ref_memmap[SBSA_GIC_ITS].size);
79
+
80
g_free(nodename);
81
}
82
+
83
/*
84
* Firmware on this machine only uses ACPI table to load OS, these limited
85
* device tree nodes are just to let firmware know the info which varies from
86
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
87
* fw compatibility.
88
*/
89
qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
90
- qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 1);
91
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 2);
92
93
if (ms->numa_state->have_numa_distance) {
94
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
95
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
96
memory_region_add_subregion(secure_sysmem, base, secram);
97
}
98
99
-static void create_gic(SBSAMachineState *sms)
100
+static void create_its(SBSAMachineState *sms)
101
+{
102
+ const char *itsclass = its_class_name();
103
+ DeviceState *dev;
104
+
105
+ dev = qdev_new(itsclass);
106
+
107
+ object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(sms->gic),
108
+ &error_abort);
109
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
110
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, sbsa_ref_memmap[SBSA_GIC_ITS].base);
111
+}
112
+
113
+static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
114
{
115
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
116
SysBusDevice *gicbusdev;
117
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms)
118
qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
119
qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
120
121
+ object_property_set_link(OBJECT(sms->gic), "sysmem",
122
+ OBJECT(mem), &error_fatal);
123
+ qdev_prop_set_bit(sms->gic, "has-lpi", true);
124
+
125
gicbusdev = SYS_BUS_DEVICE(sms->gic);
126
sysbus_realize_and_unref(gicbusdev, &error_fatal);
127
sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
128
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms)
129
sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
130
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
41
}
131
}
42
132
+ create_its(sms);
43
if (type == SMMU_CMD_TLBI_NH_VA) {
133
}
134
135
static void create_uart(const SBSAMachineState *sms, int uart,
136
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
137
138
create_secure_ram(sms, secure_sysmem);
139
140
- create_gic(sms);
141
+ create_gic(sms, sysmem);
142
143
create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
144
create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
44
--
145
--
45
2.20.1
146
2.34.1
46
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These are the only users of neon_reg_offset, so remove that.
3
Brown bag time: store instead of load results in uninitialized temp.
4
4
5
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1704
7
Reported-by: Mark Rutland <mark.rutland@arm.com>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-4-richard.henderson@linaro.org
10
Message-id: 20230620134659.817559-1-richard.henderson@linaro.org
11
Fixes: e6dd5e782be ("target/arm: Use tcg_gen_qemu_{ld, st}_i128 in gen_sve_{ld, st}r")
12
Tested-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
16
---
10
target/arm/translate.c | 14 ++------------
17
target/arm/tcg/translate-sve.c | 2 +-
11
1 file changed, 2 insertions(+), 12 deletions(-)
18
1 file changed, 1 insertion(+), 1 deletion(-)
12
19
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
22
--- a/target/arm/tcg/translate-sve.c
16
+++ b/target/arm/translate.c
23
+++ b/target/arm/tcg/translate-sve.c
17
@@ -XXX,XX +XXX,XX @@ static inline long vfp_reg_offset(bool dp, unsigned reg)
24
@@ -XXX,XX +XXX,XX @@ void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
18
}
25
/* Predicate register stores can be any multiple of 2. */
19
}
26
if (len_remain >= 8) {
20
27
t0 = tcg_temp_new_i64();
21
-/* Return the offset of a 32-bit piece of a NEON register.
28
- tcg_gen_st_i64(t0, base, vofs + len_align);
22
- zero is the least significant end of the register. */
29
+ tcg_gen_ld_i64(t0, base, vofs + len_align);
23
-static inline long
30
tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ | MO_ATOM_NONE);
24
-neon_reg_offset (int reg, int n)
31
len_remain -= 8;
25
-{
32
len_align += 8;
26
- int sreg;
27
- sreg = reg * 2 + n;
28
- return vfp_reg_offset(0, sreg);
29
-}
30
-
31
static TCGv_i32 neon_load_reg(int reg, int pass)
32
{
33
TCGv_i32 tmp = tcg_temp_new_i32();
34
- tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
35
+ tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
36
return tmp;
37
}
38
39
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
40
{
41
- tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
42
+ tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
43
tcg_temp_free_i32(var);
44
}
45
46
--
33
--
47
2.20.1
34
2.34.1
48
35
49
36
diff view generated by jsdifflib
1
If we're using the capstone disassembler, disassembly of a run of
1
The xkb official name for the Arabic keyboard layout is 'ara'.
2
instructions more than 32 bytes long disassembles the wrong data for
2
However xkb has for at least the past 15 years also permitted it to
3
instructions beyond the 32 byte mark:
3
be named via the legacy synonym 'ar'. In xkeyboard-config 2.39 this
4
synoynm was removed, which breaks compilation of QEMU:
4
5
5
(qemu) xp /16x 0x100
6
FAILED: pc-bios/keymaps/ar
6
0000000000000100: 0x00000005 0x54410001 0x00000001 0x00001000
7
/home/fred/qemu-git/src/qemu/build-full/qemu-keymap -f pc-bios/keymaps/ar -l ar
7
0000000000000110: 0x00000000 0x00000004 0x54410002 0x3c000000
8
xkbcommon: ERROR: Couldn't find file "symbols/ar" in include paths
8
0000000000000120: 0x00000000 0x00000004 0x54410009 0x74736574
9
xkbcommon: ERROR: 1 include paths searched:
9
0000000000000130: 0x00000000 0x00000000 0x00000000 0x00000000
10
xkbcommon: ERROR:     /usr/share/X11/xkb
10
(qemu) xp /16i 0x100
11
xkbcommon: ERROR: 3 include paths could not be added:
11
0x00000100: 00000005 andeq r0, r0, r5
12
xkbcommon: ERROR:     /home/fred/.config/xkb
12
0x00000104: 54410001 strbpl r0, [r1], #-1
13
xkbcommon: ERROR:     /home/fred/.xkb
13
0x00000108: 00000001 andeq r0, r0, r1
14
xkbcommon: ERROR:     /etc/xkb
14
0x0000010c: 00001000 andeq r1, r0, r0
15
xkbcommon: ERROR: Abandoning symbols file "(unnamed)"
15
0x00000110: 00000000 andeq r0, r0, r0
16
xkbcommon: ERROR: Failed to compile xkb_symbols
16
0x00000114: 00000004 andeq r0, r0, r4
17
xkbcommon: ERROR: Failed to compile keymap
17
0x00000118: 54410002 strbpl r0, [r1], #-2
18
0x0000011c: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
19
0x00000120: 54410001 strbpl r0, [r1], #-1
20
0x00000124: 00000001 andeq r0, r0, r1
21
0x00000128: 00001000 andeq r1, r0, r0
22
0x0000012c: 00000000 andeq r0, r0, r0
23
0x00000130: 00000004 andeq r0, r0, r4
24
0x00000134: 54410002 strbpl r0, [r1], #-2
25
0x00000138: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
26
0x0000013c: 00000000 andeq r0, r0, r0
27
18
28
Here the disassembly of 0x120..0x13f is using the data that is in
19
The upstream xkeyboard-config change removing the compat
29
0x104..0x123.
20
mapping is:
21
https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/commit/470ad2cd8fea84d7210377161d86b31999bb5ea6
30
22
31
This is caused by passing the wrong value to the read_memory_func().
23
Make QEMU always ask for the 'ara' xkb layout, which should work on
32
The intention is that at this point in the loop the 'cap_buf' buffer
24
both older and newer xkeyboard-config. We leave the QEMU name for
33
already contains 'csize' bytes of data for the instruction at guest
25
this keyboard layout as 'ar'; it is not the only one where our name
34
addr 'pc', and we want to read in an extra 'tsize' bytes. Those
26
for it deviates from the xkb standard name.
35
extra bytes are therefore at 'pc + csize', not 'pc'. On the first
36
time through the loop 'csize' happens to be zero, so the initial read
37
of 32 bytes into cap_buf is correct and as long as the disassembly
38
never needs to read more data we return the correct information.
39
40
Use the correct guest address in the call to read_memory_func().
41
27
42
Cc: qemu-stable@nongnu.org
28
Cc: qemu-stable@nongnu.org
43
Fixes: https://bugs.launchpad.net/qemu/+bug/1900779
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
46
Message-id: 20201022132445.25039-1-peter.maydell@linaro.org
31
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
32
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
33
Message-id: 20230620162024.1132013-1-peter.maydell@linaro.org
34
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1709
47
---
35
---
48
disas/capstone.c | 2 +-
36
pc-bios/keymaps/meson.build | 2 +-
49
1 file changed, 1 insertion(+), 1 deletion(-)
37
1 file changed, 1 insertion(+), 1 deletion(-)
50
38
51
diff --git a/disas/capstone.c b/disas/capstone.c
39
diff --git a/pc-bios/keymaps/meson.build b/pc-bios/keymaps/meson.build
52
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
53
--- a/disas/capstone.c
41
--- a/pc-bios/keymaps/meson.build
54
+++ b/disas/capstone.c
42
+++ b/pc-bios/keymaps/meson.build
55
@@ -XXX,XX +XXX,XX @@ bool cap_disas_monitor(disassemble_info *info, uint64_t pc, int count)
43
@@ -XXX,XX +XXX,XX @@
56
44
keymaps = {
57
/* Make certain that we can make progress. */
45
- 'ar': '-l ar',
58
assert(tsize != 0);
46
+ 'ar': '-l ara',
59
- info->read_memory_func(pc, cap_buf + csize, tsize, info);
47
'bepo': '-l fr -v dvorak',
60
+ info->read_memory_func(pc + csize, cap_buf + csize, tsize, info);
48
'cz': '-l cz',
61
csize += tsize;
49
'da': '-l dk',
62
63
if (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) {
64
--
50
--
65
2.20.1
51
2.34.1
66
52
67
53
diff view generated by jsdifflib