1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
1
Hi; here's a target-arm pullreq. Mostly this is RTH's FEAT_RME
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.
2
5
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
6
thanks
7
-- PMM
8
9
The following changes since commit b455ce4c2f300c8ba47cba7232dd03261368a4cb:
10
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)
4
12
5
are available in the Git repository at:
13
are available in the Git repository at:
6
14
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230623
8
16
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
17
for you to fetch changes up to 497fad38979c16b6412388927401e577eba43d26:
10
18
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
19
pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym (2023-06-23 11:46:02 +0100)
12
20
13
----------------------------------------------------------------
21
----------------------------------------------------------------
14
target-arm queue:
22
target-arm queue:
15
* more MVE instructions
23
* Add (experimental) support for FEAT_RME
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
24
* host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
17
* target/arm: Check NaN mode before silencing NaN
25
* target/arm: Restructure has_vfp_d32 test
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
26
* hw/arm/sbsa-ref: add ITS support in SBSA GIC
19
* hw/arm: Add basic power management to raspi.
27
* target/arm: Fix sve predicate store, 8 <= VQ <= 15
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
28
* pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
21
29
22
----------------------------------------------------------------
30
----------------------------------------------------------------
23
Joe Komlodi (1):
31
Peter Maydell (2):
24
target/arm: Check NaN mode before silencing NaN
32
host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
33
pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
25
34
26
Maxim Uvarov (1):
35
Richard Henderson (23):
27
hw/gpio/gpio_pwr: use shutdown function for reboot
36
target/arm: Add isar_feature_aa64_rme
37
target/arm: Update SCR and HCR for RME
38
target/arm: SCR_EL3.NS may be RES1
39
target/arm: Add RME cpregs
40
target/arm: Introduce ARMSecuritySpace
41
include/exec/memattrs: Add two bits of space to MemTxAttrs
42
target/arm: Adjust the order of Phys and Stage2 ARMMMUIdx
43
target/arm: Introduce ARMMMUIdx_Phys_{Realm,Root}
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
28
59
29
Nolan Leake (1):
60
Shashi Mallela (1):
30
hw/arm: Add basic power management to raspi.
61
hw/arm/sbsa-ref: add ITS support in SBSA GIC
31
62
32
Patrick Venture (2):
63
docs/system/arm/cpu-features.rst | 23 ++
33
docs/system/arm: Add quanta-q7l1-bmc reference
64
docs/system/arm/emulation.rst | 1 +
34
docs/system/arm: Add quanta-gbs-bmc reference
65
docs/system/arm/sbsa.rst | 14 +
35
66
include/exec/memattrs.h | 9 +-
36
Peter Maydell (18):
67
include/qemu/compiler.h | 13 +
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
68
include/qemu/host-utils.h | 2 +-
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
69
target/arm/cpu.h | 151 ++++++++---
39
target/arm: Make asimd_imm_const() public
70
target/arm/internals.h | 27 ++
40
target/arm: Use asimd_imm_const for A64 decode
71
target/arm/syndrome.h | 10 +
41
target/arm: Use dup_const() instead of bitfield_replicate()
72
hw/arm/sbsa-ref.c | 33 ++-
42
target/arm: Implement MVE logical immediate insns
73
target/arm/cpu.c | 32 ++-
43
target/arm: Implement MVE vector shift left by immediate insns
74
target/arm/helper.c | 162 ++++++++++-
44
target/arm: Implement MVE vector shift right by immediate insns
75
target/arm/ptw.c | 570 +++++++++++++++++++++++++++++++--------
45
target/arm: Implement MVE VSHLL
76
target/arm/tcg/cpu64.c | 53 ++++
46
target/arm: Implement MVE VSRI, VSLI
77
target/arm/tcg/tlb_helper.c | 96 ++++++-
47
target/arm: Implement MVE VSHRN, VRSHRN
78
target/arm/tcg/translate-sve.c | 2 +-
48
target/arm: Implement MVE saturating narrowing shifts
79
pc-bios/keymaps/meson.build | 2 +-
49
target/arm: Implement MVE VSHLC
80
17 files changed, 1034 insertions(+), 166 deletions(-)
50
target/arm: Implement MVE VADDLV
51
target/arm: Implement MVE long shifts by immediate
52
target/arm: Implement MVE long shifts by register
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
55
56
Philippe Mathieu-Daudé (1):
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
58
59
docs/system/arm/aspeed.rst | 1 +
60
docs/system/arm/nuvoton.rst | 5 +-
61
include/hw/arm/bcm2835_peripherals.h | 3 +-
62
include/hw/misc/bcm2835_powermgt.h | 29 ++
63
target/arm/helper-mve.h | 108 +++++++
64
target/arm/translate.h | 41 +++
65
target/arm/mve.decode | 177 ++++++++++-
66
target/arm/t32.decode | 71 ++++-
67
hw/arm/bcm2835_peripherals.c | 13 +-
68
hw/gpio/gpio_pwr.c | 2 +-
69
hw/misc/bcm2835_powermgt.c | 160 ++++++++++
70
target/arm/helper-a64.c | 12 +-
71
target/arm/mve_helper.c | 524 +++++++++++++++++++++++++++++++--
72
target/arm/translate-a64.c | 86 +-----
73
target/arm/translate-mve.c | 261 +++++++++++++++-
74
target/arm/translate-neon.c | 81 -----
75
target/arm/translate.c | 327 +++++++++++++++++++-
76
target/arm/vfp_helper.c | 24 +-
77
hw/misc/meson.build | 1 +
78
tests/acceptance/boot_linux_console.py | 43 +++
79
20 files changed, 1760 insertions(+), 209 deletions(-)
80
create mode 100644 include/hw/misc/bcm2835_powermgt.h
81
create mode 100644 hw/misc/bcm2835_powermgt.c
82
diff view generated by jsdifflib
1
Implement the MVE saturating shift-right-and-narrow insns
1
From: Richard Henderson <richard.henderson@linaro.org>
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
2
4
do_srshr() is borrowed from sve_helper.c.
3
Add the missing field for ID_AA64PFR0, and the predicate.
4
Disable it if EL3 is forced off by the board or command-line.
5
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-2-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-13-peter.maydell@linaro.org
9
---
11
---
10
target/arm/helper-mve.h | 30 +++++++++++
12
target/arm/cpu.h | 6 ++++++
11
target/arm/mve.decode | 28 ++++++++++
13
target/arm/cpu.c | 4 ++++
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
14
2 files changed, 10 insertions(+)
13
target/arm/translate-mve.c | 12 +++++
14
4 files changed, 174 insertions(+)
15
15
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/helper-mve.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64PFR0, SEL2, 36, 4)
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
FIELD(ID_AA64PFR0, MPAM, 40, 4)
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
FIELD(ID_AA64PFR0, AMU, 44, 4)
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
FIELD(ID_AA64PFR0, DIT, 48, 4)
24
+
24
+FIELD(ID_AA64PFR0, RME, 52, 4)
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
FIELD(ID_AA64PFR0, CSV2, 56, 4)
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
FIELD(ID_AA64PFR0, CSV3, 60, 4)
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
29
+
29
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0;
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/mve.decode
57
+++ b/target/arm/mve.decode
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
62
+
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
71
+
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
76
+
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
85
+
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/mve_helper.c
93
+++ b/target/arm/mve_helper.c
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
95
}
96
}
30
}
97
31
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
32
+static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
99
+{
33
+{
100
+ if (likely(sh < 64)) {
34
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
102
+ } else {
103
+ /* Rounding the sign bit always produces 0. */
104
+ return 0;
105
+ }
106
+}
35
+}
107
+
36
+
108
DO_VSHRN_ALL(vshrn, DO_SHR)
37
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
109
DO_VSHRN_ALL(vrshrn, do_urshr)
38
{
39
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
40
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/cpu.c
43
+++ b/target/arm/cpu.c
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
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);
110
+
48
+
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
49
+ /* Disable the realm management extension, which requires EL3. */
112
+ bool *satp)
50
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
113
+{
51
+ ID_AA64PFR0, RME, 0);
114
+ if (val > max) {
52
}
115
+ *satp = true;
53
116
+ return max;
54
if (!cpu->has_el2) {
117
+ } else if (val < min) {
118
+ *satp = true;
119
+ return min;
120
+ } else {
121
+ return val;
122
+ }
123
+}
124
+
125
+/* Saturating narrowing right shifts */
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
128
+ void *vm, uint32_t shift) \
129
+ { \
130
+ LTYPE *m = vm; \
131
+ TYPE *d = vd; \
132
+ uint16_t mask = mve_element_mask(env); \
133
+ bool qc = false; \
134
+ unsigned le; \
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
136
+ bool sat = false; \
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
140
+ } \
141
+ if (qc) { \
142
+ env->vfp.qc[0] = qc; \
143
+ } \
144
+ mve_advance_vpt(env); \
145
+ }
146
+
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
150
+
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
154
+
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
158
+
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
162
+
163
+#define DO_SHRN_SB(N, M, SATP) \
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
165
+#define DO_SHRN_UB(N, M, SATP) \
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
167
+#define DO_SHRUN_B(N, M, SATP) \
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
169
+
170
+#define DO_SHRN_SH(N, M, SATP) \
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
172
+#define DO_SHRN_UH(N, M, SATP) \
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
174
+#define DO_SHRUN_H(N, M, SATP) \
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
176
+
177
+#define DO_RSHRN_SB(N, M, SATP) \
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
179
+#define DO_RSHRN_UB(N, M, SATP) \
180
+ do_sat_bhs(do_urshr(N, M), 0, UINT8_MAX, SATP)
181
+#define DO_RSHRUN_B(N, M, SATP) \
182
+ do_sat_bhs(do_srshr(N, M), 0, UINT8_MAX, SATP)
183
+
184
+#define DO_RSHRN_SH(N, M, SATP) \
185
+ do_sat_bhs(do_srshr(N, M), INT16_MIN, INT16_MAX, SATP)
186
+#define DO_RSHRN_UH(N, M, SATP) \
187
+ do_sat_bhs(do_urshr(N, M), 0, UINT16_MAX, SATP)
188
+#define DO_RSHRUN_H(N, M, SATP) \
189
+ do_sat_bhs(do_srshr(N, M), 0, UINT16_MAX, SATP)
190
+
191
+DO_VSHRN_SAT_SB(vqshrnb_sb, vqshrnt_sb, DO_SHRN_SB)
192
+DO_VSHRN_SAT_SH(vqshrnb_sh, vqshrnt_sh, DO_SHRN_SH)
193
+DO_VSHRN_SAT_UB(vqshrnb_ub, vqshrnt_ub, DO_SHRN_UB)
194
+DO_VSHRN_SAT_UH(vqshrnb_uh, vqshrnt_uh, DO_SHRN_UH)
195
+DO_VSHRN_SAT_SB(vqshrunbb, vqshruntb, DO_SHRUN_B)
196
+DO_VSHRN_SAT_SH(vqshrunbh, vqshrunth, DO_SHRUN_H)
197
+
198
+DO_VSHRN_SAT_SB(vqrshrnb_sb, vqrshrnt_sb, DO_RSHRN_SB)
199
+DO_VSHRN_SAT_SH(vqrshrnb_sh, vqrshrnt_sh, DO_RSHRN_SH)
200
+DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
201
+DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
202
+DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
203
+DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
204
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/arm/translate-mve.c
207
+++ b/target/arm/translate-mve.c
208
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VSHRNB, vshrnb)
209
DO_2SHIFT_N(VSHRNT, vshrnt)
210
DO_2SHIFT_N(VRSHRNB, vrshrnb)
211
DO_2SHIFT_N(VRSHRNT, vrshrnt)
212
+DO_2SHIFT_N(VQSHRNB_S, vqshrnb_s)
213
+DO_2SHIFT_N(VQSHRNT_S, vqshrnt_s)
214
+DO_2SHIFT_N(VQSHRNB_U, vqshrnb_u)
215
+DO_2SHIFT_N(VQSHRNT_U, vqshrnt_u)
216
+DO_2SHIFT_N(VQSHRUNB, vqshrunb)
217
+DO_2SHIFT_N(VQSHRUNT, vqshrunt)
218
+DO_2SHIFT_N(VQRSHRNB_S, vqrshrnb_s)
219
+DO_2SHIFT_N(VQRSHRNT_S, vqrshrnt_s)
220
+DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
221
+DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
222
+DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
223
+DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
224
--
55
--
225
2.20.1
56
2.34.1
226
57
227
58
diff view generated by jsdifflib
1
Implement the MVE shifts by register, which perform
1
From: Richard Henderson <richard.henderson@linaro.org>
2
shifts on a single general-purpose register.
3
2
3
Define the missing SCR and HCR bits, allow SCR_NSE and {SCR,HCR}_GPF
4
to be set, and invalidate TLBs when NSE changes.
5
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
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
7
---
10
---
8
target/arm/helper-mve.h | 2 ++
11
target/arm/cpu.h | 5 +++--
9
target/arm/translate.h | 1 +
12
target/arm/helper.c | 10 ++++++++--
10
target/arm/t32.decode | 18 ++++++++++++++----
13
2 files changed, 11 insertions(+), 4 deletions(-)
11
target/arm/mve_helper.c | 10 ++++++++++
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
14
14
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/helper-mve.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
19
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
20
20
#define HCR_TERR (1ULL << 36)
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
21
#define HCR_TEA (1ULL << 37)
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
22
#define HCR_MIOCNCE (1ULL << 38)
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
23
-/* RES0 bit 39 */
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
24
+#define HCR_TME (1ULL << 39)
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
25
#define HCR_APK (1ULL << 40)
26
#define HCR_API (1ULL << 41)
27
#define HCR_NV (1ULL << 42)
28
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
29
#define HCR_NV2 (1ULL << 45)
30
#define HCR_FWB (1ULL << 46)
31
#define HCR_FIEN (1ULL << 47)
32
-/* RES0 bit 48 */
33
+#define HCR_GPF (1ULL << 48)
34
#define HCR_TID4 (1ULL << 49)
35
#define HCR_TICAB (1ULL << 50)
36
#define HCR_AMVOFFEN (1ULL << 51)
37
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
38
#define SCR_TRNDR (1ULL << 40)
39
#define SCR_ENTP2 (1ULL << 41)
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
26
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate.h
47
--- a/target/arm/helper.c
28
+++ b/target/arm/translate.h
48
+++ b/target/arm/helper.c
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
49
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
50
if (cpu_isar_feature(aa64_fgt, cpu)) {
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
51
valid_mask |= SCR_FGTEN;
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
52
}
33
+typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
53
+ if (cpu_isar_feature(aa64_rme, cpu)) {
34
54
+ valid_mask |= SCR_NSE | SCR_GPF;
35
/**
55
+ }
36
* arm_tbflags_from_tb:
56
} else {
37
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
57
valid_mask &= ~(SCR_RW | SCR_ST);
38
index XXXXXXX..XXXXXXX 100644
58
if (cpu_isar_feature(aa32_ras, cpu)) {
39
--- a/target/arm/t32.decode
59
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
40
+++ b/target/arm/t32.decode
60
env->cp15.scr_el3 = value;
41
@@ -XXX,XX +XXX,XX @@
61
42
&mve_shl_ri rdalo rdahi shim
62
/*
43
&mve_shl_rr rdalo rdahi rm
63
- * If SCR_EL3.NS changes, i.e. arm_is_secure_below_el3, then
44
&mve_sh_ri rda shim
64
+ * If SCR_EL3.{NS,NSE} changes, i.e. change of security state,
45
+&mve_sh_rr rda rm
65
* we must invalidate all TLBs below EL3.
46
66
*/
47
# rdahi: bits [3:1] from insn, bit 0 is 1
67
- if (changed & SCR_NS) {
48
# rdalo: bits [3:1] from insn, bit 0 is 0
68
+ if (changed & (SCR_NS | SCR_NSE)) {
49
@@ -XXX,XX +XXX,XX @@
69
tlb_flush_by_mmuidx(env_cpu(env), (ARMMMUIdxBit_E10_0 |
50
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
70
ARMMMUIdxBit_E20_0 |
51
@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
71
ARMMMUIdxBit_E10_1 |
52
&mve_sh_ri shim=%imm5_12_6
72
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
53
+@mve_sh_rr ....... .... . rda:4 rm:4 .... .... .... &mve_sh_rr
73
if (cpu_isar_feature(aa64_fwb, cpu)) {
54
74
valid_mask |= HCR_FWB;
55
{
75
}
56
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
76
+ if (cpu_isar_feature(aa64_rme, cpu)) {
57
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
77
+ valid_mask |= HCR_GPF;
58
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
78
+ }
59
}
79
}
60
80
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
81
if (cpu_isar_feature(any_evt, cpu)) {
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
65
+ {
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
69
+ }
70
+
71
+ {
72
+ SQRSHR_rr 1110101 0010 1 .... .... 1111 0010 1101 @mve_sh_rr
73
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
74
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
75
+ }
76
+
77
UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
78
SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
79
]
80
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/mve_helper.c
83
+++ b/target/arm/mve_helper.c
84
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
85
{
86
return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
87
}
88
+
89
+uint32_t HELPER(mve_uqrshl)(CPUARMState *env, uint32_t n, uint32_t shift)
90
+{
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
92
+}
93
+
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
95
+{
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
97
+}
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate.c
101
+++ b/target/arm/translate.c
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
104
}
105
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
107
+{
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
110
+ return false;
111
+ }
112
+ if (!dc_isar_feature(aa32_mve, s) ||
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
115
+ a->rm == a->rda) {
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
117
+ unallocated_encoding(s);
118
+ return true;
119
+ }
120
+
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
123
+ return true;
124
+}
125
+
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
127
+{
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
129
+}
130
+
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
132
+{
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
134
+}
135
+
136
/*
137
* Multiply and multiply accumulate
138
*/
139
--
82
--
140
2.20.1
83
2.34.1
141
142
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
With RME, SEL2 must also be present to support secure state.
4
The NS bit is RES1 if SEL2 is not present.
5
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper.c | 3 +++
12
1 file changed, 3 insertions(+)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
19
}
20
if (cpu_isar_feature(aa64_sel2, cpu)) {
21
valid_mask |= SCR_EEL2;
22
+ } else if (cpu_isar_feature(aa64_rme, cpu)) {
23
+ /* With RME and without SEL2, NS is RES1 (R_GSWWH, I_DJJQJ). */
24
+ value |= SCR_NS;
25
}
26
if (cpu_isar_feature(aa64_mte, cpu)) {
27
valid_mask |= SCR_ATA;
28
--
29
2.34.1
diff view generated by jsdifflib
1
Implement the MVE shifts by immediate, which perform shifts
1
From: Richard Henderson <richard.henderson@linaro.org>
2
on a single general-purpose register.
3
2
4
These patterns overlap with the long-shift-by-immediates,
3
This includes GPCCR, GPTBR, MFAR, the TLB flush insns PAALL, PAALLOS,
5
so we have to rearrange the grouping a little here.
4
RPALOS, RPAOS, and the cache flush insns CIPAPA and CIGDPAPA.
6
5
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
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
10
---
10
---
11
target/arm/helper-mve.h | 3 ++
11
target/arm/cpu.h | 19 ++++++++++
12
target/arm/translate.h | 1 +
12
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
13
target/arm/t32.decode | 31 ++++++++++++++-----
13
2 files changed, 103 insertions(+)
14
target/arm/mve_helper.c | 10 ++++++
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
16
5 files changed, 104 insertions(+), 9 deletions(-)
17
14
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-mve.h
17
--- a/target/arm/cpu.h
21
+++ b/target/arm/helper-mve.h
18
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
20
uint64_t fgt_read[2]; /* HFGRTR, HDFGRTR */
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
21
uint64_t fgt_write[2]; /* HFGWTR, HDFGWTR */
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
22
uint64_t fgt_exec[1]; /* HFGITR */
26
+
23
+
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
24
+ /* RME registers */
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
25
+ uint64_t gpccr_el3;
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
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
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate.h
61
--- a/target/arm/helper.c
32
+++ b/target/arm/translate.h
62
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
64
.access = PL2_RW, .accessfn = access_esm,
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
65
.type = ARM_CP_CONST, .resetvalue = 0 },
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
66
};
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
38
39
/**
40
* arm_tbflags_from_tb:
41
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/t32.decode
44
+++ b/target/arm/t32.decode
45
@@ -XXX,XX +XXX,XX @@
46
47
&mve_shl_ri rdalo rdahi shim
48
&mve_shl_rr rdalo rdahi rm
49
+&mve_sh_ri rda shim
50
51
# rdahi: bits [3:1] from insn, bit 0 is 1
52
# rdalo: bits [3:1] from insn, bit 0 is 0
53
@@ -XXX,XX +XXX,XX @@
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
58
+ &mve_sh_ri shim=%imm5_12_6
59
60
{
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
64
# handling them as r13 and r15 accesses with the same semantics as A32).
65
[
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
69
+ {
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
73
+ }
74
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
79
+ {
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
+ }
84
+
67
+
85
+ {
68
+static void tlbi_aa64_paall_write(CPUARMState *env, const ARMCPRegInfo *ri,
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
69
+ uint64_t value)
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
70
+{
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
71
+ CPUState *cs = env_cpu(env);
89
+ }
90
+
72
+
91
+ {
73
+ tlb_flush(cs);
92
+ SQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 11 1111 @mve_sh_ri
93
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
94
+ }
95
96
LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
97
ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
98
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/mve_helper.c
101
+++ b/target/arm/mve_helper.c
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
103
{
104
return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
105
}
106
+
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
108
+{
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
110
+}
74
+}
111
+
75
+
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
76
+static void gpccr_write(CPUARMState *env, const ARMCPRegInfo *ri,
77
+ uint64_t value)
113
+{
78
+{
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
79
+ /* L0GPTSZ is RO; other bits not mentioned are RES0. */
115
+}
80
+ uint64_t rw_mask = R_GPCCR_PPS_MASK | R_GPCCR_IRGN_MASK |
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
+ R_GPCCR_ORGN_MASK | R_GPCCR_SH_MASK | R_GPCCR_PGS_MASK |
117
index XXXXXXX..XXXXXXX 100644
82
+ R_GPCCR_GPC_MASK | R_GPCCR_GPCP_MASK;
118
--- a/target/arm/translate.c
119
+++ b/target/arm/translate.c
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
121
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
123
{
124
- TCGv_i32 t = tcg_temp_new_i32();
125
+ TCGv_i32 t;
126
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
128
+ if (sh == 32) {
129
+ tcg_gen_movi_i32(d, 0);
130
+ return;
131
+ }
132
+ t = tcg_temp_new_i32();
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
134
tcg_gen_sari_i32(d, a, sh);
135
tcg_gen_add_i32(d, d, t);
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
137
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
139
{
140
- TCGv_i32 t = tcg_temp_new_i32();
141
+ TCGv_i32 t;
142
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
144
+ if (sh == 32) {
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
146
+ return;
147
+ }
148
+ t = tcg_temp_new_i32();
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
150
tcg_gen_shri_i32(d, a, sh);
151
tcg_gen_add_i32(d, d, t);
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
154
}
155
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
157
+{
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
160
+ return false;
161
+ }
162
+ if (!dc_isar_feature(aa32_mve, s) ||
163
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
164
+ a->rda == 13 || a->rda == 15) {
165
+ /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
166
+ unallocated_encoding(s);
167
+ return true;
168
+ }
169
+
83
+
170
+ if (a->shim == 0) {
84
+ env->cp15.gpccr_el3 = (value & rw_mask) | (env->cp15.gpccr_el3 & ~rw_mask);
171
+ a->shim = 32;
172
+ }
173
+ fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
174
+
175
+ return true;
176
+}
85
+}
177
+
86
+
178
+static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
87
+static void gpccr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
179
+{
88
+{
180
+ return do_mve_sh_ri(s, a, gen_urshr32_i32);
89
+ env->cp15.gpccr_el3 = FIELD_DP64(0, GPCCR, L0GPTSZ,
90
+ env_archcpu(env)->reset_l0gptsz);
181
+}
91
+}
182
+
92
+
183
+static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
93
+static void tlbi_aa64_paallos_write(CPUARMState *env, const ARMCPRegInfo *ri,
94
+ uint64_t value)
184
+{
95
+{
185
+ return do_mve_sh_ri(s, a, gen_srshr32_i32);
96
+ CPUState *cs = env_cpu(env);
97
+
98
+ tlb_flush_all_cpus_synced(cs);
186
+}
99
+}
187
+
100
+
188
+static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
101
+static const ARMCPRegInfo rme_reginfo[] = {
189
+{
102
+ { .name = "GPCCR_EL3", .state = ARM_CP_STATE_AA64,
190
+ gen_helper_mve_sqshl(r, cpu_env, n, tcg_constant_i32(shift));
103
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 1, .opc2 = 6,
191
+}
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
+};
192
+
138
+
193
+static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
139
+static const ARMCPRegInfo rme_mte_reginfo[] = {
194
+{
140
+ { .name = "DC_CIGDPAPA", .state = ARM_CP_STATE_AA64,
195
+ return do_mve_sh_ri(s, a, gen_mve_sqshl);
141
+ .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 14, .opc2 = 5,
196
+}
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
}
197
+
151
+
198
+static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
152
+ if (cpu_isar_feature(aa64_rme, cpu)) {
199
+{
153
+ define_arm_cp_regs(cpu, rme_reginfo);
200
+ gen_helper_mve_uqshl(r, cpu_env, n, tcg_constant_i32(shift));
154
+ if (cpu_isar_feature(aa64_mte, cpu)) {
201
+}
155
+ define_arm_cp_regs(cpu, rme_mte_reginfo);
202
+
156
+ }
203
+static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
157
+ }
204
+{
158
#endif
205
+ return do_mve_sh_ri(s, a, gen_mve_uqshl);
159
206
+}
160
if (cpu_isar_feature(any_predinv, cpu)) {
207
+
208
/*
209
* Multiply and multiply accumulate
210
*/
211
--
161
--
212
2.20.1
162
2.34.1
213
214
diff view generated by jsdifflib
1
Implement the MVE VSHLC insn, which performs a shift left of the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
entire vector with carry in bits provided from a general purpose
3
register and carry out bits written back to that register.
4
2
3
Introduce both the enumeration and functions to retrieve
4
the current state, and state outside of EL3.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-6-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
8
---
10
---
9
target/arm/helper-mve.h | 2 ++
11
target/arm/cpu.h | 89 ++++++++++++++++++++++++++++++++++-----------
10
target/arm/mve.decode | 2 ++
12
target/arm/helper.c | 60 ++++++++++++++++++++++++++++++
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
13
2 files changed, 127 insertions(+), 22 deletions(-)
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
13
4 files changed, 72 insertions(+)
14
14
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/helper-mve.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
@@ -XXX,XX +XXX,XX @@ static inline int arm_feature(CPUARMState *env, int feature)
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp);
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
23
+
23
-#if !defined(CONFIG_USER_ONLY)
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
24
/*
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
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.
70
*/
71
static inline bool arm_is_secure_below_el3(CPUARMState *env)
72
{
73
- assert(!arm_feature(env, ARM_FEATURE_M));
74
- if (arm_feature(env, ARM_FEATURE_EL3)) {
75
- return !(env->cp15.scr_el3 & SCR_NS);
76
- } else {
77
- /* If EL3 is not supported then the secure state is implementation
78
- * defined, in which case QEMU defaults to non-secure.
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
26
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/mve.decode
143
--- a/target/arm/helper.c
28
+++ b/target/arm/mve.decode
144
+++ b/target/arm/helper.c
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
145
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
146
}
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
147
}
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
148
#endif
33
+
149
+
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
150
+#ifndef CONFIG_USER_ONLY
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
151
+ARMSecuritySpace arm_security_space(CPUARMState *env)
36
index XXXXXXX..XXXXXXX 100644
152
+{
37
--- a/target/arm/mve_helper.c
153
+ if (arm_feature(env, ARM_FEATURE_M)) {
38
+++ b/target/arm/mve_helper.c
154
+ return arm_secure_to_space(env->v7m.secure);
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
155
+ }
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
43
+
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
45
+ uint32_t shift)
46
+{
47
+ uint32_t *d = vd;
48
+ uint16_t mask = mve_element_mask(env);
49
+ unsigned e;
50
+ uint32_t r;
51
+
156
+
52
+ /*
157
+ /*
53
+ * For each 32-bit element, we shift it left, bringing in the
158
+ * If EL3 is not supported then the secure state is implementation
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
159
+ * defined, in which case QEMU defaults to non-secure.
55
+ * the top become the new rdm, if the predicate mask permits.
56
+ * The final rdm value is returned to update the register.
57
+ * shift == 0 here means "shift by 32 bits".
58
+ */
160
+ */
59
+ if (shift == 0) {
161
+ if (!arm_feature(env, ARM_FEATURE_EL3)) {
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
162
+ return ARMSS_NonSecure;
61
+ r = rdm;
163
+ }
62
+ if (mask & 1) {
164
+
63
+ rdm = d[H4(e)];
165
+ /* Check for AArch64 EL3 or AArch32 Mon. */
166
+ if (is_a64(env)) {
167
+ if (extract32(env->pstate, 2, 2) == 3) {
168
+ if (cpu_isar_feature(aa64_rme, env_archcpu(env))) {
169
+ return ARMSS_Root;
170
+ } else {
171
+ return ARMSS_Secure;
64
+ }
172
+ }
65
+ mergemask(&d[H4(e)], r, mask);
66
+ }
173
+ }
67
+ } else {
174
+ } else {
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
175
+ if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
69
+
176
+ return ARMSS_Secure;
70
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
71
+ r = (d[H4(e)] << shift) | (rdm & shiftmask);
72
+ if (mask & 1) {
73
+ rdm = d[H4(e)] >> (32 - shift);
74
+ }
75
+ mergemask(&d[H4(e)], r, mask);
76
+ }
177
+ }
77
+ }
178
+ }
78
+ mve_advance_vpt(env);
179
+
79
+ return rdm;
180
+ return arm_security_space_below_el3(env);
80
+}
181
+}
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
182
+
82
index XXXXXXX..XXXXXXX 100644
183
+ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
83
--- a/target/arm/translate-mve.c
184
+{
84
+++ b/target/arm/translate-mve.c
185
+ assert(!arm_feature(env, ARM_FEATURE_M));
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
186
+
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
89
+
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
91
+{
92
+ /*
187
+ /*
93
+ * Whole Vector Left Shift with Carry. The carry is taken
188
+ * If EL3 is not supported then the secure state is implementation
94
+ * from a general purpose register and written back there.
189
+ * defined, in which case QEMU defaults to non-secure.
95
+ * An imm of 0 means "shift by 32".
96
+ */
190
+ */
97
+ TCGv_ptr qd;
191
+ if (!arm_feature(env, ARM_FEATURE_EL3)) {
98
+ TCGv_i32 rdm;
192
+ return ARMSS_NonSecure;
99
+
193
+ }
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
194
+
101
+ return false;
195
+ /*
102
+ }
196
+ * Note NSE cannot be set without RME, and NSE & !NS is Reserved.
103
+ if (a->rdm == 13 || a->rdm == 15) {
197
+ * Ignoring NSE when !NS retains consistency without having to
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
198
+ * modify other predicates.
105
+ return false;
199
+ */
106
+ }
200
+ if (!(env->cp15.scr_el3 & SCR_NS)) {
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
201
+ return ARMSS_Secure;
108
+ return true;
202
+ } else if (env->cp15.scr_el3 & SCR_NSE) {
109
+ }
203
+ return ARMSS_Realm;
110
+
204
+ } else {
111
+ qd = mve_qreg_ptr(a->qd);
205
+ return ARMSS_NonSecure;
112
+ rdm = load_reg(s, a->rdm);
206
+ }
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
207
+}
114
+ store_reg(s, a->rdm, rdm);
208
+#endif /* !CONFIG_USER_ONLY */
115
+ tcg_temp_free_ptr(qd);
116
+ mve_update_eci(s);
117
+ return true;
118
+}
119
--
209
--
120
2.20.1
210
2.34.1
121
122
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
We will need 2 bits to represent ARMSecurityState.
4
5
Do not attempt to replace or widen secure, even though it
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.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20230620124418.805717-7-richard.henderson@linaro.org
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(-)
17
18
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/exec/memattrs.h
21
+++ b/include/exec/memattrs.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct MemTxAttrs {
23
* "didn't specify" if necessary.
24
*/
25
unsigned int unspecified:1;
26
- /* ARM/AMBA: TrustZone Secure access
27
+ /*
28
+ * ARM/AMBA: TrustZone Secure access
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).
36
+ */
37
+ unsigned int space:2;
38
/* Memory access is usermode (unprivileged) */
39
unsigned int user:1;
40
/*
41
--
42
2.34.1
diff view generated by jsdifflib
1
Implement the MVE long shifts by register, which perform shifts on a
1
From: Richard Henderson <richard.henderson@linaro.org>
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
the shift count in another general-purpose register, which might be
4
either positive or negative.
5
2
6
Like the long-shifts-by-immediate, these encodings sit in the space
3
It will be helpful to have ARMMMUIdx_Phys_* to be in the same
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
4
relative order as ARMSecuritySpace enumerators. This requires
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
5
the adjustment to the nstable check. While there, check for being
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
6
in secure state rather than rely on clearing the low bit making
10
we have to move the CSEL pattern into the same decodetree group.
7
no change to non-secure state.
11
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20230620124418.805717-8-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
15
---
13
---
16
target/arm/helper-mve.h | 6 +++
14
target/arm/cpu.h | 12 ++++++------
17
target/arm/translate.h | 1 +
15
target/arm/ptw.c | 12 +++++-------
18
target/arm/t32.decode | 16 +++++--
16
2 files changed, 11 insertions(+), 13 deletions(-)
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
21
5 files changed, 182 insertions(+), 3 deletions(-)
22
17
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-mve.h
20
--- a/target/arm/cpu.h
26
+++ b/target/arm/helper-mve.h
21
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
28
23
ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A,
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
24
ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A,
30
25
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
26
- /* TLBs with 1-1 mapping to the physical address spaces. */
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
27
- ARMMMUIdx_Phys_NS = 8 | ARM_MMU_IDX_A,
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
28
- ARMMMUIdx_Phys_S = 9 | ARM_MMU_IDX_A,
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
29
-
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
30
/*
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
31
* Used for second stage of an S12 page table walk, or for descriptor
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
* loads during first stage of an S1 page table walk. Note that both
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
* are in use simultaneously for SecureEL2: the security state for
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
34
* the S2 ptw is selected by the NS bit from the S1 ptw.
35
*/
36
- ARMMMUIdx_Stage2 = 10 | ARM_MMU_IDX_A,
37
- ARMMMUIdx_Stage2_S = 11 | ARM_MMU_IDX_A,
38
+ ARMMMUIdx_Stage2_S = 8 | ARM_MMU_IDX_A,
39
+ ARMMMUIdx_Stage2 = 9 | ARM_MMU_IDX_A,
40
+
41
+ /* TLBs with 1-1 mapping to the physical address spaces. */
42
+ ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
43
+ ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
44
45
/*
46
* These are not allocated TLBs and are used only for AT system
47
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
40
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate.h
49
--- a/target/arm/ptw.c
42
+++ b/target/arm/translate.h
50
+++ b/target/arm/ptw.c
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
51
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
52
descaddr |= (address >> (stride * (4 - level))) & indexmask;
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
53
descaddr &= ~7ULL;
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
54
nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
55
- if (nstable) {
48
56
+ if (nstable && ptw->in_secure) {
49
/**
57
/*
50
* arm_tbflags_from_tb:
58
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
- * Assert that the non-secure idx are even, and relative order.
52
index XXXXXXX..XXXXXXX 100644
60
+ * Assert the relative order of the secure/non-secure indexes.
53
--- a/target/arm/t32.decode
61
*/
54
+++ b/target/arm/t32.decode
62
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
55
@@ -XXX,XX +XXX,XX @@
63
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
56
&mcrr !extern cp opc1 crm rt rt2
64
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
57
65
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
58
&mve_shl_ri rdalo rdahi shim
66
- ptw->in_ptw_idx &= ~1;
59
+&mve_shl_rr rdalo rdahi rm
67
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_S + 1 != ARMMMUIdx_Phys_NS);
60
68
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2);
61
# rdahi: bits [3:1] from insn, bit 0 is 1
69
+ ptw->in_ptw_idx += 1;
62
# rdalo: bits [3:1] from insn, bit 0 is 0
70
ptw->in_secure = false;
63
@@ -XXX,XX +XXX,XX @@
71
}
64
72
if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
69
70
{
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
76
+
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
83
]
84
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
87
+
88
+ # v8.1M CSEL and friends
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
90
}
91
{
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
93
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
94
}
95
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
96
97
-# v8.1M CSEL and friends
98
-CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
99
-
100
# Data-processing (register-shifted register)
101
102
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
103
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/mve_helper.c
106
+++ b/target/arm/mve_helper.c
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
108
return rdm;
109
}
110
111
+uint64_t HELPER(mve_sshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
112
+{
113
+ return do_sqrshl_d(n, -(int8_t)shift, false, NULL);
114
+}
115
+
116
+uint64_t HELPER(mve_ushll)(CPUARMState *env, uint64_t n, uint32_t shift)
117
+{
118
+ return do_uqrshl_d(n, (int8_t)shift, false, NULL);
119
+}
120
+
121
uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
122
{
123
return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
124
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
{
126
return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
}
128
+
129
+uint64_t HELPER(mve_sqrshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
130
+{
131
+ return do_sqrshl_d(n, -(int8_t)shift, true, &env->QF);
132
+}
133
+
134
+uint64_t HELPER(mve_uqrshll)(CPUARMState *env, uint64_t n, uint32_t shift)
135
+{
136
+ return do_uqrshl_d(n, (int8_t)shift, true, &env->QF);
137
+}
138
+
139
+/* Operate on 64-bit values, but saturate at 48 bits */
140
+static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
141
+ bool round, uint32_t *sat)
142
+{
143
+ if (shift <= -48) {
144
+ /* Rounding the sign bit always produces 0. */
145
+ if (round) {
146
+ return 0;
147
+ }
148
+ return src >> 63;
149
+ } else if (shift < 0) {
150
+ if (round) {
151
+ src >>= -shift - 1;
152
+ return (src >> 1) + (src & 1);
153
+ }
154
+ return src >> -shift;
155
+ } else if (shift < 48) {
156
+ int64_t val = src << shift;
157
+ int64_t extval = sextract64(val, 0, 48);
158
+ if (!sat || val == extval) {
159
+ return extval;
160
+ }
161
+ } else if (!sat || src == 0) {
162
+ return 0;
163
+ }
164
+
165
+ *sat = 1;
166
+ return (1ULL << 47) - (src >= 0);
167
+}
168
+
169
+/* Operate on 64-bit values, but saturate at 48 bits */
170
+static inline uint64_t do_uqrshl48_d(uint64_t src, int64_t shift,
171
+ bool round, uint32_t *sat)
172
+{
173
+ uint64_t val, extval;
174
+
175
+ if (shift <= -(48 + round)) {
176
+ return 0;
177
+ } else if (shift < 0) {
178
+ if (round) {
179
+ val = src >> (-shift - 1);
180
+ val = (val >> 1) + (val & 1);
181
+ } else {
182
+ val = src >> -shift;
183
+ }
184
+ extval = extract64(val, 0, 48);
185
+ if (!sat || val == extval) {
186
+ return extval;
187
+ }
188
+ } else if (shift < 48) {
189
+ uint64_t val = src << shift;
190
+ uint64_t extval = extract64(val, 0, 48);
191
+ if (!sat || val == extval) {
192
+ return extval;
193
+ }
194
+ } else if (!sat || src == 0) {
195
+ return 0;
196
+ }
197
+
198
+ *sat = 1;
199
+ return MAKE_64BIT_MASK(0, 48);
200
+}
201
+
202
+uint64_t HELPER(mve_sqrshrl48)(CPUARMState *env, uint64_t n, uint32_t shift)
203
+{
204
+ return do_sqrshl48_d(n, -(int8_t)shift, true, &env->QF);
205
+}
206
+
207
+uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
208
+{
209
+ return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
210
+}
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate.c
214
+++ b/target/arm/translate.c
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
217
}
218
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
220
+{
221
+ TCGv_i64 rda;
222
+ TCGv_i32 rdalo, rdahi;
223
+
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
226
+ return false;
227
+ }
228
+ if (a->rdahi == 15) {
229
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
230
+ return false;
231
+ }
232
+ if (!dc_isar_feature(aa32_mve, s) ||
233
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
234
+ a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
235
+ a->rm == a->rdahi || a->rm == a->rdalo) {
236
+ /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
237
+ unallocated_encoding(s);
238
+ return true;
239
+ }
240
+
241
+ rda = tcg_temp_new_i64();
242
+ rdalo = load_reg(s, a->rdalo);
243
+ rdahi = load_reg(s, a->rdahi);
244
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
245
+
246
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
247
+ fn(rda, cpu_env, rda, cpu_R[a->rm]);
248
+
249
+ tcg_gen_extrl_i64_i32(rdalo, rda);
250
+ tcg_gen_extrh_i64_i32(rdahi, rda);
251
+ store_reg(s, a->rdalo, rdalo);
252
+ store_reg(s, a->rdahi, rdahi);
253
+ tcg_temp_free_i64(rda);
254
+
255
+ return true;
256
+}
257
+
258
+static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
259
+{
260
+ return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
261
+}
262
+
263
+static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
264
+{
265
+ return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
266
+}
267
+
268
+static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
269
+{
270
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
271
+}
272
+
273
+static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
274
+{
275
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
276
+}
277
+
278
+static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
279
+{
280
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
281
+}
282
+
283
+static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
284
+{
285
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
286
+}
287
+
288
/*
289
* Multiply and multiply accumulate
290
*/
291
--
73
--
292
2.20.1
74
2.34.1
293
294
diff view generated by jsdifflib
1
Implement the MVE VHLL (vector shift left long) insn. This has two
1
From: Richard Henderson <richard.henderson@linaro.org>
2
encodings: the T1 encoding is the usual shift-by-immediate format,
3
and the T2 encoding is a special case where the shift count is always
4
equal to the element size.
5
2
3
With FEAT_RME, there are four physical address spaces.
4
For now, just define the symbols, and mention them in
5
the same spots as the other Phys indexes in ptw.c.
6
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
9
---
12
---
10
target/arm/helper-mve.h | 9 +++++++
13
target/arm/cpu.h | 23 +++++++++++++++++++++--
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
14
target/arm/ptw.c | 10 ++++++++--
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
15
2 files changed, 29 insertions(+), 4 deletions(-)
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
15
16
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
19
--- a/target/arm/cpu.h
19
+++ b/target/arm/helper-mve.h
20
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
ARMMMUIdx_Stage2 = 9 | ARM_MMU_IDX_A,
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
/* TLBs with 1-1 mapping to the physical address spaces. */
25
- ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
26
- ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
27
+ ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
28
+ ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
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);
24
+
45
+
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
+ return ARMMMUIdx_Phys_S + space;
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
40
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
43
+# VSHLL encoding T2 where shift == esize
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
45
+ qd=%qd qm=%qm size=0 shift=8
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
47
+ qd=%qd qm=%qm size=1 shift=16
48
+
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
50
%rshift_i5 16:5 !function=rsub_32
51
%rshift_i4 16:4 !function=rsub_16
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
55
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
59
+# overlaps what would be size=0b11 VMULH/VRMULH
60
+{
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
63
64
-VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
65
-VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
66
+ VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
67
+}
47
+}
68
+
48
+
49
+static inline ARMSecuritySpace arm_phys_to_space(ARMMMUIdx idx)
69
+{
50
+{
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
51
+ assert(idx >= ARMMMUIdx_Phys_S && idx <= ARMMMUIdx_Phys_Realm);
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
52
+ return idx - ARMMMUIdx_Phys_S;
72
+
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
74
+}
53
+}
75
+
54
+
76
+{
55
static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
56
{
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
57
/* If all the CLIDR.Ctypem bits are 0 there are no caches, and
79
+
58
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
81
+}
82
+
83
+{
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
86
+
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
88
+}
89
90
VMAX_S 111 0 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
91
VMAX_U 111 1 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
92
@@ -XXX,XX +XXX,XX @@ VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
93
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
94
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
95
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
96
+
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
100
+
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
103
+
104
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
105
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
106
+
107
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
108
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
109
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
110
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/mve_helper.c
60
--- a/target/arm/ptw.c
112
+++ b/target/arm/mve_helper.c
61
+++ b/target/arm/ptw.c
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
62
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
63
case ARMMMUIdx_E3:
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
64
break;
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
65
117
+
66
- case ARMMMUIdx_Phys_NS:
118
+/*
67
case ARMMMUIdx_Phys_S:
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
68
+ case ARMMMUIdx_Phys_NS:
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
69
+ case ARMMMUIdx_Phys_Root:
121
+ * the input, and LESIZE, LTYPE for the output.
70
+ case ARMMMUIdx_Phys_Realm:
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
71
/* No translation for physical address spaces. */
123
+ * because the long shift is strictly left-only.
72
return true;
124
+ */
73
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
74
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
75
switch (mmu_idx) {
127
+ void *vm, uint32_t shift) \
76
case ARMMMUIdx_Stage2:
128
+ { \
77
case ARMMMUIdx_Stage2_S:
129
+ LTYPE *d = vd; \
78
- case ARMMMUIdx_Phys_NS:
130
+ TYPE *m = vm; \
79
case ARMMMUIdx_Phys_S:
131
+ uint16_t mask = mve_element_mask(env); \
80
+ case ARMMMUIdx_Phys_NS:
132
+ unsigned le; \
81
+ case ARMMMUIdx_Phys_Root:
133
+ assert(shift <= 16); \
82
+ case ARMMMUIdx_Phys_Realm:
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
83
break;
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
84
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
85
default:
137
+ } \
86
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
138
+ mve_advance_vpt(env); \
87
switch (mmu_idx) {
139
+ }
88
case ARMMMUIdx_Phys_S:
140
+
89
case ARMMMUIdx_Phys_NS:
141
+#define DO_VSHLL_ALL(OP, TOP) \
90
+ case ARMMMUIdx_Phys_Root:
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
91
+ case ARMMMUIdx_Phys_Realm:
143
+ DO_VSHLL(OP##ub, TOP, 1, uint8_t, 2, uint16_t) \
92
/* Checking Phys early avoids special casing later vs regime_el. */
144
+ DO_VSHLL(OP##sh, TOP, 2, int16_t, 4, int32_t) \
93
return get_phys_addr_disabled(env, address, access_type, mmu_idx,
145
+ DO_VSHLL(OP##uh, TOP, 2, uint16_t, 4, uint32_t) \
94
is_secure, result, fi);
146
+
147
+DO_VSHLL_ALL(vshllb, false)
148
+DO_VSHLL_ALL(vshllt, true)
149
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-mve.c
152
+++ b/target/arm/translate-mve.c
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
+
158
+#define DO_VSHLL(INSN, FN) \
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
160
+ { \
161
+ static MVEGenTwoOpShiftFn * const fns[] = { \
162
+ gen_helper_mve_##FN##b, \
163
+ gen_helper_mve_##FN##h, \
164
+ }; \
165
+ return do_2shift(s, a, fns[a->size], false); \
166
+ }
167
+
168
+DO_VSHLL(VSHLL_BS, vshllbs)
169
+DO_VSHLL(VSHLL_BU, vshllbu)
170
+DO_VSHLL(VSHLL_TS, vshllts)
171
+DO_VSHLL(VSHLL_TU, vshlltu)
172
--
95
--
173
2.20.1
96
2.34.1
174
97
175
98
diff view generated by jsdifflib
1
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
1
From: Richard Henderson <richard.henderson@linaro.org>
2
insns had some bugs:
3
* the 32x32 multiply of elements was being done as 32x32->32,
4
not 32x32->64
5
* we were incorrectly maintaining the accumulator in its full
6
72-bit form across all 4 beats of the insn; in the pseudocode
7
it is squashed back into the 64 bits of the RdaHi:RdaLo
8
registers after each beat
9
2
10
In particular, fixing the second of these allows us to recast
3
This was added in 7e98e21c098 as part of a reorg in which
11
the implementation to avoid 128-bit arithmetic entirely.
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.
12
7
13
Since the element size here is always 4, we can also drop the
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
parameterization of ESIZE to make the code a little more readable.
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
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/ptw.c | 6 ++----
15
1 file changed, 2 insertions(+), 4 deletions(-)
15
16
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
20
---
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
22
1 file changed, 21 insertions(+), 17 deletions(-)
23
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/mve_helper.c
19
--- a/target/arm/ptw.c
27
+++ b/target/arm/mve_helper.c
20
+++ b/target/arm/ptw.c
28
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
29
*/
22
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
30
23
uint64_t address,
31
#include "qemu/osdep.h"
24
MMUAccessType access_type, bool s1_is_el0,
32
-#include "qemu/int128.h"
25
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
33
#include "cpu.h"
26
- __attribute__((nonnull));
34
#include "internals.h"
27
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
35
#include "vec_internal.h"
28
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
29
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
30
target_ulong address,
38
31
MMUAccessType access_type,
39
/*
32
GetPhysAddrResult *result,
40
- * Rounding multiply add long dual accumulate high: we must keep
33
- ARMMMUFaultInfo *fi)
41
- * a 72-bit internal accumulator value and return the top 64 bits.
34
- __attribute__((nonnull));
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
35
+ ARMMMUFaultInfo *fi);
43
+ * this is implemented with a 72-bit internal accumulator value of which
36
44
+ * the top 64 bits are returned. We optimize this to avoid having to
37
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
38
static const uint8_t pamax_map[] = {
46
+ * is squashed back into 64-bits after each beat.
47
*/
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
51
void *vm, uint64_t a) \
52
{ \
53
uint16_t mask = mve_element_mask(env); \
54
unsigned e; \
55
TYPE *n = vn, *m = vm; \
56
- Int128 acc = int128_lshift(TO128(a), 8); \
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
59
if (mask & 1) { \
60
+ LTYPE mul; \
61
if (e & 1) { \
62
- acc = ODDACC(acc, TO128(n[H##ESIZE(e - 1 * XCHG)] * \
63
- m[H##ESIZE(e)])); \
64
+ mul = (LTYPE)n[H4(e - 1 * XCHG)] * m[H4(e)]; \
65
+ if (SUB) { \
66
+ mul = -mul; \
67
+ } \
68
} else { \
69
- acc = EVENACC(acc, TO128(n[H##ESIZE(e + 1 * XCHG)] * \
70
- m[H##ESIZE(e)])); \
71
+ mul = (LTYPE)n[H4(e + 1 * XCHG)] * m[H4(e)]; \
72
} \
73
- acc = int128_add(acc, int128_make64(1 << 7)); \
74
+ mul = (mul >> 8) + ((mul >> 7) & 1); \
75
+ a += mul; \
76
} \
77
} \
78
mve_advance_vpt(env); \
79
- return int128_getlo(int128_rshift(acc, 8)); \
80
+ return a; \
81
}
82
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
87
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
90
91
-DO_LDAVH(vrmlsldavhsw, 4, int32_t, false, int128_add, int128_sub, int128_makes64)
92
-DO_LDAVH(vrmlsldavhxsw, 4, int32_t, true, int128_add, int128_sub, int128_makes64)
93
+DO_LDAVH(vrmlsldavhsw, int32_t, int64_t, false, true)
94
+DO_LDAVH(vrmlsldavhxsw, int32_t, int64_t, true, true)
95
96
/* Vector add across vector */
97
#define DO_VADDV(OP, ESIZE, TYPE) \
98
--
39
--
99
2.20.1
40
2.34.1
100
41
101
42
diff view generated by jsdifflib
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
1
From: Richard Henderson <richard.henderson@linaro.org>
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
stored in a pair of general-purpose registers.
4
2
3
Add input and output space members to S1Translate. Set and adjust
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.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620124418.805717-11-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
8
---
12
---
9
target/arm/helper-mve.h | 3 ++
13
target/arm/ptw.c | 86 +++++++++++++++++++++++++++++++++++++++---------
10
target/arm/mve.decode | 6 +++-
14
1 file changed, 71 insertions(+), 15 deletions(-)
11
target/arm/mve_helper.c | 19 ++++++++++++
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 90 insertions(+), 1 deletion(-)
14
15
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
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/helper-mve.h
18
--- a/target/arm/ptw.c
18
+++ b/target/arm/helper-mve.h
19
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
20
@@ -XXX,XX +XXX,XX @@
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
typedef struct S1Translate {
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
ARMMMUIdx in_mmu_idx;
22
23
ARMMMUIdx in_ptw_idx;
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
24
+ ARMSecuritySpace in_space;
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
25
bool in_secure;
26
bool in_debug;
27
bool out_secure;
28
bool out_rw;
29
bool out_be;
30
+ ARMSecuritySpace out_space;
31
hwaddr out_virt;
32
hwaddr out_phys;
33
void *out_host;
34
@@ -XXX,XX +XXX,XX @@ static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
35
static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
36
hwaddr addr, ARMMMUFaultInfo *fi)
37
{
38
+ ARMSecuritySpace space = ptw->in_space;
39
bool is_secure = ptw->in_secure;
40
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
41
ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
42
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
43
.in_mmu_idx = s2_mmu_idx,
44
.in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
45
.in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
46
+ .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
47
+ : space == ARMSS_Realm ? ARMSS_Realm
48
+ : ARMSS_NonSecure),
49
.in_debug = true,
50
};
51
GetPhysAddrResult s2 = { };
52
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
53
ptw->out_phys = s2.f.phys_addr;
54
pte_attrs = s2.cacheattrs.attrs;
55
ptw->out_secure = s2.f.attrs.secure;
56
+ ptw->out_space = s2.f.attrs.space;
57
} else {
58
/* Regime is physical. */
59
ptw->out_phys = addr;
60
pte_attrs = 0;
61
ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
62
+ ptw->out_space = (s2_mmu_idx == ARMMMUIdx_Phys_S ? ARMSS_Secure
63
+ : space == ARMSS_Realm ? ARMSS_Realm
64
+ : ARMSS_NonSecure);
65
}
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
}
78
} else {
79
/* Page tables are in MMIO. */
80
- MemTxAttrs attrs = { .secure = ptw->out_secure };
81
+ MemTxAttrs attrs = {
82
+ .secure = ptw->out_secure,
83
+ .space = ptw->out_space,
84
+ };
85
AddressSpace *as = arm_addressspace(cs, attrs);
86
MemTxResult result = MEMTX_OK;
87
88
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
89
#endif
90
} else {
91
/* Page tables are in MMIO. */
92
- MemTxAttrs attrs = { .secure = ptw->out_secure };
93
+ MemTxAttrs attrs = {
94
+ .secure = ptw->out_secure,
95
+ .space = ptw->out_space,
96
+ };
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);
143
144
/*
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
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.
155
*/
156
result->f.attrs.secure = is_secure;
157
+ result->f.attrs.space = ptw->in_space;
158
159
switch (mmu_idx) {
160
case ARMMMUIdx_Phys_S:
161
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
162
163
default:
164
/* Single stage uses physical for ptw. */
165
- ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
166
+ ptw->in_ptw_idx = arm_space_to_phys(ptw->in_space);
167
break;
168
}
169
170
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
171
S1Translate ptw = {
172
.in_mmu_idx = mmu_idx,
173
.in_secure = is_secure,
174
+ .in_space = arm_secure_to_space(is_secure),
175
};
176
return get_phys_addr_with_struct(env, &ptw, address, access_type,
177
result, fi);
178
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
179
MMUAccessType access_type, ARMMMUIdx mmu_idx,
180
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
181
{
182
- bool is_secure;
183
+ S1Translate ptw = {
184
+ .in_mmu_idx = mmu_idx,
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);
25
+
244
+
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
245
+ ptw.in_space = ss;
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
246
+ ptw.in_secure = arm_space_is_secure(ss);
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
247
+ return get_phys_addr_with_struct(env, &ptw, address, access_type,
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
248
+ result, fi);
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/mve.decode
32
+++ b/target/arm/mve.decode
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
35
36
# Vector add across vector
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
38
+{
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
41
+ rdahi=%rdahi rdalo=%rdalo
42
+}
43
44
# Predicate operations
45
%mask_22_13 22:1 13:3
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/mve_helper.c
49
+++ b/target/arm/mve_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
51
DO_VADDV(vaddvuh, 2, uint16_t)
52
DO_VADDV(vaddvuw, 4, uint32_t)
53
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
56
+ uint64_t ra) \
57
+ { \
58
+ uint16_t mask = mve_element_mask(env); \
59
+ unsigned e; \
60
+ TYPE *m = vm; \
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
62
+ if (mask & 1) { \
63
+ ra += (LTYPE)m[H4(e)]; \
64
+ } \
65
+ } \
66
+ mve_advance_vpt(env); \
67
+ return ra; \
68
+ } \
69
+
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
72
+
73
/* Shifts by immediate */
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate-mve.c
79
+++ b/target/arm/translate-mve.c
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
81
return true;
82
}
249
}
83
250
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
251
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
85
+{
252
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
86
+ /*
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
88
+ * elements of the vector into a 64-bit result stored in
89
+ * a pair of general-purpose registers.
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
91
+ */
92
+ TCGv_ptr qm;
93
+ TCGv_i64 rda;
94
+ TCGv_i32 rdalo, rdahi;
95
+
96
+ if (!dc_isar_feature(aa32_mve, s)) {
97
+ return false;
98
+ }
99
+ /*
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
102
+ */
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
104
+ return false;
105
+ }
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
107
+ return true;
108
+ }
109
+
110
+ /*
111
+ * This insn is subject to beat-wise execution. Partial execution
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
114
+ */
115
+ if (a->a || mve_skip_first_beat(s)) {
116
+ /* Accumulate input from RdaHi:RdaLo */
117
+ rda = tcg_temp_new_i64();
118
+ rdalo = load_reg(s, a->rdalo);
119
+ rdahi = load_reg(s, a->rdahi);
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
121
+ tcg_temp_free_i32(rdalo);
122
+ tcg_temp_free_i32(rdahi);
123
+ } else {
124
+ /* Accumulate starting at zero */
125
+ rda = tcg_const_i64(0);
126
+ }
127
+
128
+ qm = mve_qreg_ptr(a->qm);
129
+ if (a->u) {
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
131
+ } else {
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
133
+ }
134
+ tcg_temp_free_ptr(qm);
135
+
136
+ rdalo = tcg_temp_new_i32();
137
+ rdahi = tcg_temp_new_i32();
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
140
+ store_reg(s, a->rdalo, rdalo);
141
+ store_reg(s, a->rdahi, rdahi);
142
+ tcg_temp_free_i64(rda);
143
+ mve_update_eci(s);
144
+ return true;
145
+}
146
+
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
148
{
253
{
149
TCGv_ptr qd;
254
ARMCPU *cpu = ARM_CPU(cs);
255
CPUARMState *env = &cpu->env;
256
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
257
+ ARMSecuritySpace ss = arm_security_space(env);
258
S1Translate ptw = {
259
- .in_mmu_idx = arm_mmu_idx(env),
260
- .in_secure = arm_is_secure(env),
261
+ .in_mmu_idx = mmu_idx,
262
+ .in_space = ss,
263
+ .in_secure = arm_space_is_secure(ss),
264
.in_debug = true,
265
};
266
GetPhysAddrResult res = {};
150
--
267
--
151
2.20.1
268
2.34.1
152
153
diff view generated by jsdifflib
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and VQSHLU.
3
2
4
The size-and-immediate encoding here is the same as Neon, and we
3
Test in_space instead of in_secure so that we don't
5
handle it the same way neon-dp.decode does.
4
switch out of Root space.
6
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-12-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
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
10
---
10
---
11
target/arm/helper-mve.h | 16 +++++++++++
11
target/arm/ptw.c | 28 ++++++++++++++--------------
12
target/arm/mve.decode | 23 +++++++++++++++
12
1 file changed, 14 insertions(+), 14 deletions(-)
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
15
4 files changed, 147 insertions(+)
16
13
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper-mve.h
16
--- a/target/arm/ptw.c
20
+++ b/target/arm/helper-mve.h
17
+++ b/target/arm/ptw.c
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
18
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
19
{
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
20
ARMCPU *cpu = env_archcpu(env);
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
21
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
25
+
22
- bool is_secure = ptw->in_secure;
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
int32_t level;
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
ARMVAParameters param;
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
uint64_t ttbr;
29
+
26
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
uint64_t descaddrmask;
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
bool aarch64 = arm_el_is_aa64(env, el);
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
uint64_t descriptor, new_descriptor;
33
+
30
- bool nstable;
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
/* TODO: This code does not support shareability levels. */
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
if (aarch64) {
37
+
34
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
descaddrmask = MAKE_64BIT_MASK(0, 40);
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/mve.decode
44
+++ b/target/arm/mve.decode
45
@@ -XXX,XX +XXX,XX @@
46
&2op qd qm qn size
47
&2scalar qd qn rm size
48
&1imm qd imm cmode op
49
+&2shift qd qm shift size
50
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
52
# Note that both Rn and Qd are 3 bits only (no D bit)
53
@@ -XXX,XX +XXX,XX @@
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
56
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
60
+
61
# Vector loads and stores
62
63
# Widening loads and narrowing stores:
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
65
# So we have a single decode line and check the cmode/op in the
66
# trans function.
67
Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
68
+
69
+# Shifts by immediate
70
+
71
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
72
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
73
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
74
+
75
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
76
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
77
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
78
+
79
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
80
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
81
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
82
+
83
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
84
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
85
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
86
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/mve_helper.c
89
+++ b/target/arm/mve_helper.c
90
@@ -XXX,XX +XXX,XX @@ DO_2OP_SAT(vqsubsw, 4, int32_t, DO_SQSUB_W)
91
WRAP_QRSHL_HELPER(do_sqrshl_bhs, N, M, true, satp)
92
#define DO_UQRSHL_OP(N, M, satp) \
93
WRAP_QRSHL_HELPER(do_uqrshl_bhs, N, M, true, satp)
94
+#define DO_SUQSHL_OP(N, M, satp) \
95
+ WRAP_QRSHL_HELPER(do_suqrshl_bhs, N, M, false, satp)
96
97
DO_2OP_SAT_S(vqshls, DO_SQSHL_OP)
98
DO_2OP_SAT_U(vqshlu, DO_UQSHL_OP)
99
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvsw, 4, uint32_t)
100
DO_VADDV(vaddvub, 1, uint8_t)
101
DO_VADDV(vaddvuh, 2, uint16_t)
102
DO_VADDV(vaddvuw, 4, uint32_t)
103
+
104
+/* Shifts by immediate */
105
+#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
106
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
107
+ void *vm, uint32_t shift) \
108
+ { \
109
+ TYPE *d = vd, *m = vm; \
110
+ uint16_t mask = mve_element_mask(env); \
111
+ unsigned e; \
112
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
113
+ mergemask(&d[H##ESIZE(e)], \
114
+ FN(m[H##ESIZE(e)], shift), mask); \
115
+ } \
116
+ mve_advance_vpt(env); \
117
+ }
118
+
119
+#define DO_2SHIFT_SAT(OP, ESIZE, TYPE, FN) \
120
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
121
+ void *vm, uint32_t shift) \
122
+ { \
123
+ TYPE *d = vd, *m = vm; \
124
+ uint16_t mask = mve_element_mask(env); \
125
+ unsigned e; \
126
+ bool qc = false; \
127
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
128
+ bool sat = false; \
129
+ mergemask(&d[H##ESIZE(e)], \
130
+ FN(m[H##ESIZE(e)], shift, &sat), mask); \
131
+ qc |= sat & mask & 1; \
132
+ } \
133
+ if (qc) { \
134
+ env->vfp.qc[0] = qc; \
135
+ } \
136
+ mve_advance_vpt(env); \
137
+ }
138
+
139
+/* provide unsigned 2-op shift helpers for all sizes */
140
+#define DO_2SHIFT_U(OP, FN) \
141
+ DO_2SHIFT(OP##b, 1, uint8_t, FN) \
142
+ DO_2SHIFT(OP##h, 2, uint16_t, FN) \
143
+ DO_2SHIFT(OP##w, 4, uint32_t, FN)
144
+
145
+#define DO_2SHIFT_SAT_U(OP, FN) \
146
+ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
147
+ DO_2SHIFT_SAT(OP##h, 2, uint16_t, FN) \
148
+ DO_2SHIFT_SAT(OP##w, 4, uint32_t, FN)
149
+#define DO_2SHIFT_SAT_S(OP, FN) \
150
+ DO_2SHIFT_SAT(OP##b, 1, int8_t, FN) \
151
+ DO_2SHIFT_SAT(OP##h, 2, int16_t, FN) \
152
+ DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
153
+
154
+DO_2SHIFT_U(vshli_u, DO_VSHLU)
155
+DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
156
+DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
157
+DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
158
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/translate-mve.c
161
+++ b/target/arm/translate-mve.c
162
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
163
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
164
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
165
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
166
+typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
167
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
168
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
169
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
170
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
171
}
36
}
172
return do_1imm(s, a, fn);
37
descaddrmask &= ~indexmask_grainsize;
173
}
38
-
174
+
39
- /*
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
40
- * Secure stage 1 accesses start with the page table in secure memory and
176
+ bool negateshift)
41
- * can be downgraded to non-secure at any step. Non-secure accesses
177
+{
42
- * remain non-secure. We implement this by just ORing in the NSTable/NS
178
+ TCGv_ptr qd, qm;
43
- * bits at each step.
179
+ int shift = a->shift;
44
- * Stage 2 never gets this kind of downgrade.
180
+
45
- */
181
+ if (!dc_isar_feature(aa32_mve, s) ||
46
- tableattrs = is_secure ? 0 : (1 << 4);
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
47
+ tableattrs = 0;
183
+ !fn) {
48
184
+ return false;
49
next_level:
185
+ }
50
descaddr |= (address >> (stride * (4 - level))) & indexmask;
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
51
descaddr &= ~7ULL;
187
+ return true;
52
- nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
188
+ }
53
- if (nstable && ptw->in_secure) {
189
+
54
+
190
+ /*
55
+ /*
191
+ * When we handle a right shift insn using a left-shift helper
56
+ * Process the NSTable bit from the previous level. This changes
192
+ * which permits a negative shift count to indicate a right-shift,
57
+ * the table address space and the output space from Secure to
193
+ * we must negate the shift count.
58
+ * NonSecure. With RME, the EL3 translation regime does not change
59
+ * from Root to NonSecure.
194
+ */
60
+ */
195
+ if (negateshift) {
61
+ if (ptw->in_space == ARMSS_Secure
196
+ shift = -shift;
62
+ && !regime_is_stage2(mmu_idx)
197
+ }
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;
72
}
198
+
73
+
199
+ qd = mve_qreg_ptr(a->qd);
74
if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
200
+ qm = mve_qreg_ptr(a->qm);
75
goto do_fault;
201
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
76
}
202
+ tcg_temp_free_ptr(qd);
77
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
203
+ tcg_temp_free_ptr(qm);
78
*/
204
+ mve_update_eci(s);
79
attrs = new_descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
205
+ return true;
80
if (!regime_is_stage2(mmu_idx)) {
206
+}
81
- attrs |= nstable << 5; /* NS */
207
+
82
+ attrs |= !ptw->in_secure << 5; /* NS */
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
83
if (!param.hpd) {
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
84
attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
210
+ { \
85
/*
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
212
+ gen_helper_mve_##FN##b, \
213
+ gen_helper_mve_##FN##h, \
214
+ gen_helper_mve_##FN##w, \
215
+ NULL, \
216
+ }; \
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
218
+ }
219
+
220
+DO_2SHIFT(VSHLI, vshli_u, false)
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
224
--
86
--
225
2.20.1
87
2.34.1
226
227
diff view generated by jsdifflib
1
In do_ldst(), the calculation of the offset needs to be based on the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
size of the memory access, not the size of the elements in the
3
vector. This meant we were getting it wrong for the widening and
4
narrowing variants of the various VLDR and VSTR insns.
5
2
3
With Realm security state, bit 55 of a block or page descriptor during
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.
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>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20230620124418.805717-13-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
9
---
17
---
10
target/arm/translate-mve.c | 17 +++++++++--------
18
target/arm/ptw.c | 89 +++++++++++++++++++++++++++++++++++++++---------
11
1 file changed, 9 insertions(+), 8 deletions(-)
19
1 file changed, 73 insertions(+), 16 deletions(-)
12
20
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
21
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-mve.c
23
--- a/target/arm/ptw.c
16
+++ b/target/arm/translate-mve.c
24
+++ b/target/arm/ptw.c
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
25
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
26
* @mmu_idx: MMU index indicating required translation regime
27
* @is_aa64: TRUE if AArch64
28
* @ap: The 2-bit simple AP (AP[2:1])
29
- * @ns: NS (non-secure) bit
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)
39
{
40
ARMCPU *cpu = env_archcpu(env);
41
bool is_user = regime_is_user(env, mmu_idx);
42
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
43
}
18
}
44
}
19
}
45
20
46
- if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) {
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
47
+ if (out_pa == ARMSS_NonSecure && in_pa == ARMSS_Secure &&
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
48
+ (env->cp15.scr_el3 & SCR_SIF)) {
23
+ unsigned msize)
49
return prot_rw;
24
{
25
TCGv_i32 addr;
26
uint32_t offset;
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
28
return true;
29
}
50
}
30
51
31
- offset = a->imm << a->size;
52
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
32
+ offset = a->imm << msize;
53
int32_t stride;
33
if (!a->a) {
54
int addrsize, inputsize, outputsize;
34
offset = -offset;
55
uint64_t tcr = regime_tcr(env, mmu_idx);
56
- int ap, ns, xn, pxn;
57
+ int ap, xn, pxn;
58
uint32_t el = regime_el(env, mmu_idx);
59
uint64_t descaddrmask;
60
bool aarch64 = arm_el_is_aa64(env, el);
61
uint64_t descriptor, new_descriptor;
62
+ ARMSecuritySpace out_space;
63
64
/* TODO: This code does not support shareability levels. */
65
if (aarch64) {
66
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
35
}
67
}
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
68
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
69
ap = extract32(attrs, 6, 2);
38
{ NULL, NULL }
70
+ out_space = ptw->in_space;
39
};
71
if (regime_is_stage2(mmu_idx)) {
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
72
- ns = mmu_idx == ARMMMUIdx_Stage2;
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
73
+ /*
42
}
74
+ * R_GYNXY: For stage2 in Realm security state, bit 55 is NS.
43
75
+ * The bit remains ignored for other security states.
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
76
+ */
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
77
+ if (out_space == ARMSS_Realm && extract64(attrs, 55, 1)) {
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
78
+ out_space = ARMSS_NonSecure;
47
{ \
79
+ }
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
80
xn = extract64(attrs, 53, 2);
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
81
result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
50
{ NULL, gen_helper_mve_##ULD }, \
82
} else {
51
}; \
83
- ns = extract32(attrs, 5, 1);
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
84
+ int nse, ns = extract32(attrs, 5, 1);
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
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);
54
}
142
}
55
143
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
144
if (!(result->f.prot & (1 << access_type))) {
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
146
}
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
147
}
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
148
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
149
- if (ns) {
62
150
- /*
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
151
- * The NS bit will (as required by the architecture) have no effect if
64
{
152
- * the CPU doesn't support TZ or this is a non-secure translation
153
- * regime, because the attribute will already be non-secure.
154
- */
155
- result->f.attrs.secure = false;
156
- result->f.attrs.space = ARMSS_NonSecure;
157
- }
158
+ result->f.attrs.space = out_space;
159
+ result->f.attrs.secure = arm_space_is_secure(out_space);
160
161
if (regime_is_stage2(mmu_idx)) {
162
result->cacheattrs.is_s2_format = true;
65
--
163
--
66
2.20.1
164
2.34.1
67
68
diff view generated by jsdifflib
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
do_urshr() is borrowed from sve_helper.c.
3
While Root and Realm may read and write data from other spaces,
4
neither may execute from other pa spaces.
4
5
6
This happens for Stage1 EL3, EL2, EL2&0, and Stage2 EL1&0.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620124418.805717-14-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
8
---
12
---
9
target/arm/helper-mve.h | 10 ++++++++++
13
target/arm/ptw.c | 52 ++++++++++++++++++++++++++++++++++++++++++------
10
target/arm/mve.decode | 11 +++++++++++
14
1 file changed, 46 insertions(+), 6 deletions(-)
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 15 ++++++++++++++
13
4 files changed, 76 insertions(+)
14
15
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
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/helper-mve.h
18
--- a/target/arm/ptw.c
18
+++ b/target/arm/helper-mve.h
19
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
@@ -XXX,XX +XXX,XX @@ do_fault:
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
* @xn: XN (execute-never) bits
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
* @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
*/
23
+
24
-static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+static int get_S2prot_noexecute(int s2ap)
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
{
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
int prot = 0;
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
28
+
29
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
if (s2ap & 2) {
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
prot |= PAGE_WRITE;
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
}
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+ return prot;
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
41
+
42
+# Narrowing shifts (which only support b and h sizes)
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
47
+
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/mve_helper.c
55
+++ b/target/arm/mve_helper.c
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
57
58
DO_VSHLL_ALL(vshllb, false)
59
DO_VSHLL_ALL(vshllt, true)
60
+
61
+/*
62
+ * Narrowing right shifts, taking a double sized input, shifting it
63
+ * and putting the result in either the top or bottom half of the output.
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
65
+ */
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
68
+ void *vm, uint32_t shift) \
69
+ { \
70
+ LTYPE *m = vm; \
71
+ TYPE *d = vd; \
72
+ uint16_t mask = mve_element_mask(env); \
73
+ unsigned le; \
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
77
+ } \
78
+ mve_advance_vpt(env); \
79
+ }
80
+
81
+#define DO_VSHRN_ALL(OP, FN) \
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
86
+
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
88
+{
89
+ if (likely(sh < 64)) {
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
91
+ } else if (sh == 64) {
92
+ return x >> 63;
93
+ } else {
94
+ return 0;
95
+ }
96
+}
34
+}
97
+
35
+
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
36
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
37
+{
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
38
+ int prot = get_S2prot_noexecute(s2ap);
101
index XXXXXXX..XXXXXXX 100644
39
102
--- a/target/arm/translate-mve.c
40
if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
103
+++ b/target/arm/translate-mve.c
41
switch (xn) {
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
42
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
105
DO_VSHLL(VSHLL_BU, vshllbu)
43
}
106
DO_VSHLL(VSHLL_TS, vshllts)
44
}
107
DO_VSHLL(VSHLL_TU, vshlltu)
45
108
+
46
- if (out_pa == ARMSS_NonSecure && in_pa == ARMSS_Secure &&
109
+#define DO_2SHIFT_N(INSN, FN) \
47
- (env->cp15.scr_el3 & SCR_SIF)) {
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
48
- return prot_rw;
111
+ { \
49
+ if (in_pa != out_pa) {
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
50
+ switch (in_pa) {
113
+ gen_helper_mve_##FN##b, \
51
+ case ARMSS_Root:
114
+ gen_helper_mve_##FN##h, \
52
+ /*
115
+ }; \
53
+ * R_ZWRVD: permission fault for insn fetched from non-Root,
116
+ return do_2shift(s, a, fns[a->size], false); \
54
+ * I_WWBFB: SIF has no effect in EL3.
117
+ }
55
+ */
118
+
56
+ return prot_rw;
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
57
+ case ARMSS_Realm:
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
58
+ /*
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
59
+ * R_PKTDS: permission fault for insn fetched from non-Realm,
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
60
+ * for Realm EL2 or EL2&0. The corresponding fault for EL1&0
61
+ * happens during any stage2 translation.
62
+ */
63
+ switch (mmu_idx) {
64
+ case ARMMMUIdx_E2:
65
+ case ARMMMUIdx_E20_0:
66
+ case ARMMMUIdx_E20_2:
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);
98
}
99
- xn = extract64(attrs, 53, 2);
100
- result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
101
} else {
102
int nse, ns = extract32(attrs, 5, 1);
103
switch (out_space) {
123
--
104
--
124
2.20.1
105
2.34.1
125
126
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add a test booting and quickly shutdown a raspi2 machine,
3
Do not provide a fast-path for physical addresses,
4
to test the power management model:
4
as those will need to be validated for GPC.
5
5
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
console: [ 0.000000] Linux version 4.14.98-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1200 SMP Tue Feb 12 20:27:48 GMT 2019
8
Message-id: 20230620124418.805717-15-richard.henderson@linaro.org
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
10
console: [ 0.000000] CPU: div instructions available: patching division code
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
13
...
14
console: Boot successful.
15
console: cat /proc/cpuinfo
16
console: / # cat /proc/cpuinfo
17
...
18
console: processor : 3
19
console: model name : ARMv7 Processor rev 5 (v7l)
20
console: BogoMIPS : 125.00
21
console: Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
22
console: CPU implementer : 0x41
23
console: CPU architecture: 7
24
console: CPU variant : 0x0
25
console: CPU part : 0xc07
26
console: CPU revision : 5
27
console: Hardware : BCM2835
28
console: Revision : 0000
29
console: Serial : 0000000000000000
30
console: cat /proc/iomem
31
console: / # cat /proc/iomem
32
console: 00000000-3bffffff : System RAM
33
console: 00008000-00afffff : Kernel code
34
console: 00c00000-00d468ef : Kernel data
35
console: 3f006000-3f006fff : dwc_otg
36
console: 3f007000-3f007eff : /soc/dma@7e007000
37
console: 3f00b880-3f00b8bf : /soc/mailbox@7e00b880
38
console: 3f100000-3f100027 : /soc/watchdog@7e100000
39
console: 3f101000-3f102fff : /soc/cprman@7e101000
40
console: 3f200000-3f2000b3 : /soc/gpio@7e200000
41
PASS (24.59 s)
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
43
JOB TIME : 25.02 s
44
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
49
---
10
---
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
11
target/arm/ptw.c | 44 +++++++++++++++++---------------------------
51
1 file changed, 43 insertions(+)
12
1 file changed, 17 insertions(+), 27 deletions(-)
52
13
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
54
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
55
--- a/tests/acceptance/boot_linux_console.py
16
--- a/target/arm/ptw.c
56
+++ b/tests/acceptance/boot_linux_console.py
17
+++ b/target/arm/ptw.c
57
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
58
from avocado import skip
19
* From gdbstub, do not use softmmu so that we don't modify the
59
from avocado import skipUnless
20
* state of the cpu at all, including softmmu tlb contents.
60
from avocado_qemu import Test
21
*/
61
+from avocado_qemu import exec_command
22
- if (regime_is_stage2(s2_mmu_idx)) {
62
from avocado_qemu import exec_command_and_wait_for_pattern
23
- S1Translate s2ptw = {
63
from avocado_qemu import interrupt_interactive_console_until_pattern
24
- .in_mmu_idx = s2_mmu_idx,
64
from avocado_qemu import wait_for_console_pattern
25
- .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
26
- .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
66
"""
27
- .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
67
self.do_test_arm_raspi2(0)
28
- : space == ARMSS_Realm ? ARMSS_Realm
68
29
- : ARMSS_NonSecure),
69
+ def test_arm_raspi2_initrd(self):
30
- .in_debug = true,
70
+ """
31
- };
71
+ :avocado: tags=arch:arm
32
- GetPhysAddrResult s2 = { };
72
+ :avocado: tags=machine:raspi2
33
+ S1Translate s2ptw = {
73
+ """
34
+ .in_mmu_idx = s2_mmu_idx,
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
35
+ .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
75
+ 'pool/main/r/raspberrypi-firmware/'
36
+ .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
37
+ .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
38
+ : space == ARMSS_Realm ? ARMSS_Realm
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
39
+ : ARMSS_NonSecure),
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
40
+ .in_debug = true,
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
41
+ };
81
+
42
+ GetPhysAddrResult s2 = { };
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
43
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
44
- if (get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
84
+ 'arm/rootfs-armv7a.cpio.gz')
45
- false, &s2, fi)) {
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
46
- goto fail;
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
47
- }
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
48
- ptw->out_phys = s2.f.phys_addr;
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
49
- pte_attrs = s2.cacheattrs.attrs;
89
+
50
- ptw->out_secure = s2.f.attrs.secure;
90
+ self.vm.set_console()
51
- ptw->out_space = s2.f.attrs.space;
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
52
- } else {
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
53
- /* Regime is physical. */
93
+ 'panic=-1 noreboot ' +
54
- ptw->out_phys = addr;
94
+ 'dwc_otg.fiq_fsm_enable=0')
55
- pte_attrs = 0;
95
+ self.vm.add_args('-kernel', kernel_path,
56
- ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
96
+ '-dtb', dtb_path,
57
- ptw->out_space = (s2_mmu_idx == ARMMMUIdx_Phys_S ? ARMSS_Secure
97
+ '-initrd', initrd_path,
58
- : space == ARMSS_Realm ? ARMSS_Realm
98
+ '-append', kernel_command_line,
59
- : ARMSS_NonSecure);
99
+ '-no-reboot')
60
+ if (get_phys_addr_with_struct(env, &s2ptw, addr,
100
+ self.vm.launch()
61
+ MMU_DATA_LOAD, &s2, fi)) {
101
+ self.wait_for_console_pattern('Boot successful.')
62
+ goto fail;
102
+
63
}
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
64
+ ptw->out_phys = s2.f.phys_addr;
104
+ 'BCM2835')
65
+ pte_attrs = s2.cacheattrs.attrs;
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
66
ptw->out_host = NULL;
106
+ '/soc/cprman@7e101000')
67
ptw->out_rw = false;
107
+ exec_command(self, 'halt')
68
+ ptw->out_secure = s2.f.attrs.secure;
108
+ # Wait for VM to shut down gracefully
69
+ ptw->out_space = s2.f.attrs.space;
109
+ self.vm.wait()
70
} else {
110
+
71
#ifdef CONFIG_TCG
111
def test_arm_exynos4210_initrd(self):
72
CPUTLBEntryFull *full;
112
"""
113
:avocado: tags=arch:arm
114
--
73
--
115
2.20.1
74
2.34.1
116
117
diff view generated by jsdifflib
1
The A64 AdvSIMD modified-immediate grouping uses almost the same
1
From: Richard Henderson <richard.henderson@linaro.org>
2
constant encoding that A32 Neon does; reuse asimd_imm_const() (to
3
which we add the AArch64-specific case for cmode 15 op 1) instead of
4
reimplementing it all.
5
2
3
Instead of passing this to get_phys_addr_lpae, stash it
4
in the S1Translate structure.
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-16-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-5-peter.maydell@linaro.org
9
---
11
---
10
target/arm/translate.h | 3 +-
12
target/arm/ptw.c | 27 ++++++++++++---------------
11
target/arm/translate-a64.c | 86 ++++----------------------------------
13
1 file changed, 12 insertions(+), 15 deletions(-)
12
target/arm/translate.c | 17 +++++++-
13
3 files changed, 24 insertions(+), 82 deletions(-)
14
14
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
17
--- a/target/arm/ptw.c
18
+++ b/target/arm/translate.h
18
+++ b/target/arm/ptw.c
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
20
* VMVN and VBIC (when cmode < 14 && op == 1).
20
ARMSecuritySpace in_space;
21
*
21
bool in_secure;
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
22
bool in_debug;
23
- * callers must catch this.
23
+ /*
24
+ * callers must catch this; we return the 64-bit constant value defined
24
+ * If this is stage 2 of a stage 1+2 page table walk, then this must
25
+ * for AArch64.
25
+ * be true if stage 1 is an EL0 access; otherwise this is ignored.
26
*
26
+ * Stage 2 is indicated by in_mmu_idx set to ARMMMUIdx_Stage2{,_S}.
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
27
+ */
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
28
+ bool in_s1_is_el0;
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
bool out_secure;
30
index XXXXXXX..XXXXXXX 100644
30
bool out_rw;
31
--- a/target/arm/translate-a64.c
31
bool out_be;
32
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
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)
34
{
59
{
35
int rd = extract32(insn, 0, 5);
60
ARMCPU *cpu = env_archcpu(env);
36
int cmode = extract32(insn, 12, 4);
61
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
37
- int cmode_3_1 = extract32(cmode, 1, 3);
62
result->f.prot = get_S2prot_noexecute(ap);
38
- int cmode_0 = extract32(cmode, 0, 1);
63
} else {
39
int o2 = extract32(insn, 11, 1);
64
xn = extract64(attrs, 53, 2);
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
65
- result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
41
bool is_neg = extract32(insn, 29, 1);
66
+ result->f.prot = get_S2prot(env, ap, xn, ptw->in_s1_is_el0);
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
67
}
43
return;
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);
44
}
94
}
45
95
fi->s2addr = ipa;
46
- /* See AdvSIMDExpandImm() in ARM ARM */
96
47
- switch (cmode_3_1) {
97
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
52
- {
53
- int shift = cmode_3_1 * 8;
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
55
- break;
56
- }
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
59
- {
60
- int shift = (cmode_3_1 & 0x1) * 8;
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
62
- break;
63
- }
64
- case 6:
65
- if (cmode_0) {
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
67
- imm = (abcdefgh << 16) | 0xffff;
68
- } else {
69
- /* Replicate(Zeros(16):imm8:Ones(8), 2) */
70
- imm = (abcdefgh << 8) | 0xff;
71
- }
72
- imm = bitfield_replicate(imm, 32);
73
- break;
74
- case 7:
75
- if (!cmode_0 && !is_neg) {
76
- imm = bitfield_replicate(abcdefgh, 8);
77
- } else if (!cmode_0 && is_neg) {
78
- int i;
79
- imm = 0;
80
- for (i = 0; i < 8; i++) {
81
- if ((abcdefgh) & (1 << i)) {
82
- imm |= 0xffULL << (i * 8);
83
- }
84
- }
85
- } else if (cmode_0) {
86
- if (is_neg) {
87
- imm = (abcdefgh & 0x3f) << 48;
88
- if (abcdefgh & 0x80) {
89
- imm |= 0x8000000000000000ULL;
90
- }
91
- if (abcdefgh & 0x40) {
92
- imm |= 0x3fc0000000000000ULL;
93
- } else {
94
- imm |= 0x4000000000000000ULL;
95
- }
96
- } else {
97
- if (o2) {
98
- /* FMOV (vector, immediate) - half-precision */
99
- imm = vfp_expand_imm(MO_16, abcdefgh);
100
- /* now duplicate across the lanes */
101
- imm = bitfield_replicate(imm, 16);
102
- } else {
103
- imm = (abcdefgh & 0x3f) << 19;
104
- if (abcdefgh & 0x80) {
105
- imm |= 0x80000000;
106
- }
107
- if (abcdefgh & 0x40) {
108
- imm |= 0x3e000000;
109
- } else {
110
- imm |= 0x40000000;
111
- }
112
- imm |= (imm << 32);
113
- }
114
- }
115
- }
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
120
-
121
- if (cmode_3_1 != 7 && is_neg) {
122
- imm = ~imm;
123
+ if (cmode == 15 && o2 && !is_neg) {
124
+ /* FMOV (vector, immediate) - half-precision */
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
126
+ /* now duplicate across the lanes */
127
+ imm = bitfield_replicate(imm, 16);
128
+ } else {
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
130
}
98
}
131
99
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
100
if (regime_using_lpae_format(env, mmu_idx)) {
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
101
- return get_phys_addr_lpae(env, ptw, address, access_type, false,
134
index XXXXXXX..XXXXXXX 100644
102
- result, fi);
135
--- a/target/arm/translate.c
103
+ return get_phys_addr_lpae(env, ptw, address, access_type, result, fi);
136
+++ b/target/arm/translate.c
104
} else if (arm_feature(env, ARM_FEATURE_V7) ||
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
105
regime_sctlr(env, mmu_idx) & SCTLR_XP) {
138
case 14:
106
return get_phys_addr_v6(env, ptw, address, access_type, result, fi);
139
if (op) {
140
/*
141
- * This is the only case where the top and bottom 32 bits
142
- * of the encoded constant differ.
143
+ * This and cmode == 15 op == 1 are the only cases where
144
+ * the top and bottom 32 bits of the encoded constant differ.
145
*/
146
uint64_t imm64 = 0;
147
int n;
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
150
break;
151
case 15:
152
+ if (op) {
153
+ /* Reserved encoding for AArch32; valid for AArch64 */
154
+ uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
155
+ if (imm & 0x80) {
156
+ imm64 |= 0x8000000000000000ULL;
157
+ }
158
+ if (imm & 0x40) {
159
+ imm64 |= 0x3fc0000000000000ULL;
160
+ } else {
161
+ imm64 |= 0x4000000000000000ULL;
162
+ }
163
+ return imm64;
164
+ }
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
167
break;
168
--
107
--
169
2.20.1
108
2.34.1
170
109
171
110
diff view generated by jsdifflib
1
From: Patrick Venture <venture@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add line item reference to quanta-gbs-bmc machine.
3
This fixes a bug in which we failed to initialize
4
the result attributes properly after the memset.
4
5
5
Signed-off-by: Patrick Venture <venture@google.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20210615192848.1065297-3-venture@google.com
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
[PMM: fixed underline Sphinx warning]
9
Message-id: 20230620124418.805717-17-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
docs/system/arm/nuvoton.rst | 5 +++--
12
target/arm/ptw.c | 11 +----------
12
1 file changed, 3 insertions(+), 2 deletions(-)
13
1 file changed, 1 insertion(+), 10 deletions(-)
13
14
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
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/docs/system/arm/nuvoton.rst
17
--- a/target/arm/ptw.c
17
+++ b/docs/system/arm/nuvoton.rst
18
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
20
void *out_host;
20
-=====================================================
21
} S1Translate;
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
22
22
+================================================================
23
-static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
23
24
- uint64_t address, MMUAccessType access_type,
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
25
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
25
designed to be used as Baseboard Management Controllers (BMCs) in various
26
-
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
27
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
28
target_ulong address,
28
Hyperscale applications. The following machines are based on this chip :
29
MMUAccessType access_type,
29
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
31
cacheattrs1 = result->cacheattrs;
31
- ``quanta-gsj`` Quanta GSJ server BMC
32
memset(result, 0, sizeof(*result));
32
33
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
34
- if (arm_feature(env, ARM_FEATURE_PMSA)) {
35
- ret = get_phys_addr_pmsav8(env, ipa, access_type,
36
- ptw->in_mmu_idx, is_secure, result, fi);
37
- } else {
38
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type, result, fi);
39
- }
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. */
34
--
44
--
35
2.20.1
45
2.34.1
36
46
37
47
diff view generated by jsdifflib
1
The function asimd_imm_const() in translate-neon.c is an
1
From: Richard Henderson <richard.henderson@linaro.org>
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
3
also want for MVE. Move the implementation to translate.c, with a
4
prototype in translate.h.
5
2
3
The function takes the fields as filled in by
4
the Arm ARM pseudocode for TakeGPCException.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-18-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
9
---
10
---
10
target/arm/translate.h | 16 ++++++++++
11
target/arm/syndrome.h | 10 ++++++++++
11
target/arm/translate-neon.c | 63 -------------------------------------
12
1 file changed, 10 insertions(+)
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
13
3 files changed, 73 insertions(+), 63 deletions(-)
14
13
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
16
--- a/target/arm/syndrome.h
18
+++ b/target/arm/translate.h
17
+++ b/target/arm/syndrome.h
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
18
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
20
return opc | s->be_data;
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;
21
}
28
}
22
29
23
+/**
30
+static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc,
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
31
+ int cm, int s1ptw, int wnr, int fsc)
25
+ *
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
29
+ *
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
31
+ * callers must catch this.
32
+ *
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
35
+ * we produce an immediate constant value of 0 in these cases.
36
+ */
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.c
43
+++ b/target/arm/translate-neon.c
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
47
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
49
-{
50
- /*
51
- * Expand the encoded constant.
52
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
53
- * We choose to not special-case this and will behave as if a
54
- * valid constant encoding of 0 had been given.
55
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
56
- */
57
- switch (cmode) {
58
- case 0: case 1:
59
- /* no-op */
60
- break;
61
- case 2: case 3:
62
- imm <<= 8;
63
- break;
64
- case 4: case 5:
65
- imm <<= 16;
66
- break;
67
- case 6: case 7:
68
- imm <<= 24;
69
- break;
70
- case 8: case 9:
71
- imm |= imm << 16;
72
- break;
73
- case 10: case 11:
74
- imm = (imm << 8) | (imm << 24);
75
- break;
76
- case 12:
77
- imm = (imm << 8) | 0xff;
78
- break;
79
- case 13:
80
- imm = (imm << 16) | 0xffff;
81
- break;
82
- case 14:
83
- if (op) {
84
- /*
85
- * This is the only case where the top and bottom 32 bits
86
- * of the encoded constant differ.
87
- */
88
- uint64_t imm64 = 0;
89
- int n;
90
-
91
- for (n = 0; n < 8; n++) {
92
- if (imm & (1 << n)) {
93
- imm64 |= (0xffULL << (n * 8));
94
- }
95
- }
96
- return imm64;
97
- }
98
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
99
- break;
100
- case 15:
101
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
102
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
103
- break;
104
- }
105
- if (op) {
106
- imm = ~imm;
107
- }
108
- return dup_const(MO_32, imm);
109
-}
110
-
111
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
112
GVecGen2iFn *fn)
113
{
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
119
a64_translate_init();
120
}
121
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
123
+{
32
+{
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
33
+ /* TODO: FEAT_NV2 adds VNCR */
125
+ switch (cmode) {
34
+ return (EC_GPC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (s2ptw << 21)
126
+ case 0: case 1:
35
+ | (ind << 20) | (gpcsc << 14) | (cm << 8) | (s1ptw << 7)
127
+ /* no-op */
36
+ | (wnr << 6) | fsc;
128
+ break;
129
+ case 2: case 3:
130
+ imm <<= 8;
131
+ break;
132
+ case 4: case 5:
133
+ imm <<= 16;
134
+ break;
135
+ case 6: case 7:
136
+ imm <<= 24;
137
+ break;
138
+ case 8: case 9:
139
+ imm |= imm << 16;
140
+ break;
141
+ case 10: case 11:
142
+ imm = (imm << 8) | (imm << 24);
143
+ break;
144
+ case 12:
145
+ imm = (imm << 8) | 0xff;
146
+ break;
147
+ case 13:
148
+ imm = (imm << 16) | 0xffff;
149
+ break;
150
+ case 14:
151
+ if (op) {
152
+ /*
153
+ * This is the only case where the top and bottom 32 bits
154
+ * of the encoded constant differ.
155
+ */
156
+ uint64_t imm64 = 0;
157
+ int n;
158
+
159
+ for (n = 0; n < 8; n++) {
160
+ if (imm & (1 << n)) {
161
+ imm64 |= (0xffULL << (n * 8));
162
+ }
163
+ }
164
+ return imm64;
165
+ }
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
167
+ break;
168
+ case 15:
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
171
+ break;
172
+ }
173
+ if (op) {
174
+ imm = ~imm;
175
+ }
176
+ return dup_const(MO_32, imm);
177
+}
37
+}
178
+
38
+
179
/* Generate a label used for skipping this instruction */
39
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
180
void arm_gen_condlabel(DisasContext *s)
181
{
40
{
41
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
182
--
42
--
183
2.20.1
43
2.34.1
184
185
diff view generated by jsdifflib
1
Implement the MVE vector shift right by immediate insns VSHRI and
1
From: Richard Henderson <richard.henderson@linaro.org>
2
VRSHRI. As with Neon, we implement these by using helper functions
3
which perform left shifts but allow negative shift counts to indicate
4
right shifts.
5
2
3
Handle GPC Fault types in arm_deliver_fault, reporting as
4
either a GPC exception at EL3, or falling through to insn
5
or data aborts at various exception levels.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-19-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
9
---
11
---
10
target/arm/helper-mve.h | 12 ++++++++++++
12
target/arm/cpu.h | 1 +
11
target/arm/translate.h | 20 ++++++++++++++++++++
13
target/arm/internals.h | 27 +++++++++++
12
target/arm/mve.decode | 28 ++++++++++++++++++++++++++++
14
target/arm/helper.c | 5 ++
13
target/arm/mve_helper.c | 7 +++++++
15
target/arm/tcg/tlb_helper.c | 96 +++++++++++++++++++++++++++++++++++--
14
target/arm/translate-mve.c | 5 +++++
16
4 files changed, 126 insertions(+), 3 deletions(-)
15
target/arm/translate-neon.c | 18 ------------------
16
6 files changed, 72 insertions(+), 18 deletions(-)
17
17
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-mve.h
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/helper-mve.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
22
@@ -XXX,XX +XXX,XX @@
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
23
#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
24
#define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */
25
25
#define EXCP_VSERR 24
26
+DEF_HELPER_FLAGS_4(mve_vshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+#define EXCP_GPC 25 /* v9 Granule Protection Check Fault */
27
+DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
28
+DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
29
+
29
#define ARMV7M_EXCP_RESET 1
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
diff --git a/target/arm/internals.h b/target/arm/internals.h
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
index XXXXXXX..XXXXXXX 100644
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
--- a/target/arm/internals.h
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+++ b/target/arm/internals.h
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
ARMFault_ICacheMaint,
36
DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
ARMFault_QEMU_NSCExec, /* v8M: NS executing in S&NSC memory */
37
+
37
ARMFault_QEMU_SFault, /* v8M: SecureFault INVTRAN, INVEP or AUVIOL */
38
+DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+ ARMFault_GPCFOnWalk,
39
+DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+ ARMFault_GPCFOnOutput,
40
+DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
} ARMFaultType;
41
+
41
42
+DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
+typedef enum ARMGPCF {
43
+DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+ GPCF_None,
44
+DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+ GPCF_AddressSize,
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
45
+ GPCF_Walk,
46
index XXXXXXX..XXXXXXX 100644
46
+ GPCF_EABT,
47
--- a/target/arm/translate.h
47
+ GPCF_Fail,
48
+++ b/target/arm/translate.h
48
+} ARMGPCF;
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
49
+
50
return x * 2 + 1;
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;
51
}
120
}
52
121
53
+static inline int rsub_64(DisasContext *s, int x)
122
+static bool report_as_gpc_exception(ARMCPU *cpu, int current_el,
123
+ ARMMMUFaultInfo *fi)
54
+{
124
+{
55
+ return 64 - x;
125
+ bool ret;
126
+
127
+ switch (fi->gpcf) {
128
+ case GPCF_None:
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;
143
+ break;
144
+ default:
145
+ g_assert_not_reached();
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;
56
+}
158
+}
57
+
159
+
58
+static inline int rsub_32(DisasContext *s, int x)
160
+static unsigned encode_gpcsc(ARMMMUFaultInfo *fi)
59
+{
161
+{
60
+ return 32 - x;
162
+ static uint8_t const gpcsc[] = {
163
+ [GPCF_AddressSize] = 0b000000,
164
+ [GPCF_Walk] = 0b000100,
165
+ [GPCF_Fail] = 0b001100,
166
+ [GPCF_EABT] = 0b010100,
167
+ };
168
+
169
+ /* Note that we've validated fi->gpcf and fi->level above. */
170
+ return gpcsc[fi->gpcf] | fi->level;
61
+}
171
+}
62
+
172
+
63
+static inline int rsub_16(DisasContext *s, int x)
173
static G_NORETURN
64
+{
174
void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
65
+ return 16 - x;
175
MMUAccessType access_type,
66
+}
176
int mmu_idx, ARMMMUFaultInfo *fi)
67
+
68
+static inline int rsub_8(DisasContext *s, int x)
69
+{
70
+ return 8 - x;
71
+}
72
+
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
74
{
177
{
75
return (dc->features & (1ULL << feature)) != 0;
178
CPUARMState *env = &cpu->env;
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
179
- int target_el;
77
index XXXXXXX..XXXXXXX 100644
180
+ int target_el = exception_target_el(env);
78
--- a/target/arm/mve.decode
181
+ int current_el = arm_current_el(env);
79
+++ b/target/arm/mve.decode
182
bool same_el;
80
@@ -XXX,XX +XXX,XX @@
183
uint32_t syn, exc, fsr, fsc;
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
184
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
185
- target_el = exception_target_el(env);
83
186
+ if (report_as_gpc_exception(cpu, current_el, fi)) {
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
187
+ target_el = 3;
85
+%rshift_i5 16:5 !function=rsub_32
188
+
86
+%rshift_i4 16:4 !function=rsub_16
189
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
87
+%rshift_i3 16:3 !function=rsub_8
190
+
88
+
191
+ syn = syn_gpc(fi->stage2 && fi->type == ARMFault_GPCFOnWalk,
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
192
+ access_type == MMU_INST_FETCH,
90
+ size=0 shift=%rshift_i3
193
+ encode_gpcsc(fi), 0, fi->s1ptw,
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
194
+ access_type == MMU_DATA_STORE, fsc);
92
+ size=1 shift=%rshift_i4
195
+
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
196
+ env->cp15.mfar_el3 = fi->paddr;
94
+ size=2 shift=%rshift_i5
197
+ switch (fi->paddr_space) {
95
+
198
+ case ARMSS_Secure:
96
# Vector loads and stores
199
+ break;
97
200
+ case ARMSS_NonSecure:
98
# Widening loads and narrowing stores:
201
+ env->cp15.mfar_el3 |= R_MFAR_NS_MASK;
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
202
+ break;
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
203
+ case ARMSS_Root:
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
204
+ env->cp15.mfar_el3 |= R_MFAR_NSE_MASK;
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
205
+ break;
103
+
206
+ case ARMSS_Realm:
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
207
+ env->cp15.mfar_el3 |= R_MFAR_NSE_MASK | R_MFAR_NS_MASK;
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
208
+ break;
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
209
+ default:
107
+
210
+ g_assert_not_reached();
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
211
+ }
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
212
+
110
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
213
+ exc = EXCP_GPC;
111
+
214
+ goto do_raise;
112
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
215
+ }
113
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
216
+
114
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
217
+ /* If SCR_EL3.GPF is unset, GPF may still be routed to EL2. */
115
+
218
+ if (fi->gpcf == GPCF_Fail && target_el < 2) {
116
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
219
+ if (arm_hcr_el2_eff(env) & HCR_GPF) {
117
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
220
+ target_el = 2;
118
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
221
+ }
119
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
222
+ }
120
index XXXXXXX..XXXXXXX 100644
223
+
121
--- a/target/arm/mve_helper.c
224
if (fi->stage2) {
122
+++ b/target/arm/mve_helper.c
225
target_el = 2;
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
226
env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
227
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
228
env->cp15.hpfar_el2 |= HPFAR_NS;
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
229
}
127
+#define DO_2SHIFT_S(OP, FN) \
230
}
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
231
- same_el = (arm_current_el(env) == target_el);
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
232
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
233
+ same_el = current_el == target_el;
131
234
fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
132
#define DO_2SHIFT_SAT_U(OP, FN) \
235
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
236
if (access_type == MMU_INST_FETCH) {
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
237
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
238
exc = EXCP_DATA_ABORT;
136
239
}
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
240
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
241
+ do_raise:
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
242
env->exception.vaddress = addr;
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
243
env->exception.fsr = fsr;
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
244
raise_exception(env, exc, syn, target_el);
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-mve.c
147
+++ b/target/arm/translate-mve.c
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
152
+/* These right shifts use a left-shift helper with negated shift count */
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/translate-neon.c
160
+++ b/target/arm/translate-neon.c
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
162
return x + 1;
163
}
164
165
-static inline int rsub_64(DisasContext *s, int x)
166
-{
167
- return 64 - x;
168
-}
169
-
170
-static inline int rsub_32(DisasContext *s, int x)
171
-{
172
- return 32 - x;
173
-}
174
-static inline int rsub_16(DisasContext *s, int x)
175
-{
176
- return 16 - x;
177
-}
178
-static inline int rsub_8(DisasContext *s, int x)
179
-{
180
- return 8 - x;
181
-}
182
-
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
184
{
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
186
--
245
--
187
2.20.1
246
2.34.1
188
189
diff view generated by jsdifflib
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
VORR and VBIC). These have essentially the same encoding
3
as their Neon equivalents, and we implement the decode
4
in the same way.
5
2
3
Place the check at the end of get_phys_addr_with_struct,
4
so that we check all physical results.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-20-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
9
---
10
---
10
target/arm/helper-mve.h | 4 +++
11
target/arm/ptw.c | 249 +++++++++++++++++++++++++++++++++++++++++++----
11
target/arm/mve.decode | 17 +++++++++++++
12
1 file changed, 232 insertions(+), 17 deletions(-)
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
14
4 files changed, 95 insertions(+)
15
13
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
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/target/arm/helper-mve.h
16
--- a/target/arm/ptw.c
19
+++ b/target/arm/helper-mve.h
17
+++ b/target/arm/ptw.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
18
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
19
void *out_host;
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
20
} S1Translate;
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
24
+
22
-static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
23
- target_ulong address,
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
24
- MMUAccessType access_type,
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
25
- GetPhysAddrResult *result,
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
26
- ARMMMUFaultInfo *fi);
29
index XXXXXXX..XXXXXXX 100644
27
+static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
30
--- a/target/arm/mve.decode
28
+ target_ulong address,
31
+++ b/target/arm/mve.decode
29
+ MMUAccessType access_type,
32
@@ -XXX,XX +XXX,XX @@
30
+ GetPhysAddrResult *result,
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
31
+ ARMMMUFaultInfo *fi);
34
%size_28 28:1 !function=plus_1
32
+
35
33
+static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
36
+# 1imm format immediate
34
+ target_ulong address,
37
+%imm_28_16_0 28:1 16:3 0:4
35
+ MMUAccessType access_type,
38
+
36
+ GetPhysAddrResult *result,
39
&vldr_vstr rn qd imm p a w size l u
37
+ ARMMMUFaultInfo *fi);
40
&1op qd qm size
38
41
&2op qd qm qn size
39
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
42
&2scalar qd qn rm size
40
static const uint8_t pamax_map[] = {
43
+&1imm qd imm cmode op
41
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
44
42
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
43
}
46
# Note that both Rn and Qd are 3 bits only (no D bit)
44
47
@@ -XXX,XX +XXX,XX @@
45
+static bool granule_protection_check(CPUARMState *env, uint64_t paddress,
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
46
+ ARMSecuritySpace pspace,
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
47
+ ARMMMUFaultInfo *fi)
50
size=%size_28
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
52
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
54
# the case for shifts. In the Arm ARM these insns are documented
55
@@ -XXX,XX +XXX,XX @@ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rd
56
# Predicate operations
57
%mask_22_13 22:1 13:3
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
59
+
60
+# Logical immediate operations (1 reg and modified-immediate)
61
+
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
63
+# not in a way we can conveniently represent in decodetree without
64
+# a lot of repetition:
65
+# VORR: op=0, (cmode & 1) && cmode < 12
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
67
+# VMOV: everything else
68
+# So we have a single decode line and check the cmode/op in the
69
+# trans function.
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/mve_helper.c
74
+++ b/target/arm/mve_helper.c
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
78
79
+/*
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
81
+ * All these insns work at 64-bit widths.
82
+ */
83
+#define DO_1OP_IMM(OP, FN) \
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
85
+ { \
86
+ uint64_t *da = vda; \
87
+ uint16_t mask = mve_element_mask(env); \
88
+ unsigned e; \
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
91
+ } \
92
+ mve_advance_vpt(env); \
93
+ }
94
+
95
+#define DO_MOVI(N, I) (I)
96
+#define DO_ANDI(N, I) ((N) & (I))
97
+#define DO_ORRI(N, I) ((N) | (I))
98
+
99
+DO_1OP_IMM(vmovi, DO_MOVI)
100
+DO_1OP_IMM(vandi, DO_ANDI)
101
+DO_1OP_IMM(vorri, DO_ORRI)
102
+
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
105
void *vd, void *vn, void *vm) \
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-mve.c
109
+++ b/target/arm/translate-mve.c
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
115
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
117
static inline long mve_qreg_offset(unsigned reg)
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
119
mve_update_eci(s);
120
return true;
121
}
122
+
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
124
+{
48
+{
125
+ TCGv_ptr qd;
49
+ MemTxAttrs attrs = {
126
+ uint64_t imm;
50
+ .secure = true,
127
+
51
+ .space = ARMSS_Root,
128
+ if (!dc_isar_feature(aa32_mve, s) ||
52
+ };
129
+ !mve_check_qreg_bank(s, a->qd) ||
53
+ ARMCPU *cpu = env_archcpu(env);
130
+ !fn) {
54
+ uint64_t gpccr = env->cp15.gpccr_el3;
131
+ return false;
55
+ unsigned pps, pgs, l0gptsz, level = 0;
132
+ }
56
+ uint64_t tableaddr, pps_mask, align, entry, index;
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
57
+ AddressSpace *as;
58
+ MemTxResult result;
59
+ int gpi;
60
+
61
+ if (!FIELD_EX64(gpccr, GPCCR, GPC)) {
134
+ return true;
62
+ return true;
135
+ }
63
+ }
136
+
64
+
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
65
+ /*
138
+
66
+ * GPC Priority 1 (R_GMGRR):
139
+ qd = mve_qreg_ptr(a->qd);
67
+ * R_JWCSM: If the configuration of GPCCR_EL3 is invalid,
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
68
+ * the access fails as GPT walk fault at level 0.
141
+ tcg_temp_free_ptr(qd);
69
+ */
142
+ mve_update_eci(s);
70
+
143
+ return true;
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;
144
+}
234
+}
145
+
235
+
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
236
static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
237
{
238
/*
239
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
240
};
241
GetPhysAddrResult s2 = { };
242
243
- if (get_phys_addr_with_struct(env, &s2ptw, addr,
244
- MMU_DATA_LOAD, &s2, fi)) {
245
+ if (get_phys_addr_gpc(env, &s2ptw, addr, MMU_DATA_LOAD, &s2, fi)) {
246
goto fail;
247
}
248
+
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,
308
}
309
}
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)
147
+{
316
+{
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
317
+ if (get_phys_addr_nogpc(env, ptw, address, access_type, result, fi)) {
149
+ MVEGenOneOpImmFn *fn;
318
+ return true;
150
+
319
+ }
151
+ if ((a->cmode & 1) && a->cmode < 12) {
320
+ if (!granule_protection_check(env, result->f.phys_addr,
152
+ if (a->op) {
321
+ result->f.attrs.space, fi)) {
153
+ /*
322
+ fi->type = ARMFault_GPCFOnOutput;
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
323
+ return true;
155
+ * so the VBIC becomes a logical AND operation.
324
+ }
156
+ */
325
+ return false;
157
+ fn = gen_helper_mve_vandi;
158
+ } else {
159
+ fn = gen_helper_mve_vorri;
160
+ }
161
+ } else {
162
+ /* There is one unallocated cmode/op combination in this space */
163
+ if (a->cmode == 15 && a->op == 1) {
164
+ return false;
165
+ }
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
167
+ fn = gen_helper_mve_vmovi;
168
+ }
169
+ return do_1imm(s, a, fn);
170
+}
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) {
171
--
360
--
172
2.20.1
361
2.34.1
173
174
diff view generated by jsdifflib
1
From: Nolan Leake <nolan@sigbus.net>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is just enough to make reboot and poweroff work. Works for
3
Add an x-rme cpu property to enable FEAT_RME.
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
4
Add an x-l0gptsz property to set GPCCR_EL3.L0GPTSZ,
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
5
for testing various possible configurations.
6
do what linux does for reset.
7
6
8
The watchdog timer functionality is not yet implemented.
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.
9
14
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
16
Message-id: 20230620124418.805717-21-richard.henderson@linaro.org
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
15
[PMM: tweaked commit title; fixed region size to 0x200;
16
moved header file to include/]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
---
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
20
target/arm/tcg/cpu64.c | 53 ++++++++++++++++++++++++++++++++++++++++++
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
21
1 file changed, 53 insertions(+)
21
hw/arm/bcm2835_peripherals.c | 13 ++-
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
23
hw/misc/meson.build | 1 +
24
5 files changed, 204 insertions(+), 2 deletions(-)
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
26
create mode 100644 hw/misc/bcm2835_powermgt.c
27
22
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
23
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
29
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/bcm2835_peripherals.h
25
--- a/target/arm/tcg/cpu64.c
31
+++ b/include/hw/arm/bcm2835_peripherals.h
26
+++ b/target/arm/tcg/cpu64.c
32
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
33
#include "hw/misc/bcm2835_mphi.h"
28
cpu->sve_max_vq = max_vq;
34
#include "hw/misc/bcm2835_thermal.h"
29
}
35
#include "hw/misc/bcm2835_cprman.h"
30
36
+#include "hw/misc/bcm2835_powermgt.h"
31
+static bool cpu_arm_get_rme(Object *obj, Error **errp)
37
#include "hw/sd/sdhci.h"
32
+{
38
#include "hw/sd/bcm2835_sdhost.h"
33
+ ARMCPU *cpu = ARM_CPU(obj);
39
#include "hw/gpio/bcm2835_gpio.h"
34
+ return cpu_isar_feature(aa64_rme, cpu);
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
35
+}
41
BCM2835MphiState mphi;
42
UnimplementedDeviceState txp;
43
UnimplementedDeviceState armtmr;
44
- UnimplementedDeviceState powermgt;
45
+ BCM2835PowerMgtState powermgt;
46
BCM2835CprmanState cprman;
47
PL011State uart0;
48
BCM2835AuxState aux;
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
50
new file mode 100644
51
index XXXXXXX..XXXXXXX
52
--- /dev/null
53
+++ b/include/hw/misc/bcm2835_powermgt.h
54
@@ -XXX,XX +XXX,XX @@
55
+/*
56
+ * BCM2835 Power Management emulation
57
+ *
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
60
+ *
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
62
+ * See the COPYING file in the top-level directory.
63
+ */
64
+
36
+
65
+#ifndef BCM2835_POWERMGT_H
37
+static void cpu_arm_set_rme(Object *obj, bool value, Error **errp)
66
+#define BCM2835_POWERMGT_H
38
+{
39
+ ARMCPU *cpu = ARM_CPU(obj);
40
+ uint64_t t;
67
+
41
+
68
+#include "hw/sysbus.h"
42
+ t = cpu->isar.id_aa64pfr0;
69
+#include "qom/object.h"
43
+ t = FIELD_DP64(t, ID_AA64PFR0, RME, value);
44
+ cpu->isar.id_aa64pfr0 = t;
45
+}
70
+
46
+
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
47
+static void cpu_max_set_l0gptsz(Object *obj, Visitor *v, const char *name,
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
48
+ void *opaque, Error **errp)
49
+{
50
+ ARMCPU *cpu = ARM_CPU(obj);
51
+ uint32_t value;
73
+
52
+
74
+struct BCM2835PowerMgtState {
53
+ if (!visit_type_uint32(v, name, &value, errp)) {
75
+ SysBusDevice busdev;
76
+ MemoryRegion iomem;
77
+
78
+ uint32_t rstc;
79
+ uint32_t rsts;
80
+ uint32_t wdog;
81
+};
82
+
83
+#endif
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/bcm2835_peripherals.c
87
+++ b/hw/arm/bcm2835_peripherals.c
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
89
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
91
OBJECT(&s->gpu_bus_mr));
92
+
93
+ /* Power Management */
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
95
+ TYPE_BCM2835_POWERMGT);
96
}
97
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
101
INTERRUPT_USB));
102
103
+ /* Power Management */
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
105
+ return;
54
+ return;
106
+ }
55
+ }
107
+
56
+
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
57
+ /* Encode the value for the GPCCR_EL3 field. */
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
58
+ switch (value) {
110
+
59
+ case 30:
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
60
+ case 34:
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
61
+ case 36:
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
62
+ case 39:
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
63
+ cpu->reset_l0gptsz = value - 30;
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
118
new file mode 100644
119
index XXXXXXX..XXXXXXX
120
--- /dev/null
121
+++ b/hw/misc/bcm2835_powermgt.c
122
@@ -XXX,XX +XXX,XX @@
123
+/*
124
+ * BCM2835 Power Management emulation
125
+ *
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
128
+ *
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
130
+ * See the COPYING file in the top-level directory.
131
+ */
132
+
133
+#include "qemu/osdep.h"
134
+#include "qemu/log.h"
135
+#include "qemu/module.h"
136
+#include "hw/misc/bcm2835_powermgt.h"
137
+#include "migration/vmstate.h"
138
+#include "sysemu/runstate.h"
139
+
140
+#define PASSWORD 0x5a000000
141
+#define PASSWORD_MASK 0xff000000
142
+
143
+#define R_RSTC 0x1c
144
+#define V_RSTC_RESET 0x20
145
+#define R_RSTS 0x20
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
147
+#define R_WDOG 0x24
148
+
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
150
+ unsigned size)
151
+{
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
153
+ uint32_t res = 0;
154
+
155
+ switch (offset) {
156
+ case R_RSTC:
157
+ res = s->rstc;
158
+ break;
64
+ break;
159
+ case R_RSTS:
160
+ res = s->rsts;
161
+ break;
162
+ case R_WDOG:
163
+ res = s->wdog;
164
+ break;
165
+
166
+ default:
65
+ default:
167
+ qemu_log_mask(LOG_UNIMP,
66
+ error_setg(errp, "invalid value for l0gptsz");
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
67
+ error_append_hint(errp, "valid values are 30, 34, 36, 39\n");
169
+ "\n", offset);
170
+ res = 0;
171
+ break;
172
+ }
173
+
174
+ return res;
175
+}
176
+
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
178
+ uint64_t value, unsigned size)
179
+{
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
181
+
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
183
+ qemu_log_mask(LOG_GUEST_ERROR,
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
186
+ value, offset);
187
+ return;
188
+ }
189
+
190
+ value = value & ~PASSWORD_MASK;
191
+
192
+ switch (offset) {
193
+ case R_RSTC:
194
+ s->rstc = value;
195
+ if (value & V_RSTC_RESET) {
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
198
+ } else {
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
200
+ }
201
+ }
202
+ break;
203
+ case R_RSTS:
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "bcm2835_powermgt_write: RSTS\n");
206
+ s->rsts = value;
207
+ break;
208
+ case R_WDOG:
209
+ qemu_log_mask(LOG_UNIMP,
210
+ "bcm2835_powermgt_write: WDOG\n");
211
+ s->wdog = value;
212
+ break;
213
+
214
+ default:
215
+ qemu_log_mask(LOG_UNIMP,
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
217
+ "\n", offset);
218
+ break;
68
+ break;
219
+ }
69
+ }
220
+}
70
+}
221
+
71
+
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
72
+static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
223
+ .read = bcm2835_powermgt_read,
73
+ void *opaque, Error **errp)
224
+ .write = bcm2835_powermgt_write,
74
+{
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
75
+ ARMCPU *cpu = ARM_CPU(obj);
226
+ .impl.min_access_size = 4,
76
+ uint32_t value = cpu->reset_l0gptsz + 30;
227
+ .impl.max_access_size = 4,
228
+};
229
+
77
+
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
78
+ visit_type_uint32(v, name, &value, errp);
231
+ .name = TYPE_BCM2835_POWERMGT,
232
+ .version_id = 1,
233
+ .minimum_version_id = 1,
234
+ .fields = (VMStateField[]) {
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
238
+ VMSTATE_END_OF_LIST()
239
+ }
240
+};
241
+
242
+static void bcm2835_powermgt_init(Object *obj)
243
+{
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
245
+
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
247
+ TYPE_BCM2835_POWERMGT, 0x200);
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
249
+}
79
+}
250
+
80
+
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
81
static Property arm_cpu_lpa2_property =
252
+{
82
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
83
254
+
84
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
255
+ /* https://elinux.org/BCM2835_registers#PM */
85
aarch64_add_sme_properties(obj);
256
+ s->rstc = 0x00000102;
86
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
257
+ s->rsts = 0x00001000;
87
cpu_max_set_sve_max_vq, NULL, NULL);
258
+ s->wdog = 0x00000000;
88
+ object_property_add_bool(obj, "x-rme", cpu_arm_get_rme, cpu_arm_set_rme);
259
+}
89
+ object_property_add(obj, "x-l0gptsz", "uint32", cpu_max_get_l0gptsz,
260
+
90
+ cpu_max_set_l0gptsz, NULL, NULL);
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
91
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
262
+{
92
}
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
93
264
+
265
+ dc->reset = bcm2835_powermgt_reset;
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
267
+}
268
+
269
+static TypeInfo bcm2835_powermgt_info = {
270
+ .name = TYPE_BCM2835_POWERMGT,
271
+ .parent = TYPE_SYS_BUS_DEVICE,
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
273
+ .class_init = bcm2835_powermgt_class_init,
274
+ .instance_init = bcm2835_powermgt_init,
275
+};
276
+
277
+static void bcm2835_powermgt_register_types(void)
278
+{
279
+ type_register_static(&bcm2835_powermgt_info);
280
+}
281
+
282
+type_init(bcm2835_powermgt_register_types)
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
284
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/misc/meson.build
286
+++ b/hw/misc/meson.build
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
288
'bcm2835_rng.c',
289
'bcm2835_thermal.c',
290
'bcm2835_cprman.c',
291
+ 'bcm2835_powermgt.c',
292
))
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
295
--
94
--
296
2.20.1
95
2.34.1
297
298
diff view generated by jsdifflib
1
From: Patrick Venture <venture@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
entry.
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
5
Message-id: 20230622143046.1578160-1-richard.henderson@linaro.org
6
Signed-off-by: Patrick Venture <venture@google.com>
6
[PMM: fixed typo; note experimental status in emulation.rst too]
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20210615192848.1065297-2-venture@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
docs/system/arm/aspeed.rst | 1 +
9
docs/system/arm/cpu-features.rst | 23 +++++++++++++++++++++++
12
1 file changed, 1 insertion(+)
10
docs/system/arm/emulation.rst | 1 +
11
2 files changed, 24 insertions(+)
13
12
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
13
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
15
--- a/docs/system/arm/cpu-features.rst
17
+++ b/docs/system/arm/aspeed.rst
16
+++ b/docs/system/arm/cpu-features.rst
18
@@ -XXX,XX +XXX,XX @@ etc.
17
@@ -XXX,XX +XXX,XX @@ As with ``sve-default-vector-length``, if the default length is larger
19
AST2400 SoC based machines :
18
than the maximum vector length enabled, the actual vector length will
20
19
be reduced. If this property is set to ``-1`` then the default vector
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
20
length is set to the maximum possible length.
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
21
+
23
22
+RME CPU Properties
24
AST2500 SoC based machines :
23
+==================
25
24
+
25
+The status of RME support with QEMU is experimental. At this time we
26
+only support RME within the CPU proper, not within the SMMU or GIC.
27
+The feature is enabled by the CPU property ``x-rme``, with the ``x-``
28
+prefix present as a reminder of the experimental status, and defaults off.
29
+
30
+The method for enabling RME will change in some future QEMU release
31
+without notice or backward compatibility.
32
+
33
+RME Level 0 GPT Size Property
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)
26
--
56
--
27
2.20.1
57
2.34.1
28
58
29
59
diff view generated by jsdifflib
1
Implement the MVE VSRI and VSLI insns, which perform a
1
We use __builtin_subcll() to do a 64-bit subtract with borrow-in and
2
shift-and-insert operation.
2
borrow-out when the host compiler supports it. Unfortunately some
3
versions of Apple Clang have a bug in their implementation of this
4
intrinsic which means it returns the wrong value. The effect is that
5
a QEMU built with the affected compiler will hang when emulating x86
6
or m68k float80 division.
3
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
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
36
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
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
7
---
40
---
8
target/arm/helper-mve.h | 8 ++++++++
41
include/qemu/compiler.h | 13 +++++++++++++
9
target/arm/mve.decode | 9 ++++++++
42
include/qemu/host-utils.h | 2 +-
10
target/arm/mve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
43
2 files changed, 14 insertions(+), 1 deletion(-)
11
target/arm/translate-mve.c | 3 +++
12
4 files changed, 62 insertions(+)
13
44
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
45
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
15
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-mve.h
47
--- a/include/qemu/compiler.h
17
+++ b/target/arm/helper-mve.h
48
+++ b/include/qemu/compiler.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
#define QEMU_DISABLE_CFI
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
#endif
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
53
+/*
54
+ * Apple clang version 14 has a bug in its __builtin_subcll(); define
55
+ * BUILTIN_SUBCLL_BROKEN for the offending versions so we can avoid it.
56
+ * When a version of Apple clang which has this bug fixed is released
57
+ * we can add an upper bound to this check.
58
+ * See https://gitlab.com/qemu-project/qemu/-/issues/1631
59
+ * and https://gitlab.com/qemu-project/qemu/-/issues/1659 for details.
60
+ * The bug never made it into any upstream LLVM releases, only Apple ones.
61
+ */
62
+#if defined(__apple_build_version__) && __clang_major__ >= 14
63
+#define BUILTIN_SUBCLL_BROKEN
64
+#endif
22
+
65
+
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
66
#endif /* COMPILER_H */
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
67
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
31
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/mve.decode
69
--- a/include/qemu/host-utils.h
33
+++ b/target/arm/mve.decode
70
+++ b/include/qemu/host-utils.h
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
71
@@ -XXX,XX +XXX,XX @@ static inline uint64_t uadd64_carry(uint64_t x, uint64_t y, bool *pcarry)
35
72
*/
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
73
static inline uint64_t usub64_borrow(uint64_t x, uint64_t y, bool *pborrow)
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
74
{
38
+
75
-#if __has_builtin(__builtin_subcll)
39
+# Shift-and-insert
76
+#if __has_builtin(__builtin_subcll) && !defined(BUILTIN_SUBCLL_BROKEN)
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
77
unsigned long long b = *pborrow;
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
78
x = __builtin_subcll(x, y, b, &b);
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
79
*pborrow = b & 1;
43
+
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/mve_helper.c
50
+++ b/target/arm/mve_helper.c
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
54
55
+/* Shift-and-insert; we always work with 64 bits at a time */
56
+#define DO_2SHIFT_INSERT(OP, ESIZE, SHIFTFN, MASKFN) \
57
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
58
+ void *vm, uint32_t shift) \
59
+ { \
60
+ uint64_t *d = vd, *m = vm; \
61
+ uint16_t mask; \
62
+ uint64_t shiftmask; \
63
+ unsigned e; \
64
+ if (shift == 0 || shift == ESIZE * 8) { \
65
+ /* \
66
+ * Only VSLI can shift by 0; only VSRI can shift by <dt>. \
67
+ * The generic logic would give the right answer for 0 but \
68
+ * fails for <dt>. \
69
+ */ \
70
+ goto done; \
71
+ } \
72
+ assert(shift < ESIZE * 8); \
73
+ mask = mve_element_mask(env); \
74
+ /* ESIZE / 2 gives the MO_* value if ESIZE is in [1,2,4] */ \
75
+ shiftmask = dup_const(ESIZE / 2, MASKFN(ESIZE * 8, shift)); \
76
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
77
+ uint64_t r = (SHIFTFN(m[H8(e)], shift) & shiftmask) | \
78
+ (d[H8(e)] & ~shiftmask); \
79
+ mergemask(&d[H8(e)], r, mask); \
80
+ } \
81
+done: \
82
+ mve_advance_vpt(env); \
83
+ }
84
+
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
88
+#define SHR_MASK(EBITS, SHIFT) MAKE_64BIT_MASK(0, (EBITS) - (SHIFT))
89
+
90
+DO_2SHIFT_INSERT(vsrib, 1, DO_SHR, SHR_MASK)
91
+DO_2SHIFT_INSERT(vsrih, 2, DO_SHR, SHR_MASK)
92
+DO_2SHIFT_INSERT(vsriw, 4, DO_SHR, SHR_MASK)
93
+DO_2SHIFT_INSERT(vslib, 1, DO_SHL, SHL_MASK)
94
+DO_2SHIFT_INSERT(vslih, 2, DO_SHL, SHL_MASK)
95
+DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
96
+
97
/*
98
* Long shifts taking half-sized inputs from top or bottom of the input
99
* vector and producing a double-width result. ESIZE, TYPE are for
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_U, vshli_u, true)
105
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
106
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
107
108
+DO_2SHIFT(VSRI, vsri, false)
109
+DO_2SHIFT(VSLI, vsli, false)
110
+
111
#define DO_VSHLL(INSN, FN) \
112
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
113
{ \
114
--
80
--
115
2.20.1
81
2.34.1
116
82
117
83
diff view generated by jsdifflib
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
3
One cannot test for feature aa32_simd_r32 without first
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
4
testing if AArch32 mode is supported at all. This leads to
5
assert due to fpst->default_nan_mode being set.
6
5
7
To avoid this, we check to see what NaN mode we're running in before we call
6
qemu-system-aarch64: ARM CPUs must have both VFP-D32 and Neon or neither
8
floatxx_silence_nan().
9
7
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
8
for Apple M1 cpus.
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
10
We already have a check for ARMv8-A never setting vfp-d32 true,
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
so restructure the code so that AArch64 avoids the test entirely.
12
13
Reported-by: Mads Ynddal <mads@ynddal.dk>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Tested-by: Philippe Mathieu-Daudé <philmd@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
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
22
---
16
target/arm/helper-a64.c | 12 +++++++++---
23
target/arm/cpu.c | 28 +++++++++++++++-------------
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
24
1 file changed, 15 insertions(+), 13 deletions(-)
18
2 files changed, 27 insertions(+), 9 deletions(-)
19
25
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
21
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper-a64.c
28
--- a/target/arm/cpu.c
23
+++ b/target/arm/helper-a64.c
29
+++ b/target/arm/cpu.c
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
30
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
25
float16 nan = a;
31
* KVM does not currently allow us to lie to the guest about its
26
if (float16_is_signaling_nan(a, fpst)) {
32
* ID/feature registers, so the guest always sees what the host has.
27
float_raise(float_flag_invalid, fpst);
33
*/
28
- nan = float16_silence_nan(a, fpst);
34
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
29
+ if (!fpst->default_nan_mode) {
35
- ? cpu_isar_feature(aa64_fp_simd, cpu)
30
+ nan = float16_silence_nan(a, fpst);
36
- : cpu_isar_feature(aa32_vfp, cpu)) {
37
- cpu->has_vfp = true;
38
- if (!kvm_enabled()) {
39
- qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
40
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
41
+ if (cpu_isar_feature(aa64_fp_simd, cpu)) {
42
+ cpu->has_vfp = true;
43
+ cpu->has_vfp_d32 = true;
44
+ if (tcg_enabled() || qtest_enabled()) {
45
+ qdev_property_add_static(DEVICE(obj),
46
+ &arm_cpu_has_vfp_property);
31
+ }
47
+ }
32
}
48
}
33
if (fpst->default_nan_mode) {
49
- }
34
nan = float16_default_nan(fpst);
50
-
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
51
- if (cpu->has_vfp && cpu_isar_feature(aa32_simd_r32, cpu)) {
36
float32 nan = a;
52
- cpu->has_vfp_d32 = true;
37
if (float32_is_signaling_nan(a, fpst)) {
53
- if (!kvm_enabled()) {
38
float_raise(float_flag_invalid, fpst);
54
+ } else if (cpu_isar_feature(aa32_vfp, cpu)) {
39
- nan = float32_silence_nan(a, fpst);
55
+ cpu->has_vfp = true;
40
+ if (!fpst->default_nan_mode) {
56
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
41
+ nan = float32_silence_nan(a, fpst);
57
+ cpu->has_vfp_d32 = true;
42
+ }
58
/*
43
}
59
* The permitted values of the SIMDReg bits [3:0] on
44
if (fpst->default_nan_mode) {
60
* Armv8-A are either 0b0000 and 0b0010. On such CPUs,
45
nan = float32_default_nan(fpst);
61
* make sure that has_vfp_d32 can not be set to false.
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
62
*/
47
float64 nan = a;
63
- if (!(arm_feature(&cpu->env, ARM_FEATURE_V8) &&
48
if (float64_is_signaling_nan(a, fpst)) {
64
- !arm_feature(&cpu->env, ARM_FEATURE_M))) {
49
float_raise(float_flag_invalid, fpst);
65
+ if ((tcg_enabled() || qtest_enabled())
50
- nan = float64_silence_nan(a, fpst);
66
+ && !(arm_feature(&cpu->env, ARM_FEATURE_V8)
51
+ if (!fpst->default_nan_mode) {
67
+ && !arm_feature(&cpu->env, ARM_FEATURE_M))) {
52
+ nan = float64_silence_nan(a, fpst);
68
qdev_property_add_static(DEVICE(obj),
53
+ }
69
&arm_cpu_has_vfp_d32_property);
54
}
70
}
55
if (fpst->default_nan_mode) {
56
nan = float64_default_nan(fpst);
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/vfp_helper.c
60
+++ b/target/arm/vfp_helper.c
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
62
float16 nan = f16;
63
if (float16_is_signaling_nan(f16, fpst)) {
64
float_raise(float_flag_invalid, fpst);
65
- nan = float16_silence_nan(f16, fpst);
66
+ if (!fpst->default_nan_mode) {
67
+ nan = float16_silence_nan(f16, fpst);
68
+ }
69
}
70
if (fpst->default_nan_mode) {
71
nan = float16_default_nan(fpst);
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
73
float32 nan = f32;
74
if (float32_is_signaling_nan(f32, fpst)) {
75
float_raise(float_flag_invalid, fpst);
76
- nan = float32_silence_nan(f32, fpst);
77
+ if (!fpst->default_nan_mode) {
78
+ nan = float32_silence_nan(f32, fpst);
79
+ }
80
}
81
if (fpst->default_nan_mode) {
82
nan = float32_default_nan(fpst);
83
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
84
float64 nan = f64;
85
if (float64_is_signaling_nan(f64, fpst)) {
86
float_raise(float_flag_invalid, fpst);
87
- nan = float64_silence_nan(f64, fpst);
88
+ if (!fpst->default_nan_mode) {
89
+ nan = float64_silence_nan(f64, fpst);
90
+ }
91
}
92
if (fpst->default_nan_mode) {
93
nan = float64_default_nan(fpst);
94
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
95
float16 nan = f16;
96
if (float16_is_signaling_nan(f16, s)) {
97
float_raise(float_flag_invalid, s);
98
- nan = float16_silence_nan(f16, s);
99
+ if (!s->default_nan_mode) {
100
+ nan = float16_silence_nan(f16, fpstp);
101
+ }
102
}
103
if (s->default_nan_mode) {
104
nan = float16_default_nan(s);
105
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
106
float32 nan = f32;
107
if (float32_is_signaling_nan(f32, s)) {
108
float_raise(float_flag_invalid, s);
109
- nan = float32_silence_nan(f32, s);
110
+ if (!s->default_nan_mode) {
111
+ nan = float32_silence_nan(f32, fpstp);
112
+ }
113
}
114
if (s->default_nan_mode) {
115
nan = float32_default_nan(s);
116
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
117
float64 nan = f64;
118
if (float64_is_signaling_nan(f64, s)) {
119
float_raise(float_flag_invalid, s);
120
- nan = float64_silence_nan(f64, s);
121
+ if (!s->default_nan_mode) {
122
+ nan = float64_silence_nan(f64, fpstp);
123
+ }
124
}
125
if (s->default_nan_mode) {
126
nan = float64_default_nan(s);
127
--
71
--
128
2.20.1
72
2.34.1
129
73
130
74
diff view generated by jsdifflib
1
The MVE extension to v8.1M includes some new shift instructions which
1
From: Shashi Mallela <shashi.mallela@linaro.org>
2
sit entirely within the non-coprocessor part of the encoding space
3
and which operate only on general-purpose registers. They take up
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
with Rm == 13 or 15.
6
2
7
Implement the long shifts by immediate, which perform shifts on a
3
Create ITS as part of SBSA platform GIC initialization.
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
an immediate shift count between 1 and 32.
10
4
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
5
GIC ITS information is in DeviceTree so TF-A can pass it to EDK2.
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
is too difficult, because the functions that generate the code are
15
shared between a dozen different kinds of arithmetic or logical
16
instruction for all A32, T16 and T32 encodings, and for some insns
17
and some encodings Rm==13,15 are valid.)
18
6
19
We make the helper functions we need for UQSHLL and SQSHLL take
7
Bumping platform version to 0.2 as this is important hardware change.
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
23
8
9
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
10
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
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>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
27
---
16
---
28
target/arm/helper-mve.h | 3 ++
17
docs/system/arm/sbsa.rst | 14 ++++++++++++++
29
target/arm/translate.h | 1 +
18
hw/arm/sbsa-ref.c | 33 ++++++++++++++++++++++++++++++---
30
target/arm/t32.decode | 28 +++++++++++++
19
2 files changed, 44 insertions(+), 3 deletions(-)
31
target/arm/mve_helper.c | 10 +++++
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
33
5 files changed, 132 insertions(+)
34
20
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
21
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
36
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper-mve.h
23
--- a/docs/system/arm/sbsa.rst
38
+++ b/target/arm/helper-mve.h
24
+++ b/docs/system/arm/sbsa.rst
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
@@ -XXX,XX +XXX,XX @@ to be a complete compliant DT. It currently reports:
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
- platform version
41
27
- GIC addresses
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
28
29
+Platform version
30
+''''''''''''''''
43
+
31
+
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
The platform version is only for informing platform firmware about
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
what kind of ``sbsa-ref`` board it is running on. It is neither
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
34
a QEMU versioned machine type nor a reflection of the level of the
35
@@ -XXX,XX +XXX,XX @@ SBSA/SystemReady SR support provided.
36
The ``machine-version-major`` value is updated when changes breaking
37
fw compatibility are introduced. The ``machine-version-minor`` value
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
47
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.h
52
--- a/hw/arm/sbsa-ref.c
49
+++ b/target/arm/translate.h
53
+++ b/hw/arm/sbsa-ref.c
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
54
@@ -XXX,XX +XXX,XX @@ enum {
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
55
SBSA_CPUPERIPHS,
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
56
SBSA_GIC_DIST,
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
57
SBSA_GIC_REDIST,
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
58
+ SBSA_GIC_ITS,
55
59
SBSA_SECURE_EC,
56
/**
60
SBSA_GWDT_WS0,
57
* arm_tbflags_from_tb:
61
SBSA_GWDT_REFRESH,
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
62
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
59
index XXXXXXX..XXXXXXX 100644
63
[SBSA_CPUPERIPHS] = { 0x40000000, 0x00040000 },
60
--- a/target/arm/t32.decode
64
[SBSA_GIC_DIST] = { 0x40060000, 0x00010000 },
61
+++ b/target/arm/t32.decode
65
[SBSA_GIC_REDIST] = { 0x40080000, 0x04000000 },
62
@@ -XXX,XX +XXX,XX @@
66
+ [SBSA_GIC_ITS] = { 0x44081000, 0x00020000 },
63
&mcr !extern cp opc1 crn crm opc2 rt
67
[SBSA_SECURE_EC] = { 0x50000000, 0x00001000 },
64
&mcrr !extern cp opc1 crm rt rt2
68
[SBSA_GWDT_REFRESH] = { 0x50010000, 0x00001000 },
65
69
[SBSA_GWDT_CONTROL] = { 0x50011000, 0x00001000 },
66
+&mve_shl_ri rdalo rdahi shim
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);
67
+
79
+
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
80
g_free(nodename);
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
70
+%rdahi_9 9:3 !function=times_2_plus_1
71
+%rdalo_17 17:3 !function=times_2
72
+
73
# Data-processing (register)
74
75
%imm5_12_6 12:3 6:2
76
@@ -XXX,XX +XXX,XX @@
77
@S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \
78
&s_rrr_shi shim=%imm5_12_6 s=1 rd=0
79
80
+@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
81
+ &mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
82
+
83
{
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
86
}
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
88
{
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
96
+ [
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
98
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
99
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
100
+
101
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
102
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
103
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
104
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
105
+ ]
106
+
107
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
108
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
109
}
110
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/mve_helper.c
113
+++ b/target/arm/mve_helper.c
114
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
115
mve_advance_vpt(env);
116
return rdm;
117
}
81
}
118
+
82
+
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
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)
120
+{
101
+{
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
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);
122
+}
111
+}
123
+
112
+
124
+uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
113
+static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
125
+{
114
{
126
+ return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
115
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
127
+}
116
SysBusDevice *gicbusdev;
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
117
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms)
129
index XXXXXXX..XXXXXXX 100644
118
qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
130
--- a/target/arm/translate.c
119
qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
131
+++ b/target/arm/translate.c
120
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
121
+ object_property_set_link(OBJECT(sms->gic), "sysmem",
133
return true;
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));
131
}
132
+ create_its(sms);
134
}
133
}
135
134
136
+/*
135
static void create_uart(const SBSAMachineState *sms, int uart,
137
+ * v8.1M MVE wide-shifts
136
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
138
+ */
137
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
138
create_secure_ram(sms, secure_sysmem);
140
+ WideShiftImmFn *fn)
139
141
+{
140
- create_gic(sms);
142
+ TCGv_i64 rda;
141
+ create_gic(sms, sysmem);
143
+ TCGv_i32 rdalo, rdahi;
142
144
+
143
create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
144
create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
147
+ return false;
148
+ }
149
+ if (a->rdahi == 15) {
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
151
+ return false;
152
+ }
153
+ if (!dc_isar_feature(aa32_mve, s) ||
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
155
+ a->rdahi == 13) {
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
157
+ unallocated_encoding(s);
158
+ return true;
159
+ }
160
+
161
+ if (a->shim == 0) {
162
+ a->shim = 32;
163
+ }
164
+
165
+ rda = tcg_temp_new_i64();
166
+ rdalo = load_reg(s, a->rdalo);
167
+ rdahi = load_reg(s, a->rdahi);
168
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
169
+
170
+ fn(rda, rda, a->shim);
171
+
172
+ tcg_gen_extrl_i64_i32(rdalo, rda);
173
+ tcg_gen_extrh_i64_i32(rdahi, rda);
174
+ store_reg(s, a->rdalo, rdalo);
175
+ store_reg(s, a->rdahi, rdahi);
176
+ tcg_temp_free_i64(rda);
177
+
178
+ return true;
179
+}
180
+
181
+static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
182
+{
183
+ return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
184
+}
185
+
186
+static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
187
+{
188
+ return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
189
+}
190
+
191
+static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
192
+{
193
+ return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
194
+}
195
+
196
+static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
197
+{
198
+ gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
199
+}
200
+
201
+static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
202
+{
203
+ return do_mve_shl_ri(s, a, gen_mve_sqshll);
204
+}
205
+
206
+static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
207
+{
208
+ gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
209
+}
210
+
211
+static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
212
+{
213
+ return do_mve_shl_ri(s, a, gen_mve_uqshll);
214
+}
215
+
216
+static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
217
+{
218
+ return do_mve_shl_ri(s, a, gen_srshr64_i64);
219
+}
220
+
221
+static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
222
+{
223
+ return do_mve_shl_ri(s, a, gen_urshr64_i64);
224
+}
225
+
226
/*
227
* Multiply and multiply accumulate
228
*/
229
--
145
--
230
2.20.1
146
2.34.1
231
232
diff view generated by jsdifflib
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
3
Brown bag time: store instead of load results in uninitialized temp.
4
function has to be used for machine shutdown. Otherwise we cause
5
a reset with a bogus "cause" value, when we intended a shutdown.
6
4
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
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>
9
Signed-off-by: Richard Henderson <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>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
10
[PMM: tweaked commit message]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
16
---
13
hw/gpio/gpio_pwr.c | 2 +-
17
target/arm/tcg/translate-sve.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
18
1 file changed, 1 insertion(+), 1 deletion(-)
15
19
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
20
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/gpio/gpio_pwr.c
22
--- a/target/arm/tcg/translate-sve.c
19
+++ b/hw/gpio/gpio_pwr.c
23
+++ b/target/arm/tcg/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
24
@@ -XXX,XX +XXX,XX @@ void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
25
/* Predicate register stores can be any multiple of 2. */
22
{
26
if (len_remain >= 8) {
23
if (level) {
27
t0 = tcg_temp_new_i64();
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
28
- tcg_gen_st_i64(t0, base, vofs + len_align);
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
29
+ tcg_gen_ld_i64(t0, base, vofs + len_align);
26
}
30
tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ | MO_ATOM_NONE);
27
}
31
len_remain -= 8;
28
32
len_align += 8;
29
--
33
--
30
2.20.1
34
2.34.1
31
35
32
36
diff view generated by jsdifflib
1
Use dup_const() instead of bitfield_replicate() in
1
The xkb official name for the Arabic keyboard layout is 'ara'.
2
disas_simd_mod_imm().
2
However xkb has for at least the past 15 years also permitted it to
3
be named via the legacy synonym 'ar'. In xkeyboard-config 2.39 this
4
synoynm was removed, which breaks compilation of QEMU:
3
5
4
(We can't replace the other use of bitfield_replicate() in this file,
6
FAILED: pc-bios/keymaps/ar
5
in logic_imm_decode_wmask(), because that location needs to handle 2
7
/home/fred/qemu-git/src/qemu/build-full/qemu-keymap -f pc-bios/keymaps/ar -l ar
6
and 4 bit elements, which dup_const() cannot.)
8
xkbcommon: ERROR: Couldn't find file "symbols/ar" in include paths
9
xkbcommon: ERROR: 1 include paths searched:
10
xkbcommon: ERROR:     /usr/share/X11/xkb
11
xkbcommon: ERROR: 3 include paths could not be added:
12
xkbcommon: ERROR:     /home/fred/.config/xkb
13
xkbcommon: ERROR:     /home/fred/.xkb
14
xkbcommon: ERROR:     /etc/xkb
15
xkbcommon: ERROR: Abandoning symbols file "(unnamed)"
16
xkbcommon: ERROR: Failed to compile xkb_symbols
17
xkbcommon: ERROR: Failed to compile keymap
7
18
19
The upstream xkeyboard-config change removing the compat
20
mapping is:
21
https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/commit/470ad2cd8fea84d7210377161d86b31999bb5ea6
22
23
Make QEMU always ask for the 'ara' xkb layout, which should work on
24
both older and newer xkeyboard-config. We leave the QEMU name for
25
this keyboard layout as 'ar'; it is not the only one where our name
26
for it deviates from the xkb standard name.
27
28
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210628135835.6690-6-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
11
---
35
---
12
target/arm/translate-a64.c | 2 +-
36
pc-bios/keymaps/meson.build | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
37
1 file changed, 1 insertion(+), 1 deletion(-)
14
38
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
39
diff --git a/pc-bios/keymaps/meson.build b/pc-bios/keymaps/meson.build
16
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
41
--- a/pc-bios/keymaps/meson.build
18
+++ b/target/arm/translate-a64.c
42
+++ b/pc-bios/keymaps/meson.build
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
43
@@ -XXX,XX +XXX,XX @@
20
/* FMOV (vector, immediate) - half-precision */
44
keymaps = {
21
imm = vfp_expand_imm(MO_16, abcdefgh);
45
- 'ar': '-l ar',
22
/* now duplicate across the lanes */
46
+ 'ar': '-l ara',
23
- imm = bitfield_replicate(imm, 16);
47
'bepo': '-l fr -v dvorak',
24
+ imm = dup_const(MO_16, imm);
48
'cz': '-l cz',
25
} else {
49
'da': '-l dk',
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
27
}
28
--
50
--
29
2.20.1
51
2.34.1
30
52
31
53
diff view generated by jsdifflib