1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
1
The following changes since commit a97978bcc2d1f650c7d411428806e5b03082b8c7:
2
2
3
thanks
3
Merge remote-tracking branch 'remotes/dg-gitlab/tags/ppc-for-6.1-20210603' into staging (2021-06-03 10:00:35 +0100)
4
-- PMM
5
6
7
The following changes since commit 2ef486e76d64436be90f7359a3071fb2a56ce835:
8
9
Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into staging (2020-05-03 14:12:56 +0100)
10
4
11
are available in the Git repository at:
5
are available in the Git repository at:
12
6
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210603
14
8
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
9
for you to fetch changes up to 1c861885894d840235954060050d240259f5340b:
16
10
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
11
tests/unit/test-vmstate: Assert that dup() and mkstemp() succeed (2021-06-03 16:43:27 +0100)
18
12
19
----------------------------------------------------------------
13
----------------------------------------------------------------
20
target-arm queue:
14
target-arm queue:
21
* Start of conversion of Neon insns to decodetree
15
* Some not-yet-enabled preliminaries for M-profile MVE support
22
* versal board: support SD and RTC
16
* Consistently use "Cortex-Axx", not "Cortex Axx" in docs, comments
23
* Implement ARMv8.2-TTS2UXN
17
* docs: Fix installation of man pages with Sphinx 4.x
24
* Make VQDMULL undefined when U=1
18
* Mark LDS{MIN,MAX} as signed operations
25
* Some minor code cleanups
19
* Fix missing syndrome value for DAIF and PAC check exceptions
20
* Implement BFloat16 extensions
21
* Refactoring of hvf accelerator code in preparation for aarch64 support
22
* Fix some coverity nits in test code
26
23
27
----------------------------------------------------------------
24
----------------------------------------------------------------
28
Edgar E. Iglesias (11):
25
Alexander Graf (12):
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
26
hvf: Move assert_hvf_ok() into common directory
30
hw/arm: versal: Move misplaced comment
27
hvf: Move vcpu thread functions into common directory
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
28
hvf: Move cpu functions into common directory
32
hw/arm: versal: Embed the UARTs into the SoC type
29
hvf: Move hvf internal definitions into common header
33
hw/arm: versal: Embed the GEMs into the SoC type
30
hvf: Make hvf_set_phys_mem() static
34
hw/arm: versal: Embed the ADMAs into the SoC type
31
hvf: Remove use of hv_uvaddr_t and hv_gpaddr_t
35
hw/arm: versal: Embed the APUs into the SoC type
32
hvf: Split out common code on vcpu init and destroy
36
hw/arm: versal: Add support for SD
33
hvf: Use cpu_synchronize_state()
37
hw/arm: versal: Add support for the RTC
34
hvf: Make synchronize functions static
38
hw/arm: versal-virt: Add support for SD
35
hvf: Remove hvf-accel-ops.h
39
hw/arm: versal-virt: Add support for the RTC
36
hvf: Introduce hvf vcpu struct
37
hvf: Simplify post reset/init/loadvm hooks
40
38
41
Fredrik Strupe (1):
39
Damien Goutte-Gattat (1):
42
target/arm: Make VQDMULL undefined when U=1
40
docs: Fix installation of man pages with Sphinx 4.x
43
41
44
Peter Maydell (25):
42
Jamie Iles (4):
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
43
target/arm: fix missing exception class
46
target/arm: Use enum constant in get_phys_addr_lpae() call
44
target/arm: fold do_raise_exception into raise_exception
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
45
target/arm: use raise_exception_ra for MTE check failure
48
target/arm: Implement ARMv8.2-TTS2UXN
46
target/arm: use raise_exception_ra for stack limit exception
49
target/arm: Use correct variable for setting 'max' cpu's ID_AA64DFR0
50
target/arm/translate-vfp.inc.c: Remove duplicate simd_r32 check
51
target/arm: Don't allow Thumb Neon insns without FEATURE_NEON
52
target/arm: Add stubs for AArch32 Neon decodetree
53
target/arm: Convert VCMLA (vector) to decodetree
54
target/arm: Convert VCADD (vector) to decodetree
55
target/arm: Convert V[US]DOT (vector) to decodetree
56
target/arm: Convert VFM[AS]L (vector) to decodetree
57
target/arm: Convert VCMLA (scalar) to decodetree
58
target/arm: Convert V[US]DOT (scalar) to decodetree
59
target/arm: Convert VFM[AS]L (scalar) to decodetree
60
target/arm: Convert Neon load/store multiple structures to decodetree
61
target/arm: Convert Neon 'load single structure to all lanes' to decodetree
62
target/arm: Convert Neon 'load/store single structure' to decodetree
63
target/arm: Convert Neon 3-reg-same VADD/VSUB to decodetree
64
target/arm: Convert Neon 3-reg-same logic ops to decodetree
65
target/arm: Convert Neon 3-reg-same VMAX/VMIN to decodetree
66
target/arm: Convert Neon 3-reg-same comparisons to decodetree
67
target/arm: Convert Neon 3-reg-same VQADD/VQSUB to decodetree
68
target/arm: Convert Neon 3-reg-same VMUL, VMLA, VMLS, VSHL to decodetree
69
target/arm: Move gen_ function typedefs to translate.h
70
47
71
Philippe Mathieu-Daudé (2):
48
Peter Maydell (15):
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
49
target/arm: Add isar feature check functions for MVE
73
target/arm: Use uint64_t for midr field in CPU state struct
50
target/arm: Update feature checks for insns which are "MVE or FP"
51
target/arm: Move fpsp/fpdp isar check into callers of do_vfp_2op_sp/dp
52
target/arm: Add MVE check to VMOV_reg_sp and VMOV_reg_dp
53
target/arm: Fix return values in fp_sysreg_checks()
54
target/arm: Implement M-profile VPR register
55
target/arm: Make FPSCR.LTPSIZE writable for MVE
56
target/arm: Allow board models to specify initial NS VTOR
57
arm: Consistently use "Cortex-Axx", not "Cortex Axx"
58
tests/qtest/bios-tables-test: Check for dup2() failure
59
tests/qtest/e1000e-test: Check qemu_recv() succeeded
60
tests/qtest/hd-geo-test: Fix checks on mkstemp() return value
61
tests/qtest/pflash-cfi02-test: Avoid potential integer overflow
62
tests/qtest/tpm-tests: Remove unnecessary NULL checks
63
tests/unit/test-vmstate: Assert that dup() and mkstemp() succeed
74
64
75
include/hw/arm/xlnx-versal.h | 31 +-
65
Richard Henderson (13):
76
target/arm/cpu-param.h | 2 +-
66
target/arm: Mark LDS{MIN,MAX} as signed operations
77
target/arm/cpu.h | 38 ++-
67
target/arm: Add isar_feature_{aa32, aa64, aa64_sve}_bf16
78
target/arm/translate-a64.h | 9 -
68
target/arm: Unify unallocated path in disas_fp_1src
79
target/arm/translate.h | 26 ++
69
target/arm: Implement scalar float32 to bfloat16 conversion
80
target/arm/neon-dp.decode | 86 +++++
70
target/arm: Implement vector float32 to bfloat16 conversion
81
target/arm/neon-ls.decode | 52 +++
71
softfpu: Add float_round_to_odd_inf
82
target/arm/neon-shared.decode | 66 ++++
72
target/arm: Implement bfloat16 dot product (vector)
83
hw/arm/mps2-tz.c | 2 +-
73
target/arm: Implement bfloat16 dot product (indexed)
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
74
target/arm: Implement bfloat16 matrix multiply accumulate
85
hw/arm/xlnx-versal.c | 115 +++++--
75
target/arm: Implement bfloat widening fma (vector)
86
target/arm/cpu.c | 3 +-
76
target/arm: Implement bfloat widening fma (indexed)
87
target/arm/cpu64.c | 8 +-
77
linux-user/aarch64: Enable hwcap bits for bfloat16
88
target/arm/helper.c | 183 ++++------
78
target/arm: Enable BFloat16 extensions
89
target/arm/translate-a64.c | 17 -
90
target/arm/translate-neon.inc.c | 714 +++++++++++++++++++++++++++++++++++++++
91
target/arm/translate-vfp.inc.c | 6 -
92
target/arm/translate.c | 716 +++-------------------------------------
93
target/arm/Makefile.objs | 18 +
94
19 files changed, 1302 insertions(+), 864 deletions(-)
95
create mode 100644 target/arm/neon-dp.decode
96
create mode 100644 target/arm/neon-ls.decode
97
create mode 100644 target/arm/neon-shared.decode
98
create mode 100644 target/arm/translate-neon.inc.c
99
79
80
docs/conf.py | 1 +
81
docs/system/arm/aspeed.rst | 4 +-
82
docs/system/arm/nuvoton.rst | 6 +-
83
docs/system/arm/sabrelite.rst | 2 +-
84
include/fpu/softfloat-types.h | 4 +-
85
include/hw/arm/allwinner-h3.h | 2 +-
86
include/hw/arm/armv7m.h | 2 +
87
include/hw/core/cpu.h | 3 +-
88
include/sysemu/hvf_int.h | 58 +++++
89
target/arm/cpu.h | 48 +++-
90
target/arm/helper-sve.h | 4 +
91
target/arm/helper.h | 15 ++
92
target/i386/hvf/hvf-accel-ops.h | 23 --
93
target/i386/hvf/hvf-i386.h | 33 +--
94
target/i386/hvf/vmx.h | 24 +-
95
target/i386/hvf/x86hvf.h | 2 -
96
target/arm/neon-dp.decode | 1 +
97
target/arm/neon-shared.decode | 11 +
98
target/arm/sve.decode | 19 +-
99
target/arm/vfp.decode | 2 +
100
accel/hvf/hvf-accel-ops.c | 471 ++++++++++++++++++++++++++++++++++++++++
101
accel/hvf/hvf-all.c | 47 ++++
102
hw/arm/armv7m.c | 7 +
103
hw/arm/aspeed.c | 6 +-
104
hw/arm/mcimx6ul-evk.c | 2 +-
105
hw/arm/mcimx7d-sabre.c | 2 +-
106
hw/arm/npcm7xx_boards.c | 4 +-
107
hw/arm/sabrelite.c | 2 +-
108
hw/misc/npcm7xx_clk.c | 2 +-
109
linux-user/elfload.c | 2 +
110
target/arm/cpu.c | 13 ++
111
target/arm/cpu64.c | 3 +
112
target/arm/cpu_tcg.c | 1 +
113
target/arm/m_helper.c | 5 +-
114
target/arm/machine.c | 20 ++
115
target/arm/mte_helper.c | 12 +-
116
target/arm/op_helper.c | 32 ++-
117
target/arm/sve_helper.c | 2 +
118
target/arm/translate-a64.c | 155 +++++++++++--
119
target/arm/translate-neon.c | 91 ++++++++
120
target/arm/translate-sve.c | 112 ++++++++++
121
target/arm/translate-vfp.c | 164 ++++++++++----
122
target/arm/vec_helper.c | 140 +++++++++++-
123
target/arm/vfp_helper.c | 21 +-
124
target/i386/hvf/hvf-accel-ops.c | 146 -------------
125
target/i386/hvf/hvf.c | 464 +++++----------------------------------
126
target/i386/hvf/x86.c | 28 +--
127
target/i386/hvf/x86_descr.c | 26 +--
128
target/i386/hvf/x86_emu.c | 62 +++---
129
target/i386/hvf/x86_mmu.c | 4 +-
130
target/i386/hvf/x86_task.c | 12 +-
131
target/i386/hvf/x86hvf.c | 222 +++++++++----------
132
tests/qtest/bios-tables-test.c | 8 +-
133
tests/qtest/e1000e-test.c | 3 +-
134
tests/qtest/hd-geo-test.c | 4 +-
135
tests/qtest/pflash-cfi02-test.c | 2 +-
136
tests/qtest/tpm-tests.c | 12 +-
137
tests/unit/test-vmstate.c | 5 +-
138
fpu/softfloat-parts.c.inc | 6 +-
139
MAINTAINERS | 8 +
140
accel/hvf/meson.build | 7 +
141
accel/meson.build | 1 +
142
target/i386/hvf/meson.build | 1 -
143
63 files changed, 1666 insertions(+), 935 deletions(-)
144
create mode 100644 include/sysemu/hvf_int.h
145
delete mode 100644 target/i386/hvf/hvf-accel-ops.h
146
create mode 100644 accel/hvf/hvf-accel-ops.c
147
create mode 100644 accel/hvf/hvf-all.c
148
delete mode 100644 target/i386/hvf/hvf-accel-ops.c
149
create mode 100644 accel/hvf/meson.build
150
diff view generated by jsdifflib
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
1
Add the isar feature check functions we will need for v8.1M MVE:
2
3-reg-same grouping to decodetree.
2
* a check for MVE present: this corresponds to the pseudocode's
3
CheckDecodeFaults(ExtType_Mve)
4
* a check for the optional floating-point part of MVE: this
5
corresponds to CheckDecodeFaults(ExtType_MveFp)
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
9
Message-id: 20210520152840.24453-2-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-dp.decode | 9 +++++++
11
target/arm/cpu.h | 22 ++++++++++++++++++++++
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
12
1 file changed, 22 insertions(+)
10
target/arm/translate.c | 28 +++------------------
11
3 files changed, 56 insertions(+), 25 deletions(-)
12
13
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
--- a/target/arm/cpu.h
16
+++ b/target/arm/neon-dp.decode
17
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
19
}
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
20
}
20
21
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
22
+static inline bool isar_feature_aa32_mve(const ARMISARegisters *id)
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
23
+
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
28
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
31
+
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
34
+
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
46
47
#define DO_3SAME_CMP(INSN, COND) \
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
53
+
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
56
+{
23
+{
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
24
+ /*
58
+ 0, gen_helper_gvec_pmul_b);
25
+ * Return true if MVE is supported (either integer or floating point).
26
+ * We must check for M-profile as the MVFR1 field means something
27
+ * else for A-profile.
28
+ */
29
+ return isar_feature_aa32_mprofile(id) &&
30
+ FIELD_EX32(id->mvfr1, MVFR1, MVE) > 0;
59
+}
31
+}
60
+
32
+
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
33
+static inline bool isar_feature_aa32_mve_fp(const ARMISARegisters *id)
62
+{
34
+{
63
+ if (a->size != 0) {
35
+ /*
64
+ return false;
36
+ * Return true if MVE is supported (either integer or floating point).
65
+ }
37
+ * We must check for M-profile as the MVFR1 field means something
66
+ return do_3same(s, a, gen_VMUL_p_3s);
38
+ * else for A-profile.
39
+ */
40
+ return isar_feature_aa32_mprofile(id) &&
41
+ FIELD_EX32(id->mvfr1, MVFR1, MVE) >= 2;
67
+}
42
+}
68
+
43
+
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
44
static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id)
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
45
{
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
46
/*
72
+ uint32_t oprsz, uint32_t maxsz) \
73
+ { \
74
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
75
+ oprsz, maxsz, &OPARRAY[vece]); \
76
+ } \
77
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
78
+
79
+
80
+DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
81
+DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
82
+
83
+#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
84
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
85
+ uint32_t rn_ofs, uint32_t rm_ofs, \
86
+ uint32_t oprsz, uint32_t maxsz) \
87
+ { \
88
+ /* Note the operation is vshl vd,vm,vn */ \
89
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
90
+ oprsz, maxsz, &OPARRAY[vece]); \
91
+ } \
92
+ DO_3SAME(INSN, gen_##INSN##_3s)
93
+
94
+DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
95
+DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
}
102
return 1;
103
104
- case NEON_3R_VMUL: /* VMUL */
105
- if (u) {
106
- /* Polynomial case allows only P8. */
107
- if (size != 0) {
108
- return 1;
109
- }
110
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
111
- 0, gen_helper_gvec_pmul_b);
112
- } else {
113
- tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
114
- vec_size, vec_size);
115
- }
116
- return 0;
117
-
118
- case NEON_3R_VML: /* VMLA, VMLS */
119
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
120
- u ? &mls_op[size] : &mla_op[size]);
121
- return 0;
122
-
123
- case NEON_3R_VSHL:
124
- /* Note the operation is vshl vd,vm,vn */
125
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
126
- u ? &ushl_op[size] : &sshl_op[size]);
127
- return 0;
128
-
129
case NEON_3R_VADD_VSUB:
130
case NEON_3R_LOGIC:
131
case NEON_3R_VMAX:
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
133
case NEON_3R_VCGE:
134
case NEON_3R_VQADD:
135
case NEON_3R_VQSUB:
136
+ case NEON_3R_VMUL:
137
+ case NEON_3R_VML:
138
+ case NEON_3R_VSHL:
139
/* Already handled by decodetree */
140
return 1;
141
}
142
--
47
--
143
2.20.1
48
2.20.1
144
49
145
50
diff view generated by jsdifflib
1
Convert the Neon "load single structure to all lanes" insns to
1
Some v8M instructions are present if either the floating point
2
decodetree.
2
extension or MVE is implemented. Update our implementation of them
3
to check for MVE as well as for FP.
4
5
This is all the insns which use CheckDecodeFaults(ExtType_MveOrFp) or
6
CheckDecodeFaults(ExtType_MveOrDpFp) in their pseudocode, which are
7
essentially the loads and stores, moves and sysreg accesses, except
8
for VMOV_reg_sp and VMOV_reg_dp, which we handle in subsequent
9
patches because they need a refactor to provide a place to put the
10
new MVE check.
3
11
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>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
14
Message-id: 20210520152840.24453-3-peter.maydell@linaro.org
7
---
15
---
8
target/arm/neon-ls.decode | 5 +++
16
target/arm/translate-vfp.c | 48 +++++++++++++++++++++++---------------
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
17
1 file changed, 29 insertions(+), 19 deletions(-)
10
target/arm/translate.c | 55 +------------------------
11
3 files changed, 80 insertions(+), 53 deletions(-)
12
18
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
19
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-ls.decode
21
--- a/target/arm/translate-vfp.c
16
+++ b/target/arm/neon-ls.decode
22
+++ b/target/arm/translate-vfp.c
17
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
18
24
/* VMOV scalar to general purpose register */
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
25
TCGv_i32 tmp;
20
vd=%vd_dp
26
21
+
27
- /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
22
+# Neon load single element to all lanes
28
- if (a->size == MO_32
23
+
29
- ? !dc_isar_feature(aa32_fpsp_v2, s)
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
30
- : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
25
+ vd=%vd_dp
31
- return false;
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
32
+ /*
27
index XXXXXXX..XXXXXXX 100644
33
+ * SIZE == MO_32 is a VFP instruction; otherwise NEON. MVE has
28
--- a/target/arm/translate-neon.inc.c
34
+ * all sizes, whether the CPU has fp or not.
29
+++ b/target/arm/translate-neon.inc.c
35
+ */
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
36
+ if (!dc_isar_feature(aa32_mve, s)) {
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
37
+ if (a->size == MO_32
32
return true;
38
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
33
}
39
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
34
+
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
36
+{
37
+ /* Neon load single structure to all lanes */
38
+ int reg, stride, vec_size;
39
+ int vd = a->vd;
40
+ int size = a->size;
41
+ int nregs = a->n + 1;
42
+ TCGv_i32 addr, tmp;
43
+
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
45
+ return false;
46
+ }
47
+
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if (size == 3) {
54
+ if (nregs != 4 || a->a == 0) {
55
+ return false;
40
+ return false;
56
+ }
41
+ }
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
42
}
58
+ size = 2;
43
59
+ }
44
/* UNDEF accesses to D16-D31 if they don't exist */
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
45
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
61
+ return false;
46
/* VMOV general purpose register to scalar */
62
+ }
47
TCGv_i32 tmp;
63
+ if (nregs == 3 && a->a == 1) {
48
64
+ return false;
49
- /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
65
+ }
50
- if (a->size == MO_32
66
+
51
- ? !dc_isar_feature(aa32_fpsp_v2, s)
67
+ if (!vfp_access_check(s)) {
52
- : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
68
+ return true;
53
- return false;
69
+ }
70
+
71
+ /*
54
+ /*
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
55
+ * SIZE == MO_32 is a VFP instruction; otherwise NEON. MVE has
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
56
+ * all sizes, whether the CPU has fp or not.
74
+ */
57
+ */
75
+ stride = a->t ? 2 : 1;
58
+ if (!dc_isar_feature(aa32_mve, s)) {
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
59
+ if (a->size == MO_32
77
+
60
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
78
+ tmp = tcg_temp_new_i32();
61
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
79
+ addr = tcg_temp_new_i32();
62
+ return false;
80
+ load_reg_var(s, addr, a->rn);
81
+ for (reg = 0; reg < nregs; reg++) {
82
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
83
+ s->be_data | size);
84
+ if ((vd & 1) && vec_size == 16) {
85
+ /*
86
+ * We cannot write 16 bytes at once because the
87
+ * destination is unaligned.
88
+ */
89
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
90
+ 8, 8, tmp);
91
+ tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
92
+ neon_reg_offset(vd, 0), 8, 8);
93
+ } else {
94
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
95
+ vec_size, vec_size, tmp);
96
+ }
63
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
64
}
98
+ vd += stride;
65
99
+ }
66
/* UNDEF accesses to D16-D31 if they don't exist */
100
+ tcg_temp_free_i32(tmp);
67
@@ -XXX,XX +XXX,XX @@ typedef enum FPSysRegCheckResult {
101
+ tcg_temp_free_i32(addr);
68
102
+
69
static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
70
{
104
+
71
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
105
+ return true;
72
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
106
+}
73
return FPSysRegCheckFailed;
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
74
}
108
index XXXXXXX..XXXXXXX 100644
75
109
--- a/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
110
+++ b/target/arm/translate.c
77
{
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
112
int size;
113
int reg;
114
int load;
115
- int vec_size;
116
TCGv_i32 addr;
117
TCGv_i32 tmp;
78
TCGv_i32 tmp;
118
79
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
80
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
120
} else {
81
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
121
size = (insn >> 10) & 3;
82
return false;
122
if (size == 3) {
83
}
123
- /* Load single element to all lanes. */
84
124
- int a = (insn >> 4) & 1;
85
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
125
- if (!load) {
86
{
126
- return 1;
87
TCGv_i32 tmp;
127
- }
88
128
- size = (insn >> 6) & 3;
89
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
129
- nregs = ((insn >> 8) & 3) + 1;
90
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
130
-
91
return false;
131
- if (size == 3) {
92
}
132
- if (nregs != 4 || a == 0) {
93
133
- return 1;
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
134
- }
95
* floating point register. Note that this does not require support
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
96
* for double precision arithmetic.
136
- size = 2;
97
*/
137
- }
98
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
138
- if (nregs == 1 && a == 1 && size == 0) {
99
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
139
- return 1;
100
return false;
140
- }
101
}
141
- if (nregs == 3 && a == 1) {
102
142
- return 1;
103
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
143
- }
104
uint32_t offset;
144
- addr = tcg_temp_new_i32();
105
TCGv_i32 addr, tmp;
145
- load_reg_var(s, addr, rn);
106
146
-
107
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
108
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
109
return false;
149
- */
110
}
150
- stride = (insn & (1 << 5)) ? 2 : 1;
111
151
- vec_size = nregs == 1 ? stride * 8 : 8;
112
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
152
-
113
uint32_t offset;
153
- tmp = tcg_temp_new_i32();
114
TCGv_i32 addr, tmp;
154
- for (reg = 0; reg < nregs; reg++) {
115
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
116
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
156
- s->be_data | size);
117
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
157
- if ((rd & 1) && vec_size == 16) {
118
return false;
158
- /* We cannot write 16 bytes at once because the
119
}
159
- * destination is unaligned.
120
160
- */
121
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
122
TCGv_i64 tmp;
162
- 8, 8, tmp);
123
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
124
/* Note that this does not require support for double arithmetic. */
164
- neon_reg_offset(rd, 0), 8, 8);
125
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
165
- } else {
126
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
127
return false;
167
- vec_size, vec_size, tmp);
128
}
168
- }
129
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
130
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
170
- rd += stride;
131
TCGv_i32 addr, tmp;
171
- }
132
int i, n;
172
- tcg_temp_free_i32(tmp);
133
173
- tcg_temp_free_i32(addr);
134
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
174
- stride = (1 << size) * nregs;
135
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
175
+ /* Load single element to all lanes -- handled by decodetree */
136
return false;
176
+ return 1;
137
}
177
} else {
138
178
/* Single element. */
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
179
int idx = (insn >> 4) & 0xf;
140
int i, n;
141
142
/* Note that this does not require support for double arithmetic. */
143
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
144
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
145
return false;
146
}
147
180
--
148
--
181
2.20.1
149
2.20.1
182
150
183
151
diff view generated by jsdifflib
1
Somewhere along theline we accidentally added a duplicate
1
The do_vfp_2op_sp() and do_vfp_2op_dp() functions currently check
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
2
whether floating point is supported via the aa32_fpdp_v2 and
3
(probably an artifact of a patchseries rebase). Remove it.
3
aa32_fpsp_v2 isar checks. For v8.1M MVE support, the VMOV_reg trans
4
functions (but not any of the others) need to update this to also
5
allow the insn if MVE is implemented. Move the check out of the do_
6
function and into its callsites (which are all implemented via the
7
DO_VFP_2OP macro), so we have a place to change the check for the
8
VMOV insns.
4
9
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20210520152840.24453-4-peter.maydell@linaro.org
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
9
---
13
---
10
target/arm/translate-vfp.inc.c | 6 ------
14
target/arm/translate-vfp.c | 37 +++++++++++++++++++------------------
11
1 file changed, 6 deletions(-)
15
1 file changed, 19 insertions(+), 18 deletions(-)
12
16
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
17
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.inc.c
19
--- a/target/arm/translate-vfp.c
16
+++ b/target/arm/translate-vfp.inc.c
20
+++ b/target/arm/translate-vfp.c
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
21
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
22
int veclen = s->vec_len;
23
TCGv_i32 f0, fd;
24
25
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
26
- return false;
27
- }
28
+ /* Note that the caller must check the aa32_fpsp_v2 feature. */
29
30
if (!dc_isar_feature(aa32_fpshvec, s) &&
31
(veclen != 0 || s->vec_stride != 0)) {
32
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_hp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
33
*/
34
TCGv_i32 f0;
35
36
+ /* Note that the caller must check the aa32_fp16_arith feature */
37
+
38
if (!dc_isar_feature(aa32_fp16_arith, s)) {
18
return false;
39
return false;
19
}
40
}
20
41
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
42
int veclen = s->vec_len;
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
43
TCGv_i64 f0, fd;
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
44
45
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
24
- return false;
46
- return false;
25
- }
47
- }
26
-
48
+ /* Note that the caller must check the aa32_fpdp_v2 feature. */
27
if (!vfp_access_check(s)) {
49
28
return true;
50
/* UNDEF accesses to D16-D31 if they don't exist */
51
if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
53
return true;
54
}
55
56
-#define DO_VFP_2OP(INSN, PREC, FN) \
57
+#define DO_VFP_2OP(INSN, PREC, FN, CHECK) \
58
static bool trans_##INSN##_##PREC(DisasContext *s, \
59
arg_##INSN##_##PREC *a) \
60
{ \
61
+ if (!dc_isar_feature(CHECK, s)) { \
62
+ return false; \
63
+ } \
64
return do_vfp_2op_##PREC(s, FN, a->vd, a->vm); \
29
}
65
}
66
67
-DO_VFP_2OP(VMOV_reg, sp, tcg_gen_mov_i32)
68
-DO_VFP_2OP(VMOV_reg, dp, tcg_gen_mov_i64)
69
+DO_VFP_2OP(VMOV_reg, sp, tcg_gen_mov_i32, aa32_fpsp_v2)
70
+DO_VFP_2OP(VMOV_reg, dp, tcg_gen_mov_i64, aa32_fpdp_v2)
71
72
-DO_VFP_2OP(VABS, hp, gen_helper_vfp_absh)
73
-DO_VFP_2OP(VABS, sp, gen_helper_vfp_abss)
74
-DO_VFP_2OP(VABS, dp, gen_helper_vfp_absd)
75
+DO_VFP_2OP(VABS, hp, gen_helper_vfp_absh, aa32_fp16_arith)
76
+DO_VFP_2OP(VABS, sp, gen_helper_vfp_abss, aa32_fpsp_v2)
77
+DO_VFP_2OP(VABS, dp, gen_helper_vfp_absd, aa32_fpdp_v2)
78
79
-DO_VFP_2OP(VNEG, hp, gen_helper_vfp_negh)
80
-DO_VFP_2OP(VNEG, sp, gen_helper_vfp_negs)
81
-DO_VFP_2OP(VNEG, dp, gen_helper_vfp_negd)
82
+DO_VFP_2OP(VNEG, hp, gen_helper_vfp_negh, aa32_fp16_arith)
83
+DO_VFP_2OP(VNEG, sp, gen_helper_vfp_negs, aa32_fpsp_v2)
84
+DO_VFP_2OP(VNEG, dp, gen_helper_vfp_negd, aa32_fpdp_v2)
85
86
static void gen_VSQRT_hp(TCGv_i32 vd, TCGv_i32 vm)
87
{
88
@@ -XXX,XX +XXX,XX @@ static void gen_VSQRT_dp(TCGv_i64 vd, TCGv_i64 vm)
89
gen_helper_vfp_sqrtd(vd, vm, cpu_env);
90
}
91
92
-DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp)
93
-DO_VFP_2OP(VSQRT, sp, gen_VSQRT_sp)
94
-DO_VFP_2OP(VSQRT, dp, gen_VSQRT_dp)
95
+DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp, aa32_fp16_arith)
96
+DO_VFP_2OP(VSQRT, sp, gen_VSQRT_sp, aa32_fpsp_v2)
97
+DO_VFP_2OP(VSQRT, dp, gen_VSQRT_dp, aa32_fpdp_v2)
98
99
static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
100
{
30
--
101
--
31
2.20.1
102
2.20.1
32
103
33
104
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
1
Split out the handling of VMOV_reg_sp and VMOV_reg_dp so that we can
2
permit the insns if either FP or MVE are present.
2
3
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
6
Message-id: 20210520152840.24453-5-peter.maydell@linaro.org
6
---
7
---
7
target/arm/neon-dp.decode | 5 +++++
8
target/arm/translate-vfp.c | 15 +++++++++++++--
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
9
1 file changed, 13 insertions(+), 2 deletions(-)
9
target/arm/translate.c | 21 ++-------------------
10
3 files changed, 21 insertions(+), 19 deletions(-)
11
10
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
11
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
13
--- a/target/arm/translate-vfp.c
15
+++ b/target/arm/neon-dp.decode
14
+++ b/target/arm/translate-vfp.c
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
16
return do_vfp_2op_##PREC(s, FN, a->vd, a->vm); \
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
17
}
19
18
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
19
-DO_VFP_2OP(VMOV_reg, sp, tcg_gen_mov_i32, aa32_fpsp_v2)
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
20
-DO_VFP_2OP(VMOV_reg, dp, tcg_gen_mov_i64, aa32_fpdp_v2)
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
21
+#define DO_VFP_VMOV(INSN, PREC, FN) \
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
22
+ static bool trans_##INSN##_##PREC(DisasContext *s, \
24
+
23
+ arg_##INSN##_##PREC *a) \
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
24
+ { \
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
25
+ if (!dc_isar_feature(aa32_fp##PREC##_v2, s) && \
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
26
+ !dc_isar_feature(aa32_mve, s)) { \
28
index XXXXXXX..XXXXXXX 100644
27
+ return false; \
29
--- a/target/arm/translate-neon.inc.c
28
+ } \
30
+++ b/target/arm/translate-neon.inc.c
29
+ return do_vfp_2op_##PREC(s, FN, a->vd, a->vm); \
31
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VEOR, tcg_gen_gvec_xor)
32
DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
33
DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
34
DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
35
+
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
38
+ { \
39
+ if (a->size == 3) { \
40
+ return false; \
41
+ } \
42
+ return do_3same(s, a, FUNC); \
43
+ }
30
+ }
44
+
31
+
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
32
+DO_VFP_VMOV(VMOV_reg, sp, tcg_gen_mov_i32)
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
33
+DO_VFP_VMOV(VMOV_reg, dp, tcg_gen_mov_i64)
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
34
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
35
DO_VFP_2OP(VABS, hp, gen_helper_vfp_absh, aa32_fp16_arith)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
36
DO_VFP_2OP(VABS, sp, gen_helper_vfp_abss, aa32_fpsp_v2)
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/translate.c
52
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
55
return 0;
56
57
- case NEON_3R_VMAX:
58
- if (u) {
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
60
- vec_size, vec_size);
61
- } else {
62
- tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
63
- vec_size, vec_size);
64
- }
65
- return 0;
66
- case NEON_3R_VMIN:
67
- if (u) {
68
- tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
69
- vec_size, vec_size);
70
- } else {
71
- tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
72
- vec_size, vec_size);
73
- }
74
- return 0;
75
-
76
case NEON_3R_VSHL:
77
/* Note the operation is vshl vd,vm,vn */
78
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
79
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
80
81
case NEON_3R_VADD_VSUB:
82
case NEON_3R_LOGIC:
83
+ case NEON_3R_VMAX:
84
+ case NEON_3R_VMIN:
85
/* Already handled by decodetree */
86
return 1;
87
}
88
--
37
--
89
2.20.1
38
2.20.1
90
39
91
40
diff view generated by jsdifflib
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
1
The fp_sysreg_checks() function is supposed to be returning an
2
to decodetree.
2
FPSysRegCheckResult, which is an enum with three possible values.
3
However, three places in the function "return false" (a hangover from
4
a previous iteration of the design where the function just returned a
5
bool). Make these return FPSysRegCheckFailed instead (for no
6
functional change, since both false and FPSysRegCheckFailed are
7
zero).
3
8
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
11
Message-id: 20210520152840.24453-6-peter.maydell@linaro.org
7
---
12
---
8
target/arm/neon-dp.decode | 6 ++++++
13
target/arm/translate-vfp.c | 6 +++---
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
14
1 file changed, 3 insertions(+), 3 deletions(-)
10
target/arm/translate.c | 14 ++------------
11
3 files changed, 23 insertions(+), 12 deletions(-)
12
15
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
18
--- a/target/arm/translate-vfp.c
16
+++ b/target/arm/neon-dp.decode
19
+++ b/target/arm/translate-vfp.c
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
21
break;
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
22
case ARM_VFP_FPSCR_NZCVQC:
20
23
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
24
- return false;
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
25
+ return FPSysRegCheckFailed;
23
+
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
25
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
26
27
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
28
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
29
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
30
31
+VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
32
+VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
33
+
34
VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
35
VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
36
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
42
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
43
}
44
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
45
+
46
+#define DO_3SAME_GVEC4(INSN, OPARRAY) \
47
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
48
+ uint32_t rn_ofs, uint32_t rm_ofs, \
49
+ uint32_t oprsz, uint32_t maxsz) \
50
+ { \
51
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
52
+ rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
53
+ } \
54
+ DO_3SAME(INSN, gen_##INSN##_3s)
55
+
56
+DO_3SAME_GVEC4(VQADD_S, sqadd_op)
57
+DO_3SAME_GVEC4(VQADD_U, uqadd_op)
58
+DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
59
+DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
}
66
return 1;
67
68
- case NEON_3R_VQADD:
69
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
70
- rn_ofs, rm_ofs, vec_size, vec_size,
71
- (u ? uqadd_op : sqadd_op) + size);
72
- return 0;
73
-
74
- case NEON_3R_VQSUB:
75
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
76
- rn_ofs, rm_ofs, vec_size, vec_size,
77
- (u ? uqsub_op : sqsub_op) + size);
78
- return 0;
79
-
80
case NEON_3R_VMUL: /* VMUL */
81
if (u) {
82
/* Polynomial case allows only P8. */
83
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
case NEON_3R_VTST_VCEQ:
85
case NEON_3R_VCGT:
86
case NEON_3R_VCGE:
87
+ case NEON_3R_VQADD:
88
+ case NEON_3R_VQSUB:
89
/* Already handled by decodetree */
90
return 1;
91
}
26
}
27
break;
28
case ARM_VFP_FPCXT_S:
29
case ARM_VFP_FPCXT_NS:
30
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
31
- return false;
32
+ return FPSysRegCheckFailed;
33
}
34
if (!s->v8m_secure) {
35
- return false;
36
+ return FPSysRegCheckFailed;
37
}
38
break;
39
default:
92
--
40
--
93
2.20.1
41
2.20.1
94
42
95
43
diff view generated by jsdifflib
1
Convert the Neon "load/store multiple structures" insns to decodetree.
1
If MVE is implemented for an M-profile CPU then it has a VPR
2
register, which tracks predication information.
3
4
Implement the read and write handling of this register, and
5
the migration of its state.
2
6
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
9
Message-id: 20210520152840.24453-7-peter.maydell@linaro.org
6
---
10
---
7
target/arm/neon-ls.decode | 7 ++
11
target/arm/cpu.h | 6 ++++++
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
12
target/arm/machine.c | 19 +++++++++++++++++++
9
target/arm/translate.c | 91 +----------------------
13
target/arm/translate-vfp.c | 38 ++++++++++++++++++++++++++++++++++++++
10
3 files changed, 133 insertions(+), 89 deletions(-)
14
3 files changed, 63 insertions(+)
11
15
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-ls.decode
18
--- a/target/arm/cpu.h
15
+++ b/target/arm/neon-ls.decode
19
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
21
uint32_t cpacr[M_REG_NUM_BANKS];
18
# This file works on the A32 encoding only; calling code for T32 has to
22
uint32_t nsacr;
19
# transform the insn into the A32 version first.
23
int ltpsize;
24
+ uint32_t vpr;
25
} v7m;
26
27
/* Information associated with an exception about to be taken:
28
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_FPCCR, ASPEN, 31, 1)
29
R_V7M_FPCCR_UFRDY_MASK | \
30
R_V7M_FPCCR_ASPEN_MASK)
31
32
+/* v7M VPR bits */
33
+FIELD(V7M_VPR, P0, 0, 16)
34
+FIELD(V7M_VPR, MASK01, 16, 4)
35
+FIELD(V7M_VPR, MASK23, 20, 4)
20
+
36
+
21
+%vd_dp 22:1 12:4
37
/*
38
* System register ID fields.
39
*/
40
diff --git a/target/arm/machine.c b/target/arm/machine.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/machine.c
43
+++ b/target/arm/machine.c
44
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_fp = {
45
}
46
};
47
48
+static bool mve_needed(void *opaque)
49
+{
50
+ ARMCPU *cpu = opaque;
22
+
51
+
23
+# Neon load/store multiple structures
52
+ return cpu_isar_feature(aa32_mve, cpu);
53
+}
24
+
54
+
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
55
+static const VMStateDescription vmstate_m_mve = {
26
+ vd=%vd_dp
56
+ .name = "cpu/m/mve",
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
57
+ .version_id = 1,
28
index XXXXXXX..XXXXXXX 100644
58
+ .minimum_version_id = 1,
29
--- a/target/arm/translate-neon.inc.c
59
+ .needed = mve_needed,
30
+++ b/target/arm/translate-neon.inc.c
60
+ .fields = (VMStateField[]) {
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
61
+ VMSTATE_UINT32(env.v7m.vpr, ARMCPU),
32
gen_helper_gvec_fmlal_idx_a32);
62
+ VMSTATE_END_OF_LIST()
33
return true;
63
+ },
34
}
35
+
36
+static struct {
37
+ int nregs;
38
+ int interleave;
39
+ int spacing;
40
+} const neon_ls_element_type[11] = {
41
+ {1, 4, 1},
42
+ {1, 4, 2},
43
+ {4, 1, 1},
44
+ {2, 2, 2},
45
+ {1, 3, 1},
46
+ {1, 3, 2},
47
+ {3, 1, 1},
48
+ {1, 1, 1},
49
+ {1, 2, 1},
50
+ {1, 2, 2},
51
+ {2, 1, 1}
52
+};
64
+};
53
+
65
+
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
66
static const VMStateDescription vmstate_m = {
55
+ int stride)
67
.name = "cpu/m",
56
+{
68
.version_id = 4,
57
+ if (rm != 15) {
69
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
58
+ TCGv_i32 base;
70
&vmstate_m_other_sp,
59
+
71
&vmstate_m_v8m,
60
+ base = load_reg(s, rn);
72
&vmstate_m_fp,
61
+ if (rm == 13) {
73
+ &vmstate_m_mve,
62
+ tcg_gen_addi_i32(base, base, stride);
74
NULL
63
+ } else {
75
}
64
+ TCGv_i32 index;
76
};
65
+ index = load_reg(s, rm);
77
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
66
+ tcg_gen_add_i32(base, base, index);
78
index XXXXXXX..XXXXXXX 100644
67
+ tcg_temp_free_i32(index);
79
--- a/target/arm/translate-vfp.c
68
+ }
80
+++ b/target/arm/translate-vfp.c
69
+ store_reg(s, rn, base);
81
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
70
+ }
82
return FPSysRegCheckFailed;
71
+}
83
}
72
+
84
break;
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
85
+ case ARM_VFP_VPR:
74
+{
86
+ case ARM_VFP_P0:
75
+ /* Neon load/store multiple structures */
87
+ if (!dc_isar_feature(aa32_mve, s)) {
76
+ int nregs, interleave, spacing, reg, n;
88
+ return FPSysRegCheckFailed;
77
+ MemOp endian = s->be_data;
78
+ int mmu_idx = get_mem_index(s);
79
+ int size = a->size;
80
+ TCGv_i64 tmp64;
81
+ TCGv_i32 addr, tmp;
82
+
83
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
84
+ return false;
85
+ }
86
+
87
+ /* UNDEF accesses to D16-D31 if they don't exist */
88
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
89
+ return false;
90
+ }
91
+ if (a->itype > 10) {
92
+ return false;
93
+ }
94
+ /* Catch UNDEF cases for bad values of align field */
95
+ switch (a->itype & 0xc) {
96
+ case 4:
97
+ if (a->align >= 2) {
98
+ return false;
99
+ }
89
+ }
100
+ break;
90
+ break;
101
+ case 8:
91
default:
102
+ if (a->align == 3) {
92
return FPSysRegCheckFailed;
103
+ return false;
93
}
94
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
95
tcg_temp_free_i32(sfpa);
96
break;
97
}
98
+ case ARM_VFP_VPR:
99
+ /* Behaves as NOP if not privileged */
100
+ if (IS_USER(s)) {
101
+ break;
104
+ }
102
+ }
103
+ tmp = loadfn(s, opaque);
104
+ store_cpu_field(tmp, v7m.vpr);
105
+ break;
105
+ break;
106
+ default:
106
+ case ARM_VFP_P0:
107
+ {
108
+ TCGv_i32 vpr;
109
+ tmp = loadfn(s, opaque);
110
+ vpr = load_cpu_field(v7m.vpr);
111
+ tcg_gen_deposit_i32(vpr, vpr, tmp,
112
+ R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH);
113
+ store_cpu_field(vpr, v7m.vpr);
114
+ tcg_temp_free_i32(tmp);
107
+ break;
115
+ break;
108
+ }
116
+ }
109
+ nregs = neon_ls_element_type[a->itype].nregs;
117
default:
110
+ interleave = neon_ls_element_type[a->itype].interleave;
118
g_assert_not_reached();
111
+ spacing = neon_ls_element_type[a->itype].spacing;
119
}
112
+ if (size == 3 && (interleave | spacing) != 1) {
120
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
113
+ return false;
121
tcg_temp_free_i32(fpscr);
114
+ }
122
break;
115
+
123
}
116
+ if (!vfp_access_check(s)) {
124
+ case ARM_VFP_VPR:
117
+ return true;
125
+ /* Behaves as NOP if not privileged */
118
+ }
126
+ if (IS_USER(s)) {
119
+
127
+ break;
120
+ /* For our purposes, bytes are always little-endian. */
121
+ if (size == 0) {
122
+ endian = MO_LE;
123
+ }
124
+ /*
125
+ * Consecutive little-endian elements from a single register
126
+ * can be promoted to a larger little-endian operation.
127
+ */
128
+ if (interleave == 1 && endian == MO_LE) {
129
+ size = 3;
130
+ }
131
+ tmp64 = tcg_temp_new_i64();
132
+ addr = tcg_temp_new_i32();
133
+ tmp = tcg_const_i32(1 << size);
134
+ load_reg_var(s, addr, a->rn);
135
+ for (reg = 0; reg < nregs; reg++) {
136
+ for (n = 0; n < 8 >> size; n++) {
137
+ int xs;
138
+ for (xs = 0; xs < interleave; xs++) {
139
+ int tt = a->vd + reg + spacing * xs;
140
+
141
+ if (a->l) {
142
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
143
+ neon_store_element64(tt, n, size, tmp64);
144
+ } else {
145
+ neon_load_element64(tmp64, tt, n, size);
146
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
147
+ }
148
+ tcg_gen_add_i32(addr, addr, tmp);
149
+ }
150
+ }
128
+ }
151
+ }
129
+ tmp = load_cpu_field(v7m.vpr);
152
+ tcg_temp_free_i32(addr);
130
+ storefn(s, opaque, tmp);
153
+ tcg_temp_free_i32(tmp);
131
+ break;
154
+ tcg_temp_free_i64(tmp64);
132
+ case ARM_VFP_P0:
155
+
133
+ tmp = load_cpu_field(v7m.vpr);
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
134
+ tcg_gen_extract_i32(tmp, tmp, R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH);
157
+ return true;
135
+ storefn(s, opaque, tmp);
158
+}
136
+ break;
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
137
default:
160
index XXXXXXX..XXXXXXX 100644
138
g_assert_not_reached();
161
--- a/target/arm/translate.c
139
}
162
+++ b/target/arm/translate.c
163
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
164
}
165
166
167
-static struct {
168
- int nregs;
169
- int interleave;
170
- int spacing;
171
-} const neon_ls_element_type[11] = {
172
- {1, 4, 1},
173
- {1, 4, 2},
174
- {4, 1, 1},
175
- {2, 2, 2},
176
- {1, 3, 1},
177
- {1, 3, 2},
178
- {3, 1, 1},
179
- {1, 1, 1},
180
- {1, 2, 1},
181
- {1, 2, 2},
182
- {2, 1, 1}
183
-};
184
-
185
/* Translate a NEON load/store element instruction. Return nonzero if the
186
instruction is invalid. */
187
static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
188
{
189
int rd, rn, rm;
190
- int op;
191
int nregs;
192
- int interleave;
193
- int spacing;
194
int stride;
195
int size;
196
int reg;
197
int load;
198
- int n;
199
int vec_size;
200
- int mmu_idx;
201
- MemOp endian;
202
TCGv_i32 addr;
203
TCGv_i32 tmp;
204
- TCGv_i32 tmp2;
205
- TCGv_i64 tmp64;
206
207
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
208
return 1;
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
210
rn = (insn >> 16) & 0xf;
211
rm = insn & 0xf;
212
load = (insn & (1 << 21)) != 0;
213
- endian = s->be_data;
214
- mmu_idx = get_mem_index(s);
215
if ((insn & (1 << 23)) == 0) {
216
- /* Load store all elements. */
217
- op = (insn >> 8) & 0xf;
218
- size = (insn >> 6) & 3;
219
- if (op > 10)
220
- return 1;
221
- /* Catch UNDEF cases for bad values of align field */
222
- switch (op & 0xc) {
223
- case 4:
224
- if (((insn >> 5) & 1) == 1) {
225
- return 1;
226
- }
227
- break;
228
- case 8:
229
- if (((insn >> 4) & 3) == 3) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- break;
235
- }
236
- nregs = neon_ls_element_type[op].nregs;
237
- interleave = neon_ls_element_type[op].interleave;
238
- spacing = neon_ls_element_type[op].spacing;
239
- if (size == 3 && (interleave | spacing) != 1) {
240
- return 1;
241
- }
242
- /* For our purposes, bytes are always little-endian. */
243
- if (size == 0) {
244
- endian = MO_LE;
245
- }
246
- /* Consecutive little-endian elements from a single register
247
- * can be promoted to a larger little-endian operation.
248
- */
249
- if (interleave == 1 && endian == MO_LE) {
250
- size = 3;
251
- }
252
- tmp64 = tcg_temp_new_i64();
253
- addr = tcg_temp_new_i32();
254
- tmp2 = tcg_const_i32(1 << size);
255
- load_reg_var(s, addr, rn);
256
- for (reg = 0; reg < nregs; reg++) {
257
- for (n = 0; n < 8 >> size; n++) {
258
- int xs;
259
- for (xs = 0; xs < interleave; xs++) {
260
- int tt = rd + reg + spacing * xs;
261
-
262
- if (load) {
263
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
264
- neon_store_element64(tt, n, size, tmp64);
265
- } else {
266
- neon_load_element64(tmp64, tt, n, size);
267
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
268
- }
269
- tcg_gen_add_i32(addr, addr, tmp2);
270
- }
271
- }
272
- }
273
- tcg_temp_free_i32(addr);
274
- tcg_temp_free_i32(tmp2);
275
- tcg_temp_free_i64(tmp64);
276
- stride = nregs * interleave * 8;
277
+ /* Load store all elements -- handled already by decodetree */
278
+ return 1;
279
} else {
280
size = (insn >> 10) & 3;
281
if (size == 3) {
282
--
140
--
283
2.20.1
141
2.20.1
284
142
285
143
diff view generated by jsdifflib
1
Convert the Neon comparison ops in the 3-reg-same grouping
1
The M-profile FPSCR has an LTPSIZE field, but if MVE is not
2
to decodetree.
2
implemented it is read-only and always reads as 4; this is how QEMU
3
currently handles it.
4
5
Make the field writable when MVE is implemented.
6
7
We can safely add the field to the MVE migration struct because
8
currently no CPUs enable MVE and so the migration struct is never
9
used.
3
10
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
13
Message-id: 20210520152840.24453-8-peter.maydell@linaro.org
7
---
14
---
8
target/arm/neon-dp.decode | 8 ++++++++
15
target/arm/cpu.h | 3 ++-
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
16
target/arm/machine.c | 1 +
10
target/arm/translate.c | 23 +++--------------------
17
target/arm/vfp_helper.c | 9 ++++++---
11
3 files changed, 33 insertions(+), 20 deletions(-)
18
3 files changed, 9 insertions(+), 4 deletions(-)
12
19
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
22
--- a/target/arm/cpu.h
16
+++ b/target/arm/neon-dp.decode
23
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
24
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
25
uint32_t fpdscr[M_REG_NUM_BANKS];
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
26
uint32_t cpacr[M_REG_NUM_BANKS];
20
27
uint32_t nsacr;
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
28
- int ltpsize;
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
29
+ uint32_t ltpsize;
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
30
uint32_t vpr;
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
31
} v7m;
32
33
@@ -XXX,XX +XXX,XX @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
34
35
#define FPCR_LTPSIZE_SHIFT 16 /* LTPSIZE, M-profile only */
36
#define FPCR_LTPSIZE_MASK (7 << FPCR_LTPSIZE_SHIFT)
37
+#define FPCR_LTPSIZE_LENGTH 3
38
39
#define FPCR_NZCV_MASK (FPCR_N | FPCR_Z | FPCR_C | FPCR_V)
40
#define FPCR_NZCVQC_MASK (FPCR_NZCV_MASK | FPCR_QC)
41
diff --git a/target/arm/machine.c b/target/arm/machine.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/machine.c
44
+++ b/target/arm/machine.c
45
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_mve = {
46
.needed = mve_needed,
47
.fields = (VMStateField[]) {
48
VMSTATE_UINT32(env.v7m.vpr, ARMCPU),
49
+ VMSTATE_UINT32(env.v7m.ltpsize, ARMCPU),
50
VMSTATE_END_OF_LIST()
51
},
52
};
53
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/vfp_helper.c
56
+++ b/target/arm/vfp_helper.c
57
@@ -XXX,XX +XXX,XX @@ uint32_t vfp_get_fpscr(CPUARMState *env)
58
59
void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
60
{
61
+ ARMCPU *cpu = env_archcpu(env);
25
+
62
+
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
63
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
64
- if (!cpu_isar_feature(any_fp16, env_archcpu(env))) {
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
65
+ if (!cpu_isar_feature(any_fp16, cpu)) {
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
66
val &= ~FPCR_FZ16;
30
67
}
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
68
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
69
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
33
+
70
* because in v7A no-short-vector-support cores still had to
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
71
* allow Stride/Len to be written with the only effect that
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
72
* some insns are required to UNDEF if the guest sets them.
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
73
- *
37
index XXXXXXX..XXXXXXX 100644
74
- * TODO: if M-profile MVE implemented, set LTPSIZE.
38
--- a/target/arm/translate-neon.inc.c
75
*/
39
+++ b/target/arm/translate-neon.inc.c
76
env->vfp.vec_len = extract32(val, 16, 3);
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
77
env->vfp.vec_stride = extract32(val, 20, 2);
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
78
+ } else if (cpu_isar_feature(aa32_mve, cpu)) {
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
79
+ env->v7m.ltpsize = extract32(val, FPCR_LTPSIZE_SHIFT,
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
80
+ FPCR_LTPSIZE_LENGTH);
44
+
81
}
45
+#define DO_3SAME_CMP(INSN, COND) \
82
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
83
if (arm_feature(env, ARM_FEATURE_NEON)) {
47
+ uint32_t rn_ofs, uint32_t rm_ofs, \
48
+ uint32_t oprsz, uint32_t maxsz) \
49
+ { \
50
+ tcg_gen_gvec_cmp(COND, vece, rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz); \
51
+ } \
52
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
53
+
54
+DO_3SAME_CMP(VCGT_S, TCG_COND_GT)
55
+DO_3SAME_CMP(VCGT_U, TCG_COND_GTU)
56
+DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
57
+DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
58
+DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
59
+
60
+static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
61
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
62
+{
63
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
64
+}
65
+DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
u ? &mls_op[size] : &mla_op[size]);
72
return 0;
73
74
- case NEON_3R_VTST_VCEQ:
75
- if (u) { /* VCEQ */
76
- tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
77
- vec_size, vec_size);
78
- } else { /* VTST */
79
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
80
- vec_size, vec_size, &cmtst_op[size]);
81
- }
82
- return 0;
83
-
84
- case NEON_3R_VCGT:
85
- tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
86
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
87
- return 0;
88
-
89
- case NEON_3R_VCGE:
90
- tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
91
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
92
- return 0;
93
-
94
case NEON_3R_VSHL:
95
/* Note the operation is vshl vd,vm,vn */
96
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
case NEON_3R_LOGIC:
99
case NEON_3R_VMAX:
100
case NEON_3R_VMIN:
101
+ case NEON_3R_VTST_VCEQ:
102
+ case NEON_3R_VCGT:
103
+ case NEON_3R_VCGE:
104
/* Already handled by decodetree */
105
return 1;
106
}
107
--
84
--
108
2.20.1
85
2.20.1
109
86
110
87
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Currently we allow board models to specify the initial value of the
2
Secure VTOR register, using an init-svtor property on the TYPE_ARMV7M
3
object which is plumbed through to the CPU. Allow board models to
4
also specify the initial value of the Non-secure VTOR via a similar
5
init-nsvtor property.
2
6
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
uint32_t.
9
Message-id: 20210520152840.24453-10-peter.maydell@linaro.org
10
---
11
include/hw/arm/armv7m.h | 2 ++
12
target/arm/cpu.h | 2 ++
13
hw/arm/armv7m.c | 7 +++++++
14
target/arm/cpu.c | 10 ++++++++++
15
4 files changed, 21 insertions(+)
6
16
7
This fixes an error when compiling with -Werror=conversion
17
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
8
because we were manipulating the register value using a
18
index XXXXXXX..XXXXXXX 100644
9
local uint64_t variable:
19
--- a/include/hw/arm/armv7m.h
10
20
+++ b/include/hw/arm/armv7m.h
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
21
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M)
12
target/arm/cpu64.c:628:21: error: conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Werror=conversion]
22
* devices will be automatically layered on top of this view.)
13
628 | cpu->midr = t;
23
* + Property "idau": IDAU interface (forwarded to CPU object)
14
| ^
24
* + Property "init-svtor": secure VTOR reset value (forwarded to CPU object)
15
25
+ * + Property "init-nsvtor": non-secure VTOR reset value (forwarded to CPU object)
16
and future-proofs us against a possible future architecture
26
* + Property "vfp": enable VFP (forwarded to CPU object)
17
change using some of the top 32 bits.
27
* + Property "dsp": enable DSP (forwarded to CPU object)
18
28
* + Property "enable-bitband": expose bitbanded IO
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
29
@@ -XXX,XX +XXX,XX @@ struct ARMv7MState {
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
30
MemoryRegion *board_memory;
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
31
Object *idau;
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
32
uint32_t init_svtor;
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
33
+ uint32_t init_nsvtor;
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
34
bool enable_bitband;
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
bool start_powered_off;
26
---
36
bool vfp;
27
target/arm/cpu.h | 2 +-
28
target/arm/cpu.c | 2 +-
29
2 files changed, 2 insertions(+), 2 deletions(-)
30
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
37
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
39
--- a/target/arm/cpu.h
34
+++ b/target/arm/cpu.h
40
+++ b/target/arm/cpu.h
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
41
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
36
uint64_t id_aa64dfr0;
42
37
uint64_t id_aa64dfr1;
43
/* For v8M, initial value of the Secure VTOR */
38
} isar;
44
uint32_t init_svtor;
39
- uint32_t midr;
45
+ /* For v8M, initial value of the Non-secure VTOR */
40
+ uint64_t midr;
46
+ uint32_t init_nsvtor;
41
uint32_t revidr;
47
42
uint32_t reset_fpsid;
48
/* [QEMU_]KVM_ARM_TARGET_* constant for this CPU, or
43
uint32_t ctr;
49
* QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type.
50
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/armv7m.c
53
+++ b/hw/arm/armv7m.c
54
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
55
return;
56
}
57
}
58
+ if (object_property_find(OBJECT(s->cpu), "init-nsvtor")) {
59
+ if (!object_property_set_uint(OBJECT(s->cpu), "init-nsvtor",
60
+ s->init_nsvtor, errp)) {
61
+ return;
62
+ }
63
+ }
64
if (object_property_find(OBJECT(s->cpu), "start-powered-off")) {
65
if (!object_property_set_bool(OBJECT(s->cpu), "start-powered-off",
66
s->start_powered_off, errp)) {
67
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
68
MemoryRegion *),
69
DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
70
DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
71
+ DEFINE_PROP_UINT32("init-nsvtor", ARMv7MState, init_nsvtor, 0),
72
DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
73
DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
74
false),
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
75
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.c
77
--- a/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
78
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
79
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
49
static Property arm_cpu_properties[] = {
80
env->regs[14] = 0xffffffff;
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
81
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
82
env->v7m.vecbase[M_REG_S] = cpu->init_svtor & 0xffffff80;
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
83
+ env->v7m.vecbase[M_REG_NS] = cpu->init_nsvtor & 0xffffff80;
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
84
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
85
/* Load the initial SP and PC from offset 0 and 4 in the vector table */
55
mp_affinity, ARM64_AFFINITY_INVALID),
86
vecbase = env->v7m.vecbase[env->v7m.secure];
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
87
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
88
&cpu->init_svtor,
89
OBJ_PROP_FLAG_READWRITE);
90
}
91
+ if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
92
+ /*
93
+ * Initial value of the NS VTOR (for cores without the Security
94
+ * extension, this is the only VTOR)
95
+ */
96
+ object_property_add_uint32_ptr(obj, "init-nsvtor",
97
+ &cpu->init_nsvtor,
98
+ OBJ_PROP_FLAG_READWRITE);
99
+ }
100
101
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
102
57
--
103
--
58
2.20.1
104
2.20.1
59
105
60
106
diff view generated by jsdifflib
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
1
The official punctuation for Arm CPU names uses a hyphen, like
2
Note that for the logic ops the 'size' field forms part of their
2
"Cortex-A9". We mostly follow this, but in a few places usage
3
decode and the actual operations are always bitwise.
3
without the hyphen has crept in. Fix those so we consistently
4
use the same way of writing the CPU name.
5
6
This commit was created with:
7
git grep -z -l 'Cortex ' | xargs -0 sed -i 's/Cortex /Cortex-/'
4
8
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: 20210527095152.10968-1-peter.maydell@linaro.org
8
---
14
---
9
target/arm/neon-dp.decode | 12 +++++++++++
15
docs/system/arm/aspeed.rst | 4 ++--
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
16
docs/system/arm/nuvoton.rst | 6 +++---
11
target/arm/translate.c | 38 +--------------------------------
17
docs/system/arm/sabrelite.rst | 2 +-
12
3 files changed, 32 insertions(+), 37 deletions(-)
18
include/hw/arm/allwinner-h3.h | 2 +-
13
19
hw/arm/aspeed.c | 6 +++---
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
20
hw/arm/mcimx6ul-evk.c | 2 +-
15
index XXXXXXX..XXXXXXX 100644
21
hw/arm/mcimx7d-sabre.c | 2 +-
16
--- a/target/arm/neon-dp.decode
22
hw/arm/npcm7xx_boards.c | 4 ++--
17
+++ b/target/arm/neon-dp.decode
23
hw/arm/sabrelite.c | 2 +-
24
hw/misc/npcm7xx_clk.c | 2 +-
25
10 files changed, 16 insertions(+), 16 deletions(-)
26
27
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
28
index XXXXXXX..XXXXXXX 100644
29
--- a/docs/system/arm/aspeed.rst
30
+++ b/docs/system/arm/aspeed.rst
31
@@ -XXX,XX +XXX,XX @@ The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
32
Aspeed evaluation boards. They are based on different releases of the
33
Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the
34
AST2500 with an ARM1176JZS CPU (800MHz) and more recently the AST2600
35
-with dual cores ARM Cortex A7 CPUs (1.2GHz).
36
+with dual cores ARM Cortex-A7 CPUs (1.2GHz).
37
38
The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
39
etc.
40
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
41
42
AST2600 SoC based machines :
43
44
-- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex A7)
45
+- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
46
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
47
48
Supported devices
49
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
50
index XXXXXXX..XXXXXXX 100644
51
--- a/docs/system/arm/nuvoton.rst
52
+++ b/docs/system/arm/nuvoton.rst
53
@@ -XXX,XX +XXX,XX @@ Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
54
55
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
56
designed to be used as Baseboard Management Controllers (BMCs) in various
57
-servers. They all feature one or two ARM Cortex A9 CPU cores, as well as an
58
+servers. They all feature one or two ARM Cortex-A9 CPU cores, as well as an
59
assortment of peripherals targeted for either Enterprise or Data Center /
60
Hyperscale applications. The former is a superset of the latter, so NPCM750 has
61
all the peripherals of NPCM730 and more.
62
63
.. _Nuvoton iBMC: https://www.nuvoton.com/products/cloud-computing/ibmc/
64
65
-The NPCM750 SoC has two Cortex A9 cores and is targeted for the Enterprise
66
+The NPCM750 SoC has two Cortex-A9 cores and is targeted for the Enterprise
67
segment. The following machines are based on this chip :
68
69
- ``npcm750-evb`` Nuvoton NPCM750 Evaluation board
70
71
-The NPCM730 SoC has two Cortex A9 cores and is targeted for Data Center and
72
+The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
73
Hyperscale applications. The following machines are based on this chip :
74
75
- ``quanta-gsj`` Quanta GSJ server BMC
76
diff --git a/docs/system/arm/sabrelite.rst b/docs/system/arm/sabrelite.rst
77
index XXXXXXX..XXXXXXX 100644
78
--- a/docs/system/arm/sabrelite.rst
79
+++ b/docs/system/arm/sabrelite.rst
80
@@ -XXX,XX +XXX,XX @@ Supported devices
81
82
The SABRE Lite machine supports the following devices:
83
84
- * Up to 4 Cortex A9 cores
85
+ * Up to 4 Cortex-A9 cores
86
* Generic Interrupt Controller
87
* 1 Clock Controller Module
88
* 1 System Reset Controller
89
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
90
index XXXXXXX..XXXXXXX 100644
91
--- a/include/hw/arm/allwinner-h3.h
92
+++ b/include/hw/arm/allwinner-h3.h
18
@@ -XXX,XX +XXX,XX @@
93
@@ -XXX,XX +XXX,XX @@
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
94
*/
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
95
21
96
/*
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
97
- * The Allwinner H3 is a System on Chip containing four ARM Cortex A7
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
98
+ * The Allwinner H3 is a System on Chip containing four ARM Cortex-A7
24
+
99
* processor cores. Features and specifications include DDR2/DDR3 memory,
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
100
* SD/MMC storage cards, 10/100/1000Mbit Ethernet, USB 2.0, HDMI and
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
101
* various I/O modules.
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
102
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
103
index XXXXXXX..XXXXXXX 100644
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
104
--- a/hw/arm/aspeed.c
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
105
+++ b/hw/arm/aspeed.c
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
106
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
107
MachineClass *mc = MACHINE_CLASS(oc);
33
+
108
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
109
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
110
- mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
111
+ mc->desc = "Aspeed AST2600 EVB (Cortex-A7)";
37
index XXXXXXX..XXXXXXX 100644
112
amc->soc_name = "ast2600-a1";
38
--- a/target/arm/translate-neon.inc.c
113
amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
39
+++ b/target/arm/translate-neon.inc.c
114
amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
41
116
MachineClass *mc = MACHINE_CLASS(oc);
42
DO_3SAME(VADD, tcg_gen_gvec_add)
117
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
118
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
119
- mc->desc = "OpenPOWER Tacoma BMC (Cortex A7)";
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
120
+ mc->desc = "OpenPOWER Tacoma BMC (Cortex-A7)";
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
121
amc->soc_name = "ast2600-a1";
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
122
amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
123
amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
49
+
124
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_rainier_class_init(ObjectClass *oc, void *data)
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
125
MachineClass *mc = MACHINE_CLASS(oc);
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
126
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
127
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
128
- mc->desc = "IBM Rainier BMC (Cortex A7)";
54
+ uint32_t oprsz, uint32_t maxsz) \
129
+ mc->desc = "IBM Rainier BMC (Cortex-A7)";
55
+ { \
130
amc->soc_name = "ast2600-a1";
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
131
amc->hw_strap1 = RAINIER_BMC_HW_STRAP1;
57
+ } \
132
amc->hw_strap2 = RAINIER_BMC_HW_STRAP2;
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
133
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
59
+
134
index XXXXXXX..XXXXXXX 100644
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
135
--- a/hw/arm/mcimx6ul-evk.c
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
136
+++ b/hw/arm/mcimx6ul-evk.c
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
137
@@ -XXX,XX +XXX,XX @@ static void mcimx6ul_evk_init(MachineState *machine)
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
138
64
index XXXXXXX..XXXXXXX 100644
139
static void mcimx6ul_evk_machine_init(MachineClass *mc)
65
--- a/target/arm/translate.c
140
{
66
+++ b/target/arm/translate.c
141
- mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex A7)";
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
142
+ mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex-A7)";
68
}
143
mc->init = mcimx6ul_evk_init;
69
return 1;
144
mc->max_cpus = FSL_IMX6UL_NUM_CPUS;
70
145
mc->default_ram_id = "mcimx6ul-evk.ram";
71
- case NEON_3R_LOGIC: /* Logic ops. */
146
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
72
- switch ((u << 2) | size) {
147
index XXXXXXX..XXXXXXX 100644
73
- case 0: /* VAND */
148
--- a/hw/arm/mcimx7d-sabre.c
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
149
+++ b/hw/arm/mcimx7d-sabre.c
75
- vec_size, vec_size);
150
@@ -XXX,XX +XXX,XX @@ static void mcimx7d_sabre_init(MachineState *machine)
76
- break;
151
77
- case 1: /* VBIC */
152
static void mcimx7d_sabre_machine_init(MachineClass *mc)
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
153
{
79
- vec_size, vec_size);
154
- mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex A7)";
80
- break;
155
+ mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex-A7)";
81
- case 2: /* VORR */
156
mc->init = mcimx7d_sabre_init;
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
157
mc->max_cpus = FSL_IMX7_NUM_CPUS;
83
- vec_size, vec_size);
158
mc->default_ram_id = "mcimx7d-sabre.ram";
84
- break;
159
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
85
- case 3: /* VORN */
160
index XXXXXXX..XXXXXXX 100644
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
161
--- a/hw/arm/npcm7xx_boards.c
87
- vec_size, vec_size);
162
+++ b/hw/arm/npcm7xx_boards.c
88
- break;
163
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_machine_class_init(ObjectClass *oc, void *data)
89
- case 4: /* VEOR */
164
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
165
npcm7xx_set_soc_type(nmc, TYPE_NPCM750);
91
- vec_size, vec_size);
166
92
- break;
167
- mc->desc = "Nuvoton NPCM750 Evaluation Board (Cortex A9)";
93
- case 5: /* VBSL */
168
+ mc->desc = "Nuvoton NPCM750 Evaluation Board (Cortex-A9)";
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
169
mc->init = npcm750_evb_init;
95
- vec_size, vec_size);
170
mc->default_ram_size = 512 * MiB;
96
- break;
171
};
97
- case 6: /* VBIT */
172
@@ -XXX,XX +XXX,XX @@ static void gsj_machine_class_init(ObjectClass *oc, void *data)
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
173
99
- vec_size, vec_size);
174
npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
100
- break;
175
101
- case 7: /* VBIF */
176
- mc->desc = "Quanta GSJ (Cortex A9)";
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
177
+ mc->desc = "Quanta GSJ (Cortex-A9)";
103
- vec_size, vec_size);
178
mc->init = quanta_gsj_init;
104
- break;
179
mc->default_ram_size = 512 * MiB;
105
- }
180
};
106
- return 0;
181
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
107
-
182
index XXXXXXX..XXXXXXX 100644
108
case NEON_3R_VQADD:
183
--- a/hw/arm/sabrelite.c
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
184
+++ b/hw/arm/sabrelite.c
110
rn_ofs, rm_ofs, vec_size, vec_size,
185
@@ -XXX,XX +XXX,XX @@ static void sabrelite_init(MachineState *machine)
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
186
112
return 0;
187
static void sabrelite_machine_init(MachineClass *mc)
113
188
{
114
case NEON_3R_VADD_VSUB:
189
- mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)";
115
+ case NEON_3R_LOGIC:
190
+ mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex-A9)";
116
/* Already handled by decodetree */
191
mc->init = sabrelite_init;
117
return 1;
192
mc->max_cpus = FSL_IMX6_NUM_CPUS;
118
}
193
mc->ignore_memory_transaction_failures = true;
194
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
195
index XXXXXXX..XXXXXXX 100644
196
--- a/hw/misc/npcm7xx_clk.c
197
+++ b/hw/misc/npcm7xx_clk.c
198
@@ -XXX,XX +XXX,XX @@
199
#define NPCM7XX_CLOCK_REF_HZ (25000000)
200
201
/* Register Field Definitions */
202
-#define NPCM7XX_CLK_WDRCR_CA9C BIT(0) /* Cortex A9 Cores */
203
+#define NPCM7XX_CLK_WDRCR_CA9C BIT(0) /* Cortex-A9 Cores */
204
205
#define PLLCON_LOKI BIT(31)
206
#define PLLCON_LOKS BIT(30)
119
--
207
--
120
2.20.1
208
2.20.1
121
209
122
210
diff view generated by jsdifflib
New patch
1
From: Damien Goutte-Gattat <dgouttegattat@incenp.org>
1
2
3
The 4.x branch of Sphinx introduces a breaking change, as generated man
4
pages are now written to subdirectories corresponding to the manual
5
section they belong to. This results in `make install` erroring out when
6
attempting to install the man pages, because they are not where it
7
expects to find them.
8
9
This patch restores the behavior of Sphinx 3.x regarding man pages.
10
11
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/256
12
Signed-off-by: Damien Goutte-Gattat <dgouttegattat@incenp.org>
13
Message-id: 20210503161422.15028-1-dgouttegattat@incenp.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
docs/conf.py | 1 +
18
1 file changed, 1 insertion(+)
19
20
diff --git a/docs/conf.py b/docs/conf.py
21
index XXXXXXX..XXXXXXX 100644
22
--- a/docs/conf.py
23
+++ b/docs/conf.py
24
@@ -XXX,XX +XXX,XX @@
25
['Stefan Hajnoczi <stefanha@redhat.com>',
26
'Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>'], 1),
27
]
28
+man_make_section_directory = False
29
30
# -- Options for Texinfo output -------------------------------------------
31
32
--
33
2.20.1
34
35
diff view generated by jsdifflib
1
We're going to want at least some of the NeonGen* typedefs
1
From: Richard Henderson <richard.henderson@linaro.org>
2
for the refactored 32-bit Neon decoder, so move them all
3
to translate.h since it makes more sense to keep them in
4
one group.
5
2
3
The operands to tcg_gen_atomic_fetch_s{min,max}_i64 must
4
be signed, so that the inputs are properly extended.
5
Zero extend the result afterward, as needed.
6
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/364
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20210602020720.47679-1-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200430181003.21682-23-peter.maydell@linaro.org
9
---
12
---
10
target/arm/translate.h | 17 +++++++++++++++++
13
target/arm/translate-a64.c | 13 ++++++++++---
11
target/arm/translate-a64.c | 17 -----------------
14
1 file changed, 10 insertions(+), 3 deletions(-)
12
2 files changed, 17 insertions(+), 17 deletions(-)
13
15
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
17
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
20
uint32_t, uint32_t, uint32_t);
21
22
+/* Function prototype for gen_ functions for calling Neon helpers */
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
41
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-a64.c
18
--- a/target/arm/translate-a64.c
43
+++ b/target/arm/translate-a64.c
19
+++ b/target/arm/translate-a64.c
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
20
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
45
AArch64DecodeFn *disas_fn;
21
int o3_opc = extract32(insn, 12, 4);
46
} AArch64DecodeTable;
22
bool r = extract32(insn, 22, 1);
47
23
bool a = extract32(insn, 23, 1);
48
-/* Function prototype for gen_ functions for calling Neon helpers */
24
- TCGv_i64 tcg_rs, clean_addr;
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
25
+ TCGv_i64 tcg_rs, tcg_rt, clean_addr;
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
26
AtomicThreeOpFn *fn = NULL;
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
27
+ MemOp mop = s->be_data | size | MO_ALIGN;
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
28
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
29
if (is_vector || !dc_isar_feature(aa64_atomics, s)) {
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
30
unallocated_encoding(s);
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
31
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
32
break;
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
33
case 004: /* LDSMAX */
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
34
fn = tcg_gen_atomic_fetch_smax_i64;
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
35
+ mop |= MO_SIGN;
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
36
break;
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
37
case 005: /* LDSMIN */
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
38
fn = tcg_gen_atomic_fetch_smin_i64;
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
39
+ mop |= MO_SIGN;
64
-
40
break;
65
/* initialize TCG globals. */
41
case 006: /* LDUMAX */
66
void a64_translate_init(void)
42
fn = tcg_gen_atomic_fetch_umax_i64;
67
{
43
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
44
}
45
46
tcg_rs = read_cpu_reg(s, rs, true);
47
+ tcg_rt = cpu_reg(s, rt);
48
49
if (o3_opc == 1) { /* LDCLR */
50
tcg_gen_not_i64(tcg_rs, tcg_rs);
51
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
52
/* The tcg atomic primitives are all full barriers. Therefore we
53
* can ignore the Acquire and Release bits of this instruction.
54
*/
55
- fn(cpu_reg(s, rt), clean_addr, tcg_rs, get_mem_index(s),
56
- s->be_data | size | MO_ALIGN);
57
+ fn(tcg_rt, clean_addr, tcg_rs, get_mem_index(s), mop);
58
+
59
+ if ((mop & MO_SIGN) && size != MO_64) {
60
+ tcg_gen_ext32u_i64(tcg_rt, tcg_rt);
61
+ }
62
}
63
64
/*
68
--
65
--
69
2.20.1
66
2.20.1
70
67
71
68
diff view generated by jsdifflib
New patch
1
From: Jamie Iles <jamie@nuviainc.com>
1
2
3
The DAIF and PAC checks used raise_exception_ra to raise an exception
4
and unwind CPU state but raise_exception_ra is currently designed for
5
handling data aborts as the syndrome is partially precomputed and
6
encoded in the TB and then merged in merge_syn_data_abort when handling
7
the data abort. Using raise_exception_ra for DAIF and PAC checks
8
results in an empty syndrome being retrieved from data[2] in
9
restore_state_to_opc and setting ESR to 0. This manifested as:
10
11
kvm [571]: Unknown exception class: esr: 0x000000 –
12
Unknown/Uncategorized
13
14
when launching a KVM guest when the host qemu used a CPU supporting
15
EL2+pointer authentication and enabling pointer authentication in the
16
guest.
17
18
Rework raise_exception_ra such that the state is restored before raising
19
the exception so that the exception is not clobbered by
20
restore_state_to_opc.
21
22
Fixes: 0d43e1a2d29a ("target/arm: Add PAuth helpers")
23
Cc: Richard Henderson <richard.henderson@linaro.org>
24
Cc: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
26
[PMM: added comment]
27
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
30
target/arm/op_helper.c | 11 +++++++++--
31
1 file changed, 9 insertions(+), 2 deletions(-)
32
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/op_helper.c
36
+++ b/target/arm/op_helper.c
37
@@ -XXX,XX +XXX,XX @@ void raise_exception(CPUARMState *env, uint32_t excp,
38
void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
39
uint32_t target_el, uintptr_t ra)
40
{
41
- CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
42
- cpu_loop_exit_restore(cs, ra);
43
+ CPUState *cs = env_cpu(env);
44
+
45
+ /*
46
+ * restore_state_to_opc() will set env->exception.syndrome, so
47
+ * we must restore CPU state here before setting the syndrome
48
+ * the caller passed us, and cannot use cpu_loop_exit_restore().
49
+ */
50
+ cpu_restore_state(cs, ra, true);
51
+ raise_exception(env, excp, syndrome, target_el);
52
}
53
54
uint64_t HELPER(neon_tbl)(CPUARMState *env, uint32_t desc,
55
--
56
2.20.1
57
58
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Jamie Iles <jamie@nuviainc.com>
2
2
3
Remove inclusion of arm_gicv3_common.h, this already gets
3
Now that there are no other users of do_raise_exception, fold it into
4
included via xlnx-versal.h.
4
raise_exception.
5
5
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Cc: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Cc: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/arm/xlnx-versal.c | 1 -
12
target/arm/op_helper.c | 12 ++----------
13
1 file changed, 1 deletion(-)
13
1 file changed, 2 insertions(+), 10 deletions(-)
14
14
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
15
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
17
--- a/target/arm/op_helper.c
18
+++ b/hw/arm/xlnx-versal.c
18
+++ b/target/arm/op_helper.c
19
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
20
#include "hw/arm/boot.h"
20
#define SIGNBIT (uint32_t)0x80000000
21
#include "kvm_arm.h"
21
#define SIGNBIT64 ((uint64_t)1 << 63)
22
#include "hw/misc/unimp.h"
22
23
-#include "hw/intc/arm_gicv3_common.h"
23
-static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
24
#include "hw/arm/xlnx-versal.h"
24
- uint32_t syndrome, uint32_t target_el)
25
#include "hw/char/pl011.h"
25
+void raise_exception(CPUARMState *env, uint32_t excp,
26
+ uint32_t syndrome, uint32_t target_el)
27
{
28
CPUState *cs = env_cpu(env);
29
30
@@ -XXX,XX +XXX,XX @@ static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
31
cs->exception_index = excp;
32
env->exception.syndrome = syndrome;
33
env->exception.target_el = target_el;
34
-
35
- return cs;
36
-}
37
-
38
-void raise_exception(CPUARMState *env, uint32_t excp,
39
- uint32_t syndrome, uint32_t target_el)
40
-{
41
- CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
42
cpu_loop_exit(cs);
43
}
26
44
27
--
45
--
28
2.20.1
46
2.20.1
29
47
30
48
diff view generated by jsdifflib
New patch
1
From: Jamie Iles <jamie@nuviainc.com>
1
2
3
Now that raise_exception_ra restores the state before raising the
4
exception we can use restore_exception_ra to perform the state restore +
5
exception raising without clobbering the syndrome.
6
7
Cc: Richard Henderson <richard.henderson@linaro.org>
8
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
10
[PMM: Keep the one line of the comment that is still relevant]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/mte_helper.c | 12 +++---------
15
1 file changed, 3 insertions(+), 9 deletions(-)
16
17
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/mte_helper.c
20
+++ b/target/arm/mte_helper.c
21
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
22
23
switch (tcf) {
24
case 1:
25
- /*
26
- * Tag check fail causes a synchronous exception.
27
- *
28
- * In restore_state_to_opc, we set the exception syndrome
29
- * for the load or store operation. Unwind first so we
30
- * may overwrite that with the syndrome for the tag check.
31
- */
32
- cpu_restore_state(env_cpu(env), ra, true);
33
+ /* Tag check fail causes a synchronous exception. */
34
env->exception.vaddress = dirty_ptr;
35
36
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
37
syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
38
is_write, 0x11);
39
- raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
40
+ raise_exception_ra(env, EXCP_DATA_ABORT, syn,
41
+ exception_target_el(env), ra);
42
/* noreturn, but fall through to the assert anyway */
43
44
case 0:
45
--
46
2.20.1
47
48
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Jamie Iles <jamie@nuviainc.com>
2
2
3
Add support for the RTC.
3
The sequence cpu_restore_state() + raise_exception() is equivalent to
4
raise_exception_ra(), so use that instead. (In this case we never
5
cared about the syndrome value, because M-profile doesn't use the
6
syndrome; the old code was just written unnecessarily awkwardly.)
4
7
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Cc: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
11
[PMM: Retain edited version of comment; rewrite commit message]
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
hw/arm/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
15
target/arm/m_helper.c | 5 +----
12
1 file changed, 22 insertions(+)
16
target/arm/op_helper.c | 9 +++------
17
2 files changed, 4 insertions(+), 10 deletions(-)
13
18
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
19
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
21
--- a/target/arm/m_helper.c
17
+++ b/hw/arm/xlnx-versal-virt.c
22
+++ b/target/arm/m_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
23
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
24
limit = is_psp ? env->v7m.psplim[false] : env->v7m.msplim[false];
25
26
if (val < limit) {
27
- CPUState *cs = env_cpu(env);
28
-
29
- cpu_restore_state(cs, GETPC(), true);
30
- raise_exception(env, EXCP_STKOF, 0, 1);
31
+ raise_exception_ra(env, EXCP_STKOF, 0, 1, GETPC());
32
}
33
34
if (is_psp) {
35
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/op_helper.c
38
+++ b/target/arm/op_helper.c
39
@@ -XXX,XX +XXX,XX @@ void HELPER(v8m_stackcheck)(CPUARMState *env, uint32_t newvalue)
40
* raising an exception if the limit is breached.
41
*/
42
if (newvalue < v7m_sp_limit(env)) {
43
- CPUState *cs = env_cpu(env);
44
-
45
/*
46
* Stack limit exceptions are a rare case, so rather than syncing
47
- * PC/condbits before the call, we use cpu_restore_state() to
48
- * get them right before raising the exception.
49
+ * PC/condbits before the call, we use raise_exception_ra() so
50
+ * that cpu_restore_state() will sort them out.
51
*/
52
- cpu_restore_state(cs, GETPC(), true);
53
- raise_exception(env, EXCP_STKOF, 0, 1);
54
+ raise_exception_ra(env, EXCP_STKOF, 0, 1, GETPC());
19
}
55
}
20
}
56
}
21
57
22
+static void fdt_add_rtc_node(VersalVirt *s)
23
+{
24
+ const char compat[] = "xlnx,zynqmp-rtc";
25
+ const char interrupt_names[] = "alarm\0sec";
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
27
+
28
+ qemu_fdt_add_subnode(s->fdt, name);
29
+
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
36
+ interrupt_names, sizeof(interrupt_names));
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
40
+ g_free(name);
41
+}
42
+
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
44
{
45
Error *err = NULL;
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
47
fdt_add_timer_nodes(s);
48
fdt_add_zdma_nodes(s);
49
fdt_add_sd_nodes(s);
50
+ fdt_add_rtc_node(s);
51
fdt_add_cpu_nodes(s, psci_conduit);
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
54
--
58
--
55
2.20.1
59
2.20.1
56
60
57
61
diff view generated by jsdifflib
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
1
From: Richard Henderson <richard.henderson@linaro.org>
2
translation table descriptors from just bit [54] to bits [54:53],
3
allowing stage 2 to control execution permissions separately for EL0
4
and EL1. Implement the new semantics of the XN field and enable
5
the feature for our 'max' CPU.
6
2
3
Note that the SVE BFLOAT16 support does not require SVE2,
4
it is an independent extension.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210525225817.400336-2-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
11
---
10
---
12
target/arm/cpu.h | 15 +++++++++++++++
11
target/arm/cpu.h | 15 +++++++++++++++
13
target/arm/cpu.c | 1 +
12
1 file changed, 15 insertions(+)
14
target/arm/cpu64.c | 2 ++
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
16
4 files changed, 49 insertions(+), 6 deletions(-)
17
13
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
16
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
19
return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
24
}
20
}
25
21
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
22
+static inline bool isar_feature_aa32_bf16(const ARMISARegisters *id)
27
+{
23
+{
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
24
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, BF16) != 0;
29
+}
25
+}
30
+
26
+
31
/*
27
static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id)
32
* 64-bit feature tests via id registers.
28
{
33
*/
29
return FIELD_EX32(id->id_isar6, ID_ISAR6, I8MM) != 0;
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
30
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
31
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
36
}
32
}
37
33
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
34
+static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id)
39
+{
35
+{
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
36
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0;
41
+}
37
+}
42
+
38
+
43
/*
39
static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
40
{
45
*/
41
/* We always set the AdvSIMD and FP fields identically. */
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
42
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
43
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
48
}
44
}
49
45
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
46
+static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id)
51
+{
47
+{
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
48
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BFLOAT16) != 0;
53
+}
49
+}
54
+
50
+
55
/*
51
static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id)
56
* Forward to the above feature tests given an ARMCPU pointer.
57
*/
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/cpu.c
61
+++ b/target/arm/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
67
cpu->isar.id_mmfr4 = t;
68
}
69
#endif
70
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/cpu64.c
73
+++ b/target/arm/cpu64.c
74
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
75
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
76
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
77
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
78
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
79
cpu->isar.id_aa64mmfr1 = t;
80
81
t = cpu->isar.id_aa64mmfr2;
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
83
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
84
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
85
u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
86
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
87
cpu->isar.id_mmfr4 = u;
88
89
u = cpu->isar.id_aa64dfr0;
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/helper.c
93
+++ b/target/arm/helper.c
94
@@ -XXX,XX +XXX,XX @@ simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
95
*
96
* @env: CPUARMState
97
* @s2ap: The 2-bit stage2 access permissions (S2AP)
98
- * @xn: XN (execute-never) bit
99
+ * @xn: XN (execute-never) bits
100
+ * @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
101
*/
102
-static int get_S2prot(CPUARMState *env, int s2ap, int xn)
103
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
104
{
52
{
105
int prot = 0;
53
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SHA3) != 0;
106
107
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
108
if (s2ap & 2) {
109
prot |= PAGE_WRITE;
110
}
111
- if (!xn) {
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
113
+
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
115
+ switch (xn) {
116
+ case 0:
117
prot |= PAGE_EXEC;
118
+ break;
119
+ case 1:
120
+ if (s1_is_el0) {
121
+ prot |= PAGE_EXEC;
122
+ }
123
+ break;
124
+ case 2:
125
+ break;
126
+ case 3:
127
+ if (!s1_is_el0) {
128
+ prot |= PAGE_EXEC;
129
+ }
130
+ break;
131
+ default:
132
+ g_assert_not_reached();
133
+ }
134
+ } else {
135
+ if (!extract32(xn, 1, 1)) {
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
137
+ prot |= PAGE_EXEC;
138
+ }
139
}
140
}
141
return prot;
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
143
}
144
145
ap = extract32(attrs, 4, 2);
146
- xn = extract32(attrs, 12, 1);
147
148
if (mmu_idx == ARMMMUIdx_Stage2) {
149
ns = true;
150
- *prot = get_S2prot(env, ap, xn);
151
+ xn = extract32(attrs, 11, 2);
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
153
} else {
154
ns = extract32(attrs, 3, 1);
155
+ xn = extract32(attrs, 12, 1);
156
pxn = extract32(attrs, 11, 1);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
158
}
159
--
54
--
160
2.20.1
55
2.20.1
161
56
162
57
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Fix typo xlnx-ve -> xlnx-versal.
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Message-id: 20210525225817.400336-3-richard.henderson@linaro.org
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
hw/arm/xlnx-versal-virt.c | 2 +-
8
target/arm/translate-a64.c | 15 ++++++---------
13
1 file changed, 1 insertion(+), 1 deletion(-)
9
1 file changed, 6 insertions(+), 9 deletions(-)
14
10
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal-virt.c
13
--- a/target/arm/translate-a64.c
18
+++ b/hw/arm/xlnx-versal-virt.c
14
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
15
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
16
int rd = extract32(insn, 0, 5);
17
18
if (mos) {
19
- unallocated_encoding(s);
20
- return;
21
+ goto do_unallocated;
21
}
22
}
22
23
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
24
switch (opcode) {
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
25
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
26
/* FCVT between half, single and double precision */
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
27
int dtype = extract32(opcode, 0, 2);
27
"ddr", &error_abort);
28
if (type == 2 || dtype == type) {
29
- unallocated_encoding(s);
30
- return;
31
+ goto do_unallocated;
32
}
33
if (!fp_access_check(s)) {
34
return;
35
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
36
37
case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */
38
if (type > 1 || !dc_isar_feature(aa64_frint, s)) {
39
- unallocated_encoding(s);
40
- return;
41
+ goto do_unallocated;
42
}
43
/* fall through */
44
case 0x0 ... 0x3:
45
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
46
break;
47
case 3:
48
if (!dc_isar_feature(aa64_fp16, s)) {
49
- unallocated_encoding(s);
50
- return;
51
+ goto do_unallocated;
52
}
53
54
if (!fp_access_check(s)) {
55
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
56
handle_fp_1src_half(s, opcode, rd, rn);
57
break;
58
default:
59
- unallocated_encoding(s);
60
+ goto do_unallocated;
61
}
62
break;
63
64
default:
65
+ do_unallocated:
66
unallocated_encoding(s);
67
break;
68
}
28
--
69
--
29
2.20.1
70
2.20.1
30
71
31
72
diff view generated by jsdifflib
1
Convert the Neon "load/store single structure to one lane" insns to
1
From: Richard Henderson <richard.henderson@linaro.org>
2
decodetree.
3
2
4
As this is the last set of insns in the neon load/store group,
3
This is the 64-bit BFCVT and the 32-bit VCVT{B,T}.BF16.F32.
5
we can remove the whole disas_neon_ls_insn() function.
6
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525225817.400336-4-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200430181003.21682-14-peter.maydell@linaro.org
10
---
9
---
11
target/arm/neon-ls.decode | 11 +++
10
target/arm/helper.h | 1 +
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
11
target/arm/vfp.decode | 2 ++
13
target/arm/translate.c | 147 --------------------------------
12
target/arm/translate-a64.c | 19 +++++++++++++++++++
14
3 files changed, 100 insertions(+), 147 deletions(-)
13
target/arm/translate-vfp.c | 24 ++++++++++++++++++++++++
14
target/arm/vfp_helper.c | 5 +++++
15
5 files changed, 51 insertions(+)
15
16
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-ls.decode
19
--- a/target/arm/helper.h
19
+++ b/target/arm/neon-ls.decode
20
+++ b/target/arm/helper.h
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
21
22
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
23
DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
23
vd=%vd_dp
24
DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
25
+DEF_HELPER_FLAGS_2(bfcvt, TCG_CALL_NO_RWG, i32, f32, ptr)
26
27
DEF_HELPER_2(vfp_uitoh, f16, i32, ptr)
28
DEF_HELPER_2(vfp_uitos, f32, i32, ptr)
29
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/vfp.decode
32
+++ b/target/arm/vfp.decode
33
@@ -XXX,XX +XXX,XX @@ VCVT_f64_f16 ---- 1110 1.11 0010 .... 1011 t:1 1.0 .... \
34
35
# VCVTB and VCVTT to f16: Vd format is always vd_sp;
36
# Vm format depends on size bit
37
+VCVT_b16_f32 ---- 1110 1.11 0011 .... 1001 t:1 1.0 .... \
38
+ vd=%vd_sp vm=%vm_sp
39
VCVT_f16_f32 ---- 1110 1.11 0011 .... 1010 t:1 1.0 .... \
40
vd=%vd_sp vm=%vm_sp
41
VCVT_f16_f64 ---- 1110 1.11 0011 .... 1011 t:1 1.0 .... \
42
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/translate-a64.c
45
+++ b/target/arm/translate-a64.c
46
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
47
case 0x3: /* FSQRT */
48
gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
49
goto done;
50
+ case 0x6: /* BFCVT */
51
+ gen_fpst = gen_helper_bfcvt;
52
+ break;
53
case 0x8: /* FRINTN */
54
case 0x9: /* FRINTP */
55
case 0xa: /* FRINTM */
56
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
57
}
58
break;
59
60
+ case 0x6:
61
+ switch (type) {
62
+ case 1: /* BFCVT */
63
+ if (!dc_isar_feature(aa64_bf16, s)) {
64
+ goto do_unallocated;
65
+ }
66
+ if (!fp_access_check(s)) {
67
+ return;
68
+ }
69
+ handle_fp_1src_single(s, opcode, rd, rn);
70
+ break;
71
+ default:
72
+ goto do_unallocated;
73
+ }
74
+ break;
24
+
75
+
25
+# Neon load/store single structure to one lane
76
default:
26
+%imm1_5_p1 5:1 !function=plus1
77
do_unallocated:
27
+%imm1_6_p1 6:1 !function=plus1
78
unallocated_encoding(s);
28
+
79
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
29
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
30
+ vd=%vd_dp size=0 stride=1
31
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
32
+ vd=%vd_dp size=1 stride=%imm1_5_p1
33
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
34
+ vd=%vd_dp size=2 stride=%imm1_6_p1
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
81
--- a/target/arm/translate-vfp.c
38
+++ b/target/arm/translate-neon.inc.c
82
+++ b/target/arm/translate-vfp.c
39
@@ -XXX,XX +XXX,XX @@
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
40
* It might be possible to convert it to a standalone .c file eventually.
41
*/
42
43
+static inline int plus1(DisasContext *s, int x)
44
+{
45
+ return x + 1;
46
+}
47
+
48
/* Include the generated Neon decoder */
49
#include "decode-neon-dp.inc.c"
50
#include "decode-neon-ls.inc.c"
51
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
52
53
return true;
84
return true;
54
}
85
}
86
87
+static bool trans_VCVT_b16_f32(DisasContext *s, arg_VCVT_b16_f32 *a)
88
+{
89
+ TCGv_ptr fpst;
90
+ TCGv_i32 tmp;
55
+
91
+
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
92
+ if (!dc_isar_feature(aa32_bf16, s)) {
57
+{
58
+ /* Neon load/store single structure to one lane */
59
+ int reg;
60
+ int nregs = a->n + 1;
61
+ int vd = a->vd;
62
+ TCGv_i32 addr, tmp;
63
+
64
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
65
+ return false;
66
+ }
67
+
68
+ /* UNDEF accesses to D16-D31 if they don't exist */
69
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
70
+ return false;
71
+ }
72
+
73
+ /* Catch the UNDEF cases. This is unavoidably a bit messy. */
74
+ switch (nregs) {
75
+ case 1:
76
+ if (((a->align & (1 << a->size)) != 0) ||
77
+ (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
78
+ return false;
79
+ }
80
+ break;
81
+ case 3:
82
+ if ((a->align & 1) != 0) {
83
+ return false;
84
+ }
85
+ /* fall through */
86
+ case 2:
87
+ if (a->size == 2 && (a->align & 2) != 0) {
88
+ return false;
89
+ }
90
+ break;
91
+ case 4:
92
+ if ((a->size == 2) && ((a->align & 3) == 3)) {
93
+ return false;
94
+ }
95
+ break;
96
+ default:
97
+ abort();
98
+ }
99
+ if ((vd + a->stride * (nregs - 1)) > 31) {
100
+ /*
101
+ * Attempts to write off the end of the register file are
102
+ * UNPREDICTABLE; we choose to UNDEF because otherwise we would
103
+ * access off the end of the array that holds the register data.
104
+ */
105
+ return false;
93
+ return false;
106
+ }
94
+ }
107
+
95
+
108
+ if (!vfp_access_check(s)) {
96
+ if (!vfp_access_check(s)) {
109
+ return true;
97
+ return true;
110
+ }
98
+ }
111
+
99
+
100
+ fpst = fpstatus_ptr(FPST_FPCR);
112
+ tmp = tcg_temp_new_i32();
101
+ tmp = tcg_temp_new_i32();
113
+ addr = tcg_temp_new_i32();
102
+
114
+ load_reg_var(s, addr, a->rn);
103
+ vfp_load_reg32(tmp, a->vm);
115
+ /*
104
+ gen_helper_bfcvt(tmp, tmp, fpst);
116
+ * TODO: if we implemented alignment exceptions, we should check
105
+ tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
117
+ * addr against the alignment encoded in a->align here.
106
+ tcg_temp_free_ptr(fpst);
118
+ */
119
+ for (reg = 0; reg < nregs; reg++) {
120
+ if (a->l) {
121
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
122
+ s->be_data | a->size);
123
+ neon_store_element(vd, a->reg_idx, a->size, tmp);
124
+ } else { /* Store */
125
+ neon_load_element(tmp, vd, a->reg_idx, a->size);
126
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
127
+ s->be_data | a->size);
128
+ }
129
+ vd += a->stride;
130
+ tcg_gen_addi_i32(addr, addr, 1 << a->size);
131
+ }
132
+ tcg_temp_free_i32(addr);
133
+ tcg_temp_free_i32(tmp);
107
+ tcg_temp_free_i32(tmp);
134
+
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
136
+
137
+ return true;
108
+ return true;
138
+}
109
+}
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
110
+
111
static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a)
112
{
113
TCGv_ptr fpst;
114
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
140
index XXXXXXX..XXXXXXX 100644
115
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
116
--- a/target/arm/vfp_helper.c
142
+++ b/target/arm/translate.c
117
+++ b/target/arm/vfp_helper.c
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
118
@@ -XXX,XX +XXX,XX @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
144
tcg_temp_free_i32(rd);
119
return float64_to_float32(x, &env->vfp.fp_status);
145
}
120
}
146
121
147
-
122
+uint32_t HELPER(bfcvt)(float32 x, void *status)
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
123
+{
149
- instruction is invalid. */
124
+ return float32_to_bfloat16(x, status);
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
125
+}
151
-{
126
+
152
- int rd, rn, rm;
127
/*
153
- int nregs;
128
* VFP3 fixed point conversion. The AArch32 versions of fix-to-float
154
- int stride;
129
* must always round-to-nearest; the AArch64 ones honour the FPSCR
155
- int size;
156
- int reg;
157
- int load;
158
- TCGv_i32 addr;
159
- TCGv_i32 tmp;
160
-
161
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
- return 1;
163
- }
164
-
165
- /* FIXME: this access check should not take precedence over UNDEF
166
- * for invalid encodings; we will generate incorrect syndrome information
167
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
168
- */
169
- if (s->fp_excp_el) {
170
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
171
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
172
- return 0;
173
- }
174
-
175
- if (!s->vfp_enabled)
176
- return 1;
177
- VFP_DREG_D(rd, insn);
178
- rn = (insn >> 16) & 0xf;
179
- rm = insn & 0xf;
180
- load = (insn & (1 << 21)) != 0;
181
- if ((insn & (1 << 23)) == 0) {
182
- /* Load store all elements -- handled already by decodetree */
183
- return 1;
184
- } else {
185
- size = (insn >> 10) & 3;
186
- if (size == 3) {
187
- /* Load single element to all lanes -- handled by decodetree */
188
- return 1;
189
- } else {
190
- /* Single element. */
191
- int idx = (insn >> 4) & 0xf;
192
- int reg_idx;
193
- switch (size) {
194
- case 0:
195
- reg_idx = (insn >> 5) & 7;
196
- stride = 1;
197
- break;
198
- case 1:
199
- reg_idx = (insn >> 6) & 3;
200
- stride = (insn & (1 << 5)) ? 2 : 1;
201
- break;
202
- case 2:
203
- reg_idx = (insn >> 7) & 1;
204
- stride = (insn & (1 << 6)) ? 2 : 1;
205
- break;
206
- default:
207
- abort();
208
- }
209
- nregs = ((insn >> 8) & 3) + 1;
210
- /* Catch the UNDEF cases. This is unavoidably a bit messy. */
211
- switch (nregs) {
212
- case 1:
213
- if (((idx & (1 << size)) != 0) ||
214
- (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
215
- return 1;
216
- }
217
- break;
218
- case 3:
219
- if ((idx & 1) != 0) {
220
- return 1;
221
- }
222
- /* fall through */
223
- case 2:
224
- if (size == 2 && (idx & 2) != 0) {
225
- return 1;
226
- }
227
- break;
228
- case 4:
229
- if ((size == 2) && ((idx & 3) == 3)) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- abort();
235
- }
236
- if ((rd + stride * (nregs - 1)) > 31) {
237
- /* Attempts to write off the end of the register file
238
- * are UNPREDICTABLE; we choose to UNDEF because otherwise
239
- * the neon_load_reg() would write off the end of the array.
240
- */
241
- return 1;
242
- }
243
- tmp = tcg_temp_new_i32();
244
- addr = tcg_temp_new_i32();
245
- load_reg_var(s, addr, rn);
246
- for (reg = 0; reg < nregs; reg++) {
247
- if (load) {
248
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
249
- s->be_data | size);
250
- neon_store_element(rd, reg_idx, size, tmp);
251
- } else { /* Store */
252
- neon_load_element(tmp, rd, reg_idx, size);
253
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
254
- s->be_data | size);
255
- }
256
- rd += stride;
257
- tcg_gen_addi_i32(addr, addr, 1 << size);
258
- }
259
- tcg_temp_free_i32(addr);
260
- tcg_temp_free_i32(tmp);
261
- stride = nregs * (1 << size);
262
- }
263
- }
264
- if (rm != 15) {
265
- TCGv_i32 base;
266
-
267
- base = load_reg(s, rn);
268
- if (rm == 13) {
269
- tcg_gen_addi_i32(base, base, stride);
270
- } else {
271
- TCGv_i32 index;
272
- index = load_reg(s, rm);
273
- tcg_gen_add_i32(base, base, index);
274
- tcg_temp_free_i32(index);
275
- }
276
- store_reg(s, rn, base);
277
- }
278
- return 0;
279
-}
280
-
281
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
282
{
283
switch (size) {
284
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
285
}
286
return;
287
}
288
- if ((insn & 0x0f100000) == 0x04000000) {
289
- /* NEON load/store. */
290
- if (disas_neon_ls_insn(s, insn)) {
291
- goto illegal_op;
292
- }
293
- return;
294
- }
295
if ((insn & 0x0e000f00) == 0x0c000100) {
296
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
297
/* iWMMXt register transfer. */
298
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
299
}
300
break;
301
case 12:
302
- if ((insn & 0x01100000) == 0x01000000) {
303
- if (disas_neon_ls_insn(s, insn)) {
304
- goto illegal_op;
305
- }
306
- break;
307
- }
308
goto illegal_op;
309
default:
310
illegal_op:
311
--
130
--
312
2.20.1
131
2.20.1
313
132
314
133
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Note that we don't need the neon_3r_sizes[op] check here because all
3
This is BFCVT{N,T} for both AArch64 AdvSIMD and SVE,
4
size values are OK for VADD and VSUB; we'll add this when we convert
4
and VCVT.BF16.F32 for AArch32 NEON.
5
the first insn that has size restrictions.
5
6
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
For this we need one of the GVecGen*Fn typedefs currently in
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
translate-a64.h; move them all to translate.h as a block so they
8
Message-id: 20210525225817.400336-5-richard.henderson@linaro.org
9
are visible to the 32-bit decoder.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
14
---
10
---
15
target/arm/translate-a64.h | 9 --------
11
target/arm/helper-sve.h | 4 ++++
16
target/arm/translate.h | 9 ++++++++
12
target/arm/helper.h | 1 +
17
target/arm/neon-dp.decode | 17 +++++++++++++++
13
target/arm/neon-dp.decode | 1 +
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
14
target/arm/sve.decode | 2 ++
19
target/arm/translate.c | 14 ++++--------
15
target/arm/sve_helper.c | 2 ++
20
5 files changed, 68 insertions(+), 19 deletions(-)
16
target/arm/translate-a64.c | 17 ++++++++++++++
21
17
target/arm/translate-neon.c | 45 +++++++++++++++++++++++++++++++++++++
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
18
target/arm/translate-sve.c | 16 +++++++++++++
23
index XXXXXXX..XXXXXXX 100644
19
target/arm/vfp_helper.c | 7 ++++++
24
--- a/target/arm/translate-a64.h
20
9 files changed, 95 insertions(+)
25
+++ b/target/arm/translate-a64.h
21
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
22
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
27
23
index XXXXXXX..XXXXXXX 100644
28
bool disas_sve(DisasContext *, uint32_t);
24
--- a/target/arm/helper-sve.h
29
25
+++ b/target/arm/helper-sve.h
30
-/* Note that the gvec expanders operate on offsets + sizes. */
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fcvt_hd, TCG_CALL_NO_RWG,
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
27
void, ptr, ptr, ptr, ptr, i32)
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
28
DEF_HELPER_FLAGS_5(sve_fcvt_sd, TCG_CALL_NO_RWG,
33
- uint32_t, uint32_t);
29
void, ptr, ptr, ptr, ptr, i32)
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
30
+DEF_HELPER_FLAGS_5(sve_bfcvt, TCG_CALL_NO_RWG,
35
- uint32_t, uint32_t, uint32_t);
31
+ void, ptr, ptr, ptr, ptr, i32)
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
32
37
- uint32_t, uint32_t, uint32_t);
33
DEF_HELPER_FLAGS_5(sve_fcvtzs_hh, TCG_CALL_NO_RWG,
38
-
34
void, ptr, ptr, ptr, ptr, i32)
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
35
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_fcvtnt_sh, TCG_CALL_NO_RWG,
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
36
void, ptr, ptr, ptr, ptr, i32)
41
index XXXXXXX..XXXXXXX 100644
37
DEF_HELPER_FLAGS_5(sve2_fcvtnt_ds, TCG_CALL_NO_RWG,
42
--- a/target/arm/translate.h
38
void, ptr, ptr, ptr, ptr, i32)
43
+++ b/target/arm/translate.h
39
+DEF_HELPER_FLAGS_5(sve_bfcvtnt, TCG_CALL_NO_RWG,
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
40
+ void, ptr, ptr, ptr, ptr, i32)
45
#define dc_isar_feature(name, ctx) \
41
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
42
DEF_HELPER_FLAGS_5(sve2_fcvtlt_hs, TCG_CALL_NO_RWG,
47
43
void, ptr, ptr, ptr, ptr, i32)
48
+/* Note that the gvec expanders operate on offsets + sizes. */
44
diff --git a/target/arm/helper.h b/target/arm/helper.h
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
45
index XXXXXXX..XXXXXXX 100644
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
46
--- a/target/arm/helper.h
51
+ uint32_t, uint32_t);
47
+++ b/target/arm/helper.h
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
48
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
53
+ uint32_t, uint32_t, uint32_t);
49
DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
50
DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
55
+ uint32_t, uint32_t, uint32_t);
51
DEF_HELPER_FLAGS_2(bfcvt, TCG_CALL_NO_RWG, i32, f32, ptr)
56
+
52
+DEF_HELPER_FLAGS_2(bfcvt_pair, TCG_CALL_NO_RWG, i32, i64, ptr)
57
#endif /* TARGET_ARM_TRANSLATE_H */
53
54
DEF_HELPER_2(vfp_uitoh, f16, i32, ptr)
55
DEF_HELPER_2(vfp_uitos, f32, i32, ptr)
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
56
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
59
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/neon-dp.decode
58
--- a/target/arm/neon-dp.decode
61
+++ b/target/arm/neon-dp.decode
59
+++ b/target/arm/neon-dp.decode
62
@@ -XXX,XX +XXX,XX @@
60
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
63
#
61
VRINTZ 1111 001 11 . 11 .. 10 .... 0 1011 . . 0 .... @2misc
64
# This file is processed by scripts/decodetree.py
62
65
#
63
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
66
+# VFP/Neon register fields; same as vfp.decode
64
+ VCVT_B16_F32 1111 001 11 . 11 .. 10 .... 0 1100 1 . 0 .... @2misc_q0
67
+%vm_dp 5:1 0:4
65
68
+%vn_dp 7:1 16:4
66
VRINTM 1111 001 11 . 11 .. 10 .... 0 1101 . . 0 .... @2misc
69
+%vd_dp 22:1 12:4
67
70
68
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
71
# Encodings for Neon data processing instructions where the T32 encoding
69
index XXXXXXX..XXXXXXX 100644
72
# is a simple transformation of the A32 encoding.
70
--- a/target/arm/sve.decode
73
@@ -XXX,XX +XXX,XX @@
71
+++ b/target/arm/sve.decode
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
72
@@ -XXX,XX +XXX,XX @@ FNMLS_zpzzz 01100101 .. 1 ..... 111 ... ..... ..... @rdn_pg_rm_ra
75
# This file works on the A32 encoding only; calling code for T32 has to
73
# SVE floating-point convert precision
76
# transform the insn into the A32 version first.
74
FCVT_sh 01100101 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
77
+
75
FCVT_hs 01100101 10 0010 01 101 ... ..... ..... @rd_pg_rn_e0
78
+######################################################################
76
+BFCVT 01100101 10 0010 10 101 ... ..... ..... @rd_pg_rn_e0
79
+# 3-reg-same grouping:
77
FCVT_dh 01100101 11 0010 00 101 ... ..... ..... @rd_pg_rn_e0
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
78
FCVT_hd 01100101 11 0010 01 101 ... ..... ..... @rd_pg_rn_e0
81
+######################################################################
79
FCVT_ds 01100101 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
82
+
80
@@ -XXX,XX +XXX,XX @@ RAX1 01000101 00 1 ..... 11110 1 ..... ..... @rd_rn_rm_e0
83
+&3same vm vn vd q size
81
FCVTXNT_ds 01100100 00 0010 10 101 ... ..... ..... @rd_pg_rn_e0
84
+
82
FCVTX_ds 01100101 00 0010 10 101 ... ..... ..... @rd_pg_rn_e0
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
83
FCVTNT_sh 01100100 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
84
+BFCVTNT 01100100 10 0010 10 101 ... ..... ..... @rd_pg_rn_e0
87
+
85
FCVTLT_hs 01100100 10 0010 01 101 ... ..... ..... @rd_pg_rn_e0
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
86
FCVTNT_ds 01100100 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
87
FCVTLT_sd 01100100 11 0010 11 101 ... ..... ..... @rd_pg_rn_e0
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
88
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
91
index XXXXXXX..XXXXXXX 100644
89
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
90
--- a/target/arm/sve_helper.c
93
+++ b/target/arm/translate-neon.inc.c
91
+++ b/target/arm/sve_helper.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
92
@@ -XXX,XX +XXX,XX @@ static inline uint64_t vfp_float64_to_uint64_rtz(float64 f, float_status *s)
95
93
94
DO_ZPZ_FP(sve_fcvt_sh, uint32_t, H1_4, sve_f32_to_f16)
95
DO_ZPZ_FP(sve_fcvt_hs, uint32_t, H1_4, sve_f16_to_f32)
96
+DO_ZPZ_FP(sve_bfcvt, uint32_t, H1_4, float32_to_bfloat16)
97
DO_ZPZ_FP(sve_fcvt_dh, uint64_t, , sve_f64_to_f16)
98
DO_ZPZ_FP(sve_fcvt_hd, uint64_t, , sve_f16_to_f64)
99
DO_ZPZ_FP(sve_fcvt_ds, uint64_t, , float64_to_float32)
100
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
101
} while (i != 0); \
102
}
103
104
+DO_FCVTNT(sve_bfcvtnt, uint32_t, uint16_t, H1_4, H1_2, float32_to_bfloat16)
105
DO_FCVTNT(sve2_fcvtnt_sh, uint32_t, uint16_t, H1_4, H1_2, sve_f32_to_f16)
106
DO_FCVTNT(sve2_fcvtnt_ds, uint64_t, uint32_t, , H1_4, float64_to_float32)
107
108
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/translate-a64.c
111
+++ b/target/arm/translate-a64.c
112
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar,
113
tcg_temp_free_i32(ahp);
114
}
115
break;
116
+ case 0x36: /* BFCVTN, BFCVTN2 */
117
+ {
118
+ TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
119
+ gen_helper_bfcvt_pair(tcg_res[pass], tcg_op, fpst);
120
+ tcg_temp_free_ptr(fpst);
121
+ }
122
+ break;
123
case 0x56: /* FCVTXN, FCVTXN2 */
124
/* 64 bit to 32 bit float conversion
125
* with von Neumann rounding (round to odd)
126
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
127
}
128
handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd);
129
return;
130
+ case 0x36: /* BFCVTN, BFCVTN2 */
131
+ if (!dc_isar_feature(aa64_bf16, s) || size != 2) {
132
+ unallocated_encoding(s);
133
+ return;
134
+ }
135
+ if (!fp_access_check(s)) {
136
+ return;
137
+ }
138
+ handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd);
139
+ return;
140
case 0x17: /* FCVTL, FCVTL2 */
141
if (!fp_access_check(s)) {
142
return;
143
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/target/arm/translate-neon.c
146
+++ b/target/arm/translate-neon.c
147
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
96
return true;
148
return true;
97
}
149
}
98
+
150
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
151
+static bool trans_VCVT_B16_F32(DisasContext *s, arg_2misc *a)
100
+{
152
+{
101
+ int vec_size = a->q ? 16 : 8;
153
+ TCGv_ptr fpst;
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
154
+ TCGv_i64 tmp;
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
155
+ TCGv_i32 dst0, dst1;
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
156
+
105
+
157
+ if (!dc_isar_feature(aa32_bf16, s)) {
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
107
+ return false;
158
+ return false;
108
+ }
159
+ }
109
+
160
+
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
161
+ /* UNDEF accesses to D16-D31 if they don't exist. */
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
162
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
163
+ ((a->vd | a->vm) & 0x10)) {
113
+ return false;
164
+ return false;
114
+ }
165
+ }
115
+
166
+
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
167
+ if ((a->vm & 1) || (a->size != 1)) {
117
+ return false;
168
+ return false;
118
+ }
169
+ }
119
+
170
+
120
+ if (!vfp_access_check(s)) {
171
+ if (!vfp_access_check(s)) {
121
+ return true;
172
+ return true;
122
+ }
173
+ }
123
+
174
+
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
175
+ fpst = fpstatus_ptr(FPST_STD);
176
+ tmp = tcg_temp_new_i64();
177
+ dst0 = tcg_temp_new_i32();
178
+ dst1 = tcg_temp_new_i32();
179
+
180
+ read_neon_element64(tmp, a->vm, 0, MO_64);
181
+ gen_helper_bfcvt_pair(dst0, tmp, fpst);
182
+
183
+ read_neon_element64(tmp, a->vm, 1, MO_64);
184
+ gen_helper_bfcvt_pair(dst1, tmp, fpst);
185
+
186
+ write_neon_element32(dst0, a->vd, 0, MO_32);
187
+ write_neon_element32(dst1, a->vd, 1, MO_32);
188
+
189
+ tcg_temp_free_i64(tmp);
190
+ tcg_temp_free_i32(dst0);
191
+ tcg_temp_free_i32(dst1);
192
+ tcg_temp_free_ptr(fpst);
125
+ return true;
193
+ return true;
126
+}
194
+}
127
+
195
+
128
+#define DO_3SAME(INSN, FUNC) \
196
static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
197
{
130
+ { \
198
TCGv_ptr fpst;
131
+ return do_3same(s, a, FUNC); \
199
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
132
+ }
200
index XXXXXXX..XXXXXXX 100644
133
+
201
--- a/target/arm/translate-sve.c
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
202
+++ b/target/arm/translate-sve.c
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
203
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a)
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
204
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hs);
137
index XXXXXXX..XXXXXXX 100644
205
}
138
--- a/target/arm/translate.c
206
139
+++ b/target/arm/translate.c
207
+static bool trans_BFCVT(DisasContext *s, arg_rpr_esz *a)
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
208
+{
141
}
209
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
142
return 0;
210
+ return false;
143
211
+ }
144
- case NEON_3R_VADD_VSUB:
212
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_bfcvt);
145
- if (u) {
213
+}
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
214
+
147
- vec_size, vec_size);
215
static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a)
148
- } else {
216
{
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
217
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_dh);
150
- vec_size, vec_size);
218
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVTNT_sh(DisasContext *s, arg_rpr_esz *a)
151
- }
219
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve2_fcvtnt_sh);
152
- return 0;
220
}
153
-
221
154
case NEON_3R_VQADD:
222
+static bool trans_BFCVTNT(DisasContext *s, arg_rpr_esz *a)
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
223
+{
156
rn_ofs, rm_ofs, vec_size, vec_size,
224
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
225
+ return false;
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
226
+ }
159
u ? &ushl_op[size] : &sshl_op[size]);
227
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_bfcvtnt);
160
return 0;
228
+}
161
+
229
+
162
+ case NEON_3R_VADD_VSUB:
230
static bool trans_FCVTNT_ds(DisasContext *s, arg_rpr_esz *a)
163
+ /* Already handled by decodetree */
231
{
164
+ return 1;
232
if (!dc_isar_feature(aa64_sve2, s)) {
165
}
233
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
166
234
index XXXXXXX..XXXXXXX 100644
167
if (size == 3) {
235
--- a/target/arm/vfp_helper.c
236
+++ b/target/arm/vfp_helper.c
237
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(bfcvt)(float32 x, void *status)
238
return float32_to_bfloat16(x, status);
239
}
240
241
+uint32_t HELPER(bfcvt_pair)(uint64_t pair, void *status)
242
+{
243
+ bfloat16 lo = float32_to_bfloat16(extract64(pair, 0, 32), status);
244
+ bfloat16 hi = float32_to_bfloat16(extract64(pair, 32, 32), status);
245
+ return deposit32(lo, 16, 16, hi);
246
+}
247
+
248
/*
249
* VFP3 fixed point conversion. The AArch32 versions of fix-to-float
250
* must always round-to-nearest; the AArch64 ones honour the FPSCR
168
--
251
--
169
2.20.1
252
2.20.1
170
253
171
254
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
By using the TYPE_* definitions for devices, we can:
3
For Arm BFDOT and BFMMLA, we need a version of round-to-odd
4
- quickly find where devices are used with 'git-grep'
4
that overflows to infinity, instead of the max normal number.
5
- easily rename a device (one-line change).
6
5
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Cc: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210525225817.400336-6-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/arm/mps2-tz.c | 2 +-
12
include/fpu/softfloat-types.h | 4 +++-
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
fpu/softfloat-parts.c.inc | 6 ++++--
14
2 files changed, 7 insertions(+), 3 deletions(-)
14
15
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
18
--- a/include/fpu/softfloat-types.h
18
+++ b/hw/arm/mps2-tz.c
19
+++ b/include/fpu/softfloat-types.h
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
20
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
20
exit(EXIT_FAILURE);
21
float_round_up = 2,
22
float_round_to_zero = 3,
23
float_round_ties_away = 4,
24
- /* Not an IEEE rounding mode: round to the closest odd mantissa value */
25
+ /* Not an IEEE rounding mode: round to closest odd, overflow to max */
26
float_round_to_odd = 5,
27
+ /* Not an IEEE rounding mode: round to closest odd, overflow to inf */
28
+ float_round_to_odd_inf = 6,
29
} FloatRoundMode;
30
31
/*
32
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
33
index XXXXXXX..XXXXXXX 100644
34
--- a/fpu/softfloat-parts.c.inc
35
+++ b/fpu/softfloat-parts.c.inc
36
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
37
g_assert_not_reached();
21
}
38
}
22
39
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
40
+ overflow_norm = false;
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
41
switch (s->float_rounding_mode) {
25
sizeof(mms->iotkit), mmc->armsse_type);
42
case float_round_nearest_even:
26
iotkitdev = DEVICE(&mms->iotkit);
43
- overflow_norm = false;
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
44
inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0);
45
break;
46
case float_round_ties_away:
47
- overflow_norm = false;
48
inc = frac_lsbm1;
49
break;
50
case float_round_to_zero:
51
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
52
break;
53
case float_round_to_odd:
54
overflow_norm = true;
55
+ /* fall through */
56
+ case float_round_to_odd_inf:
57
inc = p->frac_lo & frac_lsb ? 0 : round_mask;
58
break;
59
default:
60
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
61
? frac_lsbm1 : 0);
62
break;
63
case float_round_to_odd:
64
+ case float_round_to_odd_inf:
65
inc = p->frac_lo & frac_lsb ? 0 : round_mask;
66
break;
67
default:
28
--
68
--
29
2.20.1
69
2.20.1
30
70
31
71
diff view generated by jsdifflib
1
Convert the VCMLA (vector) insns in the 3same extension group to
1
From: Richard Henderson <richard.henderson@linaro.org>
2
decodetree.
3
2
3
This is BFDOT for both AArch64 AdvSIMD and SVE,
4
and VDOT.BF16 for AArch32 NEON.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525225817.400336-7-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-shared.decode | 11 ++++++++++
11
target/arm/helper.h | 3 +++
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
12
target/arm/neon-shared.decode | 2 ++
10
target/arm/translate.c | 11 +---------
13
target/arm/sve.decode | 3 +++
11
3 files changed, 49 insertions(+), 10 deletions(-)
14
target/arm/translate-a64.c | 20 ++++++++++++++++++
15
target/arm/translate-neon.c | 9 ++++++++
16
target/arm/translate-sve.c | 12 +++++++++++
17
target/arm/vec_helper.c | 40 +++++++++++++++++++++++++++++++++++
18
7 files changed, 89 insertions(+)
12
19
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
23
+++ b/target/arm/helper.h
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_ummla_b, TCG_CALL_NO_RWG,
25
DEF_HELPER_FLAGS_5(gvec_usmmla_b, TCG_CALL_NO_RWG,
26
void, ptr, ptr, ptr, ptr, i32)
27
28
+DEF_HELPER_FLAGS_5(gvec_bfdot, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+
31
#ifdef TARGET_AARCH64
32
#include "helper-a64.h"
33
#include "helper-sve.h"
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
34
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
36
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
37
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@ VUDOT 1111 110 00 . 10 .... .... 1101 . q:1 . 1 .... \
18
# More specifically, this covers:
39
vm=%vm_dp vn=%vn_dp vd=%vd_dp
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
40
VUSDOT 1111 110 01 . 10 .... .... 1101 . q:1 . 0 .... \
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
41
vm=%vm_dp vn=%vn_dp vd=%vd_dp
42
+VDOT_b16 1111 110 00 . 00 .... .... 1101 . q:1 . 0 .... \
43
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
44
45
# VFM[AS]L
46
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
47
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/sve.decode
50
+++ b/target/arm/sve.decode
51
@@ -XXX,XX +XXX,XX @@ FMLALT_zzzw 01100100 10 1 ..... 10 0 00 1 ..... ..... @rda_rn_rm_e0
52
FMLSLB_zzzw 01100100 10 1 ..... 10 1 00 0 ..... ..... @rda_rn_rm_e0
53
FMLSLT_zzzw 01100100 10 1 ..... 10 1 00 1 ..... ..... @rda_rn_rm_e0
54
55
+### SVE2 floating-point bfloat16 dot-product
56
+BFDOT_zzzz 01100100 01 1 ..... 10 0 00 0 ..... ..... @rda_rn_rm_e0
21
+
57
+
22
+# VFP/Neon register fields; same as vfp.decode
58
### SVE2 floating-point multiply-add long (indexed)
23
+%vm_dp 5:1 0:4
59
FMLALB_zzxw 01100100 10 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
24
+%vm_sp 0:4 5:1
60
FMLALT_zzxw 01100100 10 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
25
+%vn_dp 7:1 16:4
61
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
26
+%vn_sp 16:4 7:1
62
index XXXXXXX..XXXXXXX 100644
27
+%vd_dp 22:1 12:4
63
--- a/target/arm/translate-a64.c
28
+%vd_sp 12:4 22:1
64
+++ b/target/arm/translate-a64.c
65
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
66
}
67
feature = dc_isar_feature(aa64_fcma, s);
68
break;
69
+ case 0x1f: /* BFDOT */
70
+ switch (size) {
71
+ case 1:
72
+ feature = dc_isar_feature(aa64_bf16, s);
73
+ break;
74
+ default:
75
+ unallocated_encoding(s);
76
+ return;
77
+ }
78
+ break;
79
default:
80
unallocated_encoding(s);
81
return;
82
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
83
}
84
return;
85
86
+ case 0xf: /* BFDOT */
87
+ switch (size) {
88
+ case 1:
89
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfdot);
90
+ break;
91
+ default:
92
+ g_assert_not_reached();
93
+ }
94
+ return;
29
+
95
+
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
96
default:
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
97
g_assert_not_reached();
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
98
}
99
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
33
index XXXXXXX..XXXXXXX 100644
100
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.inc.c
101
--- a/target/arm/translate-neon.c
35
+++ b/target/arm/translate-neon.inc.c
102
+++ b/target/arm/translate-neon.c
36
@@ -XXX,XX +XXX,XX @@
103
@@ -XXX,XX +XXX,XX @@ static bool trans_VUSDOT(DisasContext *s, arg_VUSDOT *a)
37
#include "decode-neon-dp.inc.c"
104
gen_helper_gvec_usdot_b);
38
#include "decode-neon-ls.inc.c"
105
}
39
#include "decode-neon-shared.inc.c"
106
40
+
107
+static bool trans_VDOT_b16(DisasContext *s, arg_VDOT_b16 *a)
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
42
+{
108
+{
43
+ int opr_sz;
109
+ if (!dc_isar_feature(aa32_bf16, s)) {
44
+ TCGv_ptr fpst;
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
46
+
47
+ if (!dc_isar_feature(aa32_vcma, s)
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
49
+ return false;
110
+ return false;
50
+ }
111
+ }
112
+ return do_neon_ddda(s, a->q * 7, a->vd, a->vn, a->vm, 0,
113
+ gen_helper_gvec_bfdot);
114
+}
51
+
115
+
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
116
static bool trans_VFML(DisasContext *s, arg_VFML *a)
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
117
{
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
118
int opr_sz;
119
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/translate-sve.c
122
+++ b/target/arm/translate-sve.c
123
@@ -XXX,XX +XXX,XX @@ static bool trans_UMMLA(DisasContext *s, arg_rrrr_esz *a)
124
{
125
return do_i8mm_zzzz_ool(s, a, gen_helper_gvec_ummla_b, 0);
126
}
127
+
128
+static bool trans_BFDOT_zzzz(DisasContext *s, arg_rrrr_esz *a)
129
+{
130
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
55
+ return false;
131
+ return false;
56
+ }
132
+ }
57
+
133
+ if (sve_access_check(s)) {
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
134
+ gen_gvec_ool_zzzz(s, gen_helper_gvec_bfdot,
59
+ return false;
135
+ a->rd, a->rn, a->rm, a->ra, 0);
60
+ }
136
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
64
+ }
65
+
66
+ opr_sz = (1 + a->q) * 8;
67
+ fpst = get_fpstatus_ptr(1);
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
70
+ vfp_reg_offset(1, a->vn),
71
+ vfp_reg_offset(1, a->vm),
72
+ fpst, opr_sz, opr_sz, a->rot,
73
+ fn_gvec_ptr);
74
+ tcg_temp_free_ptr(fpst);
75
+ return true;
137
+ return true;
76
+}
138
+}
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
139
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
78
index XXXXXXX..XXXXXXX 100644
140
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate.c
141
--- a/target/arm/vec_helper.c
80
+++ b/target/arm/translate.c
142
+++ b/target/arm/vec_helper.c
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
143
@@ -XXX,XX +XXX,XX @@ static void do_mmla_b(void *vd, void *vn, void *vm, void *va, uint32_t desc,
82
bool is_long = false, q = extract32(insn, 6, 1);
144
DO_MMLA_B(gvec_smmla_b, do_smmla_b)
83
bool ptr_is_env = false;
145
DO_MMLA_B(gvec_ummla_b, do_ummla_b)
84
146
DO_MMLA_B(gvec_usmmla_b, do_usmmla_b)
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
147
+
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
148
+/*
87
- int size = extract32(insn, 20, 1);
149
+ * BFloat16 Dot Product
88
- data = extract32(insn, 23, 2); /* rot */
150
+ */
89
- if (!dc_isar_feature(aa32_vcma, s)
151
+
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
152
+static float32 bfdotadd(float32 sum, uint32_t e1, uint32_t e2)
91
- return 1;
153
+{
92
- }
154
+ /* FPCR is ignored for BFDOT and BFMMLA. */
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
155
+ float_status bf_status = {
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
156
+ .tininess_before_rounding = float_tininess_before_rounding,
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
157
+ .float_rounding_mode = float_round_to_odd_inf,
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
158
+ .flush_to_zero = true,
97
int size = extract32(insn, 20, 1);
159
+ .flush_inputs_to_zero = true,
98
data = extract32(insn, 24, 1); /* rot */
160
+ .default_nan_mode = true,
161
+ };
162
+ float32 t1, t2;
163
+
164
+ /*
165
+ * Extract each BFloat16 from the element pair, and shift
166
+ * them such that they become float32.
167
+ */
168
+ t1 = float32_mul(e1 << 16, e2 << 16, &bf_status);
169
+ t2 = float32_mul(e1 & 0xffff0000u, e2 & 0xffff0000u, &bf_status);
170
+ t1 = float32_add(t1, t2, &bf_status);
171
+ t1 = float32_add(sum, t1, &bf_status);
172
+
173
+ return t1;
174
+}
175
+
176
+void HELPER(gvec_bfdot)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
177
+{
178
+ intptr_t i, opr_sz = simd_oprsz(desc);
179
+ float32 *d = vd, *a = va;
180
+ uint32_t *n = vn, *m = vm;
181
+
182
+ for (i = 0; i < opr_sz / 4; ++i) {
183
+ d[i] = bfdotadd(a[i], n[i], m[i]);
184
+ }
185
+ clear_tail(d, opr_sz, simd_maxsz(desc));
186
+}
99
--
187
--
100
2.20.1
188
2.20.1
101
189
102
190
diff view generated by jsdifflib
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is BFDOT for both AArch64 AdvSIMD and SVE,
4
and VDOT.BF16 for AArch32 NEON.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525225817.400336-8-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
6
---
10
---
7
target/arm/neon-shared.decode | 5 +++++
11
target/arm/helper.h | 2 ++
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
12
target/arm/neon-shared.decode | 2 ++
9
target/arm/translate.c | 26 +--------------------
13
target/arm/sve.decode | 3 +++
10
3 files changed, 46 insertions(+), 25 deletions(-)
14
target/arm/translate-a64.c | 41 +++++++++++++++++++++++++++--------
15
target/arm/translate-neon.c | 9 ++++++++
16
target/arm/translate-sve.c | 12 ++++++++++
17
target/arm/vec_helper.c | 20 +++++++++++++++++
18
7 files changed, 80 insertions(+), 9 deletions(-)
11
19
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
23
+++ b/target/arm/helper.h
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_usmmla_b, TCG_CALL_NO_RWG,
25
26
DEF_HELPER_FLAGS_5(gvec_bfdot, TCG_CALL_NO_RWG,
27
void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(gvec_bfdot_idx, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
31
#ifdef TARGET_AARCH64
32
#include "helper-a64.h"
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
33
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
35
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
36
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
37
@@ -XXX,XX +XXX,XX @@ VUSDOT_scalar 1111 1110 1 . 00 .... .... 1101 . q:1 index:1 0 vm:4 \
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
38
vn=%vn_dp vd=%vd_dp
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
39
VSUDOT_scalar 1111 1110 1 . 00 .... .... 1101 . q:1 index:1 1 vm:4 \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
40
vn=%vn_dp vd=%vd_dp
41
+VDOT_b16_scal 1111 1110 0 . 00 .... .... 1101 . q:1 index:1 0 vm:4 \
42
+ vn=%vn_dp vd=%vd_dp
43
44
%vfml_scalar_q0_rm 0:3 5:1
45
%vfml_scalar_q1_index 5:1 3:1
46
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve.decode
49
+++ b/target/arm/sve.decode
50
@@ -XXX,XX +XXX,XX @@ FMLALB_zzxw 01100100 10 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
51
FMLALT_zzxw 01100100 10 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
52
FMLSLB_zzxw 01100100 10 1 ..... 0110.0 ..... ..... @rrxr_3a esz=2
53
FMLSLT_zzxw 01100100 10 1 ..... 0110.1 ..... ..... @rrxr_3a esz=2
20
+
54
+
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
55
+### SVE2 floating-point bfloat16 dot-product (indexed)
22
+ vn=%vn_dp vd=%vd_dp size=0
56
+BFDOT_zzxz 01100100 01 1 ..... 010000 ..... ..... @rrxr_2 esz=2
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
57
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
24
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
26
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate-neon.inc.c
59
--- a/target/arm/translate-a64.c
28
+++ b/target/arm/translate-neon.inc.c
60
+++ b/target/arm/translate-a64.c
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
61
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
30
gen_helper_gvec_fmlal_a32);
62
return;
63
}
64
break;
65
- case 0x0f: /* SUDOT, USDOT */
66
- if (is_scalar || (size & 1) || !dc_isar_feature(aa64_i8mm, s)) {
67
+ case 0x0f:
68
+ switch (size) {
69
+ case 0: /* SUDOT */
70
+ case 2: /* USDOT */
71
+ if (is_scalar || !dc_isar_feature(aa64_i8mm, s)) {
72
+ unallocated_encoding(s);
73
+ return;
74
+ }
75
+ break;
76
+ case 1: /* BFDOT */
77
+ if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
78
+ unallocated_encoding(s);
79
+ return;
80
+ }
81
+ break;
82
+ default:
83
unallocated_encoding(s);
84
return;
85
}
86
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
87
u ? gen_helper_gvec_udot_idx_b
88
: gen_helper_gvec_sdot_idx_b);
89
return;
90
- case 0x0f: /* SUDOT, USDOT */
91
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
92
- extract32(insn, 23, 1)
93
- ? gen_helper_gvec_usdot_idx_b
94
- : gen_helper_gvec_sudot_idx_b);
95
- return;
96
-
97
+ case 0x0f:
98
+ switch (extract32(insn, 22, 2)) {
99
+ case 0: /* SUDOT */
100
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
101
+ gen_helper_gvec_sudot_idx_b);
102
+ return;
103
+ case 1: /* BFDOT */
104
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
105
+ gen_helper_gvec_bfdot_idx);
106
+ return;
107
+ case 2: /* USDOT */
108
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
109
+ gen_helper_gvec_usdot_idx_b);
110
+ return;
111
+ }
112
+ g_assert_not_reached();
113
case 0x11: /* FCMLA #0 */
114
case 0x13: /* FCMLA #90 */
115
case 0x15: /* FCMLA #180 */
116
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/translate-neon.c
119
+++ b/target/arm/translate-neon.c
120
@@ -XXX,XX +XXX,XX @@ static bool trans_VSUDOT_scalar(DisasContext *s, arg_VSUDOT_scalar *a)
121
gen_helper_gvec_sudot_idx_b);
122
}
123
124
+static bool trans_VDOT_b16_scal(DisasContext *s, arg_VDOT_b16_scal *a)
125
+{
126
+ if (!dc_isar_feature(aa32_bf16, s)) {
127
+ return false;
128
+ }
129
+ return do_neon_ddda(s, a->q * 6, a->vd, a->vn, a->vm, a->index,
130
+ gen_helper_gvec_bfdot_idx);
131
+}
132
+
133
static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
134
{
135
int opr_sz;
136
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/translate-sve.c
139
+++ b/target/arm/translate-sve.c
140
@@ -XXX,XX +XXX,XX @@ static bool trans_BFDOT_zzzz(DisasContext *s, arg_rrrr_esz *a)
141
}
31
return true;
142
return true;
32
}
143
}
33
+
144
+
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
145
+static bool trans_BFDOT_zzxz(DisasContext *s, arg_rrxr_esz *a)
35
+{
146
+{
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
147
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
37
+ int opr_sz;
38
+ TCGv_ptr fpst;
39
+
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
41
+ return false;
148
+ return false;
42
+ }
149
+ }
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
150
+ if (sve_access_check(s)) {
44
+ return false;
151
+ gen_gvec_ool_zzzz(s, gen_helper_gvec_bfdot_idx,
152
+ a->rd, a->rn, a->rm, a->ra, a->index);
45
+ }
153
+ }
46
+
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if ((a->vd | a->vn) & a->q) {
54
+ return false;
55
+ }
56
+
57
+ if (!vfp_access_check(s)) {
58
+ return true;
59
+ }
60
+
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
62
+ : gen_helper_gvec_fcmlah_idx);
63
+ opr_sz = (1 + a->q) * 8;
64
+ fpst = get_fpstatus_ptr(1);
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(1, a->vn),
67
+ vfp_reg_offset(1, a->vm),
68
+ fpst, opr_sz, opr_sz,
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
70
+ tcg_temp_free_ptr(fpst);
71
+ return true;
154
+ return true;
72
+}
155
+}
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
74
index XXXXXXX..XXXXXXX 100644
157
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/translate.c
158
--- a/target/arm/vec_helper.c
76
+++ b/target/arm/translate.c
159
+++ b/target/arm/vec_helper.c
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
160
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfdot)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
78
bool is_long = false, q = extract32(insn, 6, 1);
161
}
79
bool ptr_is_env = false;
162
clear_tail(d, opr_sz, simd_maxsz(desc));
80
163
}
81
- if ((insn & 0xff000f10) == 0xfe000800) {
164
+
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
165
+void HELPER(gvec_bfdot_idx)(void *vd, void *vn, void *vm,
83
- int rot = extract32(insn, 20, 2);
166
+ void *va, uint32_t desc)
84
- int size = extract32(insn, 23, 1);
167
+{
85
- int index;
168
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
86
-
169
+ intptr_t index = simd_data(desc);
87
- if (!dc_isar_feature(aa32_vcma, s)) {
170
+ intptr_t elements = opr_sz / 4;
88
- return 1;
171
+ intptr_t eltspersegment = MIN(16 / 4, elements);
89
- }
172
+ float32 *d = vd, *a = va;
90
- if (size == 0) {
173
+ uint32_t *n = vn, *m = vm;
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
174
+
92
- return 1;
175
+ for (i = 0; i < elements; i += eltspersegment) {
93
- }
176
+ uint32_t m_idx = m[i + H4(index)];
94
- /* For fp16, rm is just Vm, and index is M. */
177
+
95
- rm = extract32(insn, 0, 4);
178
+ for (j = i; j < i + eltspersegment; j++) {
96
- index = extract32(insn, 5, 1);
179
+ d[j] = bfdotadd(a[j], n[j], m_idx);
97
- } else {
180
+ }
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
181
+ }
99
- VFP_DREG_M(rm, insn);
182
+ clear_tail(d, opr_sz, simd_maxsz(desc));
100
- index = 0;
183
+}
101
- }
102
- data = (index << 2) | rot;
103
- fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
104
- : gen_helper_gvec_fcmlah_idx);
105
- } else if ((insn & 0xffb00f00) == 0xfe200d00) {
106
+ if ((insn & 0xffb00f00) == 0xfe200d00) {
107
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
108
int u = extract32(insn, 4, 1);
109
110
--
184
--
111
2.20.1
185
2.20.1
112
186
113
187
diff view generated by jsdifflib
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
1
From: Richard Henderson <richard.henderson@linaro.org>
2
to decodetree.
3
2
3
This is BFMMLA for both AArch64 AdvSIMD and SVE,
4
and VMMLA.BF16 for AArch32 NEON.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210525225817.400336-9-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-shared.decode | 3 +++
11
target/arm/helper.h | 3 +++
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
12
target/arm/neon-shared.decode | 2 ++
10
target/arm/translate.c | 13 +-----------
13
target/arm/sve.decode | 6 +++--
11
3 files changed, 39 insertions(+), 12 deletions(-)
14
target/arm/translate-a64.c | 10 +++++++++
15
target/arm/translate-neon.c | 9 ++++++++
16
target/arm/translate-sve.c | 12 ++++++++++
17
target/arm/vec_helper.c | 42 ++++++++++++++++++++++++++++++++++-
18
7 files changed, 81 insertions(+), 3 deletions(-)
12
19
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
23
+++ b/target/arm/helper.h
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_bfdot, TCG_CALL_NO_RWG,
25
DEF_HELPER_FLAGS_5(gvec_bfdot_idx, TCG_CALL_NO_RWG,
26
void, ptr, ptr, ptr, ptr, i32)
27
28
+DEF_HELPER_FLAGS_5(gvec_bfmmla, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+
31
#ifdef TARGET_AARCH64
32
#include "helper-a64.h"
33
#include "helper-sve.h"
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
34
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
36
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
37
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
38
@@ -XXX,XX +XXX,XX @@ VUMMLA 1111 1100 0.10 .... .... 1100 .1.1 .... \
18
vn=%vn_dp vd=%vd_dp size=0
39
vm=%vm_dp vn=%vn_dp vd=%vd_dp
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
40
VUSMMLA 1111 1100 1.10 .... .... 1100 .1.0 .... \
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
41
vm=%vm_dp vn=%vn_dp vd=%vd_dp
42
+VMMLA_b16 1111 1100 0.00 .... .... 1100 .1.0 .... \
43
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
44
45
VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
46
vn=%vn_dp vd=%vd_dp size=1
47
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/sve.decode
50
+++ b/target/arm/sve.decode
51
@@ -XXX,XX +XXX,XX @@ SQRDCMLAH_zzzz 01000100 esz:2 0 rm:5 0011 rot:2 rn:5 rd:5 ra=%reg_movprfx
52
USDOT_zzzz 01000100 .. 0 ..... 011 110 ..... ..... @rda_rn_rm
53
54
### SVE2 floating point matrix multiply accumulate
55
-
56
-FMMLA 01100100 .. 1 ..... 111001 ..... ..... @rda_rn_rm
57
+{
58
+ BFMMLA 01100100 01 1 ..... 111 001 ..... ..... @rda_rn_rm_e0
59
+ FMMLA 01100100 .. 1 ..... 111 001 ..... ..... @rda_rn_rm
60
+}
61
62
### SVE2 Memory Gather Load Group
63
64
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate-a64.c
67
+++ b/target/arm/translate-a64.c
68
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
69
}
70
feature = dc_isar_feature(aa64_fcma, s);
71
break;
72
+ case 0x1d: /* BFMMLA */
73
+ if (size != MO_16 || !is_q) {
74
+ unallocated_encoding(s);
75
+ return;
76
+ }
77
+ feature = dc_isar_feature(aa64_bf16, s);
78
+ break;
79
case 0x1f: /* BFDOT */
80
switch (size) {
81
case 1:
82
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
83
}
84
return;
85
86
+ case 0xd: /* BFMMLA */
87
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfmmla);
88
+ return;
89
case 0xf: /* BFDOT */
90
switch (size) {
91
case 1:
92
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/target/arm/translate-neon.c
95
+++ b/target/arm/translate-neon.c
96
@@ -XXX,XX +XXX,XX @@ static bool trans_VUSMMLA(DisasContext *s, arg_VUSMMLA *a)
97
return do_neon_ddda(s, 7, a->vd, a->vn, a->vm, 0,
98
gen_helper_gvec_usmmla_b);
99
}
21
+
100
+
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
101
+static bool trans_VMMLA_b16(DisasContext *s, arg_VMMLA_b16 *a)
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
102
+{
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
103
+ if (!dc_isar_feature(aa32_bf16, s)) {
104
+ return false;
105
+ }
106
+ return do_neon_ddda(s, 7, a->vd, a->vn, a->vm, 0,
107
+ gen_helper_gvec_bfmmla);
108
+}
109
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
25
index XXXXXXX..XXXXXXX 100644
110
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
111
--- a/target/arm/translate-sve.c
27
+++ b/target/arm/translate-neon.inc.c
112
+++ b/target/arm/translate-sve.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
113
@@ -XXX,XX +XXX,XX @@ static bool trans_BFDOT_zzxz(DisasContext *s, arg_rrxr_esz *a)
29
tcg_temp_free_ptr(fpst);
114
}
30
return true;
115
return true;
31
}
116
}
32
+
117
+
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
118
+static bool trans_BFMMLA(DisasContext *s, arg_rrrr_esz *a)
34
+{
119
+{
35
+ gen_helper_gvec_3 *fn_gvec;
120
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
36
+ int opr_sz;
37
+ TCGv_ptr fpst;
38
+
39
+ if (!dc_isar_feature(aa32_dp, s)) {
40
+ return false;
121
+ return false;
41
+ }
122
+ }
42
+
123
+ if (sve_access_check(s)) {
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
124
+ gen_gvec_ool_zzzz(s, gen_helper_gvec_bfmmla,
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
125
+ a->rd, a->rn, a->rm, a->ra, 0);
45
+ ((a->vd | a->vn) & 0x10)) {
46
+ return false;
47
+ }
126
+ }
48
+
49
+ if ((a->vd | a->vn) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
58
+ opr_sz = (1 + a->q) * 8;
59
+ fpst = get_fpstatus_ptr(1);
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->rm),
63
+ opr_sz, opr_sz, a->index, fn_gvec);
64
+ tcg_temp_free_ptr(fpst);
65
+ return true;
127
+ return true;
66
+}
128
+}
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
129
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
68
index XXXXXXX..XXXXXXX 100644
130
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/translate.c
131
--- a/target/arm/vec_helper.c
70
+++ b/target/arm/translate.c
132
+++ b/target/arm/vec_helper.c
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
133
@@ -XXX,XX +XXX,XX @@ static void do_mmla_b(void *vd, void *vn, void *vm, void *va, uint32_t desc,
72
bool is_long = false, q = extract32(insn, 6, 1);
134
* Process the entire segment at once, writing back the
73
bool ptr_is_env = false;
135
* results only after we've consumed all of the inputs.
74
136
*
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
137
- * Key to indicies by column:
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
138
+ * Key to indices by column:
77
- int u = extract32(insn, 4, 1);
139
* i j i j
78
-
140
*/
79
- if (!dc_isar_feature(aa32_dp, s)) {
141
sum0 = a[H4(0 + 0)];
80
- return 1;
142
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfdot_idx)(void *vd, void *vn, void *vm,
81
- }
143
}
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
144
clear_tail(d, opr_sz, simd_maxsz(desc));
83
- /* rm is just Vm, and index is M. */
145
}
84
- data = extract32(insn, 5, 1); /* index */
146
+
85
- rm = extract32(insn, 0, 4);
147
+void HELPER(gvec_bfmmla)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
148
+{
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
149
+ intptr_t s, opr_sz = simd_oprsz(desc);
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
150
+ float32 *d = vd, *a = va;
89
int is_s = extract32(insn, 20, 1);
151
+ uint32_t *n = vn, *m = vm;
90
int vm20 = extract32(insn, 0, 3);
152
+
153
+ for (s = 0; s < opr_sz / 4; s += 4) {
154
+ float32 sum00, sum01, sum10, sum11;
155
+
156
+ /*
157
+ * Process the entire segment at once, writing back the
158
+ * results only after we've consumed all of the inputs.
159
+ *
160
+ * Key to indicies by column:
161
+ * i j i k j k
162
+ */
163
+ sum00 = a[s + H4(0 + 0)];
164
+ sum00 = bfdotadd(sum00, n[s + H4(0 + 0)], m[s + H4(0 + 0)]);
165
+ sum00 = bfdotadd(sum00, n[s + H4(0 + 1)], m[s + H4(0 + 1)]);
166
+
167
+ sum01 = a[s + H4(0 + 1)];
168
+ sum01 = bfdotadd(sum01, n[s + H4(0 + 0)], m[s + H4(2 + 0)]);
169
+ sum01 = bfdotadd(sum01, n[s + H4(0 + 1)], m[s + H4(2 + 1)]);
170
+
171
+ sum10 = a[s + H4(2 + 0)];
172
+ sum10 = bfdotadd(sum10, n[s + H4(2 + 0)], m[s + H4(0 + 0)]);
173
+ sum10 = bfdotadd(sum10, n[s + H4(2 + 1)], m[s + H4(0 + 1)]);
174
+
175
+ sum11 = a[s + H4(2 + 1)];
176
+ sum11 = bfdotadd(sum11, n[s + H4(2 + 0)], m[s + H4(2 + 0)]);
177
+ sum11 = bfdotadd(sum11, n[s + H4(2 + 1)], m[s + H4(2 + 1)]);
178
+
179
+ d[s + H4(0 + 0)] = sum00;
180
+ d[s + H4(0 + 1)] = sum01;
181
+ d[s + H4(2 + 0)] = sum10;
182
+ d[s + H4(2 + 1)] = sum11;
183
+ }
184
+ clear_tail(d, opr_sz, simd_maxsz(desc));
185
+}
91
--
186
--
92
2.20.1
187
2.20.1
93
188
94
189
diff view generated by jsdifflib
1
Convert the V[US]DOT (vector) insns to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is BFMLAL{B,T} for both AArch64 AdvSIMD and SVE,
4
and VFMA{B,T}.BF16 for AArch32 NEON.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210525225817.400336-10-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
6
---
10
---
7
target/arm/neon-shared.decode | 4 ++++
11
target/arm/helper.h | 3 +++
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
12
target/arm/neon-shared.decode | 3 +++
9
target/arm/translate.c | 9 +--------
13
target/arm/sve.decode | 3 +++
10
3 files changed, 37 insertions(+), 8 deletions(-)
14
target/arm/translate-a64.c | 13 +++++++++----
15
target/arm/translate-neon.c | 9 +++++++++
16
target/arm/translate-sve.c | 30 ++++++++++++++++++++++++++++++
17
target/arm/vec_helper.c | 16 ++++++++++++++++
18
7 files changed, 73 insertions(+), 4 deletions(-)
11
19
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
23
+++ b/target/arm/helper.h
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_bfdot_idx, TCG_CALL_NO_RWG,
25
DEF_HELPER_FLAGS_5(gvec_bfmmla, TCG_CALL_NO_RWG,
26
void, ptr, ptr, ptr, ptr, i32)
27
28
+DEF_HELPER_FLAGS_6(gvec_bfmlal, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, ptr, i32)
30
+
31
#ifdef TARGET_AARCH64
32
#include "helper-a64.h"
33
#include "helper-sve.h"
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
34
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
36
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
37
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
38
@@ -XXX,XX +XXX,XX @@ VUSMMLA 1111 1100 1.10 .... .... 1100 .1.0 .... \
17
39
VMMLA_b16 1111 1100 0.00 .... .... 1100 .1.0 .... \
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
40
vm=%vm_dp vn=%vn_dp vd=%vd_dp
41
42
+VFMA_b16 1111 110 0 0.11 .... .... 1000 . q:1 . 1 .... \
43
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+
44
+
21
+# VUDOT and VSDOT
45
VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
46
vn=%vn_dp vd=%vd_dp size=1
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
47
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
48
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
25
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
50
--- a/target/arm/sve.decode
27
+++ b/target/arm/translate-neon.inc.c
51
+++ b/target/arm/sve.decode
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
52
@@ -XXX,XX +XXX,XX @@ FMLALT_zzzw 01100100 10 1 ..... 10 0 00 1 ..... ..... @rda_rn_rm_e0
29
tcg_temp_free_ptr(fpst);
53
FMLSLB_zzzw 01100100 10 1 ..... 10 1 00 0 ..... ..... @rda_rn_rm_e0
54
FMLSLT_zzzw 01100100 10 1 ..... 10 1 00 1 ..... ..... @rda_rn_rm_e0
55
56
+BFMLALB_zzzw 01100100 11 1 ..... 10 0 00 0 ..... ..... @rda_rn_rm_e0
57
+BFMLALT_zzzw 01100100 11 1 ..... 10 0 00 1 ..... ..... @rda_rn_rm_e0
58
+
59
### SVE2 floating-point bfloat16 dot-product
60
BFDOT_zzzz 01100100 01 1 ..... 10 0 00 0 ..... ..... @rda_rn_rm_e0
61
62
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/arm/translate-a64.c
65
+++ b/target/arm/translate-a64.c
66
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
67
}
68
feature = dc_isar_feature(aa64_bf16, s);
69
break;
70
- case 0x1f: /* BFDOT */
71
+ case 0x1f:
72
switch (size) {
73
- case 1:
74
+ case 1: /* BFDOT */
75
+ case 3: /* BFMLAL{B,T} */
76
feature = dc_isar_feature(aa64_bf16, s);
77
break;
78
default:
79
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
80
case 0xd: /* BFMMLA */
81
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfmmla);
82
return;
83
- case 0xf: /* BFDOT */
84
+ case 0xf:
85
switch (size) {
86
- case 1:
87
+ case 1: /* BFDOT */
88
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfdot);
89
break;
90
+ case 3: /* BFMLAL{B,T} */
91
+ gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, false, is_q,
92
+ gen_helper_gvec_bfmlal);
93
+ break;
94
default:
95
g_assert_not_reached();
96
}
97
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/arm/translate-neon.c
100
+++ b/target/arm/translate-neon.c
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMMLA_b16(DisasContext *s, arg_VMMLA_b16 *a)
102
return do_neon_ddda(s, 7, a->vd, a->vn, a->vm, 0,
103
gen_helper_gvec_bfmmla);
104
}
105
+
106
+static bool trans_VFMA_b16(DisasContext *s, arg_VFMA_b16 *a)
107
+{
108
+ if (!dc_isar_feature(aa32_bf16, s)) {
109
+ return false;
110
+ }
111
+ return do_neon_ddda_fpst(s, 7, a->vd, a->vn, a->vm, a->q, FPST_STD,
112
+ gen_helper_gvec_bfmlal);
113
+}
114
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate-sve.c
117
+++ b/target/arm/translate-sve.c
118
@@ -XXX,XX +XXX,XX @@ static bool trans_BFMMLA(DisasContext *s, arg_rrrr_esz *a)
119
}
30
return true;
120
return true;
31
}
121
}
32
+
122
+
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
123
+static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
34
+{
124
+{
35
+ int opr_sz;
125
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
36
+ gen_helper_gvec_3 *fn_gvec;
37
+
38
+ if (!dc_isar_feature(aa32_dp, s)) {
39
+ return false;
126
+ return false;
40
+ }
127
+ }
128
+ if (sve_access_check(s)) {
129
+ TCGv_ptr status = fpstatus_ptr(FPST_FPCR);
130
+ unsigned vsz = vec_full_reg_size(s);
41
+
131
+
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
132
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
133
+ vec_full_reg_offset(s, a->rn),
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
134
+ vec_full_reg_offset(s, a->rm),
45
+ return false;
135
+ vec_full_reg_offset(s, a->ra),
136
+ status, vsz, vsz, sel,
137
+ gen_helper_gvec_bfmlal);
138
+ tcg_temp_free_ptr(status);
46
+ }
139
+ }
47
+
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
49
+ return false;
50
+ }
51
+
52
+ if (!vfp_access_check(s)) {
53
+ return true;
54
+ }
55
+
56
+ opr_sz = (1 + a->q) * 8;
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
58
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
59
+ vfp_reg_offset(1, a->vn),
60
+ vfp_reg_offset(1, a->vm),
61
+ opr_sz, opr_sz, 0, fn_gvec);
62
+ return true;
140
+ return true;
63
+}
141
+}
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
142
+
143
+static bool trans_BFMLALB_zzzw(DisasContext *s, arg_rrrr_esz *a)
144
+{
145
+ return do_BFMLAL_zzzw(s, a, false);
146
+}
147
+
148
+static bool trans_BFMLALT_zzzw(DisasContext *s, arg_rrrr_esz *a)
149
+{
150
+ return do_BFMLAL_zzzw(s, a, true);
151
+}
152
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
65
index XXXXXXX..XXXXXXX 100644
153
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
154
--- a/target/arm/vec_helper.c
67
+++ b/target/arm/translate.c
155
+++ b/target/arm/vec_helper.c
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
156
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfmmla)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
69
bool is_long = false, q = extract32(insn, 6, 1);
157
}
70
bool ptr_is_env = false;
158
clear_tail(d, opr_sz, simd_maxsz(desc));
71
159
}
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
160
+
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
161
+void HELPER(gvec_bfmlal)(void *vd, void *vn, void *vm, void *va,
74
- bool u = extract32(insn, 4, 1);
162
+ void *stat, uint32_t desc)
75
- if (!dc_isar_feature(aa32_dp, s)) {
163
+{
76
- return 1;
164
+ intptr_t i, opr_sz = simd_oprsz(desc);
77
- }
165
+ intptr_t sel = simd_data(desc);
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
166
+ float32 *d = vd, *a = va;
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
167
+ bfloat16 *n = vn, *m = vm;
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
168
+
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
169
+ for (i = 0; i < opr_sz / 4; ++i) {
82
int is_s = extract32(insn, 23, 1);
170
+ float32 nn = n[H2(i * 2 + sel)] << 16;
83
if (!dc_isar_feature(aa32_fhm, s)) {
171
+ float32 mm = m[H2(i * 2 + sel)] << 16;
172
+ d[H4(i)] = float32_muladd(nn, mm, a[H4(i)], 0, stat);
173
+ }
174
+ clear_tail(d, opr_sz, simd_maxsz(desc));
175
+}
84
--
176
--
85
2.20.1
177
2.20.1
86
178
87
179
diff view generated by jsdifflib
1
Convert the VCADD (vector) insns to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is BFMLAL{B,T} for both AArch64 AdvSIMD and SVE,
4
and VFMA{B,T}.BF16 for AArch32 NEON.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210525225817.400336-11-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
6
---
10
---
7
target/arm/neon-shared.decode | 3 +++
11
target/arm/helper.h | 2 ++
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
12
target/arm/neon-shared.decode | 2 ++
9
target/arm/translate.c | 11 +---------
13
target/arm/sve.decode | 2 ++
10
3 files changed, 41 insertions(+), 10 deletions(-)
14
target/arm/translate-a64.c | 15 ++++++++++++++-
15
target/arm/translate-neon.c | 10 ++++++++++
16
target/arm/translate-sve.c | 30 ++++++++++++++++++++++++++++++
17
target/arm/vec_helper.c | 22 ++++++++++++++++++++++
18
7 files changed, 82 insertions(+), 1 deletion(-)
11
19
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
23
+++ b/target/arm/helper.h
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_bfmmla, TCG_CALL_NO_RWG,
25
26
DEF_HELPER_FLAGS_6(gvec_bfmlal, TCG_CALL_NO_RWG,
27
void, ptr, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_6(gvec_bfmlal_idx, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, ptr, i32)
30
31
#ifdef TARGET_AARCH64
32
#include "helper-a64.h"
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
33
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
35
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
36
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
17
38
rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
39
VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
40
index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
20
+
41
+VFMA_b16_scal 1111 1110 0.11 .... .... 1000 . q:1 . 1 . vm:3 \
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
42
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
43
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
24
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-neon.inc.c
45
--- a/target/arm/sve.decode
26
+++ b/target/arm/translate-neon.inc.c
46
+++ b/target/arm/sve.decode
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
47
@@ -XXX,XX +XXX,XX @@ FMLALB_zzxw 01100100 10 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
28
tcg_temp_free_ptr(fpst);
48
FMLALT_zzxw 01100100 10 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
29
return true;
49
FMLSLB_zzxw 01100100 10 1 ..... 0110.0 ..... ..... @rrxr_3a esz=2
50
FMLSLT_zzxw 01100100 10 1 ..... 0110.1 ..... ..... @rrxr_3a esz=2
51
+BFMLALB_zzxw 01100100 11 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
52
+BFMLALT_zzxw 01100100 11 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
53
54
### SVE2 floating-point bfloat16 dot-product (indexed)
55
BFDOT_zzxz 01100100 01 1 ..... 010000 ..... ..... @rrxr_2 esz=2
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
60
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
61
unallocated_encoding(s);
62
return;
63
}
64
+ size = MO_32;
65
break;
66
case 1: /* BFDOT */
67
if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
68
unallocated_encoding(s);
69
return;
70
}
71
+ size = MO_32;
72
+ break;
73
+ case 3: /* BFMLAL{B,T} */
74
+ if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
75
+ unallocated_encoding(s);
76
+ return;
77
+ }
78
+ /* can't set is_fp without other incorrect size checks */
79
+ size = MO_16;
80
break;
81
default:
82
unallocated_encoding(s);
83
return;
84
}
85
- size = MO_32;
86
break;
87
case 0x11: /* FCMLA #0 */
88
case 0x13: /* FCMLA #90 */
89
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
90
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
91
gen_helper_gvec_usdot_idx_b);
92
return;
93
+ case 3: /* BFMLAL{B,T} */
94
+ gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, 0, (index << 1) | is_q,
95
+ gen_helper_gvec_bfmlal_idx);
96
+ return;
97
}
98
g_assert_not_reached();
99
case 0x11: /* FCMLA #0 */
100
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-neon.c
103
+++ b/target/arm/translate-neon.c
104
@@ -XXX,XX +XXX,XX @@ static bool trans_VFMA_b16(DisasContext *s, arg_VFMA_b16 *a)
105
return do_neon_ddda_fpst(s, 7, a->vd, a->vn, a->vm, a->q, FPST_STD,
106
gen_helper_gvec_bfmlal);
30
}
107
}
31
+
108
+
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
109
+static bool trans_VFMA_b16_scal(DisasContext *s, arg_VFMA_b16_scal *a)
33
+{
110
+{
34
+ int opr_sz;
111
+ if (!dc_isar_feature(aa32_bf16, s)) {
35
+ TCGv_ptr fpst;
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
37
+
38
+ if (!dc_isar_feature(aa32_vcma, s)
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
40
+ return false;
112
+ return false;
41
+ }
113
+ }
114
+ return do_neon_ddda_fpst(s, 6, a->vd, a->vn, a->vm,
115
+ (a->index << 1) | a->q, FPST_STD,
116
+ gen_helper_gvec_bfmlal_idx);
117
+}
118
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/arm/translate-sve.c
121
+++ b/target/arm/translate-sve.c
122
@@ -XXX,XX +XXX,XX @@ static bool trans_BFMLALT_zzzw(DisasContext *s, arg_rrrr_esz *a)
123
{
124
return do_BFMLAL_zzzw(s, a, true);
125
}
42
+
126
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
127
+static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel)
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
128
+{
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
129
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
46
+ return false;
130
+ return false;
47
+ }
131
+ }
132
+ if (sve_access_check(s)) {
133
+ TCGv_ptr status = fpstatus_ptr(FPST_FPCR);
134
+ unsigned vsz = vec_full_reg_size(s);
48
+
135
+
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
136
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
50
+ return false;
137
+ vec_full_reg_offset(s, a->rn),
138
+ vec_full_reg_offset(s, a->rm),
139
+ vec_full_reg_offset(s, a->ra),
140
+ status, vsz, vsz, (a->index << 1) | sel,
141
+ gen_helper_gvec_bfmlal_idx);
142
+ tcg_temp_free_ptr(status);
51
+ }
143
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ opr_sz = (1 + a->q) * 8;
58
+ fpst = get_fpstatus_ptr(1);
59
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
60
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->vm),
63
+ fpst, opr_sz, opr_sz, a->rot,
64
+ fn_gvec_ptr);
65
+ tcg_temp_free_ptr(fpst);
66
+ return true;
144
+ return true;
67
+}
145
+}
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
146
+
147
+static bool trans_BFMLALB_zzxw(DisasContext *s, arg_rrxr_esz *a)
148
+{
149
+ return do_BFMLAL_zzxw(s, a, false);
150
+}
151
+
152
+static bool trans_BFMLALT_zzxw(DisasContext *s, arg_rrxr_esz *a)
153
+{
154
+ return do_BFMLAL_zzxw(s, a, true);
155
+}
156
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
69
index XXXXXXX..XXXXXXX 100644
157
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/translate.c
158
--- a/target/arm/vec_helper.c
71
+++ b/target/arm/translate.c
159
+++ b/target/arm/vec_helper.c
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
160
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfmlal)(void *vd, void *vn, void *vm, void *va,
73
bool is_long = false, q = extract32(insn, 6, 1);
161
}
74
bool ptr_is_env = false;
162
clear_tail(d, opr_sz, simd_maxsz(desc));
75
163
}
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
164
+
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
165
+void HELPER(gvec_bfmlal_idx)(void *vd, void *vn, void *vm,
78
- int size = extract32(insn, 20, 1);
166
+ void *va, void *stat, uint32_t desc)
79
- data = extract32(insn, 24, 1); /* rot */
167
+{
80
- if (!dc_isar_feature(aa32_vcma, s)
168
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
169
+ intptr_t sel = extract32(desc, SIMD_DATA_SHIFT, 1);
82
- return 1;
170
+ intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 1, 3);
83
- }
171
+ intptr_t elements = opr_sz / 4;
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
172
+ intptr_t eltspersegment = MIN(16 / 4, elements);
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
173
+ float32 *d = vd, *a = va;
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
174
+ bfloat16 *n = vn, *m = vm;
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
175
+
88
bool u = extract32(insn, 4, 1);
176
+ for (i = 0; i < elements; i += eltspersegment) {
89
if (!dc_isar_feature(aa32_dp, s)) {
177
+ float32 m_idx = m[H2(2 * i + index)] << 16;
178
+
179
+ for (j = i; j < i + eltspersegment; j++) {
180
+ float32 n_j = n[H2(2 * j + sel)] << 16;
181
+ d[H4(j)] = float32_muladd(n_j, m_idx, a[H4(j)], 0, stat);
182
+ }
183
+ }
184
+ clear_tail(d, opr_sz, simd_maxsz(desc));
185
+}
90
--
186
--
91
2.20.1
187
2.20.1
92
188
93
189
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20210525225817.400336-12-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
linux-user/elfload.c | 2 ++
9
1 file changed, 2 insertions(+)
10
11
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/linux-user/elfload.c
14
+++ b/linux-user/elfload.c
15
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
16
GET_FEATURE_ID(aa64_sve_i8mm, ARM_HWCAP2_A64_SVEI8MM);
17
GET_FEATURE_ID(aa64_sve_f32mm, ARM_HWCAP2_A64_SVEF32MM);
18
GET_FEATURE_ID(aa64_sve_f64mm, ARM_HWCAP2_A64_SVEF64MM);
19
+ GET_FEATURE_ID(aa64_sve_bf16, ARM_HWCAP2_A64_SVEBF16);
20
GET_FEATURE_ID(aa64_i8mm, ARM_HWCAP2_A64_I8MM);
21
+ GET_FEATURE_ID(aa64_bf16, ARM_HWCAP2_A64_BF16);
22
GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
23
GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
24
GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
25
--
26
2.20.1
27
28
diff view generated by jsdifflib
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
1
From: Richard Henderson <richard.henderson@linaro.org>
2
registers. The intended pattern is that for 64-bit ID registers we
3
use FIELD_DP64 and the uint64_t 't' register, while 32-bit ID
4
registers use FIELD_DP32 and the uint32_t 'u' register. For
5
ID_AA64DFR0 we accidentally used 'u', meaning that the top 32 bits of
6
this 64-bit ID register would end up always zero. Luckily at the
7
moment that's what they should be anyway, so this bug has no visible
8
effects.
9
2
10
Use the right-sized variable.
3
Disable BF16 again for !have_neon and !have_vfp during realize.
11
4
12
Fixes: 3bec78447a958d481991
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210525225817.400336-13-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200423110915.10527-1-peter.maydell@linaro.org
17
---
9
---
18
target/arm/cpu64.c | 6 +++---
10
target/arm/cpu.c | 3 +++
19
1 file changed, 3 insertions(+), 3 deletions(-)
11
target/arm/cpu64.c | 3 +++
12
target/arm/cpu_tcg.c | 1 +
13
3 files changed, 7 insertions(+)
20
14
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
20
21
u = cpu->isar.id_isar6;
22
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0);
23
+ u = FIELD_DP32(u, ID_ISAR6, BF16, 0);
24
cpu->isar.id_isar6 = u;
25
26
u = cpu->isar.mvfr0;
27
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
28
29
t = cpu->isar.id_aa64isar1;
30
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0);
31
+ t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 0);
32
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 0);
33
cpu->isar.id_aa64isar1 = t;
34
35
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
36
u = cpu->isar.id_isar6;
37
u = FIELD_DP32(u, ID_ISAR6, DP, 0);
38
u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
39
+ u = FIELD_DP32(u, ID_ISAR6, BF16, 0);
40
u = FIELD_DP32(u, ID_ISAR6, I8MM, 0);
41
cpu->isar.id_isar6 = u;
42
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
43
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
22
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu64.c
45
--- a/target/arm/cpu64.c
24
+++ b/target/arm/cpu64.c
46
+++ b/target/arm/cpu64.c
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
48
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
27
cpu->isar.id_mmfr4 = u;
49
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
28
50
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
29
- u = cpu->isar.id_aa64dfr0;
51
+ t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1);
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
52
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
31
- cpu->isar.id_aa64dfr0 = u;
53
t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */
32
+ t = cpu->isar.id_aa64dfr0;
54
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1);
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
55
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
34
+ cpu->isar.id_aa64dfr0 = t;
56
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
35
57
t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* PMULL */
36
u = cpu->isar.id_dfr0;
58
t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1);
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
59
+ t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1);
60
t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1);
61
t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1);
62
t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1);
63
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
64
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
65
u = FIELD_DP32(u, ID_ISAR6, SB, 1);
66
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
67
+ u = FIELD_DP32(u, ID_ISAR6, BF16, 1);
68
u = FIELD_DP32(u, ID_ISAR6, I8MM, 1);
69
cpu->isar.id_isar6 = u;
70
71
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/cpu_tcg.c
74
+++ b/target/arm/cpu_tcg.c
75
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
76
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
77
t = FIELD_DP32(t, ID_ISAR6, SB, 1);
78
t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
79
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
80
t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
81
cpu->isar.id_isar6 = t;
82
38
--
83
--
39
2.20.1
84
2.20.1
40
85
41
86
diff view generated by jsdifflib
1
Add the infrastructure for building and invoking a decodetree decoder
1
From: Alexander Graf <agraf@csgraf.de>
2
for the AArch32 Neon encodings. At the moment the new decoder covers
2
3
nothing, so we always fall back to the existing hand-written decode.
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
We follow the same pattern we did for the VFP decodetree conversion
5
prepare for support for multiple architectures, let's start moving common
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
6
code out into its own accel directory.
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
7
8
which we #include into translate.c.
8
This patch moves assert_hvf_ok() and introduces generic build infrastructure.
9
9
10
In order to share the decode files between A32 and T32, we
10
Signed-off-by: Alexander Graf <agraf@csgraf.de>
11
split Neon into 3 parts:
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
12
* data-processing
12
Message-id: 20210519202253.76782-2-agraf@csgraf.de
13
* load-store
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
* 'shared' encodings
15
16
The first two groups of instructions have similar but not identical
17
A32 and T32 encodings, so we need to manually transform the T32
18
encoding into the A32 one before calling the decoder; the third group
19
covers the Neon instructions which are identical in A32 and T32.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
24
---
15
---
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
16
include/sysemu/hvf_int.h | 18 +++++++++++++++
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
17
accel/hvf/hvf-all.c | 47 ++++++++++++++++++++++++++++++++++++++++
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
18
target/i386/hvf/hvf.c | 33 +---------------------------
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
19
MAINTAINERS | 8 +++++++
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
20
accel/hvf/meson.build | 6 +++++
30
target/arm/Makefile.objs | 18 +++++++++++++++++
21
accel/meson.build | 1 +
31
6 files changed, 169 insertions(+), 2 deletions(-)
22
6 files changed, 81 insertions(+), 32 deletions(-)
32
create mode 100644 target/arm/neon-dp.decode
23
create mode 100644 include/sysemu/hvf_int.h
33
create mode 100644 target/arm/neon-ls.decode
24
create mode 100644 accel/hvf/hvf-all.c
34
create mode 100644 target/arm/neon-shared.decode
25
create mode 100644 accel/hvf/meson.build
35
create mode 100644 target/arm/translate-neon.inc.c
26
36
27
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
38
new file mode 100644
28
new file mode 100644
39
index XXXXXXX..XXXXXXX
29
index XXXXXXX..XXXXXXX
40
--- /dev/null
30
--- /dev/null
41
+++ b/target/arm/neon-dp.decode
31
+++ b/include/sysemu/hvf_int.h
42
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
43
+# AArch32 Neon data-processing instruction descriptions
33
+/*
44
+#
34
+ * QEMU Hypervisor.framework (HVF) support
45
+# Copyright (c) 2020 Linaro, Ltd
35
+ *
46
+#
36
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
47
+# This library is free software; you can redistribute it and/or
37
+ * See the COPYING file in the top-level directory.
48
+# modify it under the terms of the GNU Lesser General Public
38
+ *
49
+# License as published by the Free Software Foundation; either
39
+ */
50
+# version 2 of the License, or (at your option) any later version.
40
+
51
+#
41
+/* header to be included in HVF-specific code */
52
+# This library is distributed in the hope that it will be useful,
42
+
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
43
+#ifndef HVF_INT_H
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44
+#define HVF_INT_H
55
+# Lesser General Public License for more details.
45
+
56
+#
46
+#include <Hypervisor/hv.h>
57
+# You should have received a copy of the GNU Lesser General Public
47
+
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
48
+void assert_hvf_ok(hv_return_t ret);
59
+
49
+
60
+#
50
+#endif
61
+# This file is processed by scripts/decodetree.py
51
diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
62
+#
63
+
64
+# Encodings for Neon data processing instructions where the T32 encoding
65
+# is a simple transformation of the A32 encoding.
66
+# More specifically, this file covers instructions where the A32 encoding is
67
+# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
68
+# and the T32 encoding is
69
+# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
70
+# This file works on the A32 encoding only; calling code for T32 has to
71
+# transform the insn into the A32 version first.
72
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
73
new file mode 100644
52
new file mode 100644
74
index XXXXXXX..XXXXXXX
53
index XXXXXXX..XXXXXXX
75
--- /dev/null
54
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
55
+++ b/accel/hvf/hvf-all.c
77
@@ -XXX,XX +XXX,XX @@
56
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
57
+/*
79
+#
58
+ * QEMU Hypervisor.framework support
80
+# Copyright (c) 2020 Linaro, Ltd
59
+ *
81
+#
60
+ * This work is licensed under the terms of the GNU GPL, version 2. See
82
+# This library is free software; you can redistribute it and/or
61
+ * the COPYING file in the top-level directory.
83
+# modify it under the terms of the GNU Lesser General Public
62
+ *
84
+# License as published by the Free Software Foundation; either
63
+ * Contributions after 2012-01-13 are licensed under the terms of the
85
+# version 2 of the License, or (at your option) any later version.
64
+ * GNU GPL, version 2 or (at your option) any later version.
86
+#
65
+ */
87
+# This library is distributed in the hope that it will be useful,
66
+
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
67
+#include "qemu/osdep.h"
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
68
+#include "qemu-common.h"
90
+# Lesser General Public License for more details.
69
+#include "qemu/error-report.h"
91
+#
70
+#include "sysemu/hvf.h"
92
+# You should have received a copy of the GNU Lesser General Public
71
+#include "sysemu/hvf_int.h"
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
72
+
94
+
73
+void assert_hvf_ok(hv_return_t ret)
95
+#
74
+{
96
+# This file is processed by scripts/decodetree.py
75
+ if (ret == HV_SUCCESS) {
97
+#
76
+ return;
98
+
77
+ }
99
+# Encodings for Neon load/store instructions where the T32 encoding
78
+
100
+# is a simple transformation of the A32 encoding.
79
+ switch (ret) {
101
+# More specifically, this file covers instructions where the A32 encoding is
80
+ case HV_ERROR:
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
81
+ error_report("Error: HV_ERROR");
103
+# and the T32 encoding is
82
+ break;
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
83
+ case HV_BUSY:
105
+# This file works on the A32 encoding only; calling code for T32 has to
84
+ error_report("Error: HV_BUSY");
106
+# transform the insn into the A32 version first.
85
+ break;
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
86
+ case HV_BAD_ARGUMENT:
87
+ error_report("Error: HV_BAD_ARGUMENT");
88
+ break;
89
+ case HV_NO_RESOURCES:
90
+ error_report("Error: HV_NO_RESOURCES");
91
+ break;
92
+ case HV_NO_DEVICE:
93
+ error_report("Error: HV_NO_DEVICE");
94
+ break;
95
+ case HV_UNSUPPORTED:
96
+ error_report("Error: HV_UNSUPPORTED");
97
+ break;
98
+ default:
99
+ error_report("Unknown Error");
100
+ }
101
+
102
+ abort();
103
+}
104
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/i386/hvf/hvf.c
107
+++ b/target/i386/hvf/hvf.c
108
@@ -XXX,XX +XXX,XX @@
109
#include "qemu/error-report.h"
110
111
#include "sysemu/hvf.h"
112
+#include "sysemu/hvf_int.h"
113
#include "sysemu/runstate.h"
114
#include "hvf-i386.h"
115
#include "vmcs.h"
116
@@ -XXX,XX +XXX,XX @@
117
118
HVFState *hvf_state;
119
120
-static void assert_hvf_ok(hv_return_t ret)
121
-{
122
- if (ret == HV_SUCCESS) {
123
- return;
124
- }
125
-
126
- switch (ret) {
127
- case HV_ERROR:
128
- error_report("Error: HV_ERROR");
129
- break;
130
- case HV_BUSY:
131
- error_report("Error: HV_BUSY");
132
- break;
133
- case HV_BAD_ARGUMENT:
134
- error_report("Error: HV_BAD_ARGUMENT");
135
- break;
136
- case HV_NO_RESOURCES:
137
- error_report("Error: HV_NO_RESOURCES");
138
- break;
139
- case HV_NO_DEVICE:
140
- error_report("Error: HV_NO_DEVICE");
141
- break;
142
- case HV_UNSUPPORTED:
143
- error_report("Error: HV_UNSUPPORTED");
144
- break;
145
- default:
146
- error_report("Unknown Error");
147
- }
148
-
149
- abort();
150
-}
151
-
152
/* Memory slots */
153
hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
154
{
155
diff --git a/MAINTAINERS b/MAINTAINERS
156
index XXXXXXX..XXXXXXX 100644
157
--- a/MAINTAINERS
158
+++ b/MAINTAINERS
159
@@ -XXX,XX +XXX,XX @@ M: Roman Bolshakov <r.bolshakov@yadro.com>
160
W: https://wiki.qemu.org/Features/HVF
161
S: Maintained
162
F: target/i386/hvf/
163
+
164
+HVF
165
+M: Cameron Esfahani <dirty@apple.com>
166
+M: Roman Bolshakov <r.bolshakov@yadro.com>
167
+W: https://wiki.qemu.org/Features/HVF
168
+S: Maintained
169
+F: accel/hvf/
170
F: include/sysemu/hvf.h
171
+F: include/sysemu/hvf_int.h
172
173
WHPX CPUs
174
M: Sunil Muthuswamy <sunilmut@microsoft.com>
175
diff --git a/accel/hvf/meson.build b/accel/hvf/meson.build
108
new file mode 100644
176
new file mode 100644
109
index XXXXXXX..XXXXXXX
177
index XXXXXXX..XXXXXXX
110
--- /dev/null
178
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
179
+++ b/accel/hvf/meson.build
112
@@ -XXX,XX +XXX,XX @@
180
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
181
+hvf_ss = ss.source_set()
114
+#
182
+hvf_ss.add(files(
115
+# Copyright (c) 2020 Linaro, Ltd
183
+ 'hvf-all.c',
116
+#
184
+))
117
+# This library is free software; you can redistribute it and/or
185
+
118
+# modify it under the terms of the GNU Lesser General Public
186
+specific_ss.add_all(when: 'CONFIG_HVF', if_true: hvf_ss)
119
+# License as published by the Free Software Foundation; either
187
diff --git a/accel/meson.build b/accel/meson.build
120
+# version 2 of the License, or (at your option) any later version.
121
+#
122
+# This library is distributed in the hope that it will be useful,
123
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+# Lesser General Public License for more details.
126
+#
127
+# You should have received a copy of the GNU Lesser General Public
128
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+
130
+#
131
+# This file is processed by scripts/decodetree.py
132
+#
133
+
134
+# Encodings for Neon instructions whose encoding is the same for
135
+# both A32 and T32.
136
+
137
+# More specifically, this covers:
138
+# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
139
+# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
140
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
141
new file mode 100644
142
index XXXXXXX..XXXXXXX
143
--- /dev/null
144
+++ b/target/arm/translate-neon.inc.c
145
@@ -XXX,XX +XXX,XX @@
146
+/*
147
+ * ARM translation: AArch32 Neon instructions
148
+ *
149
+ * Copyright (c) 2003 Fabrice Bellard
150
+ * Copyright (c) 2005-2007 CodeSourcery
151
+ * Copyright (c) 2007 OpenedHand, Ltd.
152
+ * Copyright (c) 2020 Linaro, Ltd.
153
+ *
154
+ * This library is free software; you can redistribute it and/or
155
+ * modify it under the terms of the GNU Lesser General Public
156
+ * License as published by the Free Software Foundation; either
157
+ * version 2 of the License, or (at your option) any later version.
158
+ *
159
+ * This library is distributed in the hope that it will be useful,
160
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
161
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
162
+ * Lesser General Public License for more details.
163
+ *
164
+ * You should have received a copy of the GNU Lesser General Public
165
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
166
+ */
167
+
168
+/*
169
+ * This file is intended to be included from translate.c; it uses
170
+ * some macros and definitions provided by that file.
171
+ * It might be possible to convert it to a standalone .c file eventually.
172
+ */
173
+
174
+/* Include the generated Neon decoder */
175
+#include "decode-neon-dp.inc.c"
176
+#include "decode-neon-ls.inc.c"
177
+#include "decode-neon-shared.inc.c"
178
diff --git a/target/arm/translate.c b/target/arm/translate.c
179
index XXXXXXX..XXXXXXX 100644
188
index XXXXXXX..XXXXXXX 100644
180
--- a/target/arm/translate.c
189
--- a/accel/meson.build
181
+++ b/target/arm/translate.c
190
+++ b/accel/meson.build
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
191
@@ -XXX,XX +XXX,XX @@ specific_ss.add(files('accel-common.c'))
183
192
softmmu_ss.add(files('accel-softmmu.c'))
184
#define ARM_CP_RW_BIT (1 << 20)
193
user_ss.add(files('accel-user.c'))
185
194
186
-/* Include the VFP decoder */
195
+subdir('hvf')
187
+/* Include the VFP and Neon decoders */
196
subdir('qtest')
188
#include "translate-vfp.inc.c"
197
subdir('kvm')
189
+#include "translate-neon.inc.c"
198
subdir('tcg')
190
191
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
192
{
193
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
194
/* Unconditional instructions. */
195
/* TODO: Perhaps merge these into one decodetree output file. */
196
if (disas_a32_uncond(s, insn) ||
197
- disas_vfp_uncond(s, insn)) {
198
+ disas_vfp_uncond(s, insn) ||
199
+ disas_neon_dp(s, insn) ||
200
+ disas_neon_ls(s, insn) ||
201
+ disas_neon_shared(s, insn)) {
202
return;
203
}
204
/* fall back to legacy decoder */
205
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
206
ARCH(6T2);
207
}
208
209
+ if ((insn & 0xef000000) == 0xef000000) {
210
+ /*
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
212
+ * transform into
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
214
+ */
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
217
+
218
+ if (disas_neon_dp(s, a32_insn)) {
219
+ return;
220
+ }
221
+ }
222
+
223
+ if ((insn & 0xff100000) == 0xf9000000) {
224
+ /*
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
226
+ * transform into
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
228
+ */
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
230
+
231
+ if (disas_neon_ls(s, a32_insn)) {
232
+ return;
233
+ }
234
+ }
235
+
236
/*
237
* TODO: Perhaps merge these into one decodetree output file.
238
* Note disas_vfp is written for a32 with cond field in the
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
240
*/
241
if (disas_t32(s, insn) ||
242
disas_vfp_uncond(s, insn) ||
243
+ disas_neon_shared(s, insn) ||
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
245
return;
246
}
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
248
index XXXXXXX..XXXXXXX 100644
249
--- a/target/arm/Makefile.objs
250
+++ b/target/arm/Makefile.objs
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
253
     "GEN", $(TARGET_DIR)$@)
254
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
256
+    $(call quiet-command,\
257
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
258
+     "GEN", $(TARGET_DIR)$@)
259
+
260
+target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
261
+    $(call quiet-command,\
262
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
263
+     "GEN", $(TARGET_DIR)$@)
264
+
265
+target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
266
+    $(call quiet-command,\
267
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
268
+     "GEN", $(TARGET_DIR)$@)
269
+
270
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
271
    $(call quiet-command,\
272
     $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
273
@@ -XXX,XX +XXX,XX @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
274
     "GEN", $(TARGET_DIR)$@)
275
276
target/arm/translate-sve.o: target/arm/decode-sve.inc.c
277
+target/arm/translate.o: target/arm/decode-neon-shared.inc.c
278
+target/arm/translate.o: target/arm/decode-neon-dp.inc.c
279
+target/arm/translate.o: target/arm/decode-neon-ls.inc.c
280
target/arm/translate.o: target/arm/decode-vfp.inc.c
281
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
282
target/arm/translate.o: target/arm/decode-a32.inc.c
283
--
199
--
284
2.20.1
200
2.20.1
285
201
286
202
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Embed the ADMAs into the SoC type.
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
4
7
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
This patch moves the vCPU thread loop over.
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alexander Graf <agraf@csgraf.de>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
12
Message-id: 20210519202253.76782-3-agraf@csgraf.de
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
15
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
16
{target/i386 => accel}/hvf/hvf-accel-ops.h | 0
14
hw/arm/xlnx-versal.c | 14 +++++++-------
17
{target/i386 => accel}/hvf/hvf-accel-ops.c | 0
15
2 files changed, 9 insertions(+), 8 deletions(-)
18
target/i386/hvf/x86hvf.c | 2 +-
19
accel/hvf/meson.build | 1 +
20
target/i386/hvf/meson.build | 1 -
21
5 files changed, 2 insertions(+), 2 deletions(-)
22
rename {target/i386 => accel}/hvf/hvf-accel-ops.h (100%)
23
rename {target/i386 => accel}/hvf/hvf-accel-ops.c (100%)
16
24
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
25
diff --git a/target/i386/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
26
similarity index 100%
27
rename from target/i386/hvf/hvf-accel-ops.h
28
rename to accel/hvf/hvf-accel-ops.h
29
diff --git a/target/i386/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
30
similarity index 100%
31
rename from target/i386/hvf/hvf-accel-ops.c
32
rename to accel/hvf/hvf-accel-ops.c
33
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
18
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
35
--- a/target/i386/hvf/x86hvf.c
20
+++ b/include/hw/arm/xlnx-versal.h
36
+++ b/target/i386/hvf/x86hvf.c
21
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
22
#include "hw/arm/boot.h"
38
#include <Hypervisor/hv.h>
23
#include "hw/intc/arm_gicv3.h"
39
#include <Hypervisor/hv_vmx.h>
24
#include "hw/char/pl011.h"
40
25
+#include "hw/dma/xlnx-zdma.h"
41
-#include "hvf-accel-ops.h"
26
#include "hw/net/cadence_gem.h"
42
+#include "accel/hvf/hvf-accel-ops.h"
27
43
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
44
void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
45
SegmentCache *qseg, bool is_tr)
30
struct {
46
diff --git a/accel/hvf/meson.build b/accel/hvf/meson.build
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
33
- SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
34
+ XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
35
} iou;
36
} lpd;
37
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
48
--- a/accel/hvf/meson.build
41
+++ b/hw/arm/xlnx-versal.c
49
+++ b/accel/hvf/meson.build
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
50
@@ -XXX,XX +XXX,XX @@
43
DeviceState *dev;
51
hvf_ss = ss.source_set()
44
MemoryRegion *mr;
52
hvf_ss.add(files(
45
53
'hvf-all.c',
46
- dev = qdev_create(NULL, "xlnx.zdma");
54
+ 'hvf-accel-ops.c',
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
55
))
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
56
49
- &error_abort);
57
specific_ss.add_all(when: 'CONFIG_HVF', if_true: hvf_ss)
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
58
diff --git a/target/i386/hvf/meson.build b/target/i386/hvf/meson.build
51
+ sysbus_init_child_obj(OBJECT(s), name,
59
index XXXXXXX..XXXXXXX 100644
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
60
--- a/target/i386/hvf/meson.build
53
+ TYPE_XLNX_ZDMA);
61
+++ b/target/i386/hvf/meson.build
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
62
@@ -XXX,XX +XXX,XX @@
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
63
i386_softmmu_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files(
56
qdev_init_nofail(dev);
64
'hvf.c',
57
65
- 'hvf-accel-ops.c',
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
66
'x86.c',
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
67
'x86_cpuid.c',
60
memory_region_add_subregion(&s->mr_ps,
68
'x86_decode.c',
61
MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
62
63
- sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
64
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
65
g_free(name);
66
}
67
}
68
--
69
--
69
2.20.1
70
2.20.1
70
71
71
72
diff view generated by jsdifflib
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
1
From: Alexander Graf <agraf@csgraf.de>
2
to decodetree. These are the last ones in the group so we can remove
3
all the legacy decode for the group.
4
2
5
Note that in disas_thumb2_insn() the parts of this encoding space
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
6
where the decodetree decoder returns false will correctly be directed
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
5
prepare for support for multiple architectures, let's start moving common
8
into disas_coproc_insn() by mistake.
6
code out into its own accel directory.
9
7
8
This patch moves CPU and memory operations over. While at it, make sure
9
the code is consumable on non-i386 systems.
10
11
Signed-off-by: Alexander Graf <agraf@csgraf.de>
12
Reviewed-by: Sergio Lopez <slp@redhat.com>
13
Message-id: 20210519202253.76782-4-agraf@csgraf.de
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-11-peter.maydell@linaro.org
13
---
16
---
14
target/arm/neon-shared.decode | 7 +++
17
include/sysemu/hvf_int.h | 4 +
15
target/arm/translate-neon.inc.c | 32 ++++++++++
18
target/i386/hvf/hvf-i386.h | 2 -
16
target/arm/translate.c | 107 +-------------------------------
19
target/i386/hvf/x86hvf.h | 2 -
17
3 files changed, 40 insertions(+), 106 deletions(-)
20
accel/hvf/hvf-accel-ops.c | 308 ++++++++++++++++++++++++++++++++++++-
21
target/i386/hvf/hvf.c | 302 ------------------------------------
22
5 files changed, 311 insertions(+), 307 deletions(-)
18
23
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
24
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
26
--- a/include/sysemu/hvf_int.h
22
+++ b/target/arm/neon-shared.decode
27
+++ b/include/sysemu/hvf_int.h
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
28
@@ -XXX,XX +XXX,XX @@
24
29
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
30
#include <Hypervisor/hv.h>
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
31
27
+
32
+void hvf_set_phys_mem(MemoryRegionSection *, bool);
28
+%vfml_scalar_q0_rm 0:3 5:1
33
void assert_hvf_ok(hv_return_t ret);
29
+%vfml_scalar_q1_index 5:1 3:1
34
+hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
35
+int hvf_put_registers(CPUState *);
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
36
+int hvf_get_registers(CPUState *);
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
37
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
38
#endif
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
39
diff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h
35
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
41
--- a/target/i386/hvf/hvf-i386.h
37
+++ b/target/arm/translate-neon.inc.c
42
+++ b/target/i386/hvf/hvf-i386.h
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
43
@@ -XXX,XX +XXX,XX @@ struct HVFState {
39
tcg_temp_free_ptr(fpst);
44
};
40
return true;
45
extern HVFState *hvf_state;
46
47
-void hvf_set_phys_mem(MemoryRegionSection *, bool);
48
void hvf_handle_io(CPUArchState *, uint16_t, void *, int, int, int);
49
-hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
50
51
#ifdef NEED_CPU_H
52
/* Functions exported to host specific mode */
53
diff --git a/target/i386/hvf/x86hvf.h b/target/i386/hvf/x86hvf.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/i386/hvf/x86hvf.h
56
+++ b/target/i386/hvf/x86hvf.h
57
@@ -XXX,XX +XXX,XX @@
58
#include "x86_descr.h"
59
60
int hvf_process_events(CPUState *);
61
-int hvf_put_registers(CPUState *);
62
-int hvf_get_registers(CPUState *);
63
bool hvf_inject_interrupts(CPUState *);
64
void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
65
SegmentCache *qseg, bool is_tr);
66
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/accel/hvf/hvf-accel-ops.c
69
+++ b/accel/hvf/hvf-accel-ops.c
70
@@ -XXX,XX +XXX,XX @@
71
#include "qemu/osdep.h"
72
#include "qemu/error-report.h"
73
#include "qemu/main-loop.h"
74
+#include "exec/address-spaces.h"
75
+#include "exec/exec-all.h"
76
+#include "sysemu/cpus.h"
77
#include "sysemu/hvf.h"
78
+#include "sysemu/hvf_int.h"
79
#include "sysemu/runstate.h"
80
-#include "target/i386/cpu.h"
81
#include "qemu/guest-random.h"
82
83
#include "hvf-accel-ops.h"
84
85
+HVFState *hvf_state;
86
+
87
+/* Memory slots */
88
+
89
+hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
90
+{
91
+ hvf_slot *slot;
92
+ int x;
93
+ for (x = 0; x < hvf_state->num_slots; ++x) {
94
+ slot = &hvf_state->slots[x];
95
+ if (slot->size && start < (slot->start + slot->size) &&
96
+ (start + size) > slot->start) {
97
+ return slot;
98
+ }
99
+ }
100
+ return NULL;
101
+}
102
+
103
+struct mac_slot {
104
+ int present;
105
+ uint64_t size;
106
+ uint64_t gpa_start;
107
+ uint64_t gva;
108
+};
109
+
110
+struct mac_slot mac_slots[32];
111
+
112
+static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
113
+{
114
+ struct mac_slot *macslot;
115
+ hv_return_t ret;
116
+
117
+ macslot = &mac_slots[slot->slot_id];
118
+
119
+ if (macslot->present) {
120
+ if (macslot->size != slot->size) {
121
+ macslot->present = 0;
122
+ ret = hv_vm_unmap(macslot->gpa_start, macslot->size);
123
+ assert_hvf_ok(ret);
124
+ }
125
+ }
126
+
127
+ if (!slot->size) {
128
+ return 0;
129
+ }
130
+
131
+ macslot->present = 1;
132
+ macslot->gpa_start = slot->start;
133
+ macslot->size = slot->size;
134
+ ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
135
+ assert_hvf_ok(ret);
136
+ return 0;
137
+}
138
+
139
+void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
140
+{
141
+ hvf_slot *mem;
142
+ MemoryRegion *area = section->mr;
143
+ bool writeable = !area->readonly && !area->rom_device;
144
+ hv_memory_flags_t flags;
145
+
146
+ if (!memory_region_is_ram(area)) {
147
+ if (writeable) {
148
+ return;
149
+ } else if (!memory_region_is_romd(area)) {
150
+ /*
151
+ * If the memory device is not in romd_mode, then we actually want
152
+ * to remove the hvf memory slot so all accesses will trap.
153
+ */
154
+ add = false;
155
+ }
156
+ }
157
+
158
+ mem = hvf_find_overlap_slot(
159
+ section->offset_within_address_space,
160
+ int128_get64(section->size));
161
+
162
+ if (mem && add) {
163
+ if (mem->size == int128_get64(section->size) &&
164
+ mem->start == section->offset_within_address_space &&
165
+ mem->mem == (memory_region_get_ram_ptr(area) +
166
+ section->offset_within_region)) {
167
+ return; /* Same region was attempted to register, go away. */
168
+ }
169
+ }
170
+
171
+ /* Region needs to be reset. set the size to 0 and remap it. */
172
+ if (mem) {
173
+ mem->size = 0;
174
+ if (do_hvf_set_memory(mem, 0)) {
175
+ error_report("Failed to reset overlapping slot");
176
+ abort();
177
+ }
178
+ }
179
+
180
+ if (!add) {
181
+ return;
182
+ }
183
+
184
+ if (area->readonly ||
185
+ (!memory_region_is_ram(area) && memory_region_is_romd(area))) {
186
+ flags = HV_MEMORY_READ | HV_MEMORY_EXEC;
187
+ } else {
188
+ flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;
189
+ }
190
+
191
+ /* Now make a new slot. */
192
+ int x;
193
+
194
+ for (x = 0; x < hvf_state->num_slots; ++x) {
195
+ mem = &hvf_state->slots[x];
196
+ if (!mem->size) {
197
+ break;
198
+ }
199
+ }
200
+
201
+ if (x == hvf_state->num_slots) {
202
+ error_report("No free slots");
203
+ abort();
204
+ }
205
+
206
+ mem->size = int128_get64(section->size);
207
+ mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
208
+ mem->start = section->offset_within_address_space;
209
+ mem->region = area;
210
+
211
+ if (do_hvf_set_memory(mem, flags)) {
212
+ error_report("Error registering new memory slot");
213
+ abort();
214
+ }
215
+}
216
+
217
+static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
218
+{
219
+ if (!cpu->vcpu_dirty) {
220
+ hvf_get_registers(cpu);
221
+ cpu->vcpu_dirty = true;
222
+ }
223
+}
224
+
225
+void hvf_cpu_synchronize_state(CPUState *cpu)
226
+{
227
+ if (!cpu->vcpu_dirty) {
228
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
229
+ }
230
+}
231
+
232
+static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
233
+ run_on_cpu_data arg)
234
+{
235
+ hvf_put_registers(cpu);
236
+ cpu->vcpu_dirty = false;
237
+}
238
+
239
+void hvf_cpu_synchronize_post_reset(CPUState *cpu)
240
+{
241
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
242
+}
243
+
244
+static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
245
+ run_on_cpu_data arg)
246
+{
247
+ hvf_put_registers(cpu);
248
+ cpu->vcpu_dirty = false;
249
+}
250
+
251
+void hvf_cpu_synchronize_post_init(CPUState *cpu)
252
+{
253
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
254
+}
255
+
256
+static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
257
+ run_on_cpu_data arg)
258
+{
259
+ cpu->vcpu_dirty = true;
260
+}
261
+
262
+void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
263
+{
264
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
265
+}
266
+
267
+static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
268
+{
269
+ hvf_slot *slot;
270
+
271
+ slot = hvf_find_overlap_slot(
272
+ section->offset_within_address_space,
273
+ int128_get64(section->size));
274
+
275
+ /* protect region against writes; begin tracking it */
276
+ if (on) {
277
+ slot->flags |= HVF_SLOT_LOG;
278
+ hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
279
+ HV_MEMORY_READ);
280
+ /* stop tracking region*/
281
+ } else {
282
+ slot->flags &= ~HVF_SLOT_LOG;
283
+ hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
284
+ HV_MEMORY_READ | HV_MEMORY_WRITE);
285
+ }
286
+}
287
+
288
+static void hvf_log_start(MemoryListener *listener,
289
+ MemoryRegionSection *section, int old, int new)
290
+{
291
+ if (old != 0) {
292
+ return;
293
+ }
294
+
295
+ hvf_set_dirty_tracking(section, 1);
296
+}
297
+
298
+static void hvf_log_stop(MemoryListener *listener,
299
+ MemoryRegionSection *section, int old, int new)
300
+{
301
+ if (new != 0) {
302
+ return;
303
+ }
304
+
305
+ hvf_set_dirty_tracking(section, 0);
306
+}
307
+
308
+static void hvf_log_sync(MemoryListener *listener,
309
+ MemoryRegionSection *section)
310
+{
311
+ /*
312
+ * sync of dirty pages is handled elsewhere; just make sure we keep
313
+ * tracking the region.
314
+ */
315
+ hvf_set_dirty_tracking(section, 1);
316
+}
317
+
318
+static void hvf_region_add(MemoryListener *listener,
319
+ MemoryRegionSection *section)
320
+{
321
+ hvf_set_phys_mem(section, true);
322
+}
323
+
324
+static void hvf_region_del(MemoryListener *listener,
325
+ MemoryRegionSection *section)
326
+{
327
+ hvf_set_phys_mem(section, false);
328
+}
329
+
330
+static MemoryListener hvf_memory_listener = {
331
+ .priority = 10,
332
+ .region_add = hvf_region_add,
333
+ .region_del = hvf_region_del,
334
+ .log_start = hvf_log_start,
335
+ .log_stop = hvf_log_stop,
336
+ .log_sync = hvf_log_sync,
337
+};
338
+
339
+static void dummy_signal(int sig)
340
+{
341
+}
342
+
343
+bool hvf_allowed;
344
+
345
+static int hvf_accel_init(MachineState *ms)
346
+{
347
+ int x;
348
+ hv_return_t ret;
349
+ HVFState *s;
350
+
351
+ ret = hv_vm_create(HV_VM_DEFAULT);
352
+ assert_hvf_ok(ret);
353
+
354
+ s = g_new0(HVFState, 1);
355
+
356
+ s->num_slots = 32;
357
+ for (x = 0; x < s->num_slots; ++x) {
358
+ s->slots[x].size = 0;
359
+ s->slots[x].slot_id = x;
360
+ }
361
+
362
+ hvf_state = s;
363
+ memory_listener_register(&hvf_memory_listener, &address_space_memory);
364
+ return 0;
365
+}
366
+
367
+static void hvf_accel_class_init(ObjectClass *oc, void *data)
368
+{
369
+ AccelClass *ac = ACCEL_CLASS(oc);
370
+ ac->name = "HVF";
371
+ ac->init_machine = hvf_accel_init;
372
+ ac->allowed = &hvf_allowed;
373
+}
374
+
375
+static const TypeInfo hvf_accel_type = {
376
+ .name = TYPE_HVF_ACCEL,
377
+ .parent = TYPE_ACCEL,
378
+ .class_init = hvf_accel_class_init,
379
+};
380
+
381
+static void hvf_type_init(void)
382
+{
383
+ type_register_static(&hvf_accel_type);
384
+}
385
+
386
+type_init(hvf_type_init);
387
+
388
/*
389
* The HVF-specific vCPU thread function. This one should only run when the host
390
* CPU supports the VMX "unrestricted guest" feature.
391
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
392
index XXXXXXX..XXXXXXX 100644
393
--- a/target/i386/hvf/hvf.c
394
+++ b/target/i386/hvf/hvf.c
395
@@ -XXX,XX +XXX,XX @@
396
397
#include "hvf-accel-ops.h"
398
399
-HVFState *hvf_state;
400
-
401
-/* Memory slots */
402
-hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
403
-{
404
- hvf_slot *slot;
405
- int x;
406
- for (x = 0; x < hvf_state->num_slots; ++x) {
407
- slot = &hvf_state->slots[x];
408
- if (slot->size && start < (slot->start + slot->size) &&
409
- (start + size) > slot->start) {
410
- return slot;
411
- }
412
- }
413
- return NULL;
414
-}
415
-
416
-struct mac_slot {
417
- int present;
418
- uint64_t size;
419
- uint64_t gpa_start;
420
- uint64_t gva;
421
-};
422
-
423
-struct mac_slot mac_slots[32];
424
-
425
-static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
426
-{
427
- struct mac_slot *macslot;
428
- hv_return_t ret;
429
-
430
- macslot = &mac_slots[slot->slot_id];
431
-
432
- if (macslot->present) {
433
- if (macslot->size != slot->size) {
434
- macslot->present = 0;
435
- ret = hv_vm_unmap(macslot->gpa_start, macslot->size);
436
- assert_hvf_ok(ret);
437
- }
438
- }
439
-
440
- if (!slot->size) {
441
- return 0;
442
- }
443
-
444
- macslot->present = 1;
445
- macslot->gpa_start = slot->start;
446
- macslot->size = slot->size;
447
- ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
448
- assert_hvf_ok(ret);
449
- return 0;
450
-}
451
-
452
-void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
453
-{
454
- hvf_slot *mem;
455
- MemoryRegion *area = section->mr;
456
- bool writeable = !area->readonly && !area->rom_device;
457
- hv_memory_flags_t flags;
458
-
459
- if (!memory_region_is_ram(area)) {
460
- if (writeable) {
461
- return;
462
- } else if (!memory_region_is_romd(area)) {
463
- /*
464
- * If the memory device is not in romd_mode, then we actually want
465
- * to remove the hvf memory slot so all accesses will trap.
466
- */
467
- add = false;
468
- }
469
- }
470
-
471
- mem = hvf_find_overlap_slot(
472
- section->offset_within_address_space,
473
- int128_get64(section->size));
474
-
475
- if (mem && add) {
476
- if (mem->size == int128_get64(section->size) &&
477
- mem->start == section->offset_within_address_space &&
478
- mem->mem == (memory_region_get_ram_ptr(area) +
479
- section->offset_within_region)) {
480
- return; /* Same region was attempted to register, go away. */
481
- }
482
- }
483
-
484
- /* Region needs to be reset. set the size to 0 and remap it. */
485
- if (mem) {
486
- mem->size = 0;
487
- if (do_hvf_set_memory(mem, 0)) {
488
- error_report("Failed to reset overlapping slot");
489
- abort();
490
- }
491
- }
492
-
493
- if (!add) {
494
- return;
495
- }
496
-
497
- if (area->readonly ||
498
- (!memory_region_is_ram(area) && memory_region_is_romd(area))) {
499
- flags = HV_MEMORY_READ | HV_MEMORY_EXEC;
500
- } else {
501
- flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;
502
- }
503
-
504
- /* Now make a new slot. */
505
- int x;
506
-
507
- for (x = 0; x < hvf_state->num_slots; ++x) {
508
- mem = &hvf_state->slots[x];
509
- if (!mem->size) {
510
- break;
511
- }
512
- }
513
-
514
- if (x == hvf_state->num_slots) {
515
- error_report("No free slots");
516
- abort();
517
- }
518
-
519
- mem->size = int128_get64(section->size);
520
- mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
521
- mem->start = section->offset_within_address_space;
522
- mem->region = area;
523
-
524
- if (do_hvf_set_memory(mem, flags)) {
525
- error_report("Error registering new memory slot");
526
- abort();
527
- }
528
-}
529
-
530
void vmx_update_tpr(CPUState *cpu)
531
{
532
/* TODO: need integrate APIC handling */
533
@@ -XXX,XX +XXX,XX @@ void hvf_handle_io(CPUArchState *env, uint16_t port, void *buffer,
534
}
41
}
535
}
42
+
536
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
537
-static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
44
+{
538
-{
45
+ int opr_sz;
539
- if (!cpu->vcpu_dirty) {
46
+
540
- hvf_get_registers(cpu);
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
541
- cpu->vcpu_dirty = true;
48
+ return false;
542
- }
49
+ }
543
-}
50
+
544
-
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
545
-void hvf_cpu_synchronize_state(CPUState *cpu)
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
546
-{
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
547
- if (!cpu->vcpu_dirty) {
54
+ return false;
548
- run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
55
+ }
549
- }
56
+
550
-}
57
+ if (a->vd & a->q) {
551
-
58
+ return false;
552
-static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
59
+ }
553
- run_on_cpu_data arg)
60
+
554
-{
61
+ if (!vfp_access_check(s)) {
555
- hvf_put_registers(cpu);
62
+ return true;
556
- cpu->vcpu_dirty = false;
63
+ }
557
-}
64
+
558
-
65
+ opr_sz = (1 + a->q) * 8;
559
-void hvf_cpu_synchronize_post_reset(CPUState *cpu)
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
560
-{
67
+ vfp_reg_offset(a->q, a->vn),
561
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
68
+ vfp_reg_offset(a->q, a->rm),
562
-}
69
+ cpu_env, opr_sz, opr_sz,
563
-
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
564
-static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
71
+ gen_helper_gvec_fmlal_idx_a32);
565
- run_on_cpu_data arg)
72
+ return true;
566
-{
73
+}
567
- hvf_put_registers(cpu);
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
568
- cpu->vcpu_dirty = false;
75
index XXXXXXX..XXXXXXX 100644
569
-}
76
--- a/target/arm/translate.c
570
-
77
+++ b/target/arm/translate.c
571
-void hvf_cpu_synchronize_post_init(CPUState *cpu)
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
572
-{
573
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
574
-}
575
-
576
-static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
577
- run_on_cpu_data arg)
578
-{
579
- cpu->vcpu_dirty = true;
580
-}
581
-
582
-void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
583
-{
584
- run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
585
-}
586
-
587
static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
588
{
589
int read, write;
590
@@ -XXX,XX +XXX,XX @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
591
return false;
79
}
592
}
80
593
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
594
-static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
82
-#define VFP_SREG(insn, bigbit, smallbit) \
595
-{
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
596
- hvf_slot *slot;
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
597
-
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
598
- slot = hvf_find_overlap_slot(
86
reg = (((insn) >> (bigbit)) & 0x0f) \
599
- section->offset_within_address_space,
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
600
- int128_get64(section->size));
88
reg = ((insn) >> (bigbit)) & 0x0f; \
601
-
89
}} while (0)
602
- /* protect region against writes; begin tracking it */
90
603
- if (on) {
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
604
- slot->flags |= HVF_SLOT_LOG;
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
605
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
606
- HV_MEMORY_READ);
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
607
- /* stop tracking region*/
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
608
- } else {
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
609
- slot->flags &= ~HVF_SLOT_LOG;
97
610
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
98
static void gen_neon_dup_low16(TCGv_i32 var)
611
- HV_MEMORY_READ | HV_MEMORY_WRITE);
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
612
- }
100
return 0;
613
-}
614
-
615
-static void hvf_log_start(MemoryListener *listener,
616
- MemoryRegionSection *section, int old, int new)
617
-{
618
- if (old != 0) {
619
- return;
620
- }
621
-
622
- hvf_set_dirty_tracking(section, 1);
623
-}
624
-
625
-static void hvf_log_stop(MemoryListener *listener,
626
- MemoryRegionSection *section, int old, int new)
627
-{
628
- if (new != 0) {
629
- return;
630
- }
631
-
632
- hvf_set_dirty_tracking(section, 0);
633
-}
634
-
635
-static void hvf_log_sync(MemoryListener *listener,
636
- MemoryRegionSection *section)
637
-{
638
- /*
639
- * sync of dirty pages is handled elsewhere; just make sure we keep
640
- * tracking the region.
641
- */
642
- hvf_set_dirty_tracking(section, 1);
643
-}
644
-
645
-static void hvf_region_add(MemoryListener *listener,
646
- MemoryRegionSection *section)
647
-{
648
- hvf_set_phys_mem(section, true);
649
-}
650
-
651
-static void hvf_region_del(MemoryListener *listener,
652
- MemoryRegionSection *section)
653
-{
654
- hvf_set_phys_mem(section, false);
655
-}
656
-
657
-static MemoryListener hvf_memory_listener = {
658
- .priority = 10,
659
- .region_add = hvf_region_add,
660
- .region_del = hvf_region_del,
661
- .log_start = hvf_log_start,
662
- .log_stop = hvf_log_stop,
663
- .log_sync = hvf_log_sync,
664
-};
665
-
666
void hvf_vcpu_destroy(CPUState *cpu)
667
{
668
X86CPU *x86_cpu = X86_CPU(cpu);
669
@@ -XXX,XX +XXX,XX @@ void hvf_vcpu_destroy(CPUState *cpu)
670
assert_hvf_ok(ret);
101
}
671
}
102
672
103
-/* Advanced SIMD two registers and a scalar extension.
673
-static void dummy_signal(int sig)
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
674
-{
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
675
-}
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
676
-
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
677
static void init_tsc_freq(CPUX86State *env)
108
- *
678
{
109
- */
679
size_t length;
110
-
680
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
681
112
-{
682
return ret;
113
- gen_helper_gvec_3 *fn_gvec = NULL;
683
}
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
684
-
115
- int rd, rn, rm, opr_sz, data;
685
-bool hvf_allowed;
116
- int off_rn, off_rm;
686
-
117
- bool is_long = false, q = extract32(insn, 6, 1);
687
-static int hvf_accel_init(MachineState *ms)
118
- bool ptr_is_env = false;
688
-{
119
-
689
- int x;
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
690
- hv_return_t ret;
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
691
- HVFState *s;
122
- int is_s = extract32(insn, 20, 1);
692
-
123
- int vm20 = extract32(insn, 0, 3);
693
- ret = hv_vm_create(HV_VM_DEFAULT);
124
- int vm3 = extract32(insn, 3, 1);
694
- assert_hvf_ok(ret);
125
- int m = extract32(insn, 5, 1);
695
-
126
- int index;
696
- s = g_new0(HVFState, 1);
127
-
697
-
128
- if (!dc_isar_feature(aa32_fhm, s)) {
698
- s->num_slots = 32;
129
- return 1;
699
- for (x = 0; x < s->num_slots; ++x) {
130
- }
700
- s->slots[x].size = 0;
131
- if (q) {
701
- s->slots[x].slot_id = x;
132
- rm = vm20;
702
- }
133
- index = m * 2 + vm3;
703
-
134
- } else {
704
- hvf_state = s;
135
- rm = vm20 * 2 + m;
705
- memory_listener_register(&hvf_memory_listener, &address_space_memory);
136
- index = vm3;
137
- }
138
- is_long = true;
139
- data = (index << 2) | is_s; /* is_2 == 0 */
140
- fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
141
- ptr_is_env = true;
142
- } else {
143
- return 1;
144
- }
145
-
146
- VFP_DREG_D(rd, insn);
147
- if (rd & q) {
148
- return 1;
149
- }
150
- if (q || !is_long) {
151
- VFP_DREG_N(rn, insn);
152
- if (rn & q & !is_long) {
153
- return 1;
154
- }
155
- off_rn = vfp_reg_offset(1, rn);
156
- off_rm = vfp_reg_offset(1, rm);
157
- } else {
158
- rn = VFP_SREG_N(insn);
159
- off_rn = vfp_reg_offset(0, rn);
160
- off_rm = vfp_reg_offset(0, rm);
161
- }
162
- if (s->fp_excp_el) {
163
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
165
- return 0;
166
- }
167
- if (!s->vfp_enabled) {
168
- return 1;
169
- }
170
-
171
- opr_sz = (1 + q) * 8;
172
- if (fn_gvec_ptr) {
173
- TCGv_ptr ptr;
174
- if (ptr_is_env) {
175
- ptr = cpu_env;
176
- } else {
177
- ptr = get_fpstatus_ptr(1);
178
- }
179
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
180
- opr_sz, opr_sz, data, fn_gvec_ptr);
181
- if (!ptr_is_env) {
182
- tcg_temp_free_ptr(ptr);
183
- }
184
- } else {
185
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
186
- opr_sz, opr_sz, data, fn_gvec);
187
- }
188
- return 0;
706
- return 0;
189
-}
707
-}
190
-
708
-
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
709
-static void hvf_accel_class_init(ObjectClass *oc, void *data)
192
{
710
-{
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
711
- AccelClass *ac = ACCEL_CLASS(oc);
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
712
- ac->name = "HVF";
195
}
713
- ac->init_machine = hvf_accel_init;
196
}
714
- ac->allowed = &hvf_allowed;
197
}
715
-}
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
716
-
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
717
-static const TypeInfo hvf_accel_type = {
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
718
- .name = TYPE_HVF_ACCEL,
201
- goto illegal_op;
719
- .parent = TYPE_ACCEL,
202
- }
720
- .class_init = hvf_accel_class_init,
203
- return;
721
-};
204
}
722
-
205
goto illegal_op;
723
-static void hvf_type_init(void)
206
}
724
-{
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
725
- type_register_static(&hvf_accel_type);
208
}
726
-}
209
break;
727
-
210
}
728
-type_init(hvf_type_init);
211
- if ((insn & 0xff000a00) == 0xfe000800
212
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
213
- /* The Thumb2 and ARM encodings are identical. */
214
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
215
- goto illegal_op;
216
- }
217
- } else if (((insn >> 24) & 3) == 3) {
218
+ if (((insn >> 24) & 3) == 3) {
219
/* Translate into the equivalent ARM encoding. */
220
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
221
if (disas_neon_data_insn(s, insn)) {
222
--
729
--
223
2.20.1
730
2.20.1
224
731
225
732
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Add support for SD.
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
4
7
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
This patch moves a few internal struct and constant defines over.
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Alexander Graf <agraf@csgraf.de>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
12
Message-id: 20210519202253.76782-5-agraf@csgraf.de
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
16
include/sysemu/hvf_int.h | 30 ++++++++++++++++++++++++++++++
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
17
target/i386/hvf/hvf-i386.h | 31 +------------------------------
14
2 files changed, 43 insertions(+)
18
2 files changed, 31 insertions(+), 30 deletions(-)
15
19
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
20
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
22
--- a/include/sysemu/hvf_int.h
19
+++ b/include/hw/arm/xlnx-versal.h
23
+++ b/include/sysemu/hvf_int.h
20
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
21
25
22
#include "hw/sysbus.h"
26
#include <Hypervisor/hv.h>
23
#include "hw/arm/boot.h"
27
24
+#include "hw/sd/sdhci.h"
28
+/* hvf_slot flags */
25
#include "hw/intc/arm_gicv3.h"
29
+#define HVF_SLOT_LOG (1 << 0)
26
#include "hw/char/pl011.h"
30
+
27
#include "hw/dma/xlnx-zdma.h"
31
+typedef struct hvf_slot {
32
+ uint64_t start;
33
+ uint64_t size;
34
+ uint8_t *mem;
35
+ int slot_id;
36
+ uint32_t flags;
37
+ MemoryRegion *region;
38
+} hvf_slot;
39
+
40
+typedef struct hvf_vcpu_caps {
41
+ uint64_t vmx_cap_pinbased;
42
+ uint64_t vmx_cap_procbased;
43
+ uint64_t vmx_cap_procbased2;
44
+ uint64_t vmx_cap_entry;
45
+ uint64_t vmx_cap_exit;
46
+ uint64_t vmx_cap_preemption_timer;
47
+} hvf_vcpu_caps;
48
+
49
+struct HVFState {
50
+ AccelState parent;
51
+ hvf_slot slots[32];
52
+ int num_slots;
53
+
54
+ hvf_vcpu_caps *hvf_caps;
55
+};
56
+extern HVFState *hvf_state;
57
+
58
void hvf_set_phys_mem(MemoryRegionSection *, bool);
59
void assert_hvf_ok(hv_return_t ret);
60
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
61
diff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/i386/hvf/hvf-i386.h
64
+++ b/target/i386/hvf/hvf-i386.h
28
@@ -XXX,XX +XXX,XX @@
65
@@ -XXX,XX +XXX,XX @@
29
#define XLNX_VERSAL_NR_UARTS 2
66
30
#define XLNX_VERSAL_NR_GEMS 2
67
#include "qemu/accel.h"
31
#define XLNX_VERSAL_NR_ADMAS 8
68
#include "sysemu/hvf.h"
32
+#define XLNX_VERSAL_NR_SDS 2
69
+#include "sysemu/hvf_int.h"
33
#define XLNX_VERSAL_NR_IRQS 192
70
#include "cpu.h"
34
71
#include "x86.h"
35
typedef struct Versal {
72
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
73
-/* hvf_slot flags */
37
} iou;
74
-#define HVF_SLOT_LOG (1 << 0)
38
} lpd;
75
-
39
76
-typedef struct hvf_slot {
40
+ /* The Platform Management Controller subsystem. */
77
- uint64_t start;
41
+ struct {
78
- uint64_t size;
42
+ struct {
79
- uint8_t *mem;
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
80
- int slot_id;
44
+ } iou;
81
- uint32_t flags;
45
+ } pmc;
82
- MemoryRegion *region;
46
+
83
-} hvf_slot;
47
struct {
84
-
48
MemoryRegion *mr_ddr;
85
-typedef struct hvf_vcpu_caps {
49
uint32_t psci_conduit;
86
- uint64_t vmx_cap_pinbased;
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
87
- uint64_t vmx_cap_procbased;
51
#define VERSAL_GEM1_IRQ_0 58
88
- uint64_t vmx_cap_procbased2;
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
89
- uint64_t vmx_cap_entry;
53
#define VERSAL_ADMA_IRQ_0 60
90
- uint64_t vmx_cap_exit;
54
+#define VERSAL_SD0_IRQ_0 126
91
- uint64_t vmx_cap_preemption_timer;
55
92
-} hvf_vcpu_caps;
56
/* Architecturally reserved IRQs suitable for virtualization. */
93
-
57
#define VERSAL_RSVD_IRQ_FIRST 111
94
-struct HVFState {
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
95
- AccelState parent;
59
#define MM_FPD_CRF 0xfd1a0000U
96
- hvf_slot slots[32];
60
#define MM_FPD_CRF_SIZE 0x140000
97
- int num_slots;
61
98
-
62
+#define MM_PMC_SD0 0xf1040000U
99
- hvf_vcpu_caps *hvf_caps;
63
+#define MM_PMC_SD0_SIZE 0x10000
100
-};
64
#define MM_PMC_CRP 0xf1260000U
101
-extern HVFState *hvf_state;
65
#define MM_PMC_CRP_SIZE 0x10000
102
-
66
#endif
103
void hvf_handle_io(CPUArchState *, uint16_t, void *, int, int, int);
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
104
68
index XXXXXXX..XXXXXXX 100644
105
#ifdef NEED_CPU_H
69
--- a/hw/arm/xlnx-versal.c
70
+++ b/hw/arm/xlnx-versal.c
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
72
}
73
}
74
75
+#define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
76
+static void versal_create_sds(Versal *s, qemu_irq *pic)
77
+{
78
+ int i;
79
+
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
81
+ DeviceState *dev;
82
+ MemoryRegion *mr;
83
+
84
+ sysbus_init_child_obj(OBJECT(s), "sd[*]",
85
+ &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]),
86
+ TYPE_SYSBUS_SDHCI);
87
+ dev = DEVICE(&s->pmc.iou.sd[i]);
88
+
89
+ object_property_set_uint(OBJECT(dev),
90
+ 3, "sd-spec-version", &error_fatal);
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
92
+ &error_fatal);
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
94
+ qdev_init_nofail(dev);
95
+
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
97
+ memory_region_add_subregion(&s->mr_ps,
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
99
+
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
102
+ }
103
+}
104
+
105
/* This takes the board allocated linear DDR memory and creates aliases
106
* for each split DDR range/aperture on the Versal address map.
107
*/
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
109
versal_create_uarts(s, pic);
110
versal_create_gems(s, pic);
111
versal_create_admas(s, pic);
112
+ versal_create_sds(s, pic);
113
versal_map_ddr(s);
114
versal_unimp(s);
115
116
--
106
--
117
2.20.1
107
2.20.1
118
108
119
109
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
hw/arm: versal: Add support for the RTC.
3
The hvf_set_phys_mem() function is only called within the same file.
4
Make it static.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210519202253.76782-6-agraf@csgraf.de
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
12
include/sysemu/hvf_int.h | 1 -
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
13
accel/hvf/hvf-accel-ops.c | 2 +-
14
2 files changed, 29 insertions(+)
14
2 files changed, 1 insertion(+), 2 deletions(-)
15
15
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
18
--- a/include/sysemu/hvf_int.h
19
+++ b/include/hw/arm/xlnx-versal.h
19
+++ b/include/sysemu/hvf_int.h
20
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ struct HVFState {
21
#include "hw/char/pl011.h"
21
};
22
#include "hw/dma/xlnx-zdma.h"
22
extern HVFState *hvf_state;
23
#include "hw/net/cadence_gem.h"
23
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
24
-void hvf_set_phys_mem(MemoryRegionSection *, bool);
25
25
void assert_hvf_ok(hv_return_t ret);
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
26
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
27
int hvf_put_registers(CPUState *);
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
28
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
29
struct {
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
31
} iou;
32
+
33
+ XlnxZynqMPRTC rtc;
34
} pmc;
35
36
struct {
37
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
38
#define VERSAL_GEM1_IRQ_0 58
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
40
#define VERSAL_ADMA_IRQ_0 60
41
+#define VERSAL_RTC_APB_ERR_IRQ 121
42
#define VERSAL_SD0_IRQ_0 126
43
+#define VERSAL_RTC_ALARM_IRQ 142
44
+#define VERSAL_RTC_SECONDS_IRQ 143
45
46
/* Architecturally reserved IRQs suitable for virtualization. */
47
#define VERSAL_RSVD_IRQ_FIRST 111
48
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
49
#define MM_PMC_SD0_SIZE 0x10000
50
#define MM_PMC_CRP 0xf1260000U
51
#define MM_PMC_CRP_SIZE 0x10000
52
+#define MM_PMC_RTC 0xf12a0000
53
+#define MM_PMC_RTC_SIZE 0x10000
54
#endif
55
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
56
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/xlnx-versal.c
30
--- a/accel/hvf/hvf-accel-ops.c
58
+++ b/hw/arm/xlnx-versal.c
31
+++ b/accel/hvf/hvf-accel-ops.c
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
32
@@ -XXX,XX +XXX,XX @@ static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
60
}
33
return 0;
61
}
34
}
62
35
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
36
-void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
64
+{
37
+static void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
65
+ SysBusDevice *sbd;
38
{
66
+ MemoryRegion *mr;
39
hvf_slot *mem;
67
+
40
MemoryRegion *area = section->mr;
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
69
+ TYPE_XLNX_ZYNQMP_RTC);
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
71
+ qdev_init_nofail(DEVICE(sbd));
72
+
73
+ mr = sysbus_mmio_get_region(sbd, 0);
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
75
+
76
+ /*
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
78
+ * supports them.
79
+ */
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
81
+}
82
+
83
/* This takes the board allocated linear DDR memory and creates aliases
84
* for each split DDR range/aperture on the Versal address map.
85
*/
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
87
versal_create_gems(s, pic);
88
versal_create_admas(s, pic);
89
versal_create_sds(s, pic);
90
+ versal_create_rtc(s, pic);
91
versal_map_ddr(s);
92
versal_unimp(s);
93
94
--
41
--
95
2.20.1
42
2.20.1
96
43
97
44
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Embed the GEMs into the SoC type.
3
The ARM version of Hypervisor.framework no longer defines these two
4
types, so let's just revert to standard ones.
4
5
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210519202253.76782-7-agraf@csgraf.de
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
12
accel/hvf/hvf-accel-ops.c | 6 +++---
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
13
1 file changed, 3 insertions(+), 3 deletions(-)
15
2 files changed, 10 insertions(+), 8 deletions(-)
16
14
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
15
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
17
--- a/accel/hvf/hvf-accel-ops.c
20
+++ b/include/hw/arm/xlnx-versal.h
18
+++ b/accel/hvf/hvf-accel-ops.c
21
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
22
#include "hw/arm/boot.h"
20
macslot->present = 1;
23
#include "hw/intc/arm_gicv3.h"
21
macslot->gpa_start = slot->start;
24
#include "hw/char/pl011.h"
22
macslot->size = slot->size;
25
+#include "hw/net/cadence_gem.h"
23
- ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
26
24
+ ret = hv_vm_map(slot->mem, slot->start, slot->size, flags);
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
25
assert_hvf_ok(ret);
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
26
return 0;
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
27
}
30
28
@@ -XXX,XX +XXX,XX @@ static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
31
struct {
29
/* protect region against writes; begin tracking it */
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
30
if (on) {
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
31
slot->flags |= HVF_SLOT_LOG;
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
32
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
33
+ hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
36
} iou;
34
HV_MEMORY_READ);
37
} lpd;
35
/* stop tracking region*/
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
36
} else {
39
index XXXXXXX..XXXXXXX 100644
37
slot->flags &= ~HVF_SLOT_LOG;
40
--- a/hw/arm/xlnx-versal.c
38
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
41
+++ b/hw/arm/xlnx-versal.c
39
+ hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
40
HV_MEMORY_READ | HV_MEMORY_WRITE);
43
DeviceState *dev;
44
MemoryRegion *mr;
45
46
- dev = qdev_create(NULL, "cadence_gem");
47
- s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
48
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
49
+ sysbus_init_child_obj(OBJECT(s), name,
50
+ &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]),
51
+ TYPE_CADENCE_GEM);
52
+ dev = DEVICE(&s->lpd.iou.gem[i]);
53
if (nd->used) {
54
qemu_check_nic_model(nd, "cadence_gem");
55
qdev_set_nic_properties(dev, nd);
56
}
57
- object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
58
+ object_property_set_int(OBJECT(dev),
59
2, "num-priority-queues",
60
&error_abort);
61
- object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
62
+ object_property_set_link(OBJECT(dev),
63
OBJECT(&s->mr_ps), "dma",
64
&error_abort);
65
qdev_init_nofail(dev);
66
67
- mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
68
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
69
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
70
71
- sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
73
g_free(name);
74
}
41
}
75
}
42
}
76
--
43
--
77
2.20.1
44
2.20.1
78
45
79
46
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Add support for SD.
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
4
7
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
This patch splits the vcpu init and destroy functions into a generic and
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
an architecture specific portion. This also allows us to move the generic
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
functions into the generic hvf code, removing exported functions.
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
11
12
Signed-off-by: Alexander Graf <agraf@csgraf.de>
13
Reviewed-by: Sergio Lopez <slp@redhat.com>
14
Message-id: 20210519202253.76782-8-agraf@csgraf.de
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
17
---
11
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
18
accel/hvf/hvf-accel-ops.h | 2 --
12
1 file changed, 46 insertions(+)
19
include/sysemu/hvf_int.h | 2 ++
20
accel/hvf/hvf-accel-ops.c | 30 ++++++++++++++++++++++++++++++
21
target/i386/hvf/hvf.c | 23 ++---------------------
22
4 files changed, 34 insertions(+), 23 deletions(-)
13
23
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
24
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
26
--- a/accel/hvf/hvf-accel-ops.h
17
+++ b/hw/arm/xlnx-versal-virt.c
27
+++ b/accel/hvf/hvf-accel-ops.h
18
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
19
#include "hw/arm/sysbus-fdt.h"
29
20
#include "hw/arm/fdt.h"
30
#include "sysemu/cpus.h"
21
#include "cpu.h"
31
22
+#include "hw/qdev-properties.h"
32
-int hvf_init_vcpu(CPUState *);
23
#include "hw/arm/xlnx-versal.h"
33
int hvf_vcpu_exec(CPUState *);
24
34
void hvf_cpu_synchronize_state(CPUState *);
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
35
void hvf_cpu_synchronize_post_reset(CPUState *);
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
36
void hvf_cpu_synchronize_post_init(CPUState *);
27
}
37
void hvf_cpu_synchronize_pre_loadvm(CPUState *);
28
}
38
-void hvf_vcpu_destroy(CPUState *);
29
39
30
+static void fdt_add_sd_nodes(VersalVirt *s)
40
#endif /* HVF_CPUS_H */
41
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/include/sysemu/hvf_int.h
44
+++ b/include/sysemu/hvf_int.h
45
@@ -XXX,XX +XXX,XX @@ struct HVFState {
46
extern HVFState *hvf_state;
47
48
void assert_hvf_ok(hv_return_t ret);
49
+int hvf_arch_init_vcpu(CPUState *cpu);
50
+void hvf_arch_vcpu_destroy(CPUState *cpu);
51
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
52
int hvf_put_registers(CPUState *);
53
int hvf_get_registers(CPUState *);
54
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/accel/hvf/hvf-accel-ops.c
57
+++ b/accel/hvf/hvf-accel-ops.c
58
@@ -XXX,XX +XXX,XX @@ static void hvf_type_init(void)
59
60
type_init(hvf_type_init);
61
62
+static void hvf_vcpu_destroy(CPUState *cpu)
31
+{
63
+{
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
64
+ hv_return_t ret = hv_vcpu_destroy(cpu->hvf_fd);
33
+ const char compat[] = "arasan,sdhci-8.9a";
65
+ assert_hvf_ok(ret);
34
+ int i;
35
+
66
+
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
67
+ hvf_arch_vcpu_destroy(cpu);
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
39
+
40
+ qemu_fdt_add_subnode(s->fdt, name);
41
+
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
44
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
45
+ clocknames, sizeof(clocknames));
46
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
47
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 2,
48
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
49
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
50
+ 2, addr, 2, MM_PMC_SD0_SIZE);
51
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
52
+ g_free(name);
53
+ }
54
+}
68
+}
55
+
69
+
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
70
+static int hvf_init_vcpu(CPUState *cpu)
57
{
58
Error *err = NULL;
59
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
60
}
61
}
62
63
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
64
+{
71
+{
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
72
+ int r;
66
+ DeviceState *card;
67
+
73
+
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
74
+ /* init cpu signals */
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
75
+ sigset_t set;
70
+ &error_fatal);
76
+ struct sigaction sigact;
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
77
+
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
78
+ memset(&sigact, 0, sizeof(sigact));
79
+ sigact.sa_handler = dummy_signal;
80
+ sigaction(SIG_IPI, &sigact, NULL);
81
+
82
+ pthread_sigmask(SIG_BLOCK, NULL, &set);
83
+ sigdelset(&set, SIG_IPI);
84
+
85
+ r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
86
+ cpu->vcpu_dirty = 1;
87
+ assert_hvf_ok(r);
88
+
89
+ return hvf_arch_init_vcpu(cpu);
73
+}
90
+}
74
+
91
+
75
static void versal_virt_init(MachineState *machine)
92
/*
93
* The HVF-specific vCPU thread function. This one should only run when the host
94
* CPU supports the VMX "unrestricted guest" feature.
95
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/target/i386/hvf/hvf.c
98
+++ b/target/i386/hvf/hvf.c
99
@@ -XXX,XX +XXX,XX @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
100
return false;
101
}
102
103
-void hvf_vcpu_destroy(CPUState *cpu)
104
+void hvf_arch_vcpu_destroy(CPUState *cpu)
76
{
105
{
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
106
X86CPU *x86_cpu = X86_CPU(cpu);
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
107
CPUX86State *env = &x86_cpu->env;
79
+ int i;
108
80
109
- hv_return_t ret = hv_vcpu_destroy((hv_vcpuid_t)cpu->hvf_fd);
81
/*
110
g_free(env->hvf_mmio_buf);
82
* If the user provides an Operating System to be loaded, we expect them
111
- assert_hvf_ok(ret);
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
112
}
84
fdt_add_gic_nodes(s);
113
85
fdt_add_timer_nodes(s);
114
static void init_tsc_freq(CPUX86State *env)
86
fdt_add_zdma_nodes(s);
115
@@ -XXX,XX +XXX,XX @@ static inline bool apic_bus_freq_is_known(CPUX86State *env)
87
+ fdt_add_sd_nodes(s);
116
return env->apic_bus_freq != 0;
88
fdt_add_cpu_nodes(s, psci_conduit);
117
}
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
118
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
119
-int hvf_init_vcpu(CPUState *cpu)
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
120
+int hvf_arch_init_vcpu(CPUState *cpu)
92
memory_region_add_subregion_overlap(get_system_memory(),
121
{
93
0, &s->soc.fpd.apu.mr, 0);
122
-
94
123
X86CPU *x86cpu = X86_CPU(cpu);
95
+ /* Plugin SD cards. */
124
CPUX86State *env = &x86cpu->env;
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
125
- int r;
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
126
-
98
+ }
127
- /* init cpu signals */
99
+
128
- sigset_t set;
100
s->binfo.ram_size = machine->ram_size;
129
- struct sigaction sigact;
101
s->binfo.loader_start = 0x0;
130
-
102
s->binfo.get_dtb = versal_virt_get_dtb;
131
- memset(&sigact, 0, sizeof(sigact));
132
- sigact.sa_handler = dummy_signal;
133
- sigaction(SIG_IPI, &sigact, NULL);
134
-
135
- pthread_sigmask(SIG_BLOCK, NULL, &set);
136
- sigdelset(&set, SIG_IPI);
137
138
init_emu();
139
init_decoder();
140
@@ -XXX,XX +XXX,XX @@ int hvf_init_vcpu(CPUState *cpu)
141
}
142
}
143
144
- r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
145
- cpu->vcpu_dirty = 1;
146
- assert_hvf_ok(r);
147
-
148
if (hv_vmx_read_capability(HV_VMX_CAP_PINBASED,
149
&hvf_state->hvf_caps->vmx_cap_pinbased)) {
150
abort();
103
--
151
--
104
2.20.1
152
2.20.1
105
153
106
154
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Embed the APUs into the SoC type.
3
There is no reason to call the hvf specific hvf_cpu_synchronize_state()
4
when we can just use the generic cpu_synchronize_state() instead. This
5
allows us to have less dependency on internal function definitions and
6
allows us to make hvf_cpu_synchronize_state() static.
4
7
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Alexander Graf <agraf@csgraf.de>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Sergio Lopez <slp@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20210519202253.76782-9-agraf@csgraf.de
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
include/hw/arm/xlnx-versal.h | 2 +-
14
accel/hvf/hvf-accel-ops.h | 1 -
14
hw/arm/xlnx-versal-virt.c | 4 ++--
15
accel/hvf/hvf-accel-ops.c | 2 +-
15
hw/arm/xlnx-versal.c | 19 +++++--------------
16
target/i386/hvf/x86hvf.c | 9 ++++-----
16
3 files changed, 8 insertions(+), 17 deletions(-)
17
3 files changed, 5 insertions(+), 7 deletions(-)
17
18
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
19
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/xlnx-versal.h
21
--- a/accel/hvf/hvf-accel-ops.h
21
+++ b/include/hw/arm/xlnx-versal.h
22
+++ b/accel/hvf/hvf-accel-ops.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
23
@@ -XXX,XX +XXX,XX @@
23
struct {
24
#include "sysemu/cpus.h"
24
struct {
25
25
MemoryRegion mr;
26
int hvf_vcpu_exec(CPUState *);
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
27
-void hvf_cpu_synchronize_state(CPUState *);
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
28
void hvf_cpu_synchronize_post_reset(CPUState *);
28
GICv3State gic;
29
void hvf_cpu_synchronize_post_init(CPUState *);
29
} apu;
30
void hvf_cpu_synchronize_pre_loadvm(CPUState *);
30
} fpd;
31
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
32
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/xlnx-versal-virt.c
33
--- a/accel/hvf/hvf-accel-ops.c
34
+++ b/hw/arm/xlnx-versal-virt.c
34
+++ b/accel/hvf/hvf-accel-ops.c
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
35
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
36
s->binfo.get_dtb = versal_virt_get_dtb;
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
38
if (machine->kernel_filename) {
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
41
} else {
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
44
&s->binfo);
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
46
* Offset things by 4K. */
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/xlnx-versal.c
50
+++ b/hw/arm/xlnx-versal.c
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
52
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
54
Object *obj;
55
- char *name;
56
-
57
- obj = object_new(XLNX_VERSAL_ACPU_TYPE);
58
- if (!obj) {
59
- error_report("Unable to create apu.cpu[%d] of type %s",
60
- i, XLNX_VERSAL_ACPU_TYPE);
61
- exit(EXIT_FAILURE);
62
- }
63
-
64
- name = g_strdup_printf("apu-cpu[%d]", i);
65
- object_property_add_child(OBJECT(s), name, obj, &error_fatal);
66
- g_free(name);
67
68
+ object_initialize_child(OBJECT(s), "apu-cpu[*]",
69
+ &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]),
70
+ XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL);
71
+ obj = OBJECT(&s->fpd.apu.cpu[i]);
72
object_property_set_int(obj, s->cfg.psci_conduit,
73
"psci-conduit", &error_abort);
74
if (i) {
75
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
76
object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
77
&error_abort);
78
object_property_set_bool(obj, true, "realized", &error_fatal);
79
- s->fpd.apu.cpu[i] = ARM_CPU(obj);
80
}
36
}
81
}
37
}
82
38
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
39
-void hvf_cpu_synchronize_state(CPUState *cpu)
40
+static void hvf_cpu_synchronize_state(CPUState *cpu)
41
{
42
if (!cpu->vcpu_dirty) {
43
run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
44
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/i386/hvf/x86hvf.c
47
+++ b/target/i386/hvf/x86hvf.c
48
@@ -XXX,XX +XXX,XX @@
49
#include "cpu.h"
50
#include "x86_descr.h"
51
#include "x86_decode.h"
52
+#include "sysemu/hw_accel.h"
53
54
#include "hw/i386/apic_internal.h"
55
56
#include <Hypervisor/hv.h>
57
#include <Hypervisor/hv_vmx.h>
58
59
-#include "accel/hvf/hvf-accel-ops.h"
60
-
61
void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
62
SegmentCache *qseg, bool is_tr)
63
{
64
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
65
env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
66
67
if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {
68
- hvf_cpu_synchronize_state(cpu_state);
69
+ cpu_synchronize_state(cpu_state);
70
do_cpu_init(cpu);
84
}
71
}
85
72
86
for (i = 0; i < nr_apu_cpus; i++) {
73
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
74
cpu_state->halted = 0;
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
75
}
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
76
if (cpu_state->interrupt_request & CPU_INTERRUPT_SIPI) {
90
qemu_irq maint_irq;
77
- hvf_cpu_synchronize_state(cpu_state);
91
int ti;
78
+ cpu_synchronize_state(cpu_state);
79
do_cpu_sipi(cpu);
80
}
81
if (cpu_state->interrupt_request & CPU_INTERRUPT_TPR) {
82
cpu_state->interrupt_request &= ~CPU_INTERRUPT_TPR;
83
- hvf_cpu_synchronize_state(cpu_state);
84
+ cpu_synchronize_state(cpu_state);
85
apic_handle_tpr_access_report(cpu->apic_state, env->eip,
86
env->tpr_access_type);
87
}
92
--
88
--
93
2.20.1
89
2.20.1
94
90
95
91
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
Embed the UARTs into the SoC type.
3
The hvf accel synchronize functions are only used as input for local
4
callback functions, so we can make them static.
4
5
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210519202253.76782-10-agraf@csgraf.de
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-5-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
12
accel/hvf/hvf-accel-ops.h | 3 ---
14
hw/arm/xlnx-versal.c | 12 ++++++------
13
accel/hvf/hvf-accel-ops.c | 6 +++---
15
2 files changed, 8 insertions(+), 7 deletions(-)
14
2 files changed, 3 insertions(+), 6 deletions(-)
16
15
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
18
--- a/accel/hvf/hvf-accel-ops.h
20
+++ b/include/hw/arm/xlnx-versal.h
19
+++ b/accel/hvf/hvf-accel-ops.h
21
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
22
#include "hw/sysbus.h"
21
#include "sysemu/cpus.h"
23
#include "hw/arm/boot.h"
22
24
#include "hw/intc/arm_gicv3.h"
23
int hvf_vcpu_exec(CPUState *);
25
+#include "hw/char/pl011.h"
24
-void hvf_cpu_synchronize_post_reset(CPUState *);
26
25
-void hvf_cpu_synchronize_post_init(CPUState *);
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
26
-void hvf_cpu_synchronize_pre_loadvm(CPUState *);
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
27
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
28
#endif /* HVF_CPUS_H */
30
MemoryRegion mr_ocm;
29
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
31
32
struct {
33
- SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
34
+ PL011State uart[XLNX_VERSAL_NR_UARTS];
35
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
36
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
37
} iou;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
31
--- a/accel/hvf/hvf-accel-ops.c
41
+++ b/hw/arm/xlnx-versal.c
32
+++ b/accel/hvf/hvf-accel-ops.c
42
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
43
#include "kvm_arm.h"
34
cpu->vcpu_dirty = false;
44
#include "hw/misc/unimp.h"
35
}
45
#include "hw/arm/xlnx-versal.h"
36
46
-#include "hw/char/pl011.h"
37
-void hvf_cpu_synchronize_post_reset(CPUState *cpu)
47
38
+static void hvf_cpu_synchronize_post_reset(CPUState *cpu)
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
39
{
49
#define GEM_REVISION 0x40070106
40
run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
41
}
51
DeviceState *dev;
42
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
52
MemoryRegion *mr;
43
cpu->vcpu_dirty = false;
53
44
}
54
- dev = qdev_create(NULL, TYPE_PL011);
45
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
46
-void hvf_cpu_synchronize_post_init(CPUState *cpu)
56
+ sysbus_init_child_obj(OBJECT(s), name,
47
+static void hvf_cpu_synchronize_post_init(CPUState *cpu)
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
48
{
58
+ TYPE_PL011);
49
run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
50
}
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
51
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
52
cpu->vcpu_dirty = true;
62
qdev_init_nofail(dev);
53
}
63
54
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
55
-void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
56
+static void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
57
{
67
58
run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
68
- sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
69
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
70
g_free(name);
71
}
72
}
59
}
73
--
60
--
74
2.20.1
61
2.20.1
75
62
76
63
diff view generated by jsdifflib
1
From: Fredrik Strupe <fredrik@strupe.net>
1
From: Alexander Graf <agraf@csgraf.de>
2
2
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
3
We can move the definition of hvf_vcpu_exec() into our internal
4
U=1 is unallocated.
4
hvf header, obsoleting the need for hvf-accel-ops.h.
5
5
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
8
Message-id: 20210519202253.76782-11-agraf@csgraf.de
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/translate.c | 2 +-
12
accel/hvf/hvf-accel-ops.h | 17 -----------------
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
include/sysemu/hvf_int.h | 1 +
14
accel/hvf/hvf-accel-ops.c | 2 --
15
target/i386/hvf/hvf.c | 2 --
16
4 files changed, 1 insertion(+), 21 deletions(-)
17
delete mode 100644 accel/hvf/hvf-accel-ops.h
13
18
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
20
deleted file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- a/accel/hvf/hvf-accel-ops.h
23
+++ /dev/null
24
@@ -XXX,XX +XXX,XX @@
25
-/*
26
- * Accelerator CPUS Interface
27
- *
28
- * Copyright 2020 SUSE LLC
29
- *
30
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
31
- * See the COPYING file in the top-level directory.
32
- */
33
-
34
-#ifndef HVF_CPUS_H
35
-#define HVF_CPUS_H
36
-
37
-#include "sysemu/cpus.h"
38
-
39
-int hvf_vcpu_exec(CPUState *);
40
-
41
-#endif /* HVF_CPUS_H */
42
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
15
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
44
--- a/include/sysemu/hvf_int.h
17
+++ b/target/arm/translate.c
45
+++ b/include/sysemu/hvf_int.h
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
46
@@ -XXX,XX +XXX,XX @@ extern HVFState *hvf_state;
19
{0, 0, 0, 0}, /* VMLSL */
47
void assert_hvf_ok(hv_return_t ret);
20
{0, 0, 0, 9}, /* VQDMLSL */
48
int hvf_arch_init_vcpu(CPUState *cpu);
21
{0, 0, 0, 0}, /* Integer VMULL */
49
void hvf_arch_vcpu_destroy(CPUState *cpu);
22
- {0, 0, 0, 1}, /* VQDMULL */
50
+int hvf_vcpu_exec(CPUState *);
23
+ {0, 0, 0, 9}, /* VQDMULL */
51
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
52
int hvf_put_registers(CPUState *);
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
53
int hvf_get_registers(CPUState *);
26
};
54
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/accel/hvf/hvf-accel-ops.c
57
+++ b/accel/hvf/hvf-accel-ops.c
58
@@ -XXX,XX +XXX,XX @@
59
#include "sysemu/runstate.h"
60
#include "qemu/guest-random.h"
61
62
-#include "hvf-accel-ops.h"
63
-
64
HVFState *hvf_state;
65
66
/* Memory slots */
67
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/i386/hvf/hvf.c
70
+++ b/target/i386/hvf/hvf.c
71
@@ -XXX,XX +XXX,XX @@
72
#include "qemu/accel.h"
73
#include "target/i386/cpu.h"
74
75
-#include "hvf-accel-ops.h"
76
-
77
void vmx_update_tpr(CPUState *cpu)
78
{
79
/* TODO: need integrate APIC handling */
27
--
80
--
28
2.20.1
81
2.20.1
29
82
30
83
diff view generated by jsdifflib
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
1
From: Alexander Graf <agraf@csgraf.de>
2
insn in the legacy decoder for the 3same_ext group, so we can
3
delete the legacy decoder function for the group entirely.
4
2
5
Note that in disas_thumb2_insn() the parts of this encoding space
3
We will need more than a single field for hvf going forward. To keep
6
where the decodetree decoder returns false will correctly be directed
4
the global vcpu struct uncluttered, let's allocate a special hvf vcpu
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
5
struct, similar to how hax does it.
8
into disas_coproc_insn() by mistake.
9
6
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
8
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
9
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
12
Message-id: 20210519202253.76782-12-agraf@csgraf.de
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-8-peter.maydell@linaro.org
13
---
15
---
14
target/arm/neon-shared.decode | 6 +++
16
include/hw/core/cpu.h | 3 +-
15
target/arm/translate-neon.inc.c | 31 +++++++++++
17
include/sysemu/hvf_int.h | 4 +
16
target/arm/translate.c | 92 +--------------------------------
18
target/i386/hvf/vmx.h | 24 +++--
17
3 files changed, 38 insertions(+), 91 deletions(-)
19
accel/hvf/hvf-accel-ops.c | 8 +-
20
target/i386/hvf/hvf.c | 104 +++++++++---------
21
target/i386/hvf/x86.c | 28 ++---
22
target/i386/hvf/x86_descr.c | 26 ++---
23
target/i386/hvf/x86_emu.c | 62 +++++------
24
target/i386/hvf/x86_mmu.c | 4 +-
25
target/i386/hvf/x86_task.c | 12 +--
26
target/i386/hvf/x86hvf.c | 210 ++++++++++++++++++------------------
27
11 files changed, 248 insertions(+), 237 deletions(-)
18
28
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
29
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
20
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
31
--- a/include/hw/core/cpu.h
22
+++ b/target/arm/neon-shared.decode
32
+++ b/include/hw/core/cpu.h
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
33
@@ -XXX,XX +XXX,XX @@ struct KVMState;
24
# VUDOT and VSDOT
34
struct kvm_run;
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
35
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
36
struct hax_vcpu_state;
37
+struct hvf_vcpu_state;
38
39
#define TB_JMP_CACHE_BITS 12
40
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
41
@@ -XXX,XX +XXX,XX @@ struct CPUState {
42
43
struct hax_vcpu_state *hax_vcpu;
44
45
- int hvf_fd;
46
+ struct hvf_vcpu_state *hvf;
47
48
/* track IOMMUs whose translations we've cached in the TCG TLB */
49
GArray *iommu_notifiers;
50
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/sysemu/hvf_int.h
53
+++ b/include/sysemu/hvf_int.h
54
@@ -XXX,XX +XXX,XX @@ struct HVFState {
55
};
56
extern HVFState *hvf_state;
57
58
+struct hvf_vcpu_state {
59
+ int fd;
60
+};
27
+
61
+
28
+# VFM[AS]L
62
void assert_hvf_ok(hv_return_t ret);
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
63
int hvf_arch_init_vcpu(CPUState *cpu);
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
64
void hvf_arch_vcpu_destroy(CPUState *cpu);
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
65
diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h
32
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
67
--- a/target/i386/hvf/vmx.h
36
+++ b/target/arm/translate-neon.inc.c
68
+++ b/target/i386/hvf/vmx.h
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
69
@@ -XXX,XX +XXX,XX @@
38
opr_sz, opr_sz, 0, fn_gvec);
70
#include "vmcs.h"
39
return true;
71
#include "cpu.h"
40
}
72
#include "x86.h"
73
+#include "sysemu/hvf.h"
74
+#include "sysemu/hvf_int.h"
75
76
#include "exec/address-spaces.h"
77
78
@@ -XXX,XX +XXX,XX @@ static inline void macvm_set_rip(CPUState *cpu, uint64_t rip)
79
uint64_t val;
80
81
/* BUG, should take considering overlap.. */
82
- wreg(cpu->hvf_fd, HV_X86_RIP, rip);
83
+ wreg(cpu->hvf->fd, HV_X86_RIP, rip);
84
env->eip = rip;
85
86
/* after moving forward in rip, we need to clean INTERRUPTABILITY */
87
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
88
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY);
89
if (val & (VMCS_INTERRUPTIBILITY_STI_BLOCKING |
90
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)) {
91
env->hflags &= ~HF_INHIBIT_IRQ_MASK;
92
- wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY,
93
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY,
94
val & ~(VMCS_INTERRUPTIBILITY_STI_BLOCKING |
95
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING));
96
}
97
@@ -XXX,XX +XXX,XX @@ static inline void vmx_clear_nmi_blocking(CPUState *cpu)
98
CPUX86State *env = &x86_cpu->env;
99
100
env->hflags2 &= ~HF2_NMI_MASK;
101
- uint32_t gi = (uint32_t) rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
102
+ uint32_t gi = (uint32_t) rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY);
103
gi &= ~VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
104
- wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
105
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
106
}
107
108
static inline void vmx_set_nmi_blocking(CPUState *cpu)
109
@@ -XXX,XX +XXX,XX @@ static inline void vmx_set_nmi_blocking(CPUState *cpu)
110
CPUX86State *env = &x86_cpu->env;
111
112
env->hflags2 |= HF2_NMI_MASK;
113
- uint32_t gi = (uint32_t)rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
114
+ uint32_t gi = (uint32_t)rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY);
115
gi |= VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
116
- wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
117
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
118
}
119
120
static inline void vmx_set_nmi_window_exiting(CPUState *cpu)
121
{
122
uint64_t val;
123
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
124
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val |
125
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
126
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val |
127
VMCS_PRI_PROC_BASED_CTLS_NMI_WINDOW_EXITING);
128
129
}
130
@@ -XXX,XX +XXX,XX @@ static inline void vmx_clear_nmi_window_exiting(CPUState *cpu)
131
{
132
133
uint64_t val;
134
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
135
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val &
136
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
137
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val &
138
~VMCS_PRI_PROC_BASED_CTLS_NMI_WINDOW_EXITING);
139
}
140
141
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/accel/hvf/hvf-accel-ops.c
144
+++ b/accel/hvf/hvf-accel-ops.c
145
@@ -XXX,XX +XXX,XX @@ type_init(hvf_type_init);
146
147
static void hvf_vcpu_destroy(CPUState *cpu)
148
{
149
- hv_return_t ret = hv_vcpu_destroy(cpu->hvf_fd);
150
+ hv_return_t ret = hv_vcpu_destroy(cpu->hvf->fd);
151
assert_hvf_ok(ret);
152
153
hvf_arch_vcpu_destroy(cpu);
154
+ g_free(cpu->hvf);
155
+ cpu->hvf = NULL;
156
}
157
158
static int hvf_init_vcpu(CPUState *cpu)
159
{
160
int r;
161
162
+ cpu->hvf = g_malloc0(sizeof(*cpu->hvf));
41
+
163
+
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
164
/* init cpu signals */
43
+{
165
sigset_t set;
44
+ int opr_sz;
166
struct sigaction sigact;
45
+
167
@@ -XXX,XX +XXX,XX @@ static int hvf_init_vcpu(CPUState *cpu)
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
168
pthread_sigmask(SIG_BLOCK, NULL, &set);
47
+ return false;
169
sigdelset(&set, SIG_IPI);
48
+ }
170
49
+
171
- r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
172
+ r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf->fd, HV_VCPU_DEFAULT);
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
173
cpu->vcpu_dirty = 1;
52
+ (a->vd & 0x10)) {
174
assert_hvf_ok(r);
53
+ return false;
175
54
+ }
176
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
55
+
56
+ if (a->vd & a->q) {
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
62
+ }
63
+
64
+ opr_sz = (1 + a->q) * 8;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(a->q, a->vn),
67
+ vfp_reg_offset(a->q, a->vm),
68
+ cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
69
+ gen_helper_gvec_fmlal_a32);
70
+ return true;
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
177
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
178
--- a/target/i386/hvf/hvf.c
75
+++ b/target/arm/translate.c
179
+++ b/target/i386/hvf/hvf.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
180
@@ -XXX,XX +XXX,XX @@ void vmx_update_tpr(CPUState *cpu)
181
int tpr = cpu_get_apic_tpr(x86_cpu->apic_state) << 4;
182
int irr = apic_get_highest_priority_irr(x86_cpu->apic_state);
183
184
- wreg(cpu->hvf_fd, HV_X86_TPR, tpr);
185
+ wreg(cpu->hvf->fd, HV_X86_TPR, tpr);
186
if (irr == -1) {
187
- wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0);
188
+ wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, 0);
189
} else {
190
- wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, (irr > tpr) ? tpr >> 4 :
191
+ wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, (irr > tpr) ? tpr >> 4 :
192
irr >> 4);
193
}
194
}
195
@@ -XXX,XX +XXX,XX @@ void vmx_update_tpr(CPUState *cpu)
196
static void update_apic_tpr(CPUState *cpu)
197
{
198
X86CPU *x86_cpu = X86_CPU(cpu);
199
- int tpr = rreg(cpu->hvf_fd, HV_X86_TPR) >> 4;
200
+ int tpr = rreg(cpu->hvf->fd, HV_X86_TPR) >> 4;
201
cpu_set_apic_tpr(x86_cpu->apic_state, tpr);
202
}
203
204
@@ -XXX,XX +XXX,XX @@ int hvf_arch_init_vcpu(CPUState *cpu)
205
}
206
207
/* set VMCS control fields */
208
- wvmcs(cpu->hvf_fd, VMCS_PIN_BASED_CTLS,
209
+ wvmcs(cpu->hvf->fd, VMCS_PIN_BASED_CTLS,
210
cap2ctrl(hvf_state->hvf_caps->vmx_cap_pinbased,
211
VMCS_PIN_BASED_CTLS_EXTINT |
212
VMCS_PIN_BASED_CTLS_NMI |
213
VMCS_PIN_BASED_CTLS_VNMI));
214
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS,
215
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS,
216
cap2ctrl(hvf_state->hvf_caps->vmx_cap_procbased,
217
VMCS_PRI_PROC_BASED_CTLS_HLT |
218
VMCS_PRI_PROC_BASED_CTLS_MWAIT |
219
VMCS_PRI_PROC_BASED_CTLS_TSC_OFFSET |
220
VMCS_PRI_PROC_BASED_CTLS_TPR_SHADOW) |
221
VMCS_PRI_PROC_BASED_CTLS_SEC_CONTROL);
222
- wvmcs(cpu->hvf_fd, VMCS_SEC_PROC_BASED_CTLS,
223
+ wvmcs(cpu->hvf->fd, VMCS_SEC_PROC_BASED_CTLS,
224
cap2ctrl(hvf_state->hvf_caps->vmx_cap_procbased2,
225
VMCS_PRI_PROC_BASED2_CTLS_APIC_ACCESSES));
226
227
- wvmcs(cpu->hvf_fd, VMCS_ENTRY_CTLS, cap2ctrl(hvf_state->hvf_caps->vmx_cap_entry,
228
+ wvmcs(cpu->hvf->fd, VMCS_ENTRY_CTLS, cap2ctrl(hvf_state->hvf_caps->vmx_cap_entry,
229
0));
230
- wvmcs(cpu->hvf_fd, VMCS_EXCEPTION_BITMAP, 0); /* Double fault */
231
+ wvmcs(cpu->hvf->fd, VMCS_EXCEPTION_BITMAP, 0); /* Double fault */
232
233
- wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0);
234
+ wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, 0);
235
236
x86cpu = X86_CPU(cpu);
237
x86cpu->env.xsave_buf = qemu_memalign(4096, 4096);
238
239
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_STAR, 1);
240
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_LSTAR, 1);
241
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_CSTAR, 1);
242
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_FMASK, 1);
243
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_FSBASE, 1);
244
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_GSBASE, 1);
245
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_KERNELGSBASE, 1);
246
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_TSC_AUX, 1);
247
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_TSC, 1);
248
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_CS, 1);
249
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_EIP, 1);
250
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_ESP, 1);
251
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_STAR, 1);
252
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_LSTAR, 1);
253
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_CSTAR, 1);
254
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_FMASK, 1);
255
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_FSBASE, 1);
256
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_GSBASE, 1);
257
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_KERNELGSBASE, 1);
258
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_TSC_AUX, 1);
259
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_TSC, 1);
260
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_SYSENTER_CS, 1);
261
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_SYSENTER_EIP, 1);
262
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_SYSENTER_ESP, 1);
263
77
return 0;
264
return 0;
78
}
265
}
79
266
@@ -XXX,XX +XXX,XX @@ static void hvf_store_events(CPUState *cpu, uint32_t ins_len, uint64_t idtvec_in
80
-/* Advanced SIMD three registers of the same length extension.
267
}
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
268
if (idtvec_info & VMCS_IDT_VEC_ERRCODE_VALID) {
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
269
env->has_error_code = true;
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
270
- env->error_code = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_ERROR);
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
271
+ env->error_code = rvmcs(cpu->hvf->fd, VMCS_IDT_VECTORING_ERROR);
85
- */
272
}
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
273
}
87
-{
274
- if ((rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY) &
88
- gen_helper_gvec_3 *fn_gvec = NULL;
275
+ if ((rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY) &
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
276
VMCS_INTERRUPTIBILITY_NMI_BLOCKING)) {
90
- int rd, rn, rm, opr_sz;
277
env->hflags2 |= HF2_NMI_MASK;
91
- int data = 0;
278
} else {
92
- int off_rn, off_rm;
279
env->hflags2 &= ~HF2_NMI_MASK;
93
- bool is_long = false, q = extract32(insn, 6, 1);
280
}
94
- bool ptr_is_env = false;
281
- if (rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY) &
95
-
282
+ if (rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY) &
96
- if ((insn & 0xff300f10) == 0xfc200810) {
283
(VMCS_INTERRUPTIBILITY_STI_BLOCKING |
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
284
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)) {
98
- int is_s = extract32(insn, 23, 1);
285
env->hflags |= HF_INHIBIT_IRQ_MASK;
99
- if (!dc_isar_feature(aa32_fhm, s)) {
286
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
100
- return 1;
287
return EXCP_HLT;
101
- }
288
}
102
- is_long = true;
289
103
- data = is_s; /* is_2 == 0 */
290
- hv_return_t r = hv_vcpu_run(cpu->hvf_fd);
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
291
+ hv_return_t r = hv_vcpu_run(cpu->hvf->fd);
105
- ptr_is_env = true;
292
assert_hvf_ok(r);
106
- } else {
293
107
- return 1;
294
/* handle VMEXIT */
108
- }
295
- uint64_t exit_reason = rvmcs(cpu->hvf_fd, VMCS_EXIT_REASON);
109
-
296
- uint64_t exit_qual = rvmcs(cpu->hvf_fd, VMCS_EXIT_QUALIFICATION);
110
- VFP_DREG_D(rd, insn);
297
- uint32_t ins_len = (uint32_t)rvmcs(cpu->hvf_fd,
111
- if (rd & q) {
298
+ uint64_t exit_reason = rvmcs(cpu->hvf->fd, VMCS_EXIT_REASON);
112
- return 1;
299
+ uint64_t exit_qual = rvmcs(cpu->hvf->fd, VMCS_EXIT_QUALIFICATION);
113
- }
300
+ uint32_t ins_len = (uint32_t)rvmcs(cpu->hvf->fd,
114
- if (q || !is_long) {
301
VMCS_EXIT_INSTRUCTION_LENGTH);
115
- VFP_DREG_N(rn, insn);
302
116
- VFP_DREG_M(rm, insn);
303
- uint64_t idtvec_info = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);
117
- if ((rn | rm) & q & !is_long) {
304
+ uint64_t idtvec_info = rvmcs(cpu->hvf->fd, VMCS_IDT_VECTORING_INFO);
118
- return 1;
305
119
- }
306
hvf_store_events(cpu, ins_len, idtvec_info);
120
- off_rn = vfp_reg_offset(1, rn);
307
- rip = rreg(cpu->hvf_fd, HV_X86_RIP);
121
- off_rm = vfp_reg_offset(1, rm);
308
- env->eflags = rreg(cpu->hvf_fd, HV_X86_RFLAGS);
122
- } else {
309
+ rip = rreg(cpu->hvf->fd, HV_X86_RIP);
123
- rn = VFP_SREG_N(insn);
310
+ env->eflags = rreg(cpu->hvf->fd, HV_X86_RFLAGS);
124
- rm = VFP_SREG_M(insn);
311
125
- off_rn = vfp_reg_offset(0, rn);
312
qemu_mutex_lock_iothread();
126
- off_rm = vfp_reg_offset(0, rm);
313
127
- }
314
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
128
-
315
case EXIT_REASON_EPT_FAULT:
129
- if (s->fp_excp_el) {
316
{
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
317
hvf_slot *slot;
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
318
- uint64_t gpa = rvmcs(cpu->hvf_fd, VMCS_GUEST_PHYSICAL_ADDRESS);
132
- return 0;
319
+ uint64_t gpa = rvmcs(cpu->hvf->fd, VMCS_GUEST_PHYSICAL_ADDRESS);
133
- }
320
134
- if (!s->vfp_enabled) {
321
if (((idtvec_info & VMCS_IDT_VEC_VALID) == 0) &&
135
- return 1;
322
((exit_qual & EXIT_QUAL_NMIUDTI) != 0)) {
136
- }
323
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
137
-
324
store_regs(cpu);
138
- opr_sz = (1 + q) * 8;
325
break;
139
- if (fn_gvec_ptr) {
326
} else if (!string && !in) {
140
- TCGv_ptr ptr;
327
- RAX(env) = rreg(cpu->hvf_fd, HV_X86_RAX);
141
- if (ptr_is_env) {
328
+ RAX(env) = rreg(cpu->hvf->fd, HV_X86_RAX);
142
- ptr = cpu_env;
329
hvf_handle_io(env, port, &RAX(env), 1, size, 1);
143
- } else {
330
macvm_set_rip(cpu, rip + ins_len);
144
- ptr = get_fpstatus_ptr(1);
331
break;
145
- }
332
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
146
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
147
- opr_sz, opr_sz, data, fn_gvec_ptr);
148
- if (!ptr_is_env) {
149
- tcg_temp_free_ptr(ptr);
150
- }
151
- } else {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
153
- opr_sz, opr_sz, data, fn_gvec);
154
- }
155
- return 0;
156
-}
157
-
158
/* Advanced SIMD two registers and a scalar extension.
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
162
}
163
}
164
}
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
167
- if (disas_neon_insn_3same_ext(s, insn)) {
168
- goto illegal_op;
169
- }
170
- return;
171
} else if ((insn & 0x0f000a00) == 0x0e000800
172
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
173
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
174
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
175
}
176
break;
333
break;
177
}
334
}
178
- if ((insn & 0xfe000a00) == 0xfc000800
335
case EXIT_REASON_CPUID: {
179
+ if ((insn & 0xff000a00) == 0xfe000800
336
- uint32_t rax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
337
- uint32_t rbx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RBX);
181
/* The Thumb2 and ARM encodings are identical. */
338
- uint32_t rcx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
182
- if (disas_neon_insn_3same_ext(s, insn)) {
339
- uint32_t rdx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
183
- goto illegal_op;
340
+ uint32_t rax = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RAX);
184
- }
341
+ uint32_t rbx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RBX);
185
- } else if ((insn & 0xff000a00) == 0xfe000800
342
+ uint32_t rcx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RCX);
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
343
+ uint32_t rdx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RDX);
187
- /* The Thumb2 and ARM encodings are identical. */
344
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
345
if (rax == 1) {
189
goto illegal_op;
346
/* CPUID1.ecx.OSXSAVE needs to know CR4 */
347
- env->cr[4] = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR4);
348
+ env->cr[4] = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR4);
190
}
349
}
350
hvf_cpu_x86_cpuid(env, rax, rcx, &rax, &rbx, &rcx, &rdx);
351
352
- wreg(cpu->hvf_fd, HV_X86_RAX, rax);
353
- wreg(cpu->hvf_fd, HV_X86_RBX, rbx);
354
- wreg(cpu->hvf_fd, HV_X86_RCX, rcx);
355
- wreg(cpu->hvf_fd, HV_X86_RDX, rdx);
356
+ wreg(cpu->hvf->fd, HV_X86_RAX, rax);
357
+ wreg(cpu->hvf->fd, HV_X86_RBX, rbx);
358
+ wreg(cpu->hvf->fd, HV_X86_RCX, rcx);
359
+ wreg(cpu->hvf->fd, HV_X86_RDX, rdx);
360
361
macvm_set_rip(cpu, rip + ins_len);
362
break;
363
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
364
case EXIT_REASON_XSETBV: {
365
X86CPU *x86_cpu = X86_CPU(cpu);
366
CPUX86State *env = &x86_cpu->env;
367
- uint32_t eax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);
368
- uint32_t ecx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
369
- uint32_t edx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
370
+ uint32_t eax = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RAX);
371
+ uint32_t ecx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RCX);
372
+ uint32_t edx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RDX);
373
374
if (ecx) {
375
macvm_set_rip(cpu, rip + ins_len);
376
break;
377
}
378
env->xcr0 = ((uint64_t)edx << 32) | eax;
379
- wreg(cpu->hvf_fd, HV_X86_XCR0, env->xcr0 | 1);
380
+ wreg(cpu->hvf->fd, HV_X86_XCR0, env->xcr0 | 1);
381
macvm_set_rip(cpu, rip + ins_len);
382
break;
383
}
384
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
385
386
switch (cr) {
387
case 0x0: {
388
- macvm_set_cr0(cpu->hvf_fd, RRX(env, reg));
389
+ macvm_set_cr0(cpu->hvf->fd, RRX(env, reg));
390
break;
391
}
392
case 4: {
393
- macvm_set_cr4(cpu->hvf_fd, RRX(env, reg));
394
+ macvm_set_cr4(cpu->hvf->fd, RRX(env, reg));
395
break;
396
}
397
case 8: {
398
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
399
break;
400
}
401
case EXIT_REASON_TASK_SWITCH: {
402
- uint64_t vinfo = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);
403
+ uint64_t vinfo = rvmcs(cpu->hvf->fd, VMCS_IDT_VECTORING_INFO);
404
x68_segment_selector sel = {.sel = exit_qual & 0xffff};
405
vmx_handle_task_switch(cpu, sel, (exit_qual >> 30) & 0x3,
406
vinfo & VMCS_INTR_VALID, vinfo & VECTORING_INFO_VECTOR_MASK, vinfo
407
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
408
break;
409
}
410
case EXIT_REASON_RDPMC:
411
- wreg(cpu->hvf_fd, HV_X86_RAX, 0);
412
- wreg(cpu->hvf_fd, HV_X86_RDX, 0);
413
+ wreg(cpu->hvf->fd, HV_X86_RAX, 0);
414
+ wreg(cpu->hvf->fd, HV_X86_RDX, 0);
415
macvm_set_rip(cpu, rip + ins_len);
416
break;
417
case VMX_REASON_VMCALL:
418
diff --git a/target/i386/hvf/x86.c b/target/i386/hvf/x86.c
419
index XXXXXXX..XXXXXXX 100644
420
--- a/target/i386/hvf/x86.c
421
+++ b/target/i386/hvf/x86.c
422
@@ -XXX,XX +XXX,XX @@ bool x86_read_segment_descriptor(struct CPUState *cpu,
423
}
424
425
if (GDT_SEL == sel.ti) {
426
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_BASE);
427
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_LIMIT);
428
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_BASE);
429
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_LIMIT);
430
} else {
431
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_BASE);
432
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_LIMIT);
433
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_BASE);
434
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_LIMIT);
435
}
436
437
if (sel.index * 8 >= limit) {
438
@@ -XXX,XX +XXX,XX @@ bool x86_write_segment_descriptor(struct CPUState *cpu,
439
uint32_t limit;
440
441
if (GDT_SEL == sel.ti) {
442
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_BASE);
443
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_LIMIT);
444
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_BASE);
445
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_LIMIT);
446
} else {
447
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_BASE);
448
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_LIMIT);
449
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_BASE);
450
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_LIMIT);
451
}
452
453
if (sel.index * 8 >= limit) {
454
@@ -XXX,XX +XXX,XX @@ bool x86_write_segment_descriptor(struct CPUState *cpu,
455
bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
456
int gate)
457
{
458
- target_ulong base = rvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_BASE);
459
- uint32_t limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_LIMIT);
460
+ target_ulong base = rvmcs(cpu->hvf->fd, VMCS_GUEST_IDTR_BASE);
461
+ uint32_t limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_IDTR_LIMIT);
462
463
memset(idt_desc, 0, sizeof(*idt_desc));
464
if (gate * 8 >= limit) {
465
@@ -XXX,XX +XXX,XX @@ bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
466
467
bool x86_is_protected(struct CPUState *cpu)
468
{
469
- uint64_t cr0 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0);
470
+ uint64_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
471
return cr0 & CR0_PE;
472
}
473
474
@@ -XXX,XX +XXX,XX @@ bool x86_is_v8086(struct CPUState *cpu)
475
476
bool x86_is_long_mode(struct CPUState *cpu)
477
{
478
- return rvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER) & MSR_EFER_LMA;
479
+ return rvmcs(cpu->hvf->fd, VMCS_GUEST_IA32_EFER) & MSR_EFER_LMA;
480
}
481
482
bool x86_is_long64_mode(struct CPUState *cpu)
483
@@ -XXX,XX +XXX,XX @@ bool x86_is_long64_mode(struct CPUState *cpu)
484
485
bool x86_is_paging_mode(struct CPUState *cpu)
486
{
487
- uint64_t cr0 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0);
488
+ uint64_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
489
return cr0 & CR0_PG;
490
}
491
492
bool x86_is_pae_enabled(struct CPUState *cpu)
493
{
494
- uint64_t cr4 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR4);
495
+ uint64_t cr4 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR4);
496
return cr4 & CR4_PAE;
497
}
498
499
diff --git a/target/i386/hvf/x86_descr.c b/target/i386/hvf/x86_descr.c
500
index XXXXXXX..XXXXXXX 100644
501
--- a/target/i386/hvf/x86_descr.c
502
+++ b/target/i386/hvf/x86_descr.c
503
@@ -XXX,XX +XXX,XX @@ static const struct vmx_segment_field {
504
505
uint32_t vmx_read_segment_limit(CPUState *cpu, X86Seg seg)
506
{
507
- return (uint32_t)rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].limit);
508
+ return (uint32_t)rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].limit);
509
}
510
511
uint32_t vmx_read_segment_ar(CPUState *cpu, X86Seg seg)
512
{
513
- return (uint32_t)rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].ar_bytes);
514
+ return (uint32_t)rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].ar_bytes);
515
}
516
517
uint64_t vmx_read_segment_base(CPUState *cpu, X86Seg seg)
518
{
519
- return rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].base);
520
+ return rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].base);
521
}
522
523
x68_segment_selector vmx_read_segment_selector(CPUState *cpu, X86Seg seg)
524
{
525
x68_segment_selector sel;
526
- sel.sel = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector);
527
+ sel.sel = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].selector);
528
return sel;
529
}
530
531
void vmx_write_segment_selector(struct CPUState *cpu, x68_segment_selector selector, X86Seg seg)
532
{
533
- wvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector, selector.sel);
534
+ wvmcs(cpu->hvf->fd, vmx_segment_fields[seg].selector, selector.sel);
535
}
536
537
void vmx_read_segment_descriptor(struct CPUState *cpu, struct vmx_segment *desc, X86Seg seg)
538
{
539
- desc->sel = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector);
540
- desc->base = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].base);
541
- desc->limit = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].limit);
542
- desc->ar = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].ar_bytes);
543
+ desc->sel = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].selector);
544
+ desc->base = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].base);
545
+ desc->limit = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].limit);
546
+ desc->ar = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].ar_bytes);
547
}
548
549
void vmx_write_segment_descriptor(CPUState *cpu, struct vmx_segment *desc, X86Seg seg)
550
{
551
const struct vmx_segment_field *sf = &vmx_segment_fields[seg];
552
553
- wvmcs(cpu->hvf_fd, sf->base, desc->base);
554
- wvmcs(cpu->hvf_fd, sf->limit, desc->limit);
555
- wvmcs(cpu->hvf_fd, sf->selector, desc->sel);
556
- wvmcs(cpu->hvf_fd, sf->ar_bytes, desc->ar);
557
+ wvmcs(cpu->hvf->fd, sf->base, desc->base);
558
+ wvmcs(cpu->hvf->fd, sf->limit, desc->limit);
559
+ wvmcs(cpu->hvf->fd, sf->selector, desc->sel);
560
+ wvmcs(cpu->hvf->fd, sf->ar_bytes, desc->ar);
561
}
562
563
void x86_segment_descriptor_to_vmx(struct CPUState *cpu, x68_segment_selector selector, struct x86_segment_descriptor *desc, struct vmx_segment *vmx_desc)
564
diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c
565
index XXXXXXX..XXXXXXX 100644
566
--- a/target/i386/hvf/x86_emu.c
567
+++ b/target/i386/hvf/x86_emu.c
568
@@ -XXX,XX +XXX,XX @@ void simulate_rdmsr(struct CPUState *cpu)
569
570
switch (msr) {
571
case MSR_IA32_TSC:
572
- val = rdtscp() + rvmcs(cpu->hvf_fd, VMCS_TSC_OFFSET);
573
+ val = rdtscp() + rvmcs(cpu->hvf->fd, VMCS_TSC_OFFSET);
574
break;
575
case MSR_IA32_APICBASE:
576
val = cpu_get_apic_base(X86_CPU(cpu)->apic_state);
577
@@ -XXX,XX +XXX,XX @@ void simulate_rdmsr(struct CPUState *cpu)
578
val = x86_cpu->ucode_rev;
579
break;
580
case MSR_EFER:
581
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER);
582
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_IA32_EFER);
583
break;
584
case MSR_FSBASE:
585
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE);
586
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_FS_BASE);
587
break;
588
case MSR_GSBASE:
589
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE);
590
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_GS_BASE);
591
break;
592
case MSR_KERNELGSBASE:
593
- val = rvmcs(cpu->hvf_fd, VMCS_HOST_FS_BASE);
594
+ val = rvmcs(cpu->hvf->fd, VMCS_HOST_FS_BASE);
595
break;
596
case MSR_STAR:
597
abort();
598
@@ -XXX,XX +XXX,XX @@ void simulate_wrmsr(struct CPUState *cpu)
599
cpu_set_apic_base(X86_CPU(cpu)->apic_state, data);
600
break;
601
case MSR_FSBASE:
602
- wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE, data);
603
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_FS_BASE, data);
604
break;
605
case MSR_GSBASE:
606
- wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE, data);
607
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_GS_BASE, data);
608
break;
609
case MSR_KERNELGSBASE:
610
- wvmcs(cpu->hvf_fd, VMCS_HOST_FS_BASE, data);
611
+ wvmcs(cpu->hvf->fd, VMCS_HOST_FS_BASE, data);
612
break;
613
case MSR_STAR:
614
abort();
615
@@ -XXX,XX +XXX,XX @@ void simulate_wrmsr(struct CPUState *cpu)
616
break;
617
case MSR_EFER:
618
/*printf("new efer %llx\n", EFER(cpu));*/
619
- wvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER, data);
620
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_IA32_EFER, data);
621
if (data & MSR_EFER_NXE) {
622
- hv_vcpu_invalidate_tlb(cpu->hvf_fd);
623
+ hv_vcpu_invalidate_tlb(cpu->hvf->fd);
624
}
625
break;
626
case MSR_MTRRphysBase(0):
627
@@ -XXX,XX +XXX,XX @@ void load_regs(struct CPUState *cpu)
628
CPUX86State *env = &x86_cpu->env;
629
630
int i = 0;
631
- RRX(env, R_EAX) = rreg(cpu->hvf_fd, HV_X86_RAX);
632
- RRX(env, R_EBX) = rreg(cpu->hvf_fd, HV_X86_RBX);
633
- RRX(env, R_ECX) = rreg(cpu->hvf_fd, HV_X86_RCX);
634
- RRX(env, R_EDX) = rreg(cpu->hvf_fd, HV_X86_RDX);
635
- RRX(env, R_ESI) = rreg(cpu->hvf_fd, HV_X86_RSI);
636
- RRX(env, R_EDI) = rreg(cpu->hvf_fd, HV_X86_RDI);
637
- RRX(env, R_ESP) = rreg(cpu->hvf_fd, HV_X86_RSP);
638
- RRX(env, R_EBP) = rreg(cpu->hvf_fd, HV_X86_RBP);
639
+ RRX(env, R_EAX) = rreg(cpu->hvf->fd, HV_X86_RAX);
640
+ RRX(env, R_EBX) = rreg(cpu->hvf->fd, HV_X86_RBX);
641
+ RRX(env, R_ECX) = rreg(cpu->hvf->fd, HV_X86_RCX);
642
+ RRX(env, R_EDX) = rreg(cpu->hvf->fd, HV_X86_RDX);
643
+ RRX(env, R_ESI) = rreg(cpu->hvf->fd, HV_X86_RSI);
644
+ RRX(env, R_EDI) = rreg(cpu->hvf->fd, HV_X86_RDI);
645
+ RRX(env, R_ESP) = rreg(cpu->hvf->fd, HV_X86_RSP);
646
+ RRX(env, R_EBP) = rreg(cpu->hvf->fd, HV_X86_RBP);
647
for (i = 8; i < 16; i++) {
648
- RRX(env, i) = rreg(cpu->hvf_fd, HV_X86_RAX + i);
649
+ RRX(env, i) = rreg(cpu->hvf->fd, HV_X86_RAX + i);
650
}
651
652
- env->eflags = rreg(cpu->hvf_fd, HV_X86_RFLAGS);
653
+ env->eflags = rreg(cpu->hvf->fd, HV_X86_RFLAGS);
654
rflags_to_lflags(env);
655
- env->eip = rreg(cpu->hvf_fd, HV_X86_RIP);
656
+ env->eip = rreg(cpu->hvf->fd, HV_X86_RIP);
657
}
658
659
void store_regs(struct CPUState *cpu)
660
@@ -XXX,XX +XXX,XX @@ void store_regs(struct CPUState *cpu)
661
CPUX86State *env = &x86_cpu->env;
662
663
int i = 0;
664
- wreg(cpu->hvf_fd, HV_X86_RAX, RAX(env));
665
- wreg(cpu->hvf_fd, HV_X86_RBX, RBX(env));
666
- wreg(cpu->hvf_fd, HV_X86_RCX, RCX(env));
667
- wreg(cpu->hvf_fd, HV_X86_RDX, RDX(env));
668
- wreg(cpu->hvf_fd, HV_X86_RSI, RSI(env));
669
- wreg(cpu->hvf_fd, HV_X86_RDI, RDI(env));
670
- wreg(cpu->hvf_fd, HV_X86_RBP, RBP(env));
671
- wreg(cpu->hvf_fd, HV_X86_RSP, RSP(env));
672
+ wreg(cpu->hvf->fd, HV_X86_RAX, RAX(env));
673
+ wreg(cpu->hvf->fd, HV_X86_RBX, RBX(env));
674
+ wreg(cpu->hvf->fd, HV_X86_RCX, RCX(env));
675
+ wreg(cpu->hvf->fd, HV_X86_RDX, RDX(env));
676
+ wreg(cpu->hvf->fd, HV_X86_RSI, RSI(env));
677
+ wreg(cpu->hvf->fd, HV_X86_RDI, RDI(env));
678
+ wreg(cpu->hvf->fd, HV_X86_RBP, RBP(env));
679
+ wreg(cpu->hvf->fd, HV_X86_RSP, RSP(env));
680
for (i = 8; i < 16; i++) {
681
- wreg(cpu->hvf_fd, HV_X86_RAX + i, RRX(env, i));
682
+ wreg(cpu->hvf->fd, HV_X86_RAX + i, RRX(env, i));
683
}
684
685
lflags_to_rflags(env);
686
- wreg(cpu->hvf_fd, HV_X86_RFLAGS, env->eflags);
687
+ wreg(cpu->hvf->fd, HV_X86_RFLAGS, env->eflags);
688
macvm_set_rip(cpu, env->eip);
689
}
690
691
diff --git a/target/i386/hvf/x86_mmu.c b/target/i386/hvf/x86_mmu.c
692
index XXXXXXX..XXXXXXX 100644
693
--- a/target/i386/hvf/x86_mmu.c
694
+++ b/target/i386/hvf/x86_mmu.c
695
@@ -XXX,XX +XXX,XX @@ static bool test_pt_entry(struct CPUState *cpu, struct gpt_translation *pt,
696
pt->err_code |= MMU_PAGE_PT;
697
}
698
699
- uint32_t cr0 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0);
700
+ uint32_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
701
/* check protection */
702
if (cr0 & CR0_WP) {
703
if (pt->write_access && !pte_write_access(pte)) {
704
@@ -XXX,XX +XXX,XX @@ static bool walk_gpt(struct CPUState *cpu, target_ulong addr, int err_code,
705
{
706
int top_level, level;
707
bool is_large = false;
708
- target_ulong cr3 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR3);
709
+ target_ulong cr3 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR3);
710
uint64_t page_mask = pae ? PAE_PTE_PAGE_MASK : LEGACY_PTE_PAGE_MASK;
711
712
memset(pt, 0, sizeof(*pt));
713
diff --git a/target/i386/hvf/x86_task.c b/target/i386/hvf/x86_task.c
714
index XXXXXXX..XXXXXXX 100644
715
--- a/target/i386/hvf/x86_task.c
716
+++ b/target/i386/hvf/x86_task.c
717
@@ -XXX,XX +XXX,XX @@ static void load_state_from_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
718
X86CPU *x86_cpu = X86_CPU(cpu);
719
CPUX86State *env = &x86_cpu->env;
720
721
- wvmcs(cpu->hvf_fd, VMCS_GUEST_CR3, tss->cr3);
722
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_CR3, tss->cr3);
723
724
env->eip = tss->eip;
725
env->eflags = tss->eflags | 2;
726
@@ -XXX,XX +XXX,XX @@ static int task_switch_32(CPUState *cpu, x68_segment_selector tss_sel, x68_segme
727
728
void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int reason, bool gate_valid, uint8_t gate, uint64_t gate_type)
729
{
730
- uint64_t rip = rreg(cpu->hvf_fd, HV_X86_RIP);
731
+ uint64_t rip = rreg(cpu->hvf->fd, HV_X86_RIP);
732
if (!gate_valid || (gate_type != VMCS_INTR_T_HWEXCEPTION &&
733
gate_type != VMCS_INTR_T_HWINTR &&
734
gate_type != VMCS_INTR_T_NMI)) {
735
- int ins_len = rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
736
+ int ins_len = rvmcs(cpu->hvf->fd, VMCS_EXIT_INSTRUCTION_LENGTH);
737
macvm_set_rip(cpu, rip + ins_len);
738
return;
739
}
740
@@ -XXX,XX +XXX,XX @@ void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int rea
741
//ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
742
VM_PANIC("task_switch_16");
743
744
- macvm_set_cr0(cpu->hvf_fd, rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0) | CR0_TS);
745
+ macvm_set_cr0(cpu->hvf->fd, rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0) | CR0_TS);
746
x86_segment_descriptor_to_vmx(cpu, tss_sel, &next_tss_desc, &vmx_seg);
747
vmx_write_segment_descriptor(cpu, &vmx_seg, R_TR);
748
749
store_regs(cpu);
750
751
- hv_vcpu_invalidate_tlb(cpu->hvf_fd);
752
- hv_vcpu_flush(cpu->hvf_fd);
753
+ hv_vcpu_invalidate_tlb(cpu->hvf->fd);
754
+ hv_vcpu_flush(cpu->hvf->fd);
755
}
756
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
757
index XXXXXXX..XXXXXXX 100644
758
--- a/target/i386/hvf/x86hvf.c
759
+++ b/target/i386/hvf/x86hvf.c
760
@@ -XXX,XX +XXX,XX @@ void hvf_put_xsave(CPUState *cpu_state)
761
762
x86_cpu_xsave_all_areas(X86_CPU(cpu_state), xsave);
763
764
- if (hv_vcpu_write_fpstate(cpu_state->hvf_fd, (void*)xsave, 4096)) {
765
+ if (hv_vcpu_write_fpstate(cpu_state->hvf->fd, (void*)xsave, 4096)) {
766
abort();
767
}
768
}
769
@@ -XXX,XX +XXX,XX @@ void hvf_put_segments(CPUState *cpu_state)
770
CPUX86State *env = &X86_CPU(cpu_state)->env;
771
struct vmx_segment seg;
772
773
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_LIMIT, env->idt.limit);
774
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_BASE, env->idt.base);
775
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_LIMIT, env->idt.limit);
776
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_BASE, env->idt.base);
777
778
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_LIMIT, env->gdt.limit);
779
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_BASE, env->gdt.base);
780
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_LIMIT, env->gdt.limit);
781
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_BASE, env->gdt.base);
782
783
- /* wvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR2, env->cr[2]); */
784
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR3, env->cr[3]);
785
+ /* wvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR2, env->cr[2]); */
786
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR3, env->cr[3]);
787
vmx_update_tpr(cpu_state);
788
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IA32_EFER, env->efer);
789
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_IA32_EFER, env->efer);
790
791
- macvm_set_cr4(cpu_state->hvf_fd, env->cr[4]);
792
- macvm_set_cr0(cpu_state->hvf_fd, env->cr[0]);
793
+ macvm_set_cr4(cpu_state->hvf->fd, env->cr[4]);
794
+ macvm_set_cr0(cpu_state->hvf->fd, env->cr[0]);
795
796
hvf_set_segment(cpu_state, &seg, &env->segs[R_CS], false);
797
vmx_write_segment_descriptor(cpu_state, &seg, R_CS);
798
@@ -XXX,XX +XXX,XX @@ void hvf_put_segments(CPUState *cpu_state)
799
hvf_set_segment(cpu_state, &seg, &env->ldt, false);
800
vmx_write_segment_descriptor(cpu_state, &seg, R_LDTR);
801
802
- hv_vcpu_flush(cpu_state->hvf_fd);
803
+ hv_vcpu_flush(cpu_state->hvf->fd);
804
}
805
806
void hvf_put_msrs(CPUState *cpu_state)
807
{
808
CPUX86State *env = &X86_CPU(cpu_state)->env;
809
810
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_CS,
811
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_CS,
812
env->sysenter_cs);
813
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_ESP,
814
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_ESP,
815
env->sysenter_esp);
816
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_EIP,
817
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_EIP,
818
env->sysenter_eip);
819
820
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_STAR, env->star);
821
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_STAR, env->star);
822
823
#ifdef TARGET_X86_64
824
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_CSTAR, env->cstar);
825
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_KERNELGSBASE, env->kernelgsbase);
826
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_FMASK, env->fmask);
827
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_LSTAR, env->lstar);
828
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_CSTAR, env->cstar);
829
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_KERNELGSBASE, env->kernelgsbase);
830
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_FMASK, env->fmask);
831
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_LSTAR, env->lstar);
832
#endif
833
834
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_GSBASE, env->segs[R_GS].base);
835
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_FSBASE, env->segs[R_FS].base);
836
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_GSBASE, env->segs[R_GS].base);
837
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_FSBASE, env->segs[R_FS].base);
838
}
839
840
841
@@ -XXX,XX +XXX,XX @@ void hvf_get_xsave(CPUState *cpu_state)
842
843
xsave = X86_CPU(cpu_state)->env.xsave_buf;
844
845
- if (hv_vcpu_read_fpstate(cpu_state->hvf_fd, (void*)xsave, 4096)) {
846
+ if (hv_vcpu_read_fpstate(cpu_state->hvf->fd, (void*)xsave, 4096)) {
847
abort();
848
}
849
850
@@ -XXX,XX +XXX,XX @@ void hvf_get_segments(CPUState *cpu_state)
851
vmx_read_segment_descriptor(cpu_state, &seg, R_LDTR);
852
hvf_get_segment(&env->ldt, &seg);
853
854
- env->idt.limit = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_LIMIT);
855
- env->idt.base = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_BASE);
856
- env->gdt.limit = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_LIMIT);
857
- env->gdt.base = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_BASE);
858
+ env->idt.limit = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_LIMIT);
859
+ env->idt.base = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_BASE);
860
+ env->gdt.limit = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_LIMIT);
861
+ env->gdt.base = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_BASE);
862
863
- env->cr[0] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR0);
864
+ env->cr[0] = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR0);
865
env->cr[2] = 0;
866
- env->cr[3] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR3);
867
- env->cr[4] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR4);
868
+ env->cr[3] = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR3);
869
+ env->cr[4] = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR4);
870
871
- env->efer = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_IA32_EFER);
872
+ env->efer = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_IA32_EFER);
873
}
874
875
void hvf_get_msrs(CPUState *cpu_state)
876
@@ -XXX,XX +XXX,XX @@ void hvf_get_msrs(CPUState *cpu_state)
877
CPUX86State *env = &X86_CPU(cpu_state)->env;
878
uint64_t tmp;
879
880
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_CS, &tmp);
881
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_CS, &tmp);
882
env->sysenter_cs = tmp;
883
884
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_ESP, &tmp);
885
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_ESP, &tmp);
886
env->sysenter_esp = tmp;
887
888
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_EIP, &tmp);
889
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_EIP, &tmp);
890
env->sysenter_eip = tmp;
891
892
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_STAR, &env->star);
893
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_STAR, &env->star);
894
895
#ifdef TARGET_X86_64
896
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_CSTAR, &env->cstar);
897
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_KERNELGSBASE, &env->kernelgsbase);
898
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_FMASK, &env->fmask);
899
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_LSTAR, &env->lstar);
900
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_CSTAR, &env->cstar);
901
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_KERNELGSBASE, &env->kernelgsbase);
902
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_FMASK, &env->fmask);
903
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_LSTAR, &env->lstar);
904
#endif
905
906
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_APICBASE, &tmp);
907
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_APICBASE, &tmp);
908
909
- env->tsc = rdtscp() + rvmcs(cpu_state->hvf_fd, VMCS_TSC_OFFSET);
910
+ env->tsc = rdtscp() + rvmcs(cpu_state->hvf->fd, VMCS_TSC_OFFSET);
911
}
912
913
int hvf_put_registers(CPUState *cpu_state)
914
@@ -XXX,XX +XXX,XX @@ int hvf_put_registers(CPUState *cpu_state)
915
X86CPU *x86cpu = X86_CPU(cpu_state);
916
CPUX86State *env = &x86cpu->env;
917
918
- wreg(cpu_state->hvf_fd, HV_X86_RAX, env->regs[R_EAX]);
919
- wreg(cpu_state->hvf_fd, HV_X86_RBX, env->regs[R_EBX]);
920
- wreg(cpu_state->hvf_fd, HV_X86_RCX, env->regs[R_ECX]);
921
- wreg(cpu_state->hvf_fd, HV_X86_RDX, env->regs[R_EDX]);
922
- wreg(cpu_state->hvf_fd, HV_X86_RBP, env->regs[R_EBP]);
923
- wreg(cpu_state->hvf_fd, HV_X86_RSP, env->regs[R_ESP]);
924
- wreg(cpu_state->hvf_fd, HV_X86_RSI, env->regs[R_ESI]);
925
- wreg(cpu_state->hvf_fd, HV_X86_RDI, env->regs[R_EDI]);
926
- wreg(cpu_state->hvf_fd, HV_X86_R8, env->regs[8]);
927
- wreg(cpu_state->hvf_fd, HV_X86_R9, env->regs[9]);
928
- wreg(cpu_state->hvf_fd, HV_X86_R10, env->regs[10]);
929
- wreg(cpu_state->hvf_fd, HV_X86_R11, env->regs[11]);
930
- wreg(cpu_state->hvf_fd, HV_X86_R12, env->regs[12]);
931
- wreg(cpu_state->hvf_fd, HV_X86_R13, env->regs[13]);
932
- wreg(cpu_state->hvf_fd, HV_X86_R14, env->regs[14]);
933
- wreg(cpu_state->hvf_fd, HV_X86_R15, env->regs[15]);
934
- wreg(cpu_state->hvf_fd, HV_X86_RFLAGS, env->eflags);
935
- wreg(cpu_state->hvf_fd, HV_X86_RIP, env->eip);
936
+ wreg(cpu_state->hvf->fd, HV_X86_RAX, env->regs[R_EAX]);
937
+ wreg(cpu_state->hvf->fd, HV_X86_RBX, env->regs[R_EBX]);
938
+ wreg(cpu_state->hvf->fd, HV_X86_RCX, env->regs[R_ECX]);
939
+ wreg(cpu_state->hvf->fd, HV_X86_RDX, env->regs[R_EDX]);
940
+ wreg(cpu_state->hvf->fd, HV_X86_RBP, env->regs[R_EBP]);
941
+ wreg(cpu_state->hvf->fd, HV_X86_RSP, env->regs[R_ESP]);
942
+ wreg(cpu_state->hvf->fd, HV_X86_RSI, env->regs[R_ESI]);
943
+ wreg(cpu_state->hvf->fd, HV_X86_RDI, env->regs[R_EDI]);
944
+ wreg(cpu_state->hvf->fd, HV_X86_R8, env->regs[8]);
945
+ wreg(cpu_state->hvf->fd, HV_X86_R9, env->regs[9]);
946
+ wreg(cpu_state->hvf->fd, HV_X86_R10, env->regs[10]);
947
+ wreg(cpu_state->hvf->fd, HV_X86_R11, env->regs[11]);
948
+ wreg(cpu_state->hvf->fd, HV_X86_R12, env->regs[12]);
949
+ wreg(cpu_state->hvf->fd, HV_X86_R13, env->regs[13]);
950
+ wreg(cpu_state->hvf->fd, HV_X86_R14, env->regs[14]);
951
+ wreg(cpu_state->hvf->fd, HV_X86_R15, env->regs[15]);
952
+ wreg(cpu_state->hvf->fd, HV_X86_RFLAGS, env->eflags);
953
+ wreg(cpu_state->hvf->fd, HV_X86_RIP, env->eip);
954
955
- wreg(cpu_state->hvf_fd, HV_X86_XCR0, env->xcr0);
956
+ wreg(cpu_state->hvf->fd, HV_X86_XCR0, env->xcr0);
957
958
hvf_put_xsave(cpu_state);
959
960
@@ -XXX,XX +XXX,XX @@ int hvf_put_registers(CPUState *cpu_state)
961
962
hvf_put_msrs(cpu_state);
963
964
- wreg(cpu_state->hvf_fd, HV_X86_DR0, env->dr[0]);
965
- wreg(cpu_state->hvf_fd, HV_X86_DR1, env->dr[1]);
966
- wreg(cpu_state->hvf_fd, HV_X86_DR2, env->dr[2]);
967
- wreg(cpu_state->hvf_fd, HV_X86_DR3, env->dr[3]);
968
- wreg(cpu_state->hvf_fd, HV_X86_DR4, env->dr[4]);
969
- wreg(cpu_state->hvf_fd, HV_X86_DR5, env->dr[5]);
970
- wreg(cpu_state->hvf_fd, HV_X86_DR6, env->dr[6]);
971
- wreg(cpu_state->hvf_fd, HV_X86_DR7, env->dr[7]);
972
+ wreg(cpu_state->hvf->fd, HV_X86_DR0, env->dr[0]);
973
+ wreg(cpu_state->hvf->fd, HV_X86_DR1, env->dr[1]);
974
+ wreg(cpu_state->hvf->fd, HV_X86_DR2, env->dr[2]);
975
+ wreg(cpu_state->hvf->fd, HV_X86_DR3, env->dr[3]);
976
+ wreg(cpu_state->hvf->fd, HV_X86_DR4, env->dr[4]);
977
+ wreg(cpu_state->hvf->fd, HV_X86_DR5, env->dr[5]);
978
+ wreg(cpu_state->hvf->fd, HV_X86_DR6, env->dr[6]);
979
+ wreg(cpu_state->hvf->fd, HV_X86_DR7, env->dr[7]);
980
981
return 0;
982
}
983
@@ -XXX,XX +XXX,XX @@ int hvf_get_registers(CPUState *cpu_state)
984
X86CPU *x86cpu = X86_CPU(cpu_state);
985
CPUX86State *env = &x86cpu->env;
986
987
- env->regs[R_EAX] = rreg(cpu_state->hvf_fd, HV_X86_RAX);
988
- env->regs[R_EBX] = rreg(cpu_state->hvf_fd, HV_X86_RBX);
989
- env->regs[R_ECX] = rreg(cpu_state->hvf_fd, HV_X86_RCX);
990
- env->regs[R_EDX] = rreg(cpu_state->hvf_fd, HV_X86_RDX);
991
- env->regs[R_EBP] = rreg(cpu_state->hvf_fd, HV_X86_RBP);
992
- env->regs[R_ESP] = rreg(cpu_state->hvf_fd, HV_X86_RSP);
993
- env->regs[R_ESI] = rreg(cpu_state->hvf_fd, HV_X86_RSI);
994
- env->regs[R_EDI] = rreg(cpu_state->hvf_fd, HV_X86_RDI);
995
- env->regs[8] = rreg(cpu_state->hvf_fd, HV_X86_R8);
996
- env->regs[9] = rreg(cpu_state->hvf_fd, HV_X86_R9);
997
- env->regs[10] = rreg(cpu_state->hvf_fd, HV_X86_R10);
998
- env->regs[11] = rreg(cpu_state->hvf_fd, HV_X86_R11);
999
- env->regs[12] = rreg(cpu_state->hvf_fd, HV_X86_R12);
1000
- env->regs[13] = rreg(cpu_state->hvf_fd, HV_X86_R13);
1001
- env->regs[14] = rreg(cpu_state->hvf_fd, HV_X86_R14);
1002
- env->regs[15] = rreg(cpu_state->hvf_fd, HV_X86_R15);
1003
+ env->regs[R_EAX] = rreg(cpu_state->hvf->fd, HV_X86_RAX);
1004
+ env->regs[R_EBX] = rreg(cpu_state->hvf->fd, HV_X86_RBX);
1005
+ env->regs[R_ECX] = rreg(cpu_state->hvf->fd, HV_X86_RCX);
1006
+ env->regs[R_EDX] = rreg(cpu_state->hvf->fd, HV_X86_RDX);
1007
+ env->regs[R_EBP] = rreg(cpu_state->hvf->fd, HV_X86_RBP);
1008
+ env->regs[R_ESP] = rreg(cpu_state->hvf->fd, HV_X86_RSP);
1009
+ env->regs[R_ESI] = rreg(cpu_state->hvf->fd, HV_X86_RSI);
1010
+ env->regs[R_EDI] = rreg(cpu_state->hvf->fd, HV_X86_RDI);
1011
+ env->regs[8] = rreg(cpu_state->hvf->fd, HV_X86_R8);
1012
+ env->regs[9] = rreg(cpu_state->hvf->fd, HV_X86_R9);
1013
+ env->regs[10] = rreg(cpu_state->hvf->fd, HV_X86_R10);
1014
+ env->regs[11] = rreg(cpu_state->hvf->fd, HV_X86_R11);
1015
+ env->regs[12] = rreg(cpu_state->hvf->fd, HV_X86_R12);
1016
+ env->regs[13] = rreg(cpu_state->hvf->fd, HV_X86_R13);
1017
+ env->regs[14] = rreg(cpu_state->hvf->fd, HV_X86_R14);
1018
+ env->regs[15] = rreg(cpu_state->hvf->fd, HV_X86_R15);
1019
1020
- env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
1021
- env->eip = rreg(cpu_state->hvf_fd, HV_X86_RIP);
1022
+ env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
1023
+ env->eip = rreg(cpu_state->hvf->fd, HV_X86_RIP);
1024
1025
hvf_get_xsave(cpu_state);
1026
- env->xcr0 = rreg(cpu_state->hvf_fd, HV_X86_XCR0);
1027
+ env->xcr0 = rreg(cpu_state->hvf->fd, HV_X86_XCR0);
1028
1029
hvf_get_segments(cpu_state);
1030
hvf_get_msrs(cpu_state);
1031
1032
- env->dr[0] = rreg(cpu_state->hvf_fd, HV_X86_DR0);
1033
- env->dr[1] = rreg(cpu_state->hvf_fd, HV_X86_DR1);
1034
- env->dr[2] = rreg(cpu_state->hvf_fd, HV_X86_DR2);
1035
- env->dr[3] = rreg(cpu_state->hvf_fd, HV_X86_DR3);
1036
- env->dr[4] = rreg(cpu_state->hvf_fd, HV_X86_DR4);
1037
- env->dr[5] = rreg(cpu_state->hvf_fd, HV_X86_DR5);
1038
- env->dr[6] = rreg(cpu_state->hvf_fd, HV_X86_DR6);
1039
- env->dr[7] = rreg(cpu_state->hvf_fd, HV_X86_DR7);
1040
+ env->dr[0] = rreg(cpu_state->hvf->fd, HV_X86_DR0);
1041
+ env->dr[1] = rreg(cpu_state->hvf->fd, HV_X86_DR1);
1042
+ env->dr[2] = rreg(cpu_state->hvf->fd, HV_X86_DR2);
1043
+ env->dr[3] = rreg(cpu_state->hvf->fd, HV_X86_DR3);
1044
+ env->dr[4] = rreg(cpu_state->hvf->fd, HV_X86_DR4);
1045
+ env->dr[5] = rreg(cpu_state->hvf->fd, HV_X86_DR5);
1046
+ env->dr[6] = rreg(cpu_state->hvf->fd, HV_X86_DR6);
1047
+ env->dr[7] = rreg(cpu_state->hvf->fd, HV_X86_DR7);
1048
1049
x86_update_hflags(env);
1050
return 0;
1051
@@ -XXX,XX +XXX,XX @@ int hvf_get_registers(CPUState *cpu_state)
1052
static void vmx_set_int_window_exiting(CPUState *cpu)
1053
{
1054
uint64_t val;
1055
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
1056
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val |
1057
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
1058
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val |
1059
VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING);
1060
}
1061
1062
void vmx_clear_int_window_exiting(CPUState *cpu)
1063
{
1064
uint64_t val;
1065
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
1066
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val &
1067
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
1068
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val &
1069
~VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING);
1070
}
1071
1072
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
1073
uint64_t info = 0;
1074
if (have_event) {
1075
info = vector | intr_type | VMCS_INTR_VALID;
1076
- uint64_t reason = rvmcs(cpu_state->hvf_fd, VMCS_EXIT_REASON);
1077
+ uint64_t reason = rvmcs(cpu_state->hvf->fd, VMCS_EXIT_REASON);
1078
if (env->nmi_injected && reason != EXIT_REASON_TASK_SWITCH) {
1079
vmx_clear_nmi_blocking(cpu_state);
1080
}
1081
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
1082
info &= ~(1 << 12); /* clear undefined bit */
1083
if (intr_type == VMCS_INTR_T_SWINTR ||
1084
intr_type == VMCS_INTR_T_SWEXCEPTION) {
1085
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INST_LENGTH, env->ins_len);
1086
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INST_LENGTH, env->ins_len);
1087
}
1088
1089
if (env->has_error_code) {
1090
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_EXCEPTION_ERROR,
1091
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_EXCEPTION_ERROR,
1092
env->error_code);
1093
/* Indicate that VMCS_ENTRY_EXCEPTION_ERROR is valid */
1094
info |= VMCS_INTR_DEL_ERRCODE;
1095
}
1096
/*printf("reinject %lx err %d\n", info, err);*/
1097
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, info);
1098
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INTR_INFO, info);
1099
};
1100
}
1101
1102
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
1103
if (!(env->hflags2 & HF2_NMI_MASK) && !(info & VMCS_INTR_VALID)) {
1104
cpu_state->interrupt_request &= ~CPU_INTERRUPT_NMI;
1105
info = VMCS_INTR_VALID | VMCS_INTR_T_NMI | EXCP02_NMI;
1106
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, info);
1107
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INTR_INFO, info);
1108
} else {
1109
vmx_set_nmi_window_exiting(cpu_state);
1110
}
1111
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
1112
int line = cpu_get_pic_interrupt(&x86cpu->env);
1113
cpu_state->interrupt_request &= ~CPU_INTERRUPT_HARD;
1114
if (line >= 0) {
1115
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, line |
1116
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INTR_INFO, line |
1117
VMCS_INTR_VALID | VMCS_INTR_T_HWINTR);
1118
}
1119
}
1120
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
1121
X86CPU *cpu = X86_CPU(cpu_state);
1122
CPUX86State *env = &cpu->env;
1123
1124
- env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
1125
+ env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
1126
1127
if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {
1128
cpu_synchronize_state(cpu_state);
191
--
1129
--
192
2.20.1
1130
2.20.1
193
1131
194
1132
diff view generated by jsdifflib
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
1
From: Alexander Graf <agraf@csgraf.de>
2
TLB. However we never actually use the TLB -- all stage 2 lookups
3
are done by direct calls to get_phys_addr_lpae() followed by a
4
physical address load via address_space_ld*().
5
2
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
3
The hooks we have that call us after reset, init and loadvm really all
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
4
just want to say "The reference of all register state is in the QEMU
8
MMU indexes.
5
vcpu struct, please push it".
9
6
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
7
We already have a working pushing mechanism though called cpu->vcpu_dirty,
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
8
so we can just reuse that for all of the above, syncing state properly the
12
permission bits to the stage 2 descriptors which define execute
9
next time we actually execute a vCPU.
13
permission separatel for EL0 and EL1; supporting that while keeping
14
Stage2 in a QEMU TLB would require us to use separate TLBs for
15
"Stage2 for an EL0 access" and "Stage2 for an EL1 access", which is a
16
lot of extra complication given we aren't even using the QEMU TLB.
17
10
18
In the process of updating the comment on our MMU index use,
11
This fixes PSCI resets on ARM, as they modify CPU state even after the
19
fix a couple of other minor errors:
12
post init call has completed, but before we execute the vCPU again.
20
* NS EL2 EL2&0 was missing from the list in the comment
21
* some text hadn't been updated from when we bumped NB_MMU_MODES
22
above 8
23
13
14
To also make the scheme work for x86, we have to make sure we don't
15
move stale eflags into our env when the vcpu state is dirty.
16
17
Signed-off-by: Alexander Graf <agraf@csgraf.de>
18
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
19
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
20
Reviewed-by: Sergio Lopez <slp@redhat.com>
21
Message-id: 20210519202253.76782-13-agraf@csgraf.de
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20200330210400.11724-2-peter.maydell@linaro.org
28
---
23
---
29
target/arm/cpu-param.h | 2 +-
24
accel/hvf/hvf-accel-ops.c | 27 +++++++--------------------
30
target/arm/cpu.h | 21 +++++---
25
target/i386/hvf/x86hvf.c | 5 ++++-
31
target/arm/helper.c | 112 ++++-------------------------------------
26
2 files changed, 11 insertions(+), 21 deletions(-)
32
3 files changed, 27 insertions(+), 108 deletions(-)
33
27
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
28
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
35
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
30
--- a/accel/hvf/hvf-accel-ops.c
37
+++ b/target/arm/cpu-param.h
31
+++ b/accel/hvf/hvf-accel-ops.c
38
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ static void hvf_cpu_synchronize_state(CPUState *cpu)
39
# define TARGET_PAGE_BITS_MIN 10
33
}
40
#endif
41
42
-#define NB_MMU_MODES 12
43
+#define NB_MMU_MODES 11
44
45
#endif
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
51
* handling via the TLB. The only way to do a stage 1 translation without
52
* the immediate stage 2 translation is via the ATS or AT system insns,
53
* which can be slow-pathed and always do a page table walk.
54
+ * The only use of stage 2 translations is either as part of an s1+2
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
56
+ * and in both those cases we don't use the TLB.
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
58
* translation regimes, because they map reasonably well to each other
59
* and they can't both be active at the same time.
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
62
* NS EL1 EL1&0 stage 1+2 +PAN
63
* NS EL0 EL2&0
64
+ * NS EL2 EL2&0
65
* NS EL2 EL2&0 +PAN
66
* NS EL2 (aka NS PL2)
67
* S EL0 EL1&0 (aka S PL0)
68
* S EL1 EL1&0 (not used if EL3 is 32 bit)
69
* S EL1 EL1&0 +PAN
70
* S EL3 (aka S PL1)
71
- * NS EL1&0 stage 2
72
*
73
- * for a total of 12 different mmu_idx.
74
+ * for a total of 11 different mmu_idx.
75
*
76
* R profile CPUs have an MPU, but can use the same set of MMU indexes
77
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
78
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
79
* are not quite the same -- different CPU types (most notably M profile
80
* vs A/R profile) would like to use MMU indexes with different semantics,
81
* but since we don't ever need to use all of those in a single CPU we
82
- * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
83
+ * can avoid having to set NB_MMU_MODES to "total number of A profile MMU
84
+ * modes + total number of M profile MMU modes". The lower bits of
85
* ARMMMUIdx are the core TLB mmu index, and the higher bits are always
86
* the same for any particular CPU.
87
* Variables of type ARMMUIdx are always full values, and the core
88
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
89
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
90
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
91
92
- ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
93
-
94
/*
95
* These are not allocated TLBs and are used only for AT system
96
* instructions or for the first stage of an S12 page table walk.
97
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
98
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
99
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
100
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
101
+ /*
102
+ * Not allocated a TLB: used only for second stage of an S12 page
103
+ * table walk, or for descriptor loads during first stage of an S1
104
+ * page table walk. Note that if we ever want to have a TLB for this
105
+ * then various TLB flush insns which currently are no-ops or flush
106
+ * only stage 1 MMU indexes will need to change to flush stage 2.
107
+ */
108
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
109
110
/*
111
* M-profile.
112
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
113
TO_CORE_BIT(SE10_1),
114
TO_CORE_BIT(SE10_1_PAN),
115
TO_CORE_BIT(SE3),
116
- TO_CORE_BIT(Stage2),
117
118
TO_CORE_BIT(MUser),
119
TO_CORE_BIT(MPriv),
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/target/arm/helper.c
123
+++ b/target/arm/helper.c
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
125
tlb_flush_by_mmuidx(cs,
126
ARMMMUIdxBit_E10_1 |
127
ARMMMUIdxBit_E10_1_PAN |
128
- ARMMMUIdxBit_E10_0 |
129
- ARMMMUIdxBit_Stage2);
130
+ ARMMMUIdxBit_E10_0);
131
}
34
}
132
35
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
36
-static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
37
- run_on_cpu_data arg)
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
38
+static void do_hvf_cpu_synchronize_set_dirty(CPUState *cpu,
136
ARMMMUIdxBit_E10_1 |
39
+ run_on_cpu_data arg)
137
ARMMMUIdxBit_E10_1_PAN |
40
{
138
- ARMMMUIdxBit_E10_0 |
41
- hvf_put_registers(cpu);
139
- ARMMMUIdxBit_Stage2);
42
- cpu->vcpu_dirty = false;
140
+ ARMMMUIdxBit_E10_0);
43
+ /* QEMU state is the reference, push it to HVF now and on next entry */
44
+ cpu->vcpu_dirty = true;
141
}
45
}
142
46
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
47
static void hvf_cpu_synchronize_post_reset(CPUState *cpu)
144
- uint64_t value)
48
{
145
-{
49
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
146
- /* Invalidate by IPA. This has to invalidate any structures that
147
- * contain only stage 2 translation information, but does not need
148
- * to apply to structures that contain combined stage 1 and stage 2
149
- * translation information.
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
151
- */
152
- CPUState *cs = env_cpu(env);
153
- uint64_t pageaddr;
154
-
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
156
- return;
157
- }
158
-
159
- pageaddr = sextract64(value << 12, 0, 40);
160
-
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
162
-}
50
-}
163
-
51
-
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
52
-static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
165
- uint64_t value)
53
- run_on_cpu_data arg)
166
-{
54
-{
167
- CPUState *cs = env_cpu(env);
55
- hvf_put_registers(cpu);
168
- uint64_t pageaddr;
56
- cpu->vcpu_dirty = false;
169
-
57
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL);
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
171
- return;
172
- }
173
-
174
- pageaddr = sextract64(value << 12, 0, 40);
175
-
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
177
- ARMMMUIdxBit_Stage2);
178
-}
179
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
uint64_t value)
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
tlb_flush_by_mmuidx(cs,
184
ARMMMUIdxBit_E10_1 |
185
ARMMMUIdxBit_E10_1_PAN |
186
- ARMMMUIdxBit_E10_0 |
187
- ARMMMUIdxBit_Stage2);
188
+ ARMMMUIdxBit_E10_0);
189
raw_write(env, ri, value);
190
}
191
}
58
}
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
59
193
return ARMMMUIdxBit_SE10_1 |
60
static void hvf_cpu_synchronize_post_init(CPUState *cpu)
194
ARMMMUIdxBit_SE10_1_PAN |
61
{
195
ARMMMUIdxBit_SE10_0;
62
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
197
- return ARMMMUIdxBit_E10_1 |
198
- ARMMMUIdxBit_E10_1_PAN |
199
- ARMMMUIdxBit_E10_0 |
200
- ARMMMUIdxBit_Stage2;
201
} else {
202
return ARMMMUIdxBit_E10_1 |
203
ARMMMUIdxBit_E10_1_PAN |
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
205
ARMMMUIdxBit_SE3);
206
}
207
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
209
- uint64_t value)
210
-{
211
- /* Invalidate by IPA. This has to invalidate any structures that
212
- * contain only stage 2 translation information, but does not need
213
- * to apply to structures that contain combined stage 1 and stage 2
214
- * translation information.
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
216
- */
217
- ARMCPU *cpu = env_archcpu(env);
218
- CPUState *cs = CPU(cpu);
219
- uint64_t pageaddr;
220
-
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
222
- return;
223
- }
224
-
225
- pageaddr = sextract64(value << 12, 0, 48);
226
-
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
228
-}
63
-}
229
-
64
-
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
65
-static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
231
- uint64_t value)
66
- run_on_cpu_data arg)
232
-{
67
-{
233
- CPUState *cs = env_cpu(env);
68
- cpu->vcpu_dirty = true;
234
- uint64_t pageaddr;
69
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL);
235
-
70
}
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
71
237
- return;
72
static void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
238
- }
239
-
240
- pageaddr = sextract64(value << 12, 0, 48);
241
-
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
243
- ARMMMUIdxBit_Stage2);
244
-}
245
-
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
247
bool isread)
248
{
73
{
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
74
- run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
250
.writefn = tlbi_aa64_vae1_write },
75
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL);
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
76
}
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
77
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
78
static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
254
- .writefn = tlbi_aa64_ipas2e1is_write },
79
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
255
+ .access = PL2_W, .type = ARM_CP_NOP },
80
index XXXXXXX..XXXXXXX 100644
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
81
--- a/target/i386/hvf/x86hvf.c
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
82
+++ b/target/i386/hvf/x86hvf.c
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
83
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
259
- .writefn = tlbi_aa64_ipas2e1is_write },
84
X86CPU *cpu = X86_CPU(cpu_state);
260
+ .access = PL2_W, .type = ARM_CP_NOP },
85
CPUX86State *env = &cpu->env;
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
86
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
87
- env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
88
+ if (!cpu_state->vcpu_dirty) {
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
89
+ /* light weight sync for CPU_INTERRUPT_HARD and IF_MASK */
265
.writefn = tlbi_aa64_alle1is_write },
90
+ env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
91
+ }
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
92
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
93
if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {
269
- .writefn = tlbi_aa64_ipas2e1_write },
94
cpu_synchronize_state(cpu_state);
270
+ .access = PL2_W, .type = ARM_CP_NOP },
271
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
272
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
273
- .access = PL2_W, .type = ARM_CP_NO_RAW,
274
- .writefn = tlbi_aa64_ipas2e1_write },
275
+ .access = PL2_W, .type = ARM_CP_NOP },
276
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
277
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
278
.access = PL2_W, .type = ARM_CP_NO_RAW,
279
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
280
.writefn = tlbimva_hyp_is_write },
281
{ .name = "TLBIIPAS2",
282
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
283
- .type = ARM_CP_NO_RAW, .access = PL2_W,
284
- .writefn = tlbiipas2_write },
285
+ .type = ARM_CP_NOP, .access = PL2_W },
286
{ .name = "TLBIIPAS2IS",
287
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
288
- .type = ARM_CP_NO_RAW, .access = PL2_W,
289
- .writefn = tlbiipas2_is_write },
290
+ .type = ARM_CP_NOP, .access = PL2_W },
291
{ .name = "TLBIIPAS2L",
292
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
293
- .type = ARM_CP_NO_RAW, .access = PL2_W,
294
- .writefn = tlbiipas2_write },
295
+ .type = ARM_CP_NOP, .access = PL2_W },
296
{ .name = "TLBIIPAS2LIS",
297
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
298
- .type = ARM_CP_NO_RAW, .access = PL2_W,
299
- .writefn = tlbiipas2_is_write },
300
+ .type = ARM_CP_NOP, .access = PL2_W },
301
/* 32 bit cache operations */
302
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
303
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
304
--
95
--
305
2.20.1
96
2.20.1
306
97
307
98
diff view generated by jsdifflib
New patch
1
Coverity notes that we don't check for dup2() failing. Add some
2
assertions so that if it does ever happen we get some indication.
3
(This is similar to how we handle other "don't expect this syscall to
4
fail" checks in this test code.)
1
5
6
Fixes: Coverity CID 1432346
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
9
Message-id: 20210525134458.6675-2-peter.maydell@linaro.org
10
---
11
tests/qtest/bios-tables-test.c | 8 ++++++--
12
1 file changed, 6 insertions(+), 2 deletions(-)
13
14
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qtest/bios-tables-test.c
17
+++ b/tests/qtest/bios-tables-test.c
18
@@ -XXX,XX +XXX,XX @@ static void test_acpi_asl(test_data *data)
19
exp_sdt->asl_file, sdt->asl_file);
20
int out = dup(STDOUT_FILENO);
21
int ret G_GNUC_UNUSED;
22
+ int dupret;
23
24
- dup2(STDERR_FILENO, STDOUT_FILENO);
25
+ g_assert(out >= 0);
26
+ dupret = dup2(STDERR_FILENO, STDOUT_FILENO);
27
+ g_assert(dupret >= 0);
28
ret = system(diff) ;
29
- dup2(out, STDOUT_FILENO);
30
+ dupret = dup2(out, STDOUT_FILENO);
31
+ g_assert(dupret >= 0);
32
close(out);
33
g_free(diff);
34
}
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
New patch
1
The e1000e_send_verify() test calls qemu_recv() but doesn't
2
check that the call succeeded, which annoys Coverity. Add
3
an explicit test check for the length of the data.
1
4
5
(This is a test check, not a "we assume this syscall always
6
succeeds", so we use g_assert_cmpint() rather than g_assert().)
7
8
Fixes: Coverity CID 1432324
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
11
Message-id: 20210525134458.6675-3-peter.maydell@linaro.org
12
---
13
tests/qtest/e1000e-test.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/tests/qtest/e1000e-test.c b/tests/qtest/e1000e-test.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qtest/e1000e-test.c
19
+++ b/tests/qtest/e1000e-test.c
20
@@ -XXX,XX +XXX,XX @@ static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a
21
/* Check data sent to the backend */
22
ret = qemu_recv(test_sockets[0], &recv_len, sizeof(recv_len), 0);
23
g_assert_cmpint(ret, == , sizeof(recv_len));
24
- qemu_recv(test_sockets[0], buffer, 64, 0);
25
+ ret = qemu_recv(test_sockets[0], buffer, 64, 0);
26
+ g_assert_cmpint(ret, >=, 5);
27
g_assert_cmpstr(buffer, == , "TEST");
28
29
/* Free test data buffer */
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
1
Coverity notices that the checks against mkstemp() failing in
2
whether the stage 1 access is for EL0 or not, because whether
2
create_qcow2_with_mbr() are wrong: mkstemp returns -1 on failure but
3
exec permission is given can depend on whether this is an EL0
3
the check is just "g_assert(fd)". Fix to use "g_assert(fd >= 0)",
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
4
matching the correct check in create_test_img().
5
the call sites can pass this information in.
6
5
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
6
Fixes: Coverity CID 1432274
8
add one so we have a place to put the documentation of the
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
semantics of the new s1_is_el0 argument.
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
10
Message-id: 20210525134458.6675-4-peter.maydell@linaro.org
11
---
12
tests/qtest/hd-geo-test.c | 4 ++--
13
1 file changed, 2 insertions(+), 2 deletions(-)
10
14
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
diff --git a/tests/qtest/hd-geo-test.c b/tests/qtest/hd-geo-test.c
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
15
---
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
17
1 file changed, 28 insertions(+), 1 deletion(-)
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
17
--- a/tests/qtest/hd-geo-test.c
22
+++ b/target/arm/helper.c
18
+++ b/tests/qtest/hd-geo-test.c
23
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors)
24
25
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
27
+ bool s1_is_el0,
28
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
29
target_ulong *page_size_ptr,
30
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
31
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
32
}
33
34
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
35
+ false,
36
&s2pa, &txattrs, &s2prot, &s2size, fi,
37
pcacheattrs);
38
if (ret) {
39
@@ -XXX,XX +XXX,XX @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
40
};
41
}
42
43
+/**
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
45
+ *
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
48
+ * information on why the translation aborted, in the format of a long-format
49
+ * DFSR/IFSR fault register, with the following caveats:
50
+ * * the WnR bit is never set (the caller must do this).
51
+ *
52
+ * @env: CPUARMState
53
+ * @address: virtual address to get physical address for
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
55
+ * @mmu_idx: MMU index indicating required translation regime
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
60
+ * @attrs: set to the memory transaction attributes to use
61
+ * @prot: set to the permissions for the page containing phys_ptr
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
63
+ * @fi: set to fault info if the translation fails
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
65
+ */
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
68
+ bool s1_is_el0,
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
70
target_ulong *page_size_ptr,
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
73
74
/* S1 is done. Now do S2 translation. */
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
76
+ mmu_idx == ARMMMUIdx_E10_0,
77
phys_ptr, attrs, &s2_prot,
78
page_size, fi,
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
81
}
20
}
82
21
83
if (regime_using_lpae_format(env, mmu_idx)) {
22
fd = mkstemp(raw_path);
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
23
- g_assert(fd);
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
24
+ g_assert(fd >= 0);
86
phys_ptr, attrs, prot, page_size,
25
close(fd);
87
fi, cacheattrs);
26
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
27
fd = open(raw_path, O_WRONLY);
28
@@ -XXX,XX +XXX,XX @@ static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors)
29
close(fd);
30
31
fd = mkstemp(qcow2_path);
32
- g_assert(fd);
33
+ g_assert(fd >= 0);
34
close(fd);
35
36
qemu_img_path = getenv("QTEST_QEMU_IMG");
89
--
37
--
90
2.20.1
38
2.20.1
91
39
92
40
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
Coverity points out that we calculate a 64-bit value using 32-bit
2
arithmetic; add the cast to force the multiply to be done as 64-bits.
3
(The overflow will never happen with the current test data.)
2
4
3
Move misplaced comment.
5
Fixes: Coverity CID 1432320
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-3-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
9
Message-id: 20210525134458.6675-5-peter.maydell@linaro.org
11
---
10
---
12
hw/arm/xlnx-versal.c | 2 +-
11
tests/qtest/pflash-cfi02-test.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
13
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
14
diff --git a/tests/qtest/pflash-cfi02-test.c b/tests/qtest/pflash-cfi02-test.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
16
--- a/tests/qtest/pflash-cfi02-test.c
18
+++ b/hw/arm/xlnx-versal.c
17
+++ b/tests/qtest/pflash-cfi02-test.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
18
@@ -XXX,XX +XXX,XX @@ static void test_geometry(const void *opaque)
20
19
21
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
20
for (int region = 0; region < nb_erase_regions; ++region) {
22
if (!obj) {
21
for (uint32_t i = 0; i < c->nb_blocs[region]; ++i) {
23
- /* Secondary CPUs start in PSCI powered-down state */
22
- uint64_t byte_addr = i * c->sector_len[region];
24
error_report("Unable to create apu.cpu[%d] of type %s",
23
+ uint64_t byte_addr = (uint64_t)i * c->sector_len[region];
25
i, XLNX_VERSAL_ACPU_TYPE);
24
g_assert_cmphex(flash_read(c, byte_addr), ==, bank_mask(c));
26
exit(EXIT_FAILURE);
27
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
28
object_property_set_int(obj, s->cfg.psci_conduit,
29
"psci-conduit", &error_abort);
30
if (i) {
31
+ /* Secondary CPUs start in PSCI powered-down state */
32
object_property_set_bool(obj, true,
33
"start-powered-off", &error_abort);
34
}
25
}
26
}
35
--
27
--
36
2.20.1
28
2.20.1
37
29
38
30
diff view generated by jsdifflib
1
We were accidentally permitting decode of Thumb Neon insns even if
1
Coverity points out that in tpm_test_swtpm_migration_test() we
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
2
assume that src_tpm_addr and dst_tpm_addr are non-NULL (we
3
check was being done before the call to disas_neon_data_insn() and
3
pass them to tpm_util_migration_start_qemu() which will
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
4
unconditionally dereference them) but then later explicitly
5
Thumb decoder. Push the feature bit check down into the called
5
check them for NULL. Remove the pointless checks.
6
functions so it is done for both Arm and Thumb encodings.
6
7
Fixes: Coverity CID 1432367, 1432359
7
8
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
12
Message-id: 20210525134458.6675-6-peter.maydell@linaro.org
12
---
13
---
13
target/arm/translate.c | 16 ++++++++--------
14
tests/qtest/tpm-tests.c | 12 ++++--------
14
1 file changed, 8 insertions(+), 8 deletions(-)
15
1 file changed, 4 insertions(+), 8 deletions(-)
15
16
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/tests/qtest/tpm-tests.c b/tests/qtest/tpm-tests.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
19
--- a/tests/qtest/tpm-tests.c
19
+++ b/target/arm/translate.c
20
+++ b/tests/qtest/tpm-tests.c
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ void tpm_test_swtpm_migration_test(const char *src_tpm_path,
21
TCGv_i32 tmp2;
22
qtest_quit(src_qemu);
22
TCGv_i64 tmp64;
23
23
24
tpm_util_swtpm_kill(dst_tpm_pid);
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
25
- if (dst_tpm_addr) {
25
+ return 1;
26
- g_unlink(dst_tpm_addr->u.q_unix.path);
26
+ }
27
- qapi_free_SocketAddress(dst_tpm_addr);
27
+
28
- }
28
/* FIXME: this access check should not take precedence over UNDEF
29
+ g_unlink(dst_tpm_addr->u.q_unix.path);
29
* for invalid encodings; we will generate incorrect syndrome information
30
+ qapi_free_SocketAddress(dst_tpm_addr);
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
31
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
32
tpm_util_swtpm_kill(src_tpm_pid);
32
TCGv_ptr ptr1, ptr2, ptr3;
33
- if (src_tpm_addr) {
33
TCGv_i64 tmp64;
34
- g_unlink(src_tpm_addr->u.q_unix.path);
34
35
- qapi_free_SocketAddress(src_tpm_addr);
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
36
- }
36
+ return 1;
37
+ g_unlink(src_tpm_addr->u.q_unix.path);
37
+ }
38
+ qapi_free_SocketAddress(src_tpm_addr);
38
+
39
}
39
/* FIXME: this access check should not take precedence over UNDEF
40
* for invalid encodings; we will generate incorrect syndrome information
41
* for attempts to execute invalid vfp/neon encodings with FP disabled.
42
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
43
44
if (((insn >> 25) & 7) == 1) {
45
/* NEON Data processing. */
46
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
- goto illegal_op;
48
- }
49
-
50
if (disas_neon_data_insn(s, insn)) {
51
goto illegal_op;
52
}
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
54
}
55
if ((insn & 0x0f100000) == 0x04000000) {
56
/* NEON load/store. */
57
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
58
- goto illegal_op;
59
- }
60
-
61
if (disas_neon_ls_insn(s, insn)) {
62
goto illegal_op;
63
}
64
--
40
--
65
2.20.1
41
2.20.1
66
42
67
43
diff view generated by jsdifflib
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
1
Coverity complains that we don't check for failures from dup()
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
2
and mkstemp(); add asserts that these syscalls succeeded.
3
call it in S1_ptw_translate().
4
3
4
Fixes: Coverity CID 1432516, 1432574
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.org
8
Message-id: 20210525134458.6675-7-peter.maydell@linaro.org
9
---
9
---
10
target/arm/helper.c | 5 +++--
10
tests/unit/test-vmstate.c | 5 ++++-
11
1 file changed, 3 insertions(+), 2 deletions(-)
11
1 file changed, 4 insertions(+), 1 deletion(-)
12
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/tests/unit/test-vmstate.c b/tests/unit/test-vmstate.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
15
--- a/tests/unit/test-vmstate.c
16
+++ b/target/arm/helper.c
16
+++ b/tests/unit/test-vmstate.c
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
17
@@ -XXX,XX +XXX,XX @@ static int temp_fd;
18
pcacheattrs = &cacheattrs;
18
/* Duplicate temp_fd and seek to the beginning of the file */
19
}
19
static QEMUFile *open_test_file(bool write)
20
20
{
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
21
- int fd = dup(temp_fd);
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
22
+ int fd;
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
23
QIOChannel *ioc;
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
24
QEMUFile *f;
25
+ pcacheattrs);
25
26
if (ret) {
26
+ fd = dup(temp_fd);
27
assert(fi->type != ARMFault_None);
27
+ g_assert(fd >= 0);
28
fi->s2addr = addr;
28
lseek(fd, 0, SEEK_SET);
29
if (write) {
30
g_assert_cmpint(ftruncate(fd, 0), ==, 0);
31
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
32
g_autofree char *temp_file = g_strdup_printf("%s/vmst.test.XXXXXX",
33
g_get_tmp_dir());
34
temp_fd = mkstemp(temp_file);
35
+ g_assert(temp_fd >= 0);
36
37
module_call_init(MODULE_INIT_QOM);
38
29
--
39
--
30
2.20.1
40
2.20.1
31
41
32
42
diff view generated by jsdifflib