1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
1
The following changes since commit 64ada298b98a51eb2512607f6e6180cb330c47b1:
2
2
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
3
Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220302' into staging (2022-03-02 12:38:46 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220302
8
8
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
9
for you to fetch changes up to 268c11984e67867c22f53beb3c7f8b98900d66b2:
10
10
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
11
ui/cocoa.m: Remove unnecessary NSAutoreleasePools (2022-03-02 19:27:37 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
target-arm queue:
14
target-arm queue:
15
* more MVE instructions
15
* mps3-an547: Add missing user ahb interfaces
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
16
* hw/arm/mps2-tz.c: Update AN547 documentation URL
17
* target/arm: Check NaN mode before silencing NaN
17
* hw/input/tsc210x: Don't abort on bad SPI word widths
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
18
* hw/i2c: flatten pca954x mux device
19
* hw/arm: Add basic power management to raspi.
19
* target/arm: Support PSCI 1.1 and SMCCC 1.0
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
20
* target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv()
21
* tests/qtest: add qtests for npcm7xx sdhci
22
* Implement FEAT_LVA
23
* Implement FEAT_LPA
24
* Implement FEAT_LPA2 (but do not enable it yet)
25
* Report KVM's actual PSCI version to guest in dtb
26
* ui/cocoa.m: Fix updateUIInfo threading issues
27
* ui/cocoa.m: Remove unnecessary NSAutoreleasePools
21
28
22
----------------------------------------------------------------
29
----------------------------------------------------------------
23
Joe Komlodi (1):
30
Akihiko Odaki (1):
24
target/arm: Check NaN mode before silencing NaN
31
target/arm: Support PSCI 1.1 and SMCCC 1.0
25
32
26
Maxim Uvarov (1):
33
Jimmy Brisson (1):
27
hw/gpio/gpio_pwr: use shutdown function for reboot
34
mps3-an547: Add missing user ahb interfaces
28
35
29
Nolan Leake (1):
36
Patrick Venture (1):
30
hw/arm: Add basic power management to raspi.
37
hw/i2c: flatten pca954x mux device
31
38
32
Patrick Venture (2):
39
Peter Maydell (5):
33
docs/system/arm: Add quanta-q7l1-bmc reference
40
hw/arm/mps2-tz.c: Update AN547 documentation URL
34
docs/system/arm: Add quanta-gbs-bmc reference
41
hw/input/tsc210x: Don't abort on bad SPI word widths
42
target/arm: Report KVM's actual PSCI version to guest in dtb
43
ui/cocoa.m: Fix updateUIInfo threading issues
44
ui/cocoa.m: Remove unnecessary NSAutoreleasePools
35
45
36
Peter Maydell (18):
46
Richard Henderson (16):
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
47
hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N>
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
48
target/arm: Set TCR_EL1.TSZ for user-only
39
target/arm: Make asimd_imm_const() public
49
target/arm: Fault on invalid TCR_ELx.TxSZ
40
target/arm: Use asimd_imm_const for A64 decode
50
target/arm: Move arm_pamax out of line
41
target/arm: Use dup_const() instead of bitfield_replicate()
51
target/arm: Pass outputsize down to check_s2_mmu_setup
42
target/arm: Implement MVE logical immediate insns
52
target/arm: Use MAKE_64BIT_MASK to compute indexmask
43
target/arm: Implement MVE vector shift left by immediate insns
53
target/arm: Honor TCR_ELx.{I}PS
44
target/arm: Implement MVE vector shift right by immediate insns
54
target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA
45
target/arm: Implement MVE VSHLL
55
target/arm: Implement FEAT_LVA
46
target/arm: Implement MVE VSRI, VSLI
56
target/arm: Implement FEAT_LPA
47
target/arm: Implement MVE VSHRN, VRSHRN
57
target/arm: Extend arm_fi_to_lfsc to level -1
48
target/arm: Implement MVE saturating narrowing shifts
58
target/arm: Introduce tlbi_aa64_get_range
49
target/arm: Implement MVE VSHLC
59
target/arm: Fix TLBIRange.base for 16k and 64k pages
50
target/arm: Implement MVE VADDLV
60
target/arm: Validate tlbi TG matches translation granule in use
51
target/arm: Implement MVE long shifts by immediate
61
target/arm: Advertise all page sizes for -cpu max
52
target/arm: Implement MVE long shifts by register
62
target/arm: Implement FEAT_LPA2
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
55
63
56
Philippe Mathieu-Daudé (1):
64
Shengtan Mao (1):
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
65
tests/qtest: add qtests for npcm7xx sdhci
58
66
59
docs/system/arm/aspeed.rst | 1 +
67
Wentao_Liang (1):
60
docs/system/arm/nuvoton.rst | 5 +-
68
target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv()
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
69
70
docs/system/arm/emulation.rst | 3 +
71
include/hw/registerfields.h | 48 +++++-
72
target/arm/cpu-param.h | 4 +-
73
target/arm/cpu.h | 27 ++++
74
target/arm/internals.h | 58 ++++---
75
target/arm/kvm-consts.h | 14 +-
76
hw/arm/boot.c | 11 +-
77
hw/arm/mps2-tz.c | 6 +-
78
hw/i2c/i2c_mux_pca954x.c | 77 ++-------
79
hw/input/tsc210x.c | 8 +-
80
target/arm/cpu.c | 8 +-
81
target/arm/cpu64.c | 7 +-
82
target/arm/helper.c | 332 ++++++++++++++++++++++++++++++---------
83
target/arm/hvf/hvf.c | 27 +++-
84
target/arm/kvm64.c | 14 +-
85
target/arm/psci.c | 35 ++++-
86
target/arm/translate-a64.c | 2 +-
87
tests/qtest/npcm7xx_sdhci-test.c | 215 +++++++++++++++++++++++++
88
tests/qtest/meson.build | 1 +
89
ui/cocoa.m | 31 ++--
90
20 files changed, 736 insertions(+), 192 deletions(-)
91
create mode 100644 tests/qtest/npcm7xx_sdhci-test.c
diff view generated by jsdifflib
1
Implement the MVE shifts by immediate, which perform shifts
1
From: Jimmy Brisson <jimmy.brisson@linaro.org>
2
on a single general-purpose register.
3
2
4
These patterns overlap with the long-shift-by-immediates,
3
With these interfaces missing, TFM would delegate peripherals 0, 1,
5
so we have to rearrange the grouping a little here.
4
2, 3 and 8, and qemu would ignore the delegation of interface 8, as
5
it thought interface 4 was eth & USB.
6
6
7
This patch corrects this behavior and allows TFM to delegate the
8
eth & USB peripheral to NS mode.
9
10
(The old QEMU behaviour was based on revision B of the AN547
11
appnote; revision C corrects this error in the documentation,
12
and this commit brings QEMU in to line with how the FPGA
13
image really behaves.)
14
15
Signed-off-by: Jimmy Brisson <jimmy.brisson@linaro.org>
16
Message-id: 20220210210227.3203883-1-jimmy.brisson@linaro.org
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
[PMM: added commit message note clarifying that the old behaviour
19
was a docs issue, not because there were two different versions
20
of the FPGA image]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
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
---
22
---
11
target/arm/helper-mve.h | 3 ++
23
hw/arm/mps2-tz.c | 4 ++++
12
target/arm/translate.h | 1 +
24
1 file changed, 4 insertions(+)
13
target/arm/t32.decode | 31 ++++++++++++++-----
14
target/arm/mve_helper.c | 10 ++++++
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
16
5 files changed, 104 insertions(+), 9 deletions(-)
17
25
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
26
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-mve.h
28
--- a/hw/arm/mps2-tz.c
21
+++ b/target/arm/helper-mve.h
29
+++ b/hw/arm/mps2-tz.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
30
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
31
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
26
+
34
+ { /* port 4 USER AHB interface 0 */ },
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
35
+ { /* port 5 USER AHB interface 1 */ },
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
36
+ { /* port 6 USER AHB interface 2 */ },
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
37
+ { /* port 7 USER AHB interface 3 */ },
30
index XXXXXXX..XXXXXXX 100644
38
{ "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 49 } },
31
--- a/target/arm/translate.h
39
},
32
+++ b/target/arm/translate.h
40
},
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
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
+
85
+ {
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
89
+ }
90
+
91
+ {
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
+}
111
+
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
113
+{
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
115
+}
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
117
index XXXXXXX..XXXXXXX 100644
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
+
170
+ if (a->shim == 0) {
171
+ a->shim = 32;
172
+ }
173
+ fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
174
+
175
+ return true;
176
+}
177
+
178
+static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
179
+{
180
+ return do_mve_sh_ri(s, a, gen_urshr32_i32);
181
+}
182
+
183
+static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
184
+{
185
+ return do_mve_sh_ri(s, a, gen_srshr32_i32);
186
+}
187
+
188
+static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
189
+{
190
+ gen_helper_mve_sqshl(r, cpu_env, n, tcg_constant_i32(shift));
191
+}
192
+
193
+static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
194
+{
195
+ return do_mve_sh_ri(s, a, gen_mve_sqshl);
196
+}
197
+
198
+static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
199
+{
200
+ gen_helper_mve_uqshl(r, cpu_env, n, tcg_constant_i32(shift));
201
+}
202
+
203
+static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
204
+{
205
+ return do_mve_sh_ri(s, a, gen_mve_uqshl);
206
+}
207
+
208
/*
209
* Multiply and multiply accumulate
210
*/
211
--
41
--
212
2.20.1
42
2.25.1
213
214
diff view generated by jsdifflib
1
Implement the MVE long shifts by register, which perform shifts on a
1
The AN547 application note URL has changed: update our comment
2
pair of general-purpose registers treated as a 64-bit quantity, with
2
accordingly. (Rev B is still downloadable from the old URL,
3
the shift count in another general-purpose register, which might be
3
but there is a new Rev C of the document now.)
4
either positive or negative.
5
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
we have to move the CSEL pattern into the same decodetree group.
11
4
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20220221094144.426191-1-peter.maydell@linaro.org
15
---
9
---
16
target/arm/helper-mve.h | 6 +++
10
hw/arm/mps2-tz.c | 2 +-
17
target/arm/translate.h | 1 +
11
1 file changed, 1 insertion(+), 1 deletion(-)
18
target/arm/t32.decode | 16 +++++--
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
21
5 files changed, 182 insertions(+), 3 deletions(-)
22
12
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
24
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-mve.h
15
--- a/hw/arm/mps2-tz.c
26
+++ b/target/arm/helper-mve.h
16
+++ b/hw/arm/mps2-tz.c
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
30
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate.h
42
+++ b/target/arm/translate.h
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
48
49
/**
50
* arm_tbflags_from_tb:
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/t32.decode
54
+++ b/target/arm/t32.decode
55
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
56
&mcrr !extern cp opc1 crm rt rt2
18
* Application Note AN524:
57
19
* https://developer.arm.com/documentation/dai0524/latest/
58
&mve_shl_ri rdalo rdahi shim
20
* Application Note AN547:
59
+&mve_shl_rr rdalo rdahi rm
21
- * https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/DAI0547B_SSE300_PLUS_U55_FPGA_for_mps3.pdf
60
22
+ * https://developer.arm.com/documentation/dai0547/latest/
61
# rdahi: bits [3:1] from insn, bit 0 is 1
23
*
62
# rdalo: bits [3:1] from insn, bit 0 is 0
24
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
63
@@ -XXX,XX +XXX,XX @@
25
* (ARM ECM0601256) for the details of some of the device layout:
64
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
--
26
--
292
2.20.1
27
2.25.1
293
28
294
29
diff view generated by jsdifflib
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
1
The tsc210x doesn't support anything other than 16-bit reads on the
2
SPI bus, but the guest can program the SPI controller to attempt
3
them anyway. If this happens, don't abort QEMU, just log this as
4
a guest error.
2
5
3
do_urshr() is borrowed from sve_helper.c.
6
This fixes our machine_arm_n8x0.py:N8x0Machine.test_n800
7
acceptance test, which hits this assertion.
4
8
9
The reason we hit the assertion is because the guest kernel thinks
10
there is a TSC2005 on this SPI bus address, not a TSC210x. (The n810
11
*does* have a TSC2005 at this address.) The TSC2005 supports the
12
24-bit accesses which the guest driver makes, and the TSC210x does
13
not (that is, our TSC210x emulation is not missing support for a word
14
width the hardware can handle). It's not clear whether the problem
15
here is that the guest kernel incorrectly thinks the n800 has the
16
same device at this SPI bus address as the n810, or that QEMU's n810
17
board model doesn't get the SPI devices right. At this late date
18
there no longer appears to be any reliable information on the web
19
about the hardware behaviour, but I am inclined to think this is a
20
guest kernel bug. In any case, we prefer not to abort QEMU for
21
guest-triggerable conditions, so logging the error is the right thing
22
to do.
23
24
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/736
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
27
Message-id: 20220221140750.514557-1-peter.maydell@linaro.org
8
---
28
---
9
target/arm/helper-mve.h | 10 ++++++++++
29
hw/input/tsc210x.c | 8 ++++++--
10
target/arm/mve.decode | 11 +++++++++++
30
1 file changed, 6 insertions(+), 2 deletions(-)
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 15 ++++++++++++++
13
4 files changed, 76 insertions(+)
14
31
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
32
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
16
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
34
--- a/hw/input/tsc210x.c
18
+++ b/target/arm/helper-mve.h
35
+++ b/hw/input/tsc210x.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
@@ -XXX,XX +XXX,XX @@
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
#include "hw/hw.h"
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
#include "audio/audio.h"
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
#include "qemu/timer.h"
23
+
40
+#include "qemu/log.h"
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
#include "sysemu/reset.h"
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
#include "ui/console.h"
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
#include "hw/arm/omap.h" /* For I2SCodec */
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
@@ -XXX,XX +XXX,XX @@ uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
28
+
45
TSC210xState *s = opaque;
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
uint32_t ret = 0;
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
- if (len != 16)
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
- hw_error("%s: FIXME: bad SPI word width %i\n", __func__, len);
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
50
+ if (len != 16) {
34
index XXXXXXX..XXXXXXX 100644
51
+ qemu_log_mask(LOG_GUEST_ERROR,
35
--- a/target/arm/mve.decode
52
+ "%s: bad SPI word width %i\n", __func__, len);
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;
53
+ return 0;
95
+ }
54
+ }
96
+}
55
97
+
56
/* TODO: sequential reads etc - how do we make sure the host doesn't
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
57
* unintentionally read out a conversion result from a register while
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
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_VSHLL(VSHLL_BS, vshllbs)
105
DO_VSHLL(VSHLL_BU, vshllbu)
106
DO_VSHLL(VSHLL_TS, vshllts)
107
DO_VSHLL(VSHLL_TU, vshlltu)
108
+
109
+#define DO_2SHIFT_N(INSN, FN) \
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
111
+ { \
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
113
+ gen_helper_mve_##FN##b, \
114
+ gen_helper_mve_##FN##h, \
115
+ }; \
116
+ return do_2shift(s, a, fns[a->size], false); \
117
+ }
118
+
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
123
--
58
--
124
2.20.1
59
2.25.1
125
60
126
61
diff view generated by jsdifflib
1
From: Patrick Venture <venture@google.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
3
Previously this device created N subdevices which each owned an i2c bus.
4
entry.
4
Now this device simply owns the N i2c busses directly.
5
5
6
Tested: Verified devices behind mux are still accessible via qmp and i2c
7
from within an arm32 SoC.
8
9
Reviewed-by: Hao Wu <wuhaotsh@google.com>
6
Signed-off-by: Patrick Venture <venture@google.com>
10
Signed-off-by: Patrick Venture <venture@google.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210615192848.1065297-2-venture@google.com
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20220202164533.1283668-1-venture@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
15
---
11
docs/system/arm/aspeed.rst | 1 +
16
hw/i2c/i2c_mux_pca954x.c | 77 +++++++---------------------------------
12
1 file changed, 1 insertion(+)
17
1 file changed, 13 insertions(+), 64 deletions(-)
13
18
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
19
diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
21
--- a/hw/i2c/i2c_mux_pca954x.c
17
+++ b/docs/system/arm/aspeed.rst
22
+++ b/hw/i2c/i2c_mux_pca954x.c
18
@@ -XXX,XX +XXX,XX @@ etc.
23
@@ -XXX,XX +XXX,XX @@
19
AST2400 SoC based machines :
24
#define PCA9548_CHANNEL_COUNT 8
20
25
#define PCA9546_CHANNEL_COUNT 4
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
26
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
27
-/*
23
28
- * struct Pca954xChannel - The i2c mux device will have N of these states
24
AST2500 SoC based machines :
29
- * that own the i2c channel bus.
25
30
- * @bus: The owned channel bus.
31
- * @enabled: Is this channel active?
32
- */
33
-typedef struct Pca954xChannel {
34
- SysBusDevice parent;
35
-
36
- I2CBus *bus;
37
-
38
- bool enabled;
39
-} Pca954xChannel;
40
-
41
-#define TYPE_PCA954X_CHANNEL "pca954x-channel"
42
-#define PCA954X_CHANNEL(obj) \
43
- OBJECT_CHECK(Pca954xChannel, (obj), TYPE_PCA954X_CHANNEL)
44
-
45
/*
46
* struct Pca954xState - The pca954x state object.
47
* @control: The value written to the mux control.
48
@@ -XXX,XX +XXX,XX @@ typedef struct Pca954xState {
49
50
uint8_t control;
51
52
- /* The channel i2c buses. */
53
- Pca954xChannel channel[PCA9548_CHANNEL_COUNT];
54
+ bool enabled[PCA9548_CHANNEL_COUNT];
55
+ I2CBus *bus[PCA9548_CHANNEL_COUNT];
56
} Pca954xState;
57
58
/*
59
@@ -XXX,XX +XXX,XX @@ static bool pca954x_match(I2CSlave *candidate, uint8_t address,
60
}
61
62
for (i = 0; i < mc->nchans; i++) {
63
- if (!mux->channel[i].enabled) {
64
+ if (!mux->enabled[i]) {
65
continue;
66
}
67
68
- if (i2c_scan_bus(mux->channel[i].bus, address, broadcast,
69
+ if (i2c_scan_bus(mux->bus[i], address, broadcast,
70
current_devs)) {
71
if (!broadcast) {
72
return true;
73
@@ -XXX,XX +XXX,XX @@ static void pca954x_enable_channel(Pca954xState *s, uint8_t enable_mask)
74
*/
75
for (i = 0; i < mc->nchans; i++) {
76
if (enable_mask & (1 << i)) {
77
- s->channel[i].enabled = true;
78
+ s->enabled[i] = true;
79
} else {
80
- s->channel[i].enabled = false;
81
+ s->enabled[i] = false;
82
}
83
}
84
}
85
@@ -XXX,XX +XXX,XX @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel)
86
Pca954xState *pca954x = PCA954X(mux);
87
88
g_assert(channel < pc->nchans);
89
- return I2C_BUS(qdev_get_child_bus(DEVICE(&pca954x->channel[channel]),
90
- "i2c-bus"));
91
-}
92
-
93
-static void pca954x_channel_init(Object *obj)
94
-{
95
- Pca954xChannel *s = PCA954X_CHANNEL(obj);
96
- s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
97
-
98
- /* Start all channels as disabled. */
99
- s->enabled = false;
100
-}
101
-
102
-static void pca954x_channel_class_init(ObjectClass *klass, void *data)
103
-{
104
- DeviceClass *dc = DEVICE_CLASS(klass);
105
- dc->desc = "Pca954x Channel";
106
+ return pca954x->bus[channel];
107
}
108
109
static void pca9546_class_init(ObjectClass *klass, void *data)
110
@@ -XXX,XX +XXX,XX @@ static void pca9548_class_init(ObjectClass *klass, void *data)
111
s->nchans = PCA9548_CHANNEL_COUNT;
112
}
113
114
-static void pca954x_realize(DeviceState *dev, Error **errp)
115
-{
116
- Pca954xState *s = PCA954X(dev);
117
- Pca954xClass *c = PCA954X_GET_CLASS(s);
118
- int i;
119
-
120
- /* SMBus modules. Cannot fail. */
121
- for (i = 0; i < c->nchans; i++) {
122
- sysbus_realize(SYS_BUS_DEVICE(&s->channel[i]), &error_abort);
123
- }
124
-}
125
-
126
static void pca954x_init(Object *obj)
127
{
128
Pca954xState *s = PCA954X(obj);
129
Pca954xClass *c = PCA954X_GET_CLASS(obj);
130
int i;
131
132
- /* Only initialize the children we expect. */
133
+ /* SMBus modules. Cannot fail. */
134
for (i = 0; i < c->nchans; i++) {
135
- object_initialize_child(obj, "channel[*]", &s->channel[i],
136
- TYPE_PCA954X_CHANNEL);
137
+ g_autofree gchar *bus_name = g_strdup_printf("i2c.%d", i);
138
+
139
+ /* start all channels as disabled. */
140
+ s->enabled[i] = false;
141
+ s->bus[i] = i2c_init_bus(DEVICE(s), bus_name);
142
}
143
}
144
145
@@ -XXX,XX +XXX,XX @@ static void pca954x_class_init(ObjectClass *klass, void *data)
146
rc->phases.enter = pca954x_enter_reset;
147
148
dc->desc = "Pca954x i2c-mux";
149
- dc->realize = pca954x_realize;
150
151
k->write_data = pca954x_write_data;
152
k->receive_byte = pca954x_read_byte;
153
@@ -XXX,XX +XXX,XX @@ static const TypeInfo pca954x_info[] = {
154
.parent = TYPE_PCA954X,
155
.class_init = pca9548_class_init,
156
},
157
- {
158
- .name = TYPE_PCA954X_CHANNEL,
159
- .parent = TYPE_SYS_BUS_DEVICE,
160
- .class_init = pca954x_channel_class_init,
161
- .instance_size = sizeof(Pca954xChannel),
162
- .instance_init = pca954x_channel_init,
163
- }
164
};
165
166
DEFINE_TYPES(pca954x_info)
26
--
167
--
27
2.20.1
168
2.25.1
28
169
29
170
diff view generated by jsdifflib
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
1
From: Akihiko Odaki <akihiko.odaki@gmail.com>
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
stored in a pair of general-purpose registers.
4
2
3
Support the latest PSCI on TCG and HVF. A 64-bit function called from
4
AArch32 now returns NOT_SUPPORTED, which is necessary to adhere to SMC
5
Calling Convention 1.0. It is still not compliant with SMCCC 1.3 since
6
they do not implement mandatory functions.
7
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
9
Message-id: 20220213035753.34577-1-akihiko.odaki@gmail.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: update MISMATCH_CHECK checks on PSCI_VERSION macros to match]
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
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
---
13
---
9
target/arm/helper-mve.h | 3 ++
14
target/arm/kvm-consts.h | 13 +++++++++----
10
target/arm/mve.decode | 6 +++-
15
hw/arm/boot.c | 12 +++++++++---
11
target/arm/mve_helper.c | 19 ++++++++++++
16
target/arm/cpu.c | 5 +++--
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
17
target/arm/hvf/hvf.c | 27 ++++++++++++++++++++++++++-
13
4 files changed, 90 insertions(+), 1 deletion(-)
18
target/arm/kvm64.c | 2 +-
19
target/arm/psci.c | 35 ++++++++++++++++++++++++++++++++---
20
6 files changed, 80 insertions(+), 14 deletions(-)
14
21
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
22
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
24
--- a/target/arm/kvm-consts.h
18
+++ b/target/arm/helper-mve.h
25
+++ b/target/arm/kvm-consts.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
26
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE);
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
27
#define QEMU_PSCI_0_2_FN64_AFFINITY_INFO QEMU_PSCI_0_2_FN64(4)
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
28
#define QEMU_PSCI_0_2_FN64_MIGRATE QEMU_PSCI_0_2_FN64(5)
22
29
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
30
+#define QEMU_PSCI_1_0_FN_PSCI_FEATURES QEMU_PSCI_0_2_FN(10)
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
25
+
31
+
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
32
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_SUSPEND, PSCI_0_2_FN_CPU_SUSPEND);
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
33
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_OFF, PSCI_0_2_FN_CPU_OFF);
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
34
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_ON, PSCI_0_2_FN_CPU_ON);
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
35
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_0_2_FN_MIGRATE, PSCI_0_2_FN_MIGRATE);
30
index XXXXXXX..XXXXXXX 100644
36
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_SUSPEND, PSCI_0_2_FN64_CPU_SUSPEND);
31
--- a/target/arm/mve.decode
37
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_ON, PSCI_0_2_FN64_CPU_ON);
32
+++ b/target/arm/mve.decode
38
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_MIGRATE, PSCI_0_2_FN64_MIGRATE);
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
39
+MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
40
35
41
/* PSCI v0.2 return values used by TCG emulation of PSCI */
36
# Vector add across vector
42
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
43
/* No Trusted OS migration to worry about when offlining CPUs */
38
+{
44
#define QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED 2
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
45
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
46
-/* We implement version 0.2 only */
41
+ rdahi=%rdahi rdalo=%rdalo
47
-#define QEMU_PSCI_0_2_RET_VERSION_0_2 2
42
+}
48
+#define QEMU_PSCI_VERSION_0_1 0x00001
43
49
+#define QEMU_PSCI_VERSION_0_2 0x00002
44
# Predicate operations
50
+#define QEMU_PSCI_VERSION_1_1 0x10001
45
%mask_22_13 22:1 13:3
51
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
52
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
47
index XXXXXXX..XXXXXXX 100644
53
-MISMATCH_CHECK(QEMU_PSCI_0_2_RET_VERSION_0_2,
48
--- a/target/arm/mve_helper.c
54
- (PSCI_VERSION_MAJOR(0) | PSCI_VERSION_MINOR(2)));
49
+++ b/target/arm/mve_helper.c
55
+/* We don't bother to check every possible version value */
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
56
+MISMATCH_CHECK(QEMU_PSCI_VERSION_0_2, PSCI_VERSION(0, 2));
51
DO_VADDV(vaddvuh, 2, uint16_t)
57
+MISMATCH_CHECK(QEMU_PSCI_VERSION_1_1, PSCI_VERSION(1, 1));
52
DO_VADDV(vaddvuw, 4, uint32_t)
58
53
59
/* PSCI return values (inclusive of all PSCI versions) */
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
60
#define QEMU_PSCI_RET_SUCCESS 0
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
61
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
56
+ uint64_t ra) \
62
index XXXXXXX..XXXXXXX 100644
57
+ { \
63
--- a/hw/arm/boot.c
58
+ uint16_t mask = mve_element_mask(env); \
64
+++ b/hw/arm/boot.c
59
+ unsigned e; \
65
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
60
+ TYPE *m = vm; \
66
}
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
67
62
+ if (mask & 1) { \
68
qemu_fdt_add_subnode(fdt, "/psci");
63
+ ra += (LTYPE)m[H4(e)]; \
69
- if (armcpu->psci_version == 2) {
64
+ } \
70
- const char comp[] = "arm,psci-0.2\0arm,psci";
65
+ } \
71
- qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
66
+ mve_advance_vpt(env); \
72
+ if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
67
+ return ra; \
73
+ armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
68
+ } \
74
+ if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
69
+
75
+ const char comp[] = "arm,psci-0.2\0arm,psci";
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
76
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
77
+ } else {
72
+
78
+ const char comp[] = "arm,psci-1.0\0arm,psci-0.2\0arm,psci";
73
/* Shifts by immediate */
79
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
80
+ }
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
81
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
82
cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
77
index XXXXXXX..XXXXXXX 100644
83
if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
78
--- a/target/arm/translate-mve.c
84
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
79
+++ b/target/arm/translate-mve.c
85
index XXXXXXX..XXXXXXX 100644
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
86
--- a/target/arm/cpu.c
81
return true;
87
+++ b/target/arm/cpu.c
88
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
89
* picky DTB consumer will also provide a helpful error message.
90
*/
91
cpu->dtb_compatible = "qemu,unknown";
92
- cpu->psci_version = 1; /* By default assume PSCI v0.1 */
93
+ cpu->psci_version = QEMU_PSCI_VERSION_0_1; /* By default assume PSCI v0.1 */
94
cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
95
96
if (tcg_enabled() || hvf_enabled()) {
97
- cpu->psci_version = 2; /* TCG and HVF implement PSCI 0.2 */
98
+ /* TCG and HVF implement PSCI 1.1 */
99
+ cpu->psci_version = QEMU_PSCI_VERSION_1_1;
100
}
82
}
101
}
83
102
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
103
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
85
+{
104
index XXXXXXX..XXXXXXX 100644
86
+ /*
105
--- a/target/arm/hvf/hvf.c
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
106
+++ b/target/arm/hvf/hvf.c
88
+ * elements of the vector into a 64-bit result stored in
107
@@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu)
89
+ * a pair of general-purpose registers.
108
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
109
switch (param[0]) {
91
+ */
110
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
92
+ TCGv_ptr qm;
111
- ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
93
+ TCGv_i64 rda;
112
+ ret = QEMU_PSCI_VERSION_1_1;
94
+ TCGv_i32 rdalo, rdahi;
113
break;
95
+
114
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
96
+ if (!dc_isar_feature(aa32_mve, s)) {
115
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
97
+ return false;
116
@@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu)
98
+ }
117
case QEMU_PSCI_0_2_FN_MIGRATE:
99
+ /*
118
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
119
break;
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
120
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
102
+ */
121
+ switch (param[1]) {
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
122
+ case QEMU_PSCI_0_2_FN_PSCI_VERSION:
104
+ return false;
123
+ case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
105
+ }
124
+ case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
125
+ case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
107
+ return true;
126
+ case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
108
+ }
127
+ case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
109
+
128
+ case QEMU_PSCI_0_1_FN_CPU_ON:
110
+ /*
129
+ case QEMU_PSCI_0_2_FN_CPU_ON:
111
+ * This insn is subject to beat-wise execution. Partial execution
130
+ case QEMU_PSCI_0_2_FN64_CPU_ON:
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
131
+ case QEMU_PSCI_0_1_FN_CPU_OFF:
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
132
+ case QEMU_PSCI_0_2_FN_CPU_OFF:
114
+ */
133
+ case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
115
+ if (a->a || mve_skip_first_beat(s)) {
134
+ case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
116
+ /* Accumulate input from RdaHi:RdaLo */
135
+ case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
117
+ rda = tcg_temp_new_i64();
136
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
118
+ rdalo = load_reg(s, a->rdalo);
137
+ ret = 0;
119
+ rdahi = load_reg(s, a->rdahi);
138
+ break;
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
139
+ case QEMU_PSCI_0_1_FN_MIGRATE:
121
+ tcg_temp_free_i32(rdalo);
140
+ case QEMU_PSCI_0_2_FN_MIGRATE:
122
+ tcg_temp_free_i32(rdahi);
141
+ default:
123
+ } else {
142
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
124
+ /* Accumulate starting at zero */
143
+ }
125
+ rda = tcg_const_i64(0);
144
+ break;
126
+ }
145
default:
127
+
146
return false;
128
+ qm = mve_qreg_ptr(a->qm);
147
}
129
+ if (a->u) {
148
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
149
index XXXXXXX..XXXXXXX 100644
131
+ } else {
150
--- a/target/arm/kvm64.c
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
151
+++ b/target/arm/kvm64.c
133
+ }
152
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
134
+ tcg_temp_free_ptr(qm);
153
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
135
+
154
}
136
+ rdalo = tcg_temp_new_i32();
155
if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
137
+ rdahi = tcg_temp_new_i32();
156
- cpu->psci_version = 2;
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
157
+ cpu->psci_version = QEMU_PSCI_VERSION_0_2;
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
158
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
140
+ store_reg(s, a->rdalo, rdalo);
159
}
141
+ store_reg(s, a->rdahi, rdahi);
160
if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
142
+ tcg_temp_free_i64(rda);
161
diff --git a/target/arm/psci.c b/target/arm/psci.c
143
+ mve_update_eci(s);
162
index XXXXXXX..XXXXXXX 100644
144
+ return true;
163
--- a/target/arm/psci.c
145
+}
164
+++ b/target/arm/psci.c
146
+
165
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
148
{
166
{
149
TCGv_ptr qd;
167
/*
168
* This function partially implements the logic for dispatching Power State
169
- * Coordination Interface (PSCI) calls (as described in ARM DEN 0022B.b),
170
+ * Coordination Interface (PSCI) calls (as described in ARM DEN 0022D.b),
171
* to the extent required for bringing up and taking down secondary cores,
172
* and for handling reset and poweroff requests.
173
* Additional information about the calling convention used is available in
174
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
175
}
176
177
if ((param[0] & QEMU_PSCI_0_2_64BIT) && !is_a64(env)) {
178
- ret = QEMU_PSCI_RET_INVALID_PARAMS;
179
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
180
goto err;
181
}
182
183
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
184
ARMCPU *target_cpu;
185
186
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
187
- ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
188
+ ret = QEMU_PSCI_VERSION_1_1;
189
break;
190
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
191
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
192
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
193
}
194
helper_wfi(env, 4);
195
break;
196
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
197
+ switch (param[1]) {
198
+ case QEMU_PSCI_0_2_FN_PSCI_VERSION:
199
+ case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
200
+ case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
201
+ case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
202
+ case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
203
+ case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
204
+ case QEMU_PSCI_0_1_FN_CPU_ON:
205
+ case QEMU_PSCI_0_2_FN_CPU_ON:
206
+ case QEMU_PSCI_0_2_FN64_CPU_ON:
207
+ case QEMU_PSCI_0_1_FN_CPU_OFF:
208
+ case QEMU_PSCI_0_2_FN_CPU_OFF:
209
+ case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
210
+ case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
211
+ case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
212
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
213
+ if (!(param[1] & QEMU_PSCI_0_2_64BIT) || is_a64(env)) {
214
+ ret = 0;
215
+ break;
216
+ }
217
+ /* fallthrough */
218
+ case QEMU_PSCI_0_1_FN_MIGRATE:
219
+ case QEMU_PSCI_0_2_FN_MIGRATE:
220
+ default:
221
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
222
+ break;
223
+ }
224
+ break;
225
case QEMU_PSCI_0_1_FN_MIGRATE:
226
case QEMU_PSCI_0_2_FN_MIGRATE:
227
default:
150
--
228
--
151
2.20.1
229
2.25.1
152
153
diff view generated by jsdifflib
1
Use dup_const() instead of bitfield_replicate() in
1
From: Wentao_Liang <Wentao_Liang_g@163.com>
2
disas_simd_mod_imm().
3
2
4
(We can't replace the other use of bitfield_replicate() in this file,
3
handle_simd_shift_fpint_conv() was accidentally freeing the TCG
5
in logic_imm_decode_wmask(), because that location needs to handle 2
4
temporary tcg_fpstatus too early, before the last use of it. Move
6
and 4 bit elements, which dup_const() cannot.)
5
the free down to where it belongs.
7
6
7
Signed-off-by: Wentao_Liang <Wentao_Liang_g@163.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
[PMM: cleaned up commit message]
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210628135835.6690-6-peter.maydell@linaro.org
11
---
11
---
12
target/arm/translate-a64.c | 2 +-
12
target/arm/translate-a64.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
20
/* FMOV (vector, immediate) - half-precision */
20
}
21
imm = vfp_expand_imm(MO_16, abcdefgh);
22
/* now duplicate across the lanes */
23
- imm = bitfield_replicate(imm, 16);
24
+ imm = dup_const(MO_16, imm);
25
} else {
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
27
}
21
}
22
23
- tcg_temp_free_ptr(tcg_fpstatus);
24
tcg_temp_free_i32(tcg_shift);
25
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
26
+ tcg_temp_free_ptr(tcg_fpstatus);
27
tcg_temp_free_i32(tcg_rmode);
28
}
29
28
--
30
--
29
2.20.1
31
2.25.1
30
31
diff view generated by jsdifflib
1
From: Nolan Leake <nolan@sigbus.net>
1
From: Shengtan Mao <stmao@google.com>
2
2
3
This is just enough to make reboot and poweroff work. Works for
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
4
Reviewed-by: Chris Rauer <crauer@google.com>
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
5
Signed-off-by: Shengtan Mao <stmao@google.com>
6
do what linux does for reset.
6
Signed-off-by: Patrick Venture <venture@google.com>
7
7
Message-id: 20220225174451.192304-1-wuhaotsh@google.com
8
The watchdog timer functionality is not yet implemented.
9
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
9
---
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
10
tests/qtest/npcm7xx_sdhci-test.c | 215 +++++++++++++++++++++++++++++++
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
11
tests/qtest/meson.build | 1 +
21
hw/arm/bcm2835_peripherals.c | 13 ++-
12
2 files changed, 216 insertions(+)
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
13
create mode 100644 tests/qtest/npcm7xx_sdhci-test.c
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
14
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
15
diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/bcm2835_peripherals.h
31
+++ b/include/hw/arm/bcm2835_peripherals.h
32
@@ -XXX,XX +XXX,XX @@
33
#include "hw/misc/bcm2835_mphi.h"
34
#include "hw/misc/bcm2835_thermal.h"
35
#include "hw/misc/bcm2835_cprman.h"
36
+#include "hw/misc/bcm2835_powermgt.h"
37
#include "hw/sd/sdhci.h"
38
#include "hw/sd/bcm2835_sdhost.h"
39
#include "hw/gpio/bcm2835_gpio.h"
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
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
16
new file mode 100644
51
index XXXXXXX..XXXXXXX
17
index XXXXXXX..XXXXXXX
52
--- /dev/null
18
--- /dev/null
53
+++ b/include/hw/misc/bcm2835_powermgt.h
19
+++ b/tests/qtest/npcm7xx_sdhci-test.c
54
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
55
+/*
21
+/*
56
+ * BCM2835 Power Management emulation
22
+ * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
57
+ *
23
+ *
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
24
+ * Copyright (c) 2022 Google LLC
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
60
+ *
25
+ *
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
26
+ * This program is free software; you can redistribute it and/or modify it
62
+ * See the COPYING file in the top-level directory.
27
+ * under the terms of the GNU General Public License as published by the
28
+ * Free Software Foundation; either version 2 of the License, or
29
+ * (at your option) any later version.
30
+ *
31
+ * This program is distributed in the hope that it will be useful, but WITHOUT
32
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
33
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34
+ * for more details.
63
+ */
35
+ */
64
+
36
+
65
+#ifndef BCM2835_POWERMGT_H
37
+#include "qemu/osdep.h"
66
+#define BCM2835_POWERMGT_H
38
+#include "hw/sd/npcm7xx_sdhci.h"
67
+
39
+
68
+#include "hw/sysbus.h"
40
+#include "libqos/libqtest.h"
69
+#include "qom/object.h"
41
+#include "libqtest-single.h"
70
+
42
+#include "libqos/sdhci-cmd.h"
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
43
+
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
44
+#define NPCM7XX_REG_SIZE 0x100
73
+
45
+#define NPCM7XX_MMC_BA 0xF0842000
74
+struct BCM2835PowerMgtState {
46
+#define NPCM7XX_BLK_SIZE 512
75
+ SysBusDevice busdev;
47
+#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
76
+ MemoryRegion iomem;
48
+
77
+
49
+char *sd_path;
78
+ uint32_t rstc;
50
+
79
+ uint32_t rsts;
51
+static QTestState *setup_sd_card(void)
80
+ uint32_t wdog;
52
+{
81
+};
53
+ QTestState *qts = qtest_initf(
82
+
54
+ "-machine kudo-bmc "
83
+#endif
55
+ "-device sd-card,drive=drive0 "
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
56
+ "-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off",
57
+ sd_path);
58
+
59
+ qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL);
60
+ qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON,
61
+ SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE |
62
+ SDHC_CLOCK_INT_EN);
63
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD);
64
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x41200000, 0, (41 << 8));
65
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID);
66
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR);
67
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x45670000, 0,
68
+ SDHC_SELECT_DESELECT_CARD);
69
+
70
+ return qts;
71
+}
72
+
73
+static void write_sdread(QTestState *qts, const char *msg)
74
+{
75
+ int fd, ret;
76
+ size_t len = strlen(msg);
77
+ char *rmsg = g_malloc(len);
78
+
79
+ /* write message to sd */
80
+ fd = open(sd_path, O_WRONLY);
81
+ g_assert(fd >= 0);
82
+ ret = write(fd, msg, len);
83
+ close(fd);
84
+ g_assert(ret == len);
85
+
86
+ /* read message using sdhci */
87
+ ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len);
88
+ g_assert(ret == len);
89
+ g_assert(!memcmp(rmsg, msg, len));
90
+
91
+ g_free(rmsg);
92
+}
93
+
94
+/* Check MMC can read values from sd */
95
+static void test_read_sd(void)
96
+{
97
+ QTestState *qts = setup_sd_card();
98
+
99
+ write_sdread(qts, "hello world");
100
+ write_sdread(qts, "goodbye");
101
+
102
+ qtest_quit(qts);
103
+}
104
+
105
+static void sdwrite_read(QTestState *qts, const char *msg)
106
+{
107
+ int fd, ret;
108
+ size_t len = strlen(msg);
109
+ char *rmsg = g_malloc(len);
110
+
111
+ /* write message using sdhci */
112
+ sdhci_write_cmd(qts, NPCM7XX_MMC_BA, msg, len, NPCM7XX_BLK_SIZE);
113
+
114
+ /* read message from sd */
115
+ fd = open(sd_path, O_RDONLY);
116
+ g_assert(fd >= 0);
117
+ ret = read(fd, rmsg, len);
118
+ close(fd);
119
+ g_assert(ret == len);
120
+
121
+ g_assert(!memcmp(rmsg, msg, len));
122
+
123
+ g_free(rmsg);
124
+}
125
+
126
+/* Check MMC can write values to sd */
127
+static void test_write_sd(void)
128
+{
129
+ QTestState *qts = setup_sd_card();
130
+
131
+ sdwrite_read(qts, "hello world");
132
+ sdwrite_read(qts, "goodbye");
133
+
134
+ qtest_quit(qts);
135
+}
136
+
137
+/* Check SDHCI has correct default values. */
138
+static void test_reset(void)
139
+{
140
+ QTestState *qts = qtest_init("-machine kudo-bmc");
141
+ uint64_t addr = NPCM7XX_MMC_BA;
142
+ uint64_t end_addr = addr + NPCM7XX_REG_SIZE;
143
+ uint16_t prstvals_resets[] = {NPCM7XX_PRSTVALS_0_RESET,
144
+ NPCM7XX_PRSTVALS_1_RESET,
145
+ 0,
146
+ NPCM7XX_PRSTVALS_3_RESET,
147
+ 0,
148
+ 0};
149
+ int i;
150
+ uint32_t mask;
151
+
152
+ while (addr < end_addr) {
153
+ switch (addr - NPCM7XX_MMC_BA) {
154
+ case SDHC_PRNSTS:
155
+ /*
156
+ * ignores bits 20 to 24: they are changed when reading registers
157
+ */
158
+ mask = 0x1f00000;
159
+ g_assert_cmphex(qtest_readl(qts, addr) | mask, ==,
160
+ NPCM7XX_PRSNTS_RESET | mask);
161
+ addr += 4;
162
+ break;
163
+ case SDHC_BLKGAP:
164
+ g_assert_cmphex(qtest_readb(qts, addr), ==, NPCM7XX_BLKGAP_RESET);
165
+ addr += 1;
166
+ break;
167
+ case SDHC_CAPAB:
168
+ g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_CAPAB_RESET);
169
+ addr += 8;
170
+ break;
171
+ case SDHC_MAXCURR:
172
+ g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_MAXCURR_RESET);
173
+ addr += 8;
174
+ break;
175
+ case SDHC_HCVER:
176
+ g_assert_cmphex(qtest_readw(qts, addr), ==, NPCM7XX_HCVER_RESET);
177
+ addr += 2;
178
+ break;
179
+ case NPCM7XX_PRSTVALS:
180
+ for (i = 0; i < NPCM7XX_PRSTVALS_SIZE; ++i) {
181
+ g_assert_cmphex(qtest_readw(qts, addr + 2 * i), ==,
182
+ prstvals_resets[i]);
183
+ }
184
+ addr += NPCM7XX_PRSTVALS_SIZE * 2;
185
+ break;
186
+ default:
187
+ g_assert_cmphex(qtest_readb(qts, addr), ==, 0);
188
+ addr += 1;
189
+ }
190
+ }
191
+
192
+ qtest_quit(qts);
193
+}
194
+
195
+static void drive_destroy(void)
196
+{
197
+ unlink(sd_path);
198
+ g_free(sd_path);
199
+}
200
+
201
+static void drive_create(void)
202
+{
203
+ int fd, ret;
204
+ GError *error = NULL;
205
+
206
+ /* Create a temporary raw image */
207
+ fd = g_file_open_tmp("sdhci_XXXXXX", &sd_path, &error);
208
+ if (fd == -1) {
209
+ fprintf(stderr, "unable to create sdhci file: %s\n", error->message);
210
+ g_error_free(error);
211
+ }
212
+ g_assert(sd_path != NULL);
213
+
214
+ ret = ftruncate(fd, NPCM7XX_TEST_IMAGE_SIZE);
215
+ g_assert_cmpint(ret, ==, 0);
216
+ g_message("%s", sd_path);
217
+ close(fd);
218
+}
219
+
220
+int main(int argc, char **argv)
221
+{
222
+ int ret;
223
+
224
+ drive_create();
225
+
226
+ g_test_init(&argc, &argv, NULL);
227
+
228
+ qtest_add_func("npcm7xx_sdhci/reset", test_reset);
229
+ qtest_add_func("npcm7xx_sdhci/write_sd", test_write_sd);
230
+ qtest_add_func("npcm7xx_sdhci/read_sd", test_read_sd);
231
+
232
+ ret = g_test_run();
233
+ drive_destroy();
234
+ return ret;
235
+}
236
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
85
index XXXXXXX..XXXXXXX 100644
237
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/bcm2835_peripherals.c
238
--- a/tests/qtest/meson.build
87
+++ b/hw/arm/bcm2835_peripherals.c
239
+++ b/tests/qtest/meson.build
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
240
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
89
241
'npcm7xx_gpio-test',
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
242
'npcm7xx_pwm-test',
91
OBJECT(&s->gpu_bus_mr));
243
'npcm7xx_rng-test',
92
+
244
+ 'npcm7xx_sdhci-test',
93
+ /* Power Management */
245
'npcm7xx_smbus-test',
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
246
'npcm7xx_timer-test',
95
+ TYPE_BCM2835_POWERMGT);
247
'npcm7xx_watchdog_timer-test'] + \
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;
106
+ }
107
+
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
110
+
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
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;
159
+ case R_RSTS:
160
+ res = s->rsts;
161
+ break;
162
+ case R_WDOG:
163
+ res = s->wdog;
164
+ break;
165
+
166
+ default:
167
+ qemu_log_mask(LOG_UNIMP,
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
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;
219
+ }
220
+}
221
+
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
223
+ .read = bcm2835_powermgt_read,
224
+ .write = bcm2835_powermgt_write,
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
226
+ .impl.min_access_size = 4,
227
+ .impl.max_access_size = 4,
228
+};
229
+
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
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
+}
250
+
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
252
+{
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
254
+
255
+ /* https://elinux.org/BCM2835_registers#PM */
256
+ s->rstc = 0x00000102;
257
+ s->rsts = 0x00001000;
258
+ s->wdog = 0x00000000;
259
+}
260
+
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
262
+{
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
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
--
248
--
296
2.20.1
249
2.25.1
297
298
diff view generated by jsdifflib
1
The MVE extension to v8.1M includes some new shift instructions which
1
From: Richard Henderson <richard.henderson@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
Add new macros to manipulate signed fields within the register.
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
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
7
Message-id: 20220301215958.157011-2-richard.henderson@linaro.org
14
is too difficult, because the functions that generate the code are
8
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
15
shared between a dozen different kinds of arithmetic or logical
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
instruction for all A32, T16 and T32 encodings, and for some insns
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
and some encodings Rm==13,15 are valid.)
11
---
12
include/hw/registerfields.h | 48 ++++++++++++++++++++++++++++++++++++-
13
1 file changed, 47 insertions(+), 1 deletion(-)
18
14
19
We make the helper functions we need for UQSHLL and SQSHLL take
15
diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
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
24
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
---
28
target/arm/helper-mve.h | 3 ++
29
target/arm/translate.h | 1 +
30
target/arm/t32.decode | 28 +++++++++++++
31
target/arm/mve_helper.c | 10 +++++
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
33
5 files changed, 132 insertions(+)
34
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
36
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper-mve.h
17
--- a/include/hw/registerfields.h
38
+++ b/target/arm/helper-mve.h
18
+++ b/include/hw/registerfields.h
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
@@ -XXX,XX +XXX,XX @@
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
extract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
41
21
R_ ## reg ## _ ## field ## _LENGTH)
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
22
23
+#define FIELD_SEX8(storage, reg, field) \
24
+ sextract8((storage), R_ ## reg ## _ ## field ## _SHIFT, \
25
+ R_ ## reg ## _ ## field ## _LENGTH)
26
+#define FIELD_SEX16(storage, reg, field) \
27
+ sextract16((storage), R_ ## reg ## _ ## field ## _SHIFT, \
28
+ R_ ## reg ## _ ## field ## _LENGTH)
29
+#define FIELD_SEX32(storage, reg, field) \
30
+ sextract32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
31
+ R_ ## reg ## _ ## field ## _LENGTH)
32
+#define FIELD_SEX64(storage, reg, field) \
33
+ sextract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
34
+ R_ ## reg ## _ ## field ## _LENGTH)
43
+
35
+
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
36
/* Extract a field from an array of registers */
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
37
#define ARRAY_FIELD_EX32(regs, reg, field) \
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
38
FIELD_EX32((regs)[R_ ## reg], reg, field)
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.h
49
+++ b/target/arm/translate.h
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
55
56
/**
57
* arm_tbflags_from_tb:
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
61
+++ b/target/arm/t32.decode
62
@@ -XXX,XX +XXX,XX @@
39
@@ -XXX,XX +XXX,XX @@
63
&mcr !extern cp opc1 crn crm opc2 rt
40
_d; })
64
&mcrr !extern cp opc1 crm rt rt2
41
#define FIELD_DP64(storage, reg, field, val) ({ \
65
42
struct { \
66
+&mve_shl_ri rdalo rdahi shim
43
- uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
44
+ uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
45
+ } _v = { .v = val }; \
46
+ uint64_t _d; \
47
+ _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
48
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
49
+ _d; })
67
+
50
+
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
51
+#define FIELD_SDP8(storage, reg, field, val) ({ \
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
52
+ struct { \
70
+%rdahi_9 9:3 !function=times_2_plus_1
53
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
71
+%rdalo_17 17:3 !function=times_2
54
+ } _v = { .v = val }; \
72
+
55
+ uint8_t _d; \
73
# Data-processing (register)
56
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
74
57
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
75
%imm5_12_6 12:3 6:2
58
+ _d; })
76
@@ -XXX,XX +XXX,XX @@
59
+#define FIELD_SDP16(storage, reg, field, val) ({ \
77
@S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \
60
+ struct { \
78
&s_rrr_shi shim=%imm5_12_6 s=1 rd=0
61
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
79
62
+ } _v = { .v = val }; \
80
+@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
63
+ uint16_t _d; \
81
+ &mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
64
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
82
+
65
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
83
{
66
+ _d; })
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
67
+#define FIELD_SDP32(storage, reg, field, val) ({ \
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
68
+ struct { \
86
}
69
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
70
+ } _v = { .v = val }; \
88
{
71
+ uint32_t _d; \
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
72
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
73
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
74
+ _d; })
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
75
+#define FIELD_SDP64(storage, reg, field, val) ({ \
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
76
+ struct { \
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
77
+ int64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
78
} _v = { .v = val }; \
96
+ [
79
uint64_t _d; \
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
80
_d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
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
}
118
+
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
120
+{
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
122
+}
123
+
124
+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
diff --git a/target/arm/translate.c b/target/arm/translate.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate.c
131
+++ b/target/arm/translate.c
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
133
return true;
134
}
135
136
+/*
137
+ * v8.1M MVE wide-shifts
138
+ */
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
140
+ WideShiftImmFn *fn)
141
+{
142
+ TCGv_i64 rda;
143
+ TCGv_i32 rdalo, rdahi;
144
+
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
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
--
81
--
230
2.20.1
82
2.25.1
231
83
232
84
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Set this as the kernel would, to 48 bits, to keep the computation
4
of the address space correct for PAuth.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220301215958.157011-3-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.c | 3 ++-
12
1 file changed, 2 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
19
aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1);
20
}
21
/*
22
+ * Enable 48-bit address space (TODO: take reserved_va into account).
23
* Enable TBI0 but not TBI1.
24
* Note that this must match useronly_clean_ptr.
25
*/
26
- env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
27
+ env->cp15.tcr_el[1].raw_tcr = 5 | (1ULL << 37);
28
29
/* Enable MTE */
30
if (cpu_isar_feature(aa64_mte, cpu)) {
31
--
32
2.25.1
diff view generated by jsdifflib
1
Implement the MVE VSRI and VSLI insns, which perform a
1
From: Richard Henderson <richard.henderson@linaro.org>
2
shift-and-insert operation.
3
2
3
Without FEAT_LVA, the behaviour of programming an invalid value
4
is IMPLEMENTATION DEFINED. With FEAT_LVA, programming an invalid
5
minimum value requires a Translation fault.
6
7
It is most self-consistent to choose to generate the fault always.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220301215958.157011-4-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
7
---
13
---
8
target/arm/helper-mve.h | 8 ++++++++
14
target/arm/internals.h | 1 +
9
target/arm/mve.decode | 9 ++++++++
15
target/arm/helper.c | 32 ++++++++++++++++++++++++++++----
10
target/arm/mve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
16
2 files changed, 29 insertions(+), 4 deletions(-)
11
target/arm/translate-mve.c | 3 +++
12
4 files changed, 62 insertions(+)
13
17
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
18
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-mve.h
20
--- a/target/arm/internals.h
17
+++ b/target/arm/helper-mve.h
21
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
bool hpd : 1;
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
bool using16k : 1;
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
bool using64k : 1;
26
+ bool tsz_oob : 1; /* tsz has been clamped to legal range */
27
} ARMVAParameters;
28
29
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
33
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
35
ARMMMUIdx mmu_idx, bool data)
36
{
37
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
38
- bool epd, hpd, using16k, using64k;
39
- int select, tsz, tbi, max_tsz;
40
+ bool epd, hpd, using16k, using64k, tsz_oob;
41
+ int select, tsz, tbi, max_tsz, min_tsz;
42
43
if (!regime_has_2_ranges(mmu_idx)) {
44
select = 0;
45
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
46
} else {
47
max_tsz = 39;
48
}
49
+ min_tsz = 16; /* TODO: ARMv8.2-LVA */
50
51
- tsz = MIN(tsz, max_tsz);
52
- tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
53
+ if (tsz > max_tsz) {
54
+ tsz = max_tsz;
55
+ tsz_oob = true;
56
+ } else if (tsz < min_tsz) {
57
+ tsz = min_tsz;
58
+ tsz_oob = true;
59
+ } else {
60
+ tsz_oob = false;
61
+ }
62
63
/* Present TBI as a composite with TBID. */
64
tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
65
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
66
.hpd = hpd,
67
.using16k = using16k,
68
.using64k = using64k,
69
+ .tsz_oob = tsz_oob,
70
};
71
}
72
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
74
param = aa64_va_parameters(env, address, mmu_idx,
75
access_type != MMU_INST_FETCH);
76
level = 0;
22
+
77
+
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
78
+ /*
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
79
+ * If TxSZ is programmed to a value larger than the maximum,
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
80
+ * or smaller than the effective minimum, it is IMPLEMENTATION
81
+ * DEFINED whether we behave as if the field were programmed
82
+ * within bounds, or if a level 0 Translation fault is generated.
83
+ *
84
+ * With FEAT_LVA, fault on less than minimum becomes required,
85
+ * so our choice is to always raise the fault.
86
+ */
87
+ if (param.tsz_oob) {
88
+ fault_type = ARMFault_Translation;
89
+ goto do_fault;
90
+ }
26
+
91
+
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
92
addrsize = 64 - 8 * param.tbi;
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
93
inputsize = 64 - param.tsz;
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
94
} else {
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/mve.decode
33
+++ b/target/arm/mve.decode
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
35
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
38
+
39
+# Shift-and-insert
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
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
--
95
--
115
2.20.1
96
2.25.1
116
117
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
We will shortly share parts of this function with other portions
5
handle it the same way neon-dp.decode does.
4
of address translation.
6
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220301215958.157011-5-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
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
---
12
---
11
target/arm/helper-mve.h | 16 +++++++++++
13
target/arm/internals.h | 19 +------------------
12
target/arm/mve.decode | 23 +++++++++++++++
14
target/arm/helper.c | 22 ++++++++++++++++++++++
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
15
2 files changed, 23 insertions(+), 18 deletions(-)
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
15
4 files changed, 147 insertions(+)
16
16
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper-mve.h
19
--- a/target/arm/internals.h
20
+++ b/target/arm/helper-mve.h
20
+++ b/target/arm/internals.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
@@ -XXX,XX +XXX,XX @@ static inline void update_spsel(CPUARMState *env, uint32_t imm)
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
22
* Returns the implementation defined bit-width of physical addresses.
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
23
* The ARMv8 reference manuals refer to this as PAMax().
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
24
*/
25
+
25
-static inline unsigned int arm_pamax(ARMCPU *cpu)
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
-{
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
- static const unsigned int pamax_map[] = {
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
- [0] = 32,
29
+
29
- [1] = 36,
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
- [2] = 40,
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
- [3] = 42,
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
- [4] = 44,
33
+
33
- [5] = 48,
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
- };
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
- unsigned int parange =
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
- FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
37
+
37
-
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
- /* id_aa64mmfr0 is a read-only register so values outside of the
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
- * supported mappings can be considered an implementation error. */
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
- assert(parange < ARRAY_SIZE(pamax_map));
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
41
- return pamax_map[parange];
42
-}
43
+unsigned int arm_pamax(ARMCPU *cpu);
44
45
/* Return true if extended addresses are enabled.
46
* This is always the case if our translation regime is 64 bit,
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
42
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/mve.decode
49
--- a/target/arm/helper.c
44
+++ b/target/arm/mve.decode
50
+++ b/target/arm/helper.c
45
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
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
}
172
return do_1imm(s, a, fn);
173
}
52
}
174
+
53
#endif /* !CONFIG_USER_ONLY */
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
54
176
+ bool negateshift)
55
+/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
56
+unsigned int arm_pamax(ARMCPU *cpu)
177
+{
57
+{
178
+ TCGv_ptr qd, qm;
58
+ static const unsigned int pamax_map[] = {
179
+ int shift = a->shift;
59
+ [0] = 32,
180
+
60
+ [1] = 36,
181
+ if (!dc_isar_feature(aa32_mve, s) ||
61
+ [2] = 40,
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
62
+ [3] = 42,
183
+ !fn) {
63
+ [4] = 44,
184
+ return false;
64
+ [5] = 48,
185
+ }
65
+ };
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
66
+ unsigned int parange =
187
+ return true;
67
+ FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
188
+ }
189
+
68
+
190
+ /*
69
+ /*
191
+ * When we handle a right shift insn using a left-shift helper
70
+ * id_aa64mmfr0 is a read-only register so values outside of the
192
+ * which permits a negative shift count to indicate a right-shift,
71
+ * supported mappings can be considered an implementation error.
193
+ * we must negate the shift count.
194
+ */
72
+ */
195
+ if (negateshift) {
73
+ assert(parange < ARRAY_SIZE(pamax_map));
196
+ shift = -shift;
74
+ return pamax_map[parange];
197
+ }
198
+
199
+ qd = mve_qreg_ptr(a->qd);
200
+ qm = mve_qreg_ptr(a->qm);
201
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
202
+ tcg_temp_free_ptr(qd);
203
+ tcg_temp_free_ptr(qm);
204
+ mve_update_eci(s);
205
+ return true;
206
+}
75
+}
207
+
76
+
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
77
static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
78
{
210
+ { \
79
if (regime_has_2_ranges(mmu_idx)) {
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
--
80
--
225
2.20.1
81
2.25.1
226
82
227
83
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
Pass down the width of the output address from translation.
4
For now this is still just PAMax, but a subsequent patch will
5
compute the correct value from TCR_ELx.{I}PS.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220301215958.157011-6-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/helper.c | 21 ++++++++++-----------
11
target/arm/translate-a64.c | 86 ++++----------------------------------
13
1 file changed, 10 insertions(+), 11 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/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
17
--- a/target/arm/helper.c
18
+++ b/target/arm/translate.h
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
19
@@ -XXX,XX +XXX,XX @@ do_fault:
20
* VMVN and VBIC (when cmode < 14 && op == 1).
20
* false otherwise.
21
*
21
*/
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
22
static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
23
- * callers must catch this.
23
- int inputsize, int stride)
24
+ * callers must catch this; we return the 64-bit constant value defined
24
+ int inputsize, int stride, int outputsize)
25
+ * for AArch64.
26
*
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
34
{
25
{
35
int rd = extract32(insn, 0, 5);
26
const int grainsize = stride + 3;
36
int cmode = extract32(insn, 12, 4);
27
int startsizecheck;
37
- int cmode_3_1 = extract32(cmode, 1, 3);
28
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
38
- int cmode_0 = extract32(cmode, 0, 1);
39
int o2 = extract32(insn, 11, 1);
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
41
bool is_neg = extract32(insn, 29, 1);
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
43
return;
44
}
29
}
45
30
46
- /* See AdvSIMDExpandImm() in ARM ARM */
31
if (is_aa64) {
47
- switch (cmode_3_1) {
32
- CPUARMState *env = &cpu->env;
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
33
- unsigned int pamax = arm_pamax(cpu);
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
-
34
-
121
- if (cmode_3_1 != 7 && is_neg) {
35
switch (stride) {
122
- imm = ~imm;
36
case 13: /* 64KB Pages. */
123
+ if (cmode == 15 && o2 && !is_neg) {
37
- if (level == 0 || (level == 1 && pamax <= 42)) {
124
+ /* FMOV (vector, immediate) - half-precision */
38
+ if (level == 0 || (level == 1 && outputsize <= 42)) {
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
39
return false;
126
+ /* now duplicate across the lanes */
40
}
127
+ imm = bitfield_replicate(imm, 16);
41
break;
128
+ } else {
42
case 11: /* 16KB Pages. */
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
43
- if (level == 0 || (level == 1 && pamax <= 40)) {
44
+ if (level == 0 || (level == 1 && outputsize <= 40)) {
45
return false;
46
}
47
break;
48
case 9: /* 4KB Pages. */
49
- if (level == 0 && pamax <= 42) {
50
+ if (level == 0 && outputsize <= 42) {
51
return false;
52
}
53
break;
54
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
55
}
56
57
/* Inputsize checks. */
58
- if (inputsize > pamax &&
59
- (arm_el_is_aa64(env, 1) || inputsize > 40)) {
60
+ if (inputsize > outputsize &&
61
+ (arm_el_is_aa64(&cpu->env, 1) || inputsize > 40)) {
62
/* This is CONSTRAINED UNPREDICTABLE and we choose to fault. */
63
return false;
64
}
65
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
66
target_ulong page_size;
67
uint32_t attrs;
68
int32_t stride;
69
- int addrsize, inputsize;
70
+ int addrsize, inputsize, outputsize;
71
TCR *tcr = regime_tcr(env, mmu_idx);
72
int ap, ns, xn, pxn;
73
uint32_t el = regime_el(env, mmu_idx);
74
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
75
76
addrsize = 64 - 8 * param.tbi;
77
inputsize = 64 - param.tsz;
78
+ outputsize = arm_pamax(cpu);
79
} else {
80
param = aa32_va_parameters(env, address, mmu_idx);
81
level = 1;
82
addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
83
inputsize = addrsize - param.tsz;
84
+ outputsize = 40;
130
}
85
}
131
86
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
87
/*
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
134
index XXXXXXX..XXXXXXX 100644
89
135
--- a/target/arm/translate.c
90
/* Check that the starting level is valid. */
136
+++ b/target/arm/translate.c
91
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
92
- inputsize, stride);
138
case 14:
93
+ inputsize, stride, outputsize);
139
if (op) {
94
if (!ok) {
140
/*
95
fault_type = ARMFault_Translation;
141
- * This is the only case where the top and bottom 32 bits
96
goto do_fault;
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
--
97
--
169
2.20.1
98
2.25.1
170
171
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
The macro is a bit more readable than the inlined computation.
11
the implementation to avoid 128-bit arithmetic entirely.
12
4
13
Since the element size here is always 4, we can also drop the
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
parameterization of ESIZE to make the code a little more readable.
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220301215958.157011-7-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.c | 4 ++--
11
1 file changed, 2 insertions(+), 2 deletions(-)
15
12
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
13
diff --git a/target/arm/helper.c b/target/arm/helper.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
14
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/mve_helper.c
15
--- a/target/arm/helper.c
27
+++ b/target/arm/mve_helper.c
16
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
29
*/
18
level = startlevel;
30
31
#include "qemu/osdep.h"
32
-#include "qemu/int128.h"
33
#include "cpu.h"
34
#include "internals.h"
35
#include "vec_internal.h"
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
38
39
/*
40
- * Rounding multiply add long dual accumulate high: we must keep
41
- * a 72-bit internal accumulator value and return the top 64 bits.
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
43
+ * this is implemented with a 72-bit internal accumulator value of which
44
+ * the top 64 bits are returned. We optimize this to avoid having to
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
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
}
19
}
82
20
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
21
- indexmask_grainsize = (1ULL << (stride + 3)) - 1;
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
22
- indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
23
+ indexmask_grainsize = MAKE_64BIT_MASK(0, stride + 3);
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
24
+ indexmask = MAKE_64BIT_MASK(0, inputsize - (stride * (4 - level)));
87
25
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
26
/* Now we can extract the actual base address from the TTBR */
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
27
descaddr = extract64(ttbr, 0, 48);
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
--
28
--
99
2.20.1
29
2.25.1
100
30
101
31
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
This field controls the output (intermediate) physical address size
4
of the translation process. V8 requires to raise an AddressSize
5
fault if the page tables are programmed incorrectly, such that any
6
intermediate descriptor address, or the final translated address,
7
is out of range.
8
9
Add a PS field to ARMVAParameters, and properly compute outputsize
10
in get_phys_addr_lpae. Test the descaddr as extracted from TTBR
11
and from page table entries.
12
13
Restrict descaddrmask so that we won't raise the fault for v7.
14
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20220301215958.157011-8-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
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
---
20
---
9
target/arm/helper-mve.h | 2 ++
21
target/arm/internals.h | 1 +
10
target/arm/mve.decode | 2 ++
22
target/arm/helper.c | 72 ++++++++++++++++++++++++++++++++----------
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
23
2 files changed, 57 insertions(+), 16 deletions(-)
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
13
4 files changed, 72 insertions(+)
14
24
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
25
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
27
--- a/target/arm/internals.h
18
+++ b/target/arm/helper-mve.h
28
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
*/
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
typedef struct ARMVAParameters {
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
unsigned tsz : 8;
33
+ unsigned ps : 3;
34
unsigned select : 1;
35
bool tbi : 1;
36
bool epd : 1;
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
42
}
43
#endif /* !CONFIG_USER_ONLY */
44
45
+/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
46
+static const uint8_t pamax_map[] = {
47
+ [0] = 32,
48
+ [1] = 36,
49
+ [2] = 40,
50
+ [3] = 42,
51
+ [4] = 44,
52
+ [5] = 48,
53
+};
23
+
54
+
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
55
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
56
unsigned int arm_pamax(ARMCPU *cpu)
26
index XXXXXXX..XXXXXXX 100644
57
{
27
--- a/target/arm/mve.decode
58
- static const unsigned int pamax_map[] = {
28
+++ b/target/arm/mve.decode
59
- [0] = 32,
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
60
- [1] = 36,
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
61
- [2] = 40,
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
62
- [3] = 42,
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
63
- [4] = 44,
64
- [5] = 48,
65
- };
66
unsigned int parange =
67
FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
68
69
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
70
{
71
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
72
bool epd, hpd, using16k, using64k, tsz_oob;
73
- int select, tsz, tbi, max_tsz, min_tsz;
74
+ int select, tsz, tbi, max_tsz, min_tsz, ps;
75
76
if (!regime_has_2_ranges(mmu_idx)) {
77
select = 0;
78
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
79
hpd = extract32(tcr, 24, 1);
80
}
81
epd = false;
82
+ ps = extract32(tcr, 16, 3);
83
} else {
84
/*
85
* Bit 55 is always between the two regions, and is canonical for
86
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
87
epd = extract32(tcr, 23, 1);
88
hpd = extract64(tcr, 42, 1);
89
}
90
+ ps = extract64(tcr, 32, 3);
91
}
92
93
if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
94
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
95
96
return (ARMVAParameters) {
97
.tsz = tsz,
98
+ .ps = ps,
99
.select = select,
100
.tbi = tbi,
101
.epd = epd,
102
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
103
104
/* TODO: This code does not support shareability levels. */
105
if (aarch64) {
106
+ int ps;
33
+
107
+
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
108
param = aa64_va_parameters(env, address, mmu_idx,
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
109
access_type != MMU_INST_FETCH);
36
index XXXXXXX..XXXXXXX 100644
110
level = 0;
37
--- a/target/arm/mve_helper.c
111
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
38
+++ b/target/arm/mve_helper.c
112
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
113
addrsize = 64 - 8 * param.tbi;
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
114
inputsize = 64 - param.tsz;
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
115
- outputsize = arm_pamax(cpu);
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
43
+
116
+
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
117
+ /*
45
+ uint32_t shift)
118
+ * Bound PS by PARANGE to find the effective output address size.
46
+{
119
+ * ID_AA64MMFR0 is a read-only register so values outside of the
47
+ uint32_t *d = vd;
120
+ * supported mappings can be considered an implementation error.
48
+ uint16_t mask = mve_element_mask(env);
121
+ */
49
+ unsigned e;
122
+ ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
50
+ uint32_t r;
123
+ ps = MIN(ps, param.ps);
124
+ assert(ps < ARRAY_SIZE(pamax_map));
125
+ outputsize = pamax_map[ps];
126
} else {
127
param = aa32_va_parameters(env, address, mmu_idx);
128
level = 1;
129
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
130
131
/* Now we can extract the actual base address from the TTBR */
132
descaddr = extract64(ttbr, 0, 48);
51
+
133
+
52
+ /*
134
+ /*
53
+ * For each 32-bit element, we shift it left, bringing in the
135
+ * If the base address is out of range, raise AddressSizeFault.
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
136
+ * In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
55
+ * the top become the new rdm, if the predicate mask permits.
137
+ * but we've just cleared the bits above 47, so simplify the test.
56
+ * The final rdm value is returned to update the register.
57
+ * shift == 0 here means "shift by 32 bits".
58
+ */
138
+ */
59
+ if (shift == 0) {
139
+ if (descaddr >> outputsize) {
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
140
+ level = 0;
61
+ r = rdm;
141
+ fault_type = ARMFault_AddressSize;
62
+ if (mask & 1) {
142
+ goto do_fault;
63
+ rdm = d[H4(e)];
64
+ }
65
+ mergemask(&d[H4(e)], r, mask);
66
+ }
67
+ } else {
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
69
+
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
+ }
77
+ }
78
+ mve_advance_vpt(env);
79
+ return rdm;
80
+}
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/translate-mve.c
84
+++ b/target/arm/translate-mve.c
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
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
+ /*
93
+ * Whole Vector Left Shift with Carry. The carry is taken
94
+ * from a general purpose register and written back there.
95
+ * An imm of 0 means "shift by 32".
96
+ */
97
+ TCGv_ptr qd;
98
+ TCGv_i32 rdm;
99
+
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
101
+ return false;
102
+ }
103
+ if (a->rdm == 13 || a->rdm == 15) {
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
105
+ return false;
106
+ }
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
108
+ return true;
109
+ }
143
+ }
110
+
144
+
111
+ qd = mve_qreg_ptr(a->qd);
145
/*
112
+ rdm = load_reg(s, a->rdm);
146
* We rely on this masking to clear the RES0 bits at the bottom of the TTBR
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
147
* and also to mask out CnP (bit 0) which could validly be non-zero.
114
+ store_reg(s, a->rdm, rdm);
148
*/
115
+ tcg_temp_free_ptr(qd);
149
descaddr &= ~indexmask;
116
+ mve_update_eci(s);
150
117
+ return true;
151
- /* The address field in the descriptor goes up to bit 39 for ARMv7
118
+}
152
- * but up to bit 47 for ARMv8, but we use the descaddrmask
153
- * up to bit 39 for AArch32, because we don't need other bits in that case
154
- * to construct next descriptor address (anyway they should be all zeroes).
155
+ /*
156
+ * For AArch32, the address field in the descriptor goes up to bit 39
157
+ * for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0
158
+ * or an AddressSize fault is raised. So for v8 we extract those SBZ
159
+ * bits as part of the address, which will be checked via outputsize.
160
+ * For AArch64, the address field always goes up to bit 47 (with extra
161
+ * bits for FEAT_LPA placed elsewhere). AArch64 implies v8.
162
*/
163
- descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) &
164
- ~indexmask_grainsize;
165
+ if (arm_feature(env, ARM_FEATURE_V8)) {
166
+ descaddrmask = MAKE_64BIT_MASK(0, 48);
167
+ } else {
168
+ descaddrmask = MAKE_64BIT_MASK(0, 40);
169
+ }
170
+ descaddrmask &= ~indexmask_grainsize;
171
172
/* Secure accesses start with the page table in secure memory and
173
* can be downgraded to non-secure at any step. Non-secure accesses
174
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
175
/* Invalid, or the Reserved level 3 encoding */
176
goto do_fault;
177
}
178
+
179
descaddr = descriptor & descaddrmask;
180
+ if (descaddr >> outputsize) {
181
+ fault_type = ARMFault_AddressSize;
182
+ goto do_fault;
183
+ }
184
185
if ((descriptor & 2) && (level < 3)) {
186
/* Table entry. The top five bits are attributes which may
119
--
187
--
120
2.20.1
188
2.25.1
121
189
122
190
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
The original A.a revision of the AArch64 ARM required that we
4
force-extend the addresses in these registers from 49 bits.
5
This language has been loosened via a combination of IMPLEMENTATION
6
DEFINED and CONSTRAINTED UNPREDICTABLE to allow consideration of
7
the entire aligned address.
8
9
This means that we do not have to consider whether or not FEAT_LVA
10
is enabled, and decide from which bit an address might need to be
11
extended.
12
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220301215958.157011-9-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-10-peter.maydell@linaro.org
9
---
17
---
10
target/arm/helper-mve.h | 9 +++++++
18
target/arm/helper.c | 32 ++++++++++++++++++++++++--------
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
19
1 file changed, 24 insertions(+), 8 deletions(-)
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
15
20
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
23
--- a/target/arm/helper.c
19
+++ b/target/arm/helper-mve.h
24
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
@@ -XXX,XX +XXX,XX @@ static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
ARMCPU *cpu = env_archcpu(env);
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
int i = ri->crm;
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
24
+
29
- /* Bits [63:49] are hardwired to the value of bit [48]; that is, the
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
- * register reads and behaves as if values written are sign extended.
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+ /*
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
* Bits [1:0] are RES0.
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+ *
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+ * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+ * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+ * they contain the value written. It is CONSTRAINED UNPREDICTABLE
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+ * whether the RESS bits are ignored when comparing an address.
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
38
+ *
34
index XXXXXXX..XXXXXXX 100644
39
+ * Therefore we are allowed to compare the entire register, which lets
35
--- a/target/arm/mve.decode
40
+ * us avoid considering whether or not FEAT_LVA is actually enabled.
36
+++ b/target/arm/mve.decode
41
*/
37
@@ -XXX,XX +XXX,XX @@
42
- value = sextract64(value, 0, 49) & ~3ULL;
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
43
+ value &= ~3ULL;
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
44
40
45
raw_write(env, ri, value);
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
46
hw_watchpoint_update(cpu, i);
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
47
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
43
+# VSHLL encoding T2 where shift == esize
48
case 0: /* unlinked address match */
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
49
case 1: /* linked address match */
45
+ qd=%qd qm=%qm size=0 shift=8
50
{
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
51
- /* Bits [63:49] are hardwired to the value of bit [48]; that is,
47
+ qd=%qd qm=%qm size=1 shift=16
52
- * we behave as if the register was sign extended. Bits [1:0] are
48
+
53
- * RES0. The BAS field is used to allow setting breakpoints on 16
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
54
- * bit wide instructions; it is CONSTRAINED UNPREDICTABLE whether
50
%rshift_i5 16:5 !function=rsub_32
55
+ /*
51
%rshift_i4 16:4 !function=rsub_16
56
+ * Bits [1:0] are RES0.
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
57
+ *
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
58
+ * It is IMPLEMENTATION DEFINED whether bits [63:49]
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
59
+ * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
55
60
+ * of the VA field ([48] or [52] for FEAT_LVA), or whether the
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
61
+ * value is read as written. It is CONSTRAINED UNPREDICTABLE
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
62
+ * whether the RESS bits are ignored when comparing an address.
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
63
+ * Therefore we are allowed to compare the entire register, which
59
+# overlaps what would be size=0b11 VMULH/VRMULH
64
+ * lets us avoid considering whether FEAT_LVA is actually enabled.
60
+{
65
+ *
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
66
+ * The BAS field is used to allow setting breakpoints on 16-bit
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
67
+ * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
63
68
* a bp will fire if the addresses covered by the bp and the addresses
64
-VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
69
* covered by the insn overlap but the insn doesn't start at the
65
-VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
70
* start of the bp address range. We choose to require the insn and
66
+ VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
71
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
67
+}
72
* See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
68
+
73
*/
69
+{
74
int bas = extract64(bcr, 5, 4);
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
75
- addr = sextract64(bvr, 0, 49) & ~3ULL;
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
76
+ addr = bvr & ~3ULL;
72
+
77
if (bas == 0) {
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
78
return;
74
+}
79
}
75
+
76
+{
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
79
+
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
111
--- a/target/arm/mve_helper.c
112
+++ b/target/arm/mve_helper.c
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
117
+
118
+/*
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
121
+ * the input, and LESIZE, LTYPE for the output.
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
123
+ * because the long shift is strictly left-only.
124
+ */
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
127
+ void *vm, uint32_t shift) \
128
+ { \
129
+ LTYPE *d = vd; \
130
+ TYPE *m = vm; \
131
+ uint16_t mask = mve_element_mask(env); \
132
+ unsigned le; \
133
+ assert(shift <= 16); \
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
137
+ } \
138
+ mve_advance_vpt(env); \
139
+ }
140
+
141
+#define DO_VSHLL_ALL(OP, TOP) \
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
143
+ DO_VSHLL(OP##ub, TOP, 1, uint8_t, 2, uint16_t) \
144
+ DO_VSHLL(OP##sh, TOP, 2, int16_t, 4, int32_t) \
145
+ DO_VSHLL(OP##uh, TOP, 2, uint16_t, 4, uint32_t) \
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
--
80
--
173
2.20.1
81
2.25.1
174
175
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
This feature is relatively small, as it applies only to
4
64k pages and thus requires no additional changes to the
5
table descriptor walking algorithm, only a change to the
6
minimum TSZ (which is the inverse of the maximum virtual
7
address space size).
5
8
9
Note that this feature widens VBAR_ELx, but we already
10
treat the register as being 64 bits wide.
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20220301215958.157011-10-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
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
---
16
---
10
target/arm/helper-mve.h | 30 +++++++++++
17
docs/system/arm/emulation.rst | 1 +
11
target/arm/mve.decode | 28 ++++++++++
18
target/arm/cpu-param.h | 2 +-
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
19
target/arm/cpu.h | 5 +++++
13
target/arm/translate-mve.c | 12 +++++
20
target/arm/cpu64.c | 1 +
14
4 files changed, 174 insertions(+)
21
target/arm/helper.c | 9 ++++++++-
22
5 files changed, 16 insertions(+), 2 deletions(-)
15
23
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
24
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
26
--- a/docs/system/arm/emulation.rst
19
+++ b/target/arm/helper-mve.h
27
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
- FEAT_LRCPC (Load-acquire RCpc instructions)
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
- FEAT_LSE (Large System Extensions)
24
+
32
+- FEAT_LVA (Large Virtual Address space)
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
- FEAT_MTE (Memory Tagging Extension)
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
- FEAT_MTE2 (Memory Tagging Extension)
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
29
+
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
37
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/mve.decode
38
--- a/target/arm/cpu-param.h
57
+++ b/target/arm/mve.decode
39
+++ b/target/arm/cpu-param.h
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
40
@@ -XXX,XX +XXX,XX @@
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
41
#ifdef TARGET_AARCH64
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
42
# define TARGET_LONG_BITS 64
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
43
# define TARGET_PHYS_ADDR_SPACE_BITS 48
62
+
44
-# define TARGET_VIRT_ADDR_SPACE_BITS 48
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
45
+# define TARGET_VIRT_ADDR_SPACE_BITS 52
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
46
#else
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
47
# define TARGET_LONG_BITS 32
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
48
# define TARGET_PHYS_ADDR_SPACE_BITS 40
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
49
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
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
50
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/mve_helper.c
51
--- a/target/arm/cpu.h
93
+++ b/target/arm/mve_helper.c
52
+++ b/target/arm/cpu.h
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
53
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
95
}
54
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
96
}
55
}
97
56
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
57
+static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
99
+{
58
+{
100
+ if (likely(sh < 64)) {
59
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
102
+ } else {
103
+ /* Rounding the sign bit always produces 0. */
104
+ return 0;
105
+ }
106
+}
60
+}
107
+
61
+
108
DO_VSHRN_ALL(vshrn, DO_SHR)
62
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
109
DO_VSHRN_ALL(vrshrn, do_urshr)
63
{
64
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
65
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/cpu64.c
68
+++ b/target/arm/cpu64.c
69
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
70
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
71
t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
72
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */
73
+ t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
74
cpu->isar.id_aa64mmfr2 = t;
75
76
t = cpu->isar.id_aa64zfr0;
77
diff --git a/target/arm/helper.c b/target/arm/helper.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/helper.c
80
+++ b/target/arm/helper.c
81
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
82
} else {
83
max_tsz = 39;
84
}
85
- min_tsz = 16; /* TODO: ARMv8.2-LVA */
110
+
86
+
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
87
+ min_tsz = 16;
112
+ bool *satp)
88
+ if (using64k) {
113
+{
89
+ if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
114
+ if (val > max) {
90
+ min_tsz = 12;
115
+ *satp = true;
91
+ }
116
+ return max;
117
+ } else if (val < min) {
118
+ *satp = true;
119
+ return min;
120
+ } else {
121
+ return val;
122
+ }
92
+ }
123
+}
93
+ /* TODO: FEAT_LPA2 */
124
+
94
125
+/* Saturating narrowing right shifts */
95
if (tsz > max_tsz) {
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
96
tsz = max_tsz;
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
--
97
--
225
2.20.1
98
2.25.1
226
227
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
This feature widens physical addresses (and intermediate physical
4
addresses for 2-stage translation) from 48 to 52 bits, when using
5
64k pages. The only thing left at this point is to handle the
6
extra bits in the TTBR and in the table descriptors.
7
8
Note that PAR_EL1 and HPFAR_EL2 are nominally extended, but we don't
9
mask out the high bits when writing to those registers, so no changes
10
are required there.
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20220301215958.157011-11-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
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
---
16
---
10
target/arm/helper-mve.h | 4 +++
17
docs/system/arm/emulation.rst | 1 +
11
target/arm/mve.decode | 17 +++++++++++++
18
target/arm/cpu-param.h | 2 +-
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
19
target/arm/cpu64.c | 2 +-
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
20
target/arm/helper.c | 19 ++++++++++++++++---
14
4 files changed, 95 insertions(+)
21
4 files changed, 19 insertions(+), 5 deletions(-)
15
22
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
23
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
25
--- a/docs/system/arm/emulation.rst
19
+++ b/target/arm/helper-mve.h
26
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
27
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
28
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
29
- FEAT_JSCVT (JavaScript conversion instructions)
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
30
- FEAT_LOR (Limited ordering regions)
31
+- FEAT_LPA (Large Physical Address space)
32
- FEAT_LRCPC (Load-acquire RCpc instructions)
33
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
34
- FEAT_LSE (Large System Extensions)
35
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu-param.h
38
+++ b/target/arm/cpu-param.h
39
@@ -XXX,XX +XXX,XX @@
40
41
#ifdef TARGET_AARCH64
42
# define TARGET_LONG_BITS 64
43
-# define TARGET_PHYS_ADDR_SPACE_BITS 48
44
+# define TARGET_PHYS_ADDR_SPACE_BITS 52
45
# define TARGET_VIRT_ADDR_SPACE_BITS 52
46
#else
47
# define TARGET_LONG_BITS 32
48
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/cpu64.c
51
+++ b/target/arm/cpu64.c
52
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
53
cpu->isar.id_aa64pfr1 = t;
54
55
t = cpu->isar.id_aa64mmfr0;
56
- t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits */
57
+ t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
58
cpu->isar.id_aa64mmfr0 = t;
59
60
t = cpu->isar.id_aa64mmfr1;
61
diff --git a/target/arm/helper.c b/target/arm/helper.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/helper.c
64
+++ b/target/arm/helper.c
65
@@ -XXX,XX +XXX,XX @@ static const uint8_t pamax_map[] = {
66
[3] = 42,
67
[4] = 44,
68
[5] = 48,
69
+ [6] = 52,
70
};
71
72
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
74
descaddr = extract64(ttbr, 0, 48);
75
76
/*
77
- * If the base address is out of range, raise AddressSizeFault.
78
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [5:2] of TTBR.
79
+ *
80
+ * Otherwise, if the base address is out of range, raise AddressSizeFault.
81
* In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
82
* but we've just cleared the bits above 47, so simplify the test.
83
*/
84
- if (descaddr >> outputsize) {
85
+ if (outputsize > 48) {
86
+ descaddr |= extract64(ttbr, 2, 4) << 48;
87
+ } else if (descaddr >> outputsize) {
88
level = 0;
89
fault_type = ARMFault_AddressSize;
90
goto do_fault;
91
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
92
}
93
94
descaddr = descriptor & descaddrmask;
95
- if (descaddr >> outputsize) {
24
+
96
+
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
97
+ /*
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
98
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
99
+ * of descriptor. Otherwise, if descaddr is out of range, raise
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
100
+ * AddressSizeFault.
29
index XXXXXXX..XXXXXXX 100644
101
+ */
30
--- a/target/arm/mve.decode
102
+ if (outputsize > 48) {
31
+++ b/target/arm/mve.decode
103
+ descaddr |= extract64(descriptor, 12, 4) << 48;
32
@@ -XXX,XX +XXX,XX @@
104
+ } else if (descaddr >> outputsize) {
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
105
fault_type = ARMFault_AddressSize;
34
%size_28 28:1 !function=plus_1
106
goto do_fault;
35
107
}
36
+# 1imm format immediate
37
+%imm_28_16_0 28:1 16:3 0:4
38
+
39
&vldr_vstr rn qd imm p a w size l u
40
&1op qd qm size
41
&2op qd qm qn size
42
&2scalar qd qn rm size
43
+&1imm qd imm cmode op
44
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
46
# Note that both Rn and Qd are 3 bits only (no D bit)
47
@@ -XXX,XX +XXX,XX @@
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
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
+{
125
+ TCGv_ptr qd;
126
+ uint64_t imm;
127
+
128
+ if (!dc_isar_feature(aa32_mve, s) ||
129
+ !mve_check_qreg_bank(s, a->qd) ||
130
+ !fn) {
131
+ return false;
132
+ }
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
134
+ return true;
135
+ }
136
+
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
138
+
139
+ qd = mve_qreg_ptr(a->qd);
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
141
+ tcg_temp_free_ptr(qd);
142
+ mve_update_eci(s);
143
+ return true;
144
+}
145
+
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
147
+{
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
149
+ MVEGenOneOpImmFn *fn;
150
+
151
+ if ((a->cmode & 1) && a->cmode < 12) {
152
+ if (a->op) {
153
+ /*
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
155
+ * so the VBIC becomes a logical AND operation.
156
+ */
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
+}
171
--
108
--
172
2.20.1
109
2.25.1
173
174
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
With FEAT_LPA2, rather than introducing translation level 4,
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
4
we introduce level -1, below the current level 0. Extend
5
assert due to fpst->default_nan_mode being set.
5
arm_fi_to_lfsc to handle these faults.
6
6
7
To avoid this, we check to see what NaN mode we're running in before we call
7
Assert that this new translation level does not leak into
8
floatxx_silence_nan().
8
fault types for which it is not defined, which allows some
9
masking of fi->level to be removed.
9
10
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20220301215958.157011-12-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
15
---
16
target/arm/helper-a64.c | 12 +++++++++---
16
target/arm/internals.h | 35 +++++++++++++++++++++++++++++------
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
17
1 file changed, 29 insertions(+), 6 deletions(-)
18
2 files changed, 27 insertions(+), 9 deletions(-)
19
18
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
21
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper-a64.c
21
--- a/target/arm/internals.h
23
+++ b/target/arm/helper-a64.c
22
+++ b/target/arm/internals.h
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
23
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
25
float16 nan = a;
24
case ARMFault_None:
26
if (float16_is_signaling_nan(a, fpst)) {
25
return 0;
27
float_raise(float_flag_invalid, fpst);
26
case ARMFault_AddressSize:
28
- nan = float16_silence_nan(a, fpst);
27
- fsc = fi->level & 3;
29
+ if (!fpst->default_nan_mode) {
28
+ assert(fi->level >= -1 && fi->level <= 3);
30
+ nan = float16_silence_nan(a, fpst);
29
+ if (fi->level < 0) {
31
+ }
30
+ fsc = 0b101001;
32
}
31
+ } else {
33
if (fpst->default_nan_mode) {
32
+ fsc = fi->level;
34
nan = float16_default_nan(fpst);
33
+ }
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
34
break;
36
float32 nan = a;
35
case ARMFault_AccessFlag:
37
if (float32_is_signaling_nan(a, fpst)) {
36
- fsc = (fi->level & 3) | (0x2 << 2);
38
float_raise(float_flag_invalid, fpst);
37
+ assert(fi->level >= 0 && fi->level <= 3);
39
- nan = float32_silence_nan(a, fpst);
38
+ fsc = 0b001000 | fi->level;
40
+ if (!fpst->default_nan_mode) {
39
break;
41
+ nan = float32_silence_nan(a, fpst);
40
case ARMFault_Permission:
42
+ }
41
- fsc = (fi->level & 3) | (0x3 << 2);
43
}
42
+ assert(fi->level >= 0 && fi->level <= 3);
44
if (fpst->default_nan_mode) {
43
+ fsc = 0b001100 | fi->level;
45
nan = float32_default_nan(fpst);
44
break;
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
45
case ARMFault_Translation:
47
float64 nan = a;
46
- fsc = (fi->level & 3) | (0x1 << 2);
48
if (float64_is_signaling_nan(a, fpst)) {
47
+ assert(fi->level >= -1 && fi->level <= 3);
49
float_raise(float_flag_invalid, fpst);
48
+ if (fi->level < 0) {
50
- nan = float64_silence_nan(a, fpst);
49
+ fsc = 0b101011;
51
+ if (!fpst->default_nan_mode) {
50
+ } else {
52
+ nan = float64_silence_nan(a, fpst);
51
+ fsc = 0b000100 | fi->level;
53
+ }
52
+ }
54
}
53
break;
55
if (fpst->default_nan_mode) {
54
case ARMFault_SyncExternal:
56
nan = float64_default_nan(fpst);
55
fsc = 0x10 | (fi->ea << 12);
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
56
break;
58
index XXXXXXX..XXXXXXX 100644
57
case ARMFault_SyncExternalOnWalk:
59
--- a/target/arm/vfp_helper.c
58
- fsc = (fi->level & 3) | (0x5 << 2) | (fi->ea << 12);
60
+++ b/target/arm/vfp_helper.c
59
+ assert(fi->level >= -1 && fi->level <= 3);
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
60
+ if (fi->level < 0) {
62
float16 nan = f16;
61
+ fsc = 0b010011;
63
if (float16_is_signaling_nan(f16, fpst)) {
62
+ } else {
64
float_raise(float_flag_invalid, fpst);
63
+ fsc = 0b010100 | fi->level;
65
- nan = float16_silence_nan(f16, fpst);
64
+ }
66
+ if (!fpst->default_nan_mode) {
65
+ fsc |= fi->ea << 12;
67
+ nan = float16_silence_nan(f16, fpst);
66
break;
68
+ }
67
case ARMFault_SyncParity:
69
}
68
fsc = 0x18;
70
if (fpst->default_nan_mode) {
69
break;
71
nan = float16_default_nan(fpst);
70
case ARMFault_SyncParityOnWalk:
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
71
- fsc = (fi->level & 3) | (0x7 << 2);
73
float32 nan = f32;
72
+ assert(fi->level >= -1 && fi->level <= 3);
74
if (float32_is_signaling_nan(f32, fpst)) {
73
+ if (fi->level < 0) {
75
float_raise(float_flag_invalid, fpst);
74
+ fsc = 0b011011;
76
- nan = float32_silence_nan(f32, fpst);
75
+ } else {
77
+ if (!fpst->default_nan_mode) {
76
+ fsc = 0b011100 | fi->level;
78
+ nan = float32_silence_nan(f32, fpst);
77
+ }
79
+ }
78
break;
80
}
79
case ARMFault_AsyncParity:
81
if (fpst->default_nan_mode) {
80
fsc = 0x19;
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
--
81
--
128
2.20.1
82
2.25.1
129
130
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
Merge tlbi_aa64_range_get_length and tlbi_aa64_range_get_base,
4
function has to be used for machine shutdown. Otherwise we cause
4
returning a structure containing both results. Pass in the
5
a reset with a bogus "cause" value, when we intended a shutdown.
5
ARMMMUIdx, rather than the digested two_ranges boolean.
6
6
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
7
This is in preparation for FEAT_LPA2, where the interpretation
8
of 'value' depends on the effective value of DS for the regime.
9
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
[PMM: tweaked commit message]
12
Message-id: 20220301215958.157011-13-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
14
---
13
hw/gpio/gpio_pwr.c | 2 +-
15
target/arm/helper.c | 58 +++++++++++++++++++--------------------------
14
1 file changed, 1 insertion(+), 1 deletion(-)
16
1 file changed, 24 insertions(+), 34 deletions(-)
15
17
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/gpio/gpio_pwr.c
20
--- a/target/arm/helper.c
19
+++ b/hw/gpio/gpio_pwr.c
21
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
22
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
23
}
24
25
#ifdef TARGET_AARCH64
26
-static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
27
- uint64_t value)
28
-{
29
- unsigned int page_shift;
30
- unsigned int page_size_granule;
31
- uint64_t num;
32
- uint64_t scale;
33
- uint64_t exponent;
34
+typedef struct {
35
+ uint64_t base;
36
uint64_t length;
37
+} TLBIRange;
38
+
39
+static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
40
+ uint64_t value)
41
+{
42
+ unsigned int page_size_granule, page_shift, num, scale, exponent;
43
+ TLBIRange ret = { };
44
45
- num = extract64(value, 39, 5);
46
- scale = extract64(value, 44, 2);
47
page_size_granule = extract64(value, 46, 2);
48
49
if (page_size_granule == 0) {
50
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
51
page_size_granule);
52
- return 0;
53
+ return ret;
54
}
55
56
page_shift = (page_size_granule - 1) * 2 + 12;
57
-
58
+ num = extract64(value, 39, 5);
59
+ scale = extract64(value, 44, 2);
60
exponent = (5 * scale) + 1;
61
- length = (num + 1) << (exponent + page_shift);
62
63
- return length;
64
-}
65
+ ret.length = (num + 1) << (exponent + page_shift);
66
67
-static uint64_t tlbi_aa64_range_get_base(CPUARMState *env, uint64_t value,
68
- bool two_ranges)
69
-{
70
- /* TODO: ARMv8.7 FEAT_LPA2 */
71
- uint64_t pageaddr;
72
-
73
- if (two_ranges) {
74
- pageaddr = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
75
+ if (regime_has_2_ranges(mmuidx)) {
76
+ ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
77
} else {
78
- pageaddr = extract64(value, 0, 37) << TARGET_PAGE_BITS;
79
+ ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
80
}
81
82
- return pageaddr;
83
+ return ret;
84
}
85
86
static void do_rvae_write(CPUARMState *env, uint64_t value,
87
int idxmap, bool synced)
22
{
88
{
23
if (level) {
89
ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
90
- bool two_ranges = regime_has_2_ranges(one_idx);
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
91
- uint64_t baseaddr, length;
92
+ TLBIRange range;
93
int bits;
94
95
- baseaddr = tlbi_aa64_range_get_base(env, value, two_ranges);
96
- length = tlbi_aa64_range_get_length(env, value);
97
- bits = tlbbits_for_regime(env, one_idx, baseaddr);
98
+ range = tlbi_aa64_get_range(env, one_idx, value);
99
+ bits = tlbbits_for_regime(env, one_idx, range.base);
100
101
if (synced) {
102
tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env),
103
- baseaddr,
104
- length,
105
+ range.base,
106
+ range.length,
107
idxmap,
108
bits);
109
} else {
110
- tlb_flush_range_by_mmuidx(env_cpu(env), baseaddr,
111
- length, idxmap, bits);
112
+ tlb_flush_range_by_mmuidx(env_cpu(env), range.base,
113
+ range.length, idxmap, bits);
26
}
114
}
27
}
115
}
28
116
29
--
117
--
30
2.20.1
118
2.25.1
31
32
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
The shift of the BaseADDR field depends on the translation
4
granule in use.
4
5
5
Signed-off-by: Patrick Venture <venture@google.com>
6
Fixes: 84940ed8255 ("target/arm: Add support for FEAT_TLBIRANGE")
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Reported-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20210615192848.1065297-3-venture@google.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
[PMM: fixed underline Sphinx warning]
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220301215958.157011-14-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
docs/system/arm/nuvoton.rst | 5 +++--
13
target/arm/helper.c | 5 +++--
12
1 file changed, 3 insertions(+), 2 deletions(-)
14
1 file changed, 3 insertions(+), 2 deletions(-)
13
15
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/nuvoton.rst
18
--- a/target/arm/helper.c
17
+++ b/docs/system/arm/nuvoton.rst
19
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
21
ret.length = (num + 1) << (exponent + page_shift);
20
-=====================================================
22
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
23
if (regime_has_2_ranges(mmuidx)) {
22
+================================================================
24
- ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
23
25
+ ret.base = sextract64(value, 0, 37);
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
26
} else {
25
designed to be used as Baseboard Management Controllers (BMCs) in various
27
- ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
28
+ ret.base = extract64(value, 0, 37);
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
29
}
28
Hyperscale applications. The following machines are based on this chip :
30
+ ret.base <<= page_shift;
29
31
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
32
return ret;
31
- ``quanta-gsj`` Quanta GSJ server BMC
33
}
32
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
34
--
34
--
35
2.20.1
35
2.25.1
36
37
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
For FEAT_LPA2, we will need other ARMVAParameters, which themselves
4
to test the power management model:
4
depend on the translation granule in use. We might as well validate
5
that the given TG matches; the architecture "does not require that
6
the instruction invalidates any entries" if this is not true.
5
7
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
9
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
10
Message-id: 20220301215958.157011-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>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
49
---
12
---
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
13
target/arm/helper.c | 10 +++++++---
51
1 file changed, 43 insertions(+)
14
1 file changed, 7 insertions(+), 3 deletions(-)
52
15
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
54
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
55
--- a/tests/acceptance/boot_linux_console.py
18
--- a/target/arm/helper.c
56
+++ b/tests/acceptance/boot_linux_console.py
19
+++ b/target/arm/helper.c
57
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
58
from avocado import skip
21
uint64_t value)
59
from avocado import skipUnless
22
{
60
from avocado_qemu import Test
23
unsigned int page_size_granule, page_shift, num, scale, exponent;
61
+from avocado_qemu import exec_command
24
+ /* Extract one bit to represent the va selector in use. */
62
from avocado_qemu import exec_command_and_wait_for_pattern
25
+ uint64_t select = sextract64(value, 36, 1);
63
from avocado_qemu import interrupt_interactive_console_until_pattern
26
+ ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
64
from avocado_qemu import wait_for_console_pattern
27
TLBIRange ret = { };
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
28
66
"""
29
page_size_granule = extract64(value, 46, 2);
67
self.do_test_arm_raspi2(0)
30
68
31
- if (page_size_granule == 0) {
69
+ def test_arm_raspi2_initrd(self):
32
- qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
70
+ """
33
+ /* The granule encoded in value must match the granule in use. */
71
+ :avocado: tags=arch:arm
34
+ if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) {
72
+ :avocado: tags=machine:raspi2
35
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
73
+ """
36
page_size_granule);
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
37
return ret;
75
+ 'pool/main/r/raspberrypi-firmware/'
38
}
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
39
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
40
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
41
ret.length = (num + 1) << (exponent + page_shift);
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
42
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
43
- if (regime_has_2_ranges(mmuidx)) {
81
+
44
+ if (param.select) {
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
45
ret.base = sextract64(value, 0, 37);
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
46
} else {
84
+ 'arm/rootfs-armv7a.cpio.gz')
47
ret.base = extract64(value, 0, 37);
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
89
+
90
+ self.vm.set_console()
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
93
+ 'panic=-1 noreboot ' +
94
+ 'dwc_otg.fiq_fsm_enable=0')
95
+ self.vm.add_args('-kernel', kernel_path,
96
+ '-dtb', dtb_path,
97
+ '-initrd', initrd_path,
98
+ '-append', kernel_command_line,
99
+ '-no-reboot')
100
+ self.vm.launch()
101
+ self.wait_for_console_pattern('Boot successful.')
102
+
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
104
+ 'BCM2835')
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
106
+ '/soc/cprman@7e101000')
107
+ exec_command(self, 'halt')
108
+ # Wait for VM to shut down gracefully
109
+ self.vm.wait()
110
+
111
def test_arm_exynos4210_initrd(self):
112
"""
113
:avocado: tags=arch:arm
114
--
48
--
115
2.20.1
49
2.25.1
116
117
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
We support 16k pages, but do not advertize that in ID_AA64MMFR0.
4
5
The value 0 in the TGRAN*_2 fields indicates that stage2 lookups defer
6
to the same support as stage1 lookups. This setting is deprecated, so
7
indicate support for all stage2 page sizes directly.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20220301215958.157011-16-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/cpu64.c | 4 ++++
15
1 file changed, 4 insertions(+)
16
17
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu64.c
20
+++ b/target/arm/cpu64.c
21
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
22
23
t = cpu->isar.id_aa64mmfr0;
24
t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
25
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */
26
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */
27
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
28
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
29
cpu->isar.id_aa64mmfr0 = t;
30
31
t = cpu->isar.id_aa64mmfr1;
32
--
33
2.25.1
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
2
3
which perform left shifts but allow negative shift counts to indicate
3
This feature widens physical addresses (and intermediate physical
4
right shifts.
4
addresses for 2-stage translation) from 48 to 52 bits, when using
5
5
4k or 16k pages.
6
7
This introduces the DS bit to TCR_ELx, which is RES0 unless the
8
page size is enabled and supports LPA2, resulting in the effective
9
value of DS for a given table walk. The DS bit changes the format
10
of the page table descriptor slightly, moving the PS field out to
11
TCR so that all pages have the same sharability and repurposing
12
those bits of the page table descriptor for the highest bits of
13
the output address.
14
15
Do not yet enable FEAT_LPA2; we need extra plumbing to avoid
16
tickling an old kernel bug.
17
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20220301215958.157011-17-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
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
---
22
---
10
target/arm/helper-mve.h | 12 ++++++++++++
23
docs/system/arm/emulation.rst | 1 +
11
target/arm/translate.h | 20 ++++++++++++++++++++
24
target/arm/cpu.h | 22 ++++++++
12
target/arm/mve.decode | 28 ++++++++++++++++++++++++++++
25
target/arm/internals.h | 2 +
13
target/arm/mve_helper.c | 7 +++++++
26
target/arm/helper.c | 102 +++++++++++++++++++++++++++++-----
14
target/arm/translate-mve.c | 5 +++++
27
4 files changed, 112 insertions(+), 15 deletions(-)
15
target/arm/translate-neon.c | 18 ------------------
28
16
6 files changed, 72 insertions(+), 18 deletions(-)
29
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
19
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-mve.h
31
--- a/docs/system/arm/emulation.rst
21
+++ b/target/arm/helper-mve.h
32
+++ b/docs/system/arm/emulation.rst
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
33
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
34
- FEAT_JSCVT (JavaScript conversion instructions)
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
35
- FEAT_LOR (Limited ordering regions)
25
36
- FEAT_LPA (Large Physical Address space)
26
+DEF_HELPER_FLAGS_4(mve_vshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+- FEAT_LPA2 (Large Physical and virtual Address space v2)
27
+DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
- FEAT_LRCPC (Load-acquire RCpc instructions)
28
+DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
29
+
40
- FEAT_LSE (Large System Extensions)
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+
42
+DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
46
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate.h
43
--- a/target/arm/cpu.h
48
+++ b/target/arm/translate.h
44
+++ b/target/arm/cpu.h
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
45
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
50
return x * 2 + 1;
46
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0;
51
}
47
}
52
48
53
+static inline int rsub_64(DisasContext *s, int x)
49
+static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
54
+{
50
+{
55
+ return 64 - x;
51
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
56
+}
52
+}
57
+
53
+
58
+static inline int rsub_32(DisasContext *s, int x)
54
+static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
59
+{
55
+{
60
+ return 32 - x;
56
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
57
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
61
+}
58
+}
62
+
59
+
63
+static inline int rsub_16(DisasContext *s, int x)
60
+static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
64
+{
61
+{
65
+ return 16 - x;
62
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
66
+}
63
+}
67
+
64
+
68
+static inline int rsub_8(DisasContext *s, int x)
65
+static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
69
+{
66
+{
70
+ return 8 - x;
67
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
68
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
71
+}
69
+}
72
+
70
+
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
71
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
74
{
72
{
75
return (dc->features & (1ULL << feature)) != 0;
73
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
74
diff --git a/target/arm/internals.h b/target/arm/internals.h
77
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/mve.decode
76
--- a/target/arm/internals.h
79
+++ b/target/arm/mve.decode
77
+++ b/target/arm/internals.h
80
@@ -XXX,XX +XXX,XX @@
78
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
79
typedef struct ARMVAParameters {
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
80
unsigned tsz : 8;
83
81
unsigned ps : 3;
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
82
+ unsigned sh : 2;
85
+%rshift_i5 16:5 !function=rsub_32
83
unsigned select : 1;
86
+%rshift_i4 16:4 !function=rsub_16
84
bool tbi : 1;
87
+%rshift_i3 16:3 !function=rsub_8
85
bool epd : 1;
88
+
86
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
87
bool using16k : 1;
90
+ size=0 shift=%rshift_i3
88
bool using64k : 1;
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
89
bool tsz_oob : 1; /* tsz has been clamped to legal range */
92
+ size=1 shift=%rshift_i4
90
+ bool ds : 1;
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
91
} ARMVAParameters;
94
+ size=2 shift=%rshift_i5
92
95
+
93
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
96
# Vector loads and stores
94
diff --git a/target/arm/helper.c b/target/arm/helper.c
97
98
# Widening loads and narrowing stores:
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
103
+
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
107
+
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
110
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
111
+
112
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
113
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
114
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
115
+
116
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
117
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
118
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
119
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
120
index XXXXXXX..XXXXXXX 100644
95
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/mve_helper.c
96
--- a/target/arm/helper.c
122
+++ b/target/arm/mve_helper.c
97
+++ b/target/arm/helper.c
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
98
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
99
} else {
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
100
ret.base = extract64(value, 0, 37);
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
101
}
127
+#define DO_2SHIFT_S(OP, FN) \
102
+ if (param.ds) {
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
103
+ /*
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
104
+ * With DS=1, BaseADDR is always shifted 16 so that it is able
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
105
+ * to address all 52 va bits. The input address is perforce
131
106
+ * aligned on a 64k boundary regardless of translation granule.
132
#define DO_2SHIFT_SAT_U(OP, FN) \
107
+ */
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
108
+ page_shift = 16;
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
109
+ }
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
110
ret.base <<= page_shift;
136
111
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
112
return ret;
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
113
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
114
const int grainsize = stride + 3;
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
115
int startsizecheck;
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
116
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
117
- /* Negative levels are never allowed. */
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
118
- if (level < 0) {
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
119
+ /*
145
index XXXXXXX..XXXXXXX 100644
120
+ * Negative levels are usually not allowed...
146
--- a/target/arm/translate-mve.c
121
+ * Except for FEAT_LPA2, 4k page table, 52-bit address space, which
147
+++ b/target/arm/translate-mve.c
122
+ * begins with level -1. Note that previous feature tests will have
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
123
+ * eliminated this combination if it is not enabled.
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
124
+ */
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
125
+ if (level < (inputsize == 52 && stride == 9 ? -1 : 0)) {
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
126
return false;
152
+/* These right shifts use a left-shift helper with negated shift count */
127
}
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
128
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
129
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
130
ARMMMUIdx mmu_idx, bool data)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
131
{
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
132
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
158
index XXXXXXX..XXXXXXX 100644
133
- bool epd, hpd, using16k, using64k, tsz_oob;
159
--- a/target/arm/translate-neon.c
134
- int select, tsz, tbi, max_tsz, min_tsz, ps;
160
+++ b/target/arm/translate-neon.c
135
+ bool epd, hpd, using16k, using64k, tsz_oob, ds;
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
136
+ int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
162
return x + 1;
137
+ ARMCPU *cpu = env_archcpu(env);
138
139
if (!regime_has_2_ranges(mmu_idx)) {
140
select = 0;
141
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
142
hpd = extract32(tcr, 24, 1);
143
}
144
epd = false;
145
+ sh = extract32(tcr, 12, 2);
146
ps = extract32(tcr, 16, 3);
147
+ ds = extract64(tcr, 32, 1);
148
} else {
149
/*
150
* Bit 55 is always between the two regions, and is canonical for
151
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
152
if (!select) {
153
tsz = extract32(tcr, 0, 6);
154
epd = extract32(tcr, 7, 1);
155
+ sh = extract32(tcr, 12, 2);
156
using64k = extract32(tcr, 14, 1);
157
using16k = extract32(tcr, 15, 1);
158
hpd = extract64(tcr, 41, 1);
159
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
160
using64k = tg == 3;
161
tsz = extract32(tcr, 16, 6);
162
epd = extract32(tcr, 23, 1);
163
+ sh = extract32(tcr, 28, 2);
164
hpd = extract64(tcr, 42, 1);
165
}
166
ps = extract64(tcr, 32, 3);
167
+ ds = extract64(tcr, 59, 1);
168
}
169
170
- if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
171
+ if (cpu_isar_feature(aa64_st, cpu)) {
172
max_tsz = 48 - using64k;
173
} else {
174
max_tsz = 39;
175
}
176
177
+ /*
178
+ * DS is RES0 unless FEAT_LPA2 is supported for the given page size;
179
+ * adjust the effective value of DS, as documented.
180
+ */
181
min_tsz = 16;
182
if (using64k) {
183
- if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
184
+ if (cpu_isar_feature(aa64_lva, cpu)) {
185
+ min_tsz = 12;
186
+ }
187
+ ds = false;
188
+ } else if (ds) {
189
+ switch (mmu_idx) {
190
+ case ARMMMUIdx_Stage2:
191
+ case ARMMMUIdx_Stage2_S:
192
+ if (using16k) {
193
+ ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
194
+ } else {
195
+ ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
196
+ }
197
+ break;
198
+ default:
199
+ if (using16k) {
200
+ ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
201
+ } else {
202
+ ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
203
+ }
204
+ break;
205
+ }
206
+ if (ds) {
207
min_tsz = 12;
208
}
209
}
210
- /* TODO: FEAT_LPA2 */
211
212
if (tsz > max_tsz) {
213
tsz = max_tsz;
214
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
215
return (ARMVAParameters) {
216
.tsz = tsz,
217
.ps = ps,
218
+ .sh = sh,
219
.select = select,
220
.tbi = tbi,
221
.epd = epd,
222
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
223
.using16k = using16k,
224
.using64k = using64k,
225
.tsz_oob = tsz_oob,
226
+ .ds = ds,
227
};
163
}
228
}
164
229
165
-static inline int rsub_64(DisasContext *s, int x)
230
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
166
-{
231
* VTCR_EL2.SL0 field (whose interpretation depends on the page size)
167
- return 64 - x;
232
*/
168
-}
233
uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
169
-
234
+ uint32_t sl2 = extract64(tcr->raw_tcr, 33, 1);
170
-static inline int rsub_32(DisasContext *s, int x)
235
uint32_t startlevel;
171
-{
236
bool ok;
172
- return 32 - x;
237
173
-}
238
- if (!aarch64 || stride == 9) {
174
-static inline int rsub_16(DisasContext *s, int x)
239
+ /* SL2 is RES0 unless DS=1 & 4kb granule. */
175
-{
240
+ if (param.ds && stride == 9 && sl2) {
176
- return 16 - x;
241
+ if (sl0 != 0) {
177
-}
242
+ level = 0;
178
-static inline int rsub_8(DisasContext *s, int x)
243
+ fault_type = ARMFault_Translation;
179
-{
244
+ goto do_fault;
180
- return 8 - x;
245
+ }
181
-}
246
+ startlevel = -1;
182
-
247
+ } else if (!aarch64 || stride == 9) {
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
248
/* AArch32 or 4KB pages */
184
{
249
startlevel = 2 - sl0;
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
250
251
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
252
* for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0
253
* or an AddressSize fault is raised. So for v8 we extract those SBZ
254
* bits as part of the address, which will be checked via outputsize.
255
- * For AArch64, the address field always goes up to bit 47 (with extra
256
- * bits for FEAT_LPA placed elsewhere). AArch64 implies v8.
257
+ * For AArch64, the address field goes up to bit 47, or 49 with FEAT_LPA2;
258
+ * the highest bits of a 52-bit output are placed elsewhere.
259
*/
260
- if (arm_feature(env, ARM_FEATURE_V8)) {
261
+ if (param.ds) {
262
+ descaddrmask = MAKE_64BIT_MASK(0, 50);
263
+ } else if (arm_feature(env, ARM_FEATURE_V8)) {
264
descaddrmask = MAKE_64BIT_MASK(0, 48);
265
} else {
266
descaddrmask = MAKE_64BIT_MASK(0, 40);
267
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
268
269
/*
270
* For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
271
- * of descriptor. Otherwise, if descaddr is out of range, raise
272
- * AddressSizeFault.
273
+ * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of
274
+ * descaddr are in [9:8]. Otherwise, if descaddr is out of range,
275
+ * raise AddressSizeFault.
276
*/
277
if (outputsize > 48) {
278
- descaddr |= extract64(descriptor, 12, 4) << 48;
279
+ if (param.ds) {
280
+ descaddr |= extract64(descriptor, 8, 2) << 50;
281
+ } else {
282
+ descaddr |= extract64(descriptor, 12, 4) << 48;
283
+ }
284
} else if (descaddr >> outputsize) {
285
fault_type = ARMFault_AddressSize;
286
goto do_fault;
287
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
288
assert(attrindx <= 7);
289
cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
290
}
291
- cacheattrs->shareability = extract32(attrs, 6, 2);
292
+
293
+ /*
294
+ * For FEAT_LPA2 and effective DS, the SH field in the attributes
295
+ * was re-purposed for output address bits. The SH attribute in
296
+ * that case comes from TCR_ELx, which we extracted earlier.
297
+ */
298
+ if (param.ds) {
299
+ cacheattrs->shareability = param.sh;
300
+ } else {
301
+ cacheattrs->shareability = extract32(attrs, 6, 2);
302
+ }
303
304
*phys_ptr = descaddr;
305
*page_size_ptr = page_size;
186
--
306
--
187
2.20.1
307
2.25.1
188
189
diff view generated by jsdifflib
1
Implement the MVE shifts by register, which perform
1
When we're using KVM, the PSCI implementation is provided by the
2
shifts on a single general-purpose register.
2
kernel, but QEMU has to tell the guest about it via the device tree.
3
Currently we look at the KVM_CAP_ARM_PSCI_0_2 capability to determine
4
if the kernel is providing at least PSCI 0.2, but if the kernel
5
provides a newer version than that we will still only tell the guest
6
it has PSCI 0.2. (This is fairly harmless; it just means the guest
7
won't use newer parts of the PSCI API.)
8
9
The kernel exposes the specific PSCI version it is implementing via
10
the ONE_REG API; use this to report in the dtb that the PSCI
11
implementation is 1.0-compatible if appropriate. (The device tree
12
binding currently only distinguishes "pre-0.2", "0.2-compatible" and
13
"1.0-compatible".)
3
14
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Marc Zyngier <maz@kernel.org>
17
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
19
Reviewed-by: Andrew Jones <drjones@redhat.com>
20
Message-id: 20220224134655.1207865-1-peter.maydell@linaro.org
7
---
21
---
8
target/arm/helper-mve.h | 2 ++
22
target/arm/kvm-consts.h | 1 +
9
target/arm/translate.h | 1 +
23
hw/arm/boot.c | 5 ++---
10
target/arm/t32.decode | 18 ++++++++++++++----
24
target/arm/kvm64.c | 12 ++++++++++++
11
target/arm/mve_helper.c | 10 ++++++++++
25
3 files changed, 15 insertions(+), 3 deletions(-)
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
14
26
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
27
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
16
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
29
--- a/target/arm/kvm-consts.h
18
+++ b/target/arm/helper-mve.h
30
+++ b/target/arm/kvm-consts.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
31
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
20
32
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
33
#define QEMU_PSCI_VERSION_0_1 0x00001
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
34
#define QEMU_PSCI_VERSION_0_2 0x00002
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
35
+#define QEMU_PSCI_VERSION_1_0 0x10000
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
36
#define QEMU_PSCI_VERSION_1_1 0x10001
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
37
38
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
39
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
26
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate.h
41
--- a/hw/arm/boot.c
28
+++ b/target/arm/translate.h
42
+++ b/hw/arm/boot.c
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
43
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
44
}
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
45
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
46
qemu_fdt_add_subnode(fdt, "/psci");
33
+typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
47
- if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
34
48
- armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
35
/**
49
- if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
36
* arm_tbflags_from_tb:
50
+ if (armcpu->psci_version >= QEMU_PSCI_VERSION_0_2) {
37
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
51
+ if (armcpu->psci_version < QEMU_PSCI_VERSION_1_0) {
52
const char comp[] = "arm,psci-0.2\0arm,psci";
53
qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
54
} else {
55
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
38
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/t32.decode
57
--- a/target/arm/kvm64.c
40
+++ b/target/arm/t32.decode
58
+++ b/target/arm/kvm64.c
41
@@ -XXX,XX +XXX,XX @@
59
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
42
&mve_shl_ri rdalo rdahi shim
60
uint64_t mpidr;
43
&mve_shl_rr rdalo rdahi rm
61
ARMCPU *cpu = ARM_CPU(cs);
44
&mve_sh_ri rda shim
62
CPUARMState *env = &cpu->env;
45
+&mve_sh_rr rda rm
63
+ uint64_t psciver;
46
64
47
# rdahi: bits [3:1] from insn, bit 0 is 1
65
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
48
# rdalo: bits [3:1] from insn, bit 0 is 0
66
!object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
49
@@ -XXX,XX +XXX,XX @@
67
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
50
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
68
}
51
@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
52
&mve_sh_ri shim=%imm5_12_6
53
+@mve_sh_rr ....... .... . rda:4 rm:4 .... .... .... &mve_sh_rr
54
55
{
56
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
57
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
58
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
59
}
69
}
60
70
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
71
+ /*
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
72
+ * KVM reports the exact PSCI version it is implementing via a
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
73
+ * special sysreg. If it is present, use its contents to determine
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
74
+ * what to report to the guest in the dtb (it is the PSCI version,
65
+ {
75
+ * in the same 15-bits major 16-bits minor format that PSCI_VERSION
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
76
+ * returns).
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
77
+ */
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
78
+ if (!kvm_get_one_reg(cs, KVM_REG_ARM_PSCI_VERSION, &psciver)) {
79
+ cpu->psci_version = psciver;
69
+ }
80
+ }
70
+
81
+
71
+ {
82
/*
72
+ SQRSHR_rr 1110101 0010 1 .... .... 1111 0010 1101 @mve_sh_rr
83
* When KVM is in use, PSCI is emulated in-kernel and not by qemu.
73
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
84
* Currently KVM has its own idea about MPIDR assignment, so we
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
--
85
--
140
2.20.1
86
2.25.1
141
142
diff view generated by jsdifflib
1
In do_ldst(), the calculation of the offset needs to be based on the
1
The updateUIInfo method makes Cocoa API calls. It also calls back
2
size of the memory access, not the size of the elements in the
2
into QEMU functions like dpy_set_ui_info(). To do this safely, we
3
vector. This meant we were getting it wrong for the widening and
3
need to follow two rules:
4
narrowing variants of the various VLDR and VSTR insns.
4
* Cocoa API calls are made on the Cocoa UI thread
5
* When calling back into QEMU we must hold the iothread lock
6
7
Fix the places where we got this wrong, by taking the iothread lock
8
while executing updateUIInfo, and moving the call in cocoa_switch()
9
inside the dispatch_async block.
10
11
Some of the Cocoa UI methods which call updateUIInfo are invoked as
12
part of the initial application startup, while we're still doing the
13
little cross-thread dance described in the comment just above
14
call_qemu_main(). This meant they were calling back into the QEMU UI
15
layer before we'd actually finished initializing our display and
16
registered the DisplayChangeListener, which isn't really valid. Once
17
updateUIInfo takes the iothread lock, we no longer get away with
18
this, because during this startup phase the iothread lock is held by
19
the QEMU main-loop thread which is waiting for us to finish our
20
display initialization. So we must suppress updateUIInfo until
21
applicationDidFinishLaunching allows the QEMU main-loop thread to
22
continue.
5
23
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
26
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
27
Message-id: 20220224101330.967429-2-peter.maydell@linaro.org
9
---
28
---
10
target/arm/translate-mve.c | 17 +++++++++--------
29
ui/cocoa.m | 25 ++++++++++++++++++++++---
11
1 file changed, 9 insertions(+), 8 deletions(-)
30
1 file changed, 22 insertions(+), 3 deletions(-)
12
31
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
32
diff --git a/ui/cocoa.m b/ui/cocoa.m
14
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-mve.c
34
--- a/ui/cocoa.m
16
+++ b/target/arm/translate-mve.c
35
+++ b/ui/cocoa.m
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
36
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
18
}
37
}
19
}
38
}
20
39
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
40
-- (void) updateUIInfo
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
41
+- (void) updateUIInfoLocked
23
+ unsigned msize)
24
{
42
{
25
TCGv_i32 addr;
43
+ /* Must be called with the iothread lock, i.e. via updateUIInfo */
26
uint32_t offset;
44
NSSize frameSize;
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
45
QemuUIInfo info;
28
return true;
46
29
}
47
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
30
48
dpy_set_ui_info(dcl.con, &info, TRUE);
31
- offset = a->imm << a->size;
32
+ offset = a->imm << msize;
33
if (!a->a) {
34
offset = -offset;
35
}
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
38
{ NULL, NULL }
39
};
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
42
}
49
}
43
50
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
51
+- (void) updateUIInfo
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
52
+{
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
53
+ if (!allow_events) {
47
{ \
54
+ /*
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
55
+ * Don't try to tell QEMU about UI information in the application
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
56
+ * startup phase -- we haven't yet registered dcl with the QEMU UI
50
{ NULL, gen_helper_mve_##ULD }, \
57
+ * layer, and also trying to take the iothread lock would deadlock.
51
}; \
58
+ * When cocoa_display_init() does register the dcl, the UI layer
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
59
+ * will call cocoa_switch(), which will call updateUIInfo, so
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
60
+ * we don't lose any information here.
54
}
61
+ */
55
62
+ return;
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
63
+ }
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
64
+
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
65
+ with_iothread_lock(^{
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
66
+ [self updateUIInfoLocked];
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
67
+ });
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
68
+}
62
69
+
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
70
- (void)viewDidMoveToWindow
64
{
71
{
72
[self updateUIInfo];
73
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
74
75
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
76
77
- [cocoaView updateUIInfo];
78
-
79
// The DisplaySurface will be freed as soon as this callback returns.
80
// We take a reference to the underlying pixman image here so it does
81
// not disappear from under our feet; the switchSurface method will
82
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
83
pixman_image_ref(image);
84
85
dispatch_async(dispatch_get_main_queue(), ^{
86
+ [cocoaView updateUIInfo];
87
[cocoaView switchSurface:image];
88
});
89
[pool release];
65
--
90
--
66
2.20.1
91
2.25.1
67
68
diff view generated by jsdifflib
1
The function asimd_imm_const() in translate-neon.c is an
1
In commit 6e657e64cdc478 in 2013 we added some autorelease pools to
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
2
deal with complaints from macOS when we made calls into Cocoa from
3
also want for MVE. Move the implementation to translate.c, with a
3
threads that didn't have automatically created autorelease pools.
4
prototype in translate.h.
4
Later on, macOS got stricter about forbidding cross-thread Cocoa
5
calls, and in commit 5588840ff77800e839d8 we restructured the code to
6
avoid them. This left the autorelease pool creation in several
7
functions without any purpose; delete it.
8
9
We still need the pool in cocoa_refresh() for the clipboard related
10
code which is called directly there.
5
11
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
14
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
15
Message-id: 20220224101330.967429-3-peter.maydell@linaro.org
9
---
16
---
10
target/arm/translate.h | 16 ++++++++++
17
ui/cocoa.m | 6 ------
11
target/arm/translate-neon.c | 63 -------------------------------------
18
1 file changed, 6 deletions(-)
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
13
3 files changed, 73 insertions(+), 63 deletions(-)
14
19
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
20
diff --git a/ui/cocoa.m b/ui/cocoa.m
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
22
--- a/ui/cocoa.m
18
+++ b/target/arm/translate.h
23
+++ b/ui/cocoa.m
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
24
@@ -XXX,XX +XXX,XX @@ int main (int argc, char **argv) {
20
return opc | s->be_data;
25
static void cocoa_update(DisplayChangeListener *dcl,
26
int x, int y, int w, int h)
27
{
28
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
29
-
30
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
31
32
dispatch_async(dispatch_get_main_queue(), ^{
33
@@ -XXX,XX +XXX,XX @@ static void cocoa_update(DisplayChangeListener *dcl,
34
}
35
[cocoaView setNeedsDisplayInRect:rect];
36
});
37
-
38
- [pool release];
21
}
39
}
22
40
23
+/**
41
static void cocoa_switch(DisplayChangeListener *dcl,
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
42
DisplaySurface *surface)
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
{
43
{
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
44
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
115
index XXXXXXX..XXXXXXX 100644
45
pixman_image_t *image = surface->image;
116
--- a/target/arm/translate.c
46
117
+++ b/target/arm/translate.c
47
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
48
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
119
a64_translate_init();
49
[cocoaView updateUIInfo];
50
[cocoaView switchSurface:image];
51
});
52
- [pool release];
120
}
53
}
121
54
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
55
static void cocoa_refresh(DisplayChangeListener *dcl)
123
+{
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
125
+ switch (cmode) {
126
+ case 0: case 1:
127
+ /* no-op */
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
+}
178
+
179
/* Generate a label used for skipping this instruction */
180
void arm_gen_condlabel(DisasContext *s)
181
{
182
--
56
--
183
2.20.1
57
2.25.1
184
185
diff view generated by jsdifflib