1
Another lump of target-arm patches. I still have some patches in
1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
2
my to-review queue, but this is a big enough set that I wanted
3
to send it out.
4
2
5
thanks
3
thanks
6
-- PMM
4
-- PMM
7
5
8
The following changes since commit 04bb7fe2bf55bdf66d5b7a5a719b40bbb4048178:
9
6
10
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20180208' into staging (2018-02-08 17:41:15 +0000)
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)
11
10
12
are available in the Git repository at:
11
are available in the Git repository at:
13
12
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180209
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
15
14
16
for you to fetch changes up to bbba7757bacc9f890a3f028d328b4b429dbe78ec:
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
17
16
18
hw/core/generic-loader: Allow PC to be set on command line (2018-02-09 10:55:40 +0000)
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
19
18
20
----------------------------------------------------------------
19
----------------------------------------------------------------
21
target-arm queue:
20
target-arm queue:
22
* Support M profile derived exceptions on exception entry and exit
21
* Start of conversion of Neon insns to decodetree
23
* Implement AArch64 v8.2 crypto insns (SHA-512, SHA-3, SM3, SM4)
22
* versal board: support SD and RTC
24
* Implement working i.MX6 SD controller
23
* Implement ARMv8.2-TTS2UXN
25
* Various devices preparatory to i.MX7 support
24
* Make VQDMULL undefined when U=1
26
* Preparatory patches for SVE emulation
25
* Some minor code cleanups
27
* v8M: Fix bug in implementation of 'TT' insn
28
* Give useful error if user tries to use userspace GICv3 with KVM
29
26
30
----------------------------------------------------------------
27
----------------------------------------------------------------
31
Andrey Smirnov (10):
28
Edgar E. Iglesias (11):
32
sdhci: Add i.MX specific subtype of SDHCI
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
33
hw: i.MX: Convert i.MX6 to use TYPE_IMX_USDHC
30
hw/arm: versal: Move misplaced comment
34
i.MX: Add code to emulate i.MX7 CCM, PMU and ANALOG IP blocks
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
35
i.MX: Add code to emulate i.MX2 watchdog IP block
32
hw/arm: versal: Embed the UARTs into the SoC type
36
i.MX: Add code to emulate i.MX7 SNVS IP-block
33
hw/arm: versal: Embed the GEMs into the SoC type
37
i.MX: Add code to emulate GPCv2 IP block
34
hw/arm: versal: Embed the ADMAs into the SoC type
38
i.MX: Add i.MX7 GPT variant
35
hw/arm: versal: Embed the APUs into the SoC type
39
i.MX: Add implementation of i.MX7 GPR IP block
36
hw/arm: versal: Add support for SD
40
usb: Add basic code to emulate Chipidea USB IP
37
hw/arm: versal: Add support for the RTC
41
hw/arm: Move virt's PSCI DT fixup code to arm/boot.c
38
hw/arm: versal-virt: Add support for SD
39
hw/arm: versal-virt: Add support for the RTC
42
40
43
Ard Biesheuvel (5):
41
Fredrik Strupe (1):
44
target/arm: implement SHA-512 instructions
42
target/arm: Make VQDMULL undefined when U=1
45
target/arm: implement SHA-3 instructions
46
target/arm: implement SM3 instructions
47
target/arm: implement SM4 instructions
48
target/arm: enable user-mode SHA-3, SM3, SM4 and SHA-512 instruction support
49
43
50
Christoffer Dall (1):
44
Peter Maydell (25):
51
target/arm/kvm: gic: Prevent creating userspace GICv3 with KVM
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
46
target/arm: Use enum constant in get_phys_addr_lpae() call
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
48
target/arm: Implement ARMv8.2-TTS2UXN
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
52
70
53
Peter Maydell (9):
71
Philippe Mathieu-Daudé (2):
54
target/arm: Add armv7m_nvic_set_pending_derived()
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
55
target/arm: Split "get pending exception info" from "acknowledge it"
73
target/arm: Use uint64_t for midr field in CPU state struct
56
target/arm: Add ignore_stackfaults argument to v7m_exception_taken()
57
target/arm: Make v7M exception entry stack push check MPU
58
target/arm: Make v7m_push_callee_stack() honour MPU
59
target/arm: Make exception vector loads honour the SAU
60
target/arm: Handle exceptions during exception stack pop
61
target/arm/translate.c: Fix missing 'break' for TT insns
62
hw/core/generic-loader: Allow PC to be set on command line
63
74
64
Richard Henderson (5):
75
include/hw/arm/xlnx-versal.h | 31 +-
65
target/arm: Expand vector registers for SVE
76
target/arm/cpu-param.h | 2 +-
66
target/arm: Add predicate registers for SVE
77
target/arm/cpu.h | 38 ++-
67
target/arm: Add SVE to migration state
78
target/arm/translate-a64.h | 9 -
68
target/arm: Add ZCR_ELx
79
target/arm/translate.h | 26 ++
69
target/arm: Add SVE state to TB->FLAGS
80
target/arm/neon-dp.decode | 86 +++++
81
target/arm/neon-ls.decode | 52 +++
82
target/arm/neon-shared.decode | 66 ++++
83
hw/arm/mps2-tz.c | 2 +-
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
85
hw/arm/xlnx-versal.c | 115 +++++--
86
target/arm/cpu.c | 3 +-
87
target/arm/cpu64.c | 8 +-
88
target/arm/helper.c | 183 ++++------
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
70
99
71
hw/intc/Makefile.objs | 2 +-
72
hw/misc/Makefile.objs | 4 +
73
hw/usb/Makefile.objs | 1 +
74
hw/sd/sdhci-internal.h | 23 ++
75
include/hw/intc/imx_gpcv2.h | 22 ++
76
include/hw/misc/imx2_wdt.h | 33 +++
77
include/hw/misc/imx7_ccm.h | 139 +++++++++++
78
include/hw/misc/imx7_gpr.h | 28 +++
79
include/hw/misc/imx7_snvs.h | 35 +++
80
include/hw/sd/sdhci.h | 13 ++
81
include/hw/timer/imx_gpt.h | 1 +
82
include/hw/usb/chipidea.h | 16 ++
83
target/arm/cpu.h | 120 ++++++++--
84
target/arm/helper.h | 12 +
85
target/arm/kvm_arm.h | 4 +
86
target/arm/translate.h | 2 +
87
hw/arm/boot.c | 65 ++++++
88
hw/arm/fsl-imx6.c | 2 +-
89
hw/arm/virt.c | 61 -----
90
hw/core/generic-loader.c | 2 +-
91
hw/intc/armv7m_nvic.c | 98 +++++++-
92
hw/intc/imx_gpcv2.c | 125 ++++++++++
93
hw/misc/imx2_wdt.c | 89 +++++++
94
hw/misc/imx7_ccm.c | 277 ++++++++++++++++++++++
95
hw/misc/imx7_gpr.c | 124 ++++++++++
96
hw/misc/imx7_snvs.c | 83 +++++++
97
hw/sd/sdhci.c | 230 ++++++++++++++++++-
98
hw/timer/imx_gpt.c | 25 ++
99
hw/usb/chipidea.c | 176 ++++++++++++++
100
linux-user/elfload.c | 19 ++
101
target/arm/cpu64.c | 4 +
102
target/arm/crypto_helper.c | 277 +++++++++++++++++++++-
103
target/arm/helper.c | 548 +++++++++++++++++++++++++++++++++++++-------
104
target/arm/machine.c | 88 ++++++-
105
target/arm/translate-a64.c | 350 +++++++++++++++++++++++++++-
106
target/arm/translate.c | 8 +-
107
hw/intc/trace-events | 5 +-
108
hw/misc/trace-events | 4 +
109
38 files changed, 2928 insertions(+), 187 deletions(-)
110
create mode 100644 include/hw/intc/imx_gpcv2.h
111
create mode 100644 include/hw/misc/imx2_wdt.h
112
create mode 100644 include/hw/misc/imx7_ccm.h
113
create mode 100644 include/hw/misc/imx7_gpr.h
114
create mode 100644 include/hw/misc/imx7_snvs.h
115
create mode 100644 include/hw/usb/chipidea.h
116
create mode 100644 hw/intc/imx_gpcv2.c
117
create mode 100644 hw/misc/imx2_wdt.c
118
create mode 100644 hw/misc/imx7_ccm.c
119
create mode 100644 hw/misc/imx7_gpr.c
120
create mode 100644 hw/misc/imx7_snvs.c
121
create mode 100644 hw/usb/chipidea.c
122
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fredrik Strupe <fredrik@strupe.net>
2
2
3
Change vfp.regs as a uint64_t to vfp.zregs as an ARMVectorReg.
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
4
The previous patches have made the change in representation
4
U=1 is unallocated.
5
relatively painless.
6
5
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20180123035349.24538-2-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/cpu.h | 59 +++++++++++++++++++++++++++++++---------------
11
target/arm/translate.c | 2 +-
14
target/arm/machine.c | 35 ++++++++++++++++++++++++++-
12
1 file changed, 1 insertion(+), 1 deletion(-)
15
target/arm/translate-a64.c | 8 +++----
16
target/arm/translate.c | 7 +++---
17
4 files changed, 81 insertions(+), 28 deletions(-)
18
13
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
24
uint32_t base_mask;
25
} TCR;
26
27
+/* Define a maximum sized vector register.
28
+ * For 32-bit, this is a 128-bit NEON/AdvSIMD register.
29
+ * For 64-bit, this is a 2048-bit SVE register.
30
+ *
31
+ * Note that the mapping between S, D, and Q views of the register bank
32
+ * differs between AArch64 and AArch32.
33
+ * In AArch32:
34
+ * Qn = regs[n].d[1]:regs[n].d[0]
35
+ * Dn = regs[n / 2].d[n & 1]
36
+ * Sn = regs[n / 4].d[n % 4 / 2],
37
+ * bits 31..0 for even n, and bits 63..32 for odd n
38
+ * (and regs[16] to regs[31] are inaccessible)
39
+ * In AArch64:
40
+ * Zn = regs[n].d[*]
41
+ * Qn = regs[n].d[1]:regs[n].d[0]
42
+ * Dn = regs[n].d[0]
43
+ * Sn = regs[n].d[0] bits 31..0
44
+ *
45
+ * This corresponds to the architecturally defined mapping between
46
+ * the two execution states, and means we do not need to explicitly
47
+ * map these registers when changing states.
48
+ *
49
+ * Align the data for use with TCG host vector operations.
50
+ */
51
+
52
+#ifdef TARGET_AARCH64
53
+# define ARM_MAX_VQ 16
54
+#else
55
+# define ARM_MAX_VQ 1
56
+#endif
57
+
58
+typedef struct ARMVectorReg {
59
+ uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
60
+} ARMVectorReg;
61
+
62
+
63
typedef struct CPUARMState {
64
/* Regs for current mode. */
65
uint32_t regs[16];
66
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
67
68
/* VFP coprocessor state. */
69
struct {
70
- /* VFP/Neon register state. Note that the mapping between S, D and Q
71
- * views of the register bank differs between AArch64 and AArch32:
72
- * In AArch32:
73
- * Qn = regs[2n+1]:regs[2n]
74
- * Dn = regs[n]
75
- * Sn = regs[n/2] bits 31..0 for even n, and bits 63..32 for odd n
76
- * (and regs[32] to regs[63] are inaccessible)
77
- * In AArch64:
78
- * Qn = regs[2n+1]:regs[2n]
79
- * Dn = regs[2n]
80
- * Sn = regs[2n] bits 31..0
81
- * This corresponds to the architecturally defined mapping between
82
- * the two execution states, and means we do not need to explicitly
83
- * map these registers when changing states.
84
- */
85
- uint64_t regs[64] QEMU_ALIGNED(16);
86
+ ARMVectorReg zregs[32];
87
88
uint32_t xregs[16];
89
/* We store these fpcsr fields separately for convenience. */
90
@@ -XXX,XX +XXX,XX @@ static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
91
*/
92
static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
93
{
94
- return &env->vfp.regs[regno];
95
+ return &env->vfp.zregs[regno >> 1].d[regno & 1];
96
}
97
98
/**
99
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
100
*/
101
static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
102
{
103
- return &env->vfp.regs[2 * regno];
104
+ return &env->vfp.zregs[regno].d[0];
105
}
106
107
/**
108
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
109
*/
110
static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
111
{
112
- return &env->vfp.regs[2 * regno];
113
+ return &env->vfp.zregs[regno].d[0];
114
}
115
116
#endif
117
diff --git a/target/arm/machine.c b/target/arm/machine.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/machine.c
120
+++ b/target/arm/machine.c
121
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_vfp = {
122
.minimum_version_id = 3,
123
.needed = vfp_needed,
124
.fields = (VMStateField[]) {
125
- VMSTATE_UINT64_ARRAY(env.vfp.regs, ARMCPU, 64),
126
+ /* For compatibility, store Qn out of Zn here. */
127
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[0].d, ARMCPU, 0, 2),
128
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[1].d, ARMCPU, 0, 2),
129
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[2].d, ARMCPU, 0, 2),
130
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[3].d, ARMCPU, 0, 2),
131
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[4].d, ARMCPU, 0, 2),
132
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[5].d, ARMCPU, 0, 2),
133
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[6].d, ARMCPU, 0, 2),
134
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[7].d, ARMCPU, 0, 2),
135
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[8].d, ARMCPU, 0, 2),
136
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[9].d, ARMCPU, 0, 2),
137
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[10].d, ARMCPU, 0, 2),
138
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[11].d, ARMCPU, 0, 2),
139
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[12].d, ARMCPU, 0, 2),
140
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[13].d, ARMCPU, 0, 2),
141
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[14].d, ARMCPU, 0, 2),
142
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[15].d, ARMCPU, 0, 2),
143
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[16].d, ARMCPU, 0, 2),
144
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[17].d, ARMCPU, 0, 2),
145
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[18].d, ARMCPU, 0, 2),
146
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[19].d, ARMCPU, 0, 2),
147
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[20].d, ARMCPU, 0, 2),
148
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[21].d, ARMCPU, 0, 2),
149
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[22].d, ARMCPU, 0, 2),
150
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[23].d, ARMCPU, 0, 2),
151
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[24].d, ARMCPU, 0, 2),
152
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[25].d, ARMCPU, 0, 2),
153
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[26].d, ARMCPU, 0, 2),
154
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[27].d, ARMCPU, 0, 2),
155
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[28].d, ARMCPU, 0, 2),
156
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[29].d, ARMCPU, 0, 2),
157
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[30].d, ARMCPU, 0, 2),
158
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[31].d, ARMCPU, 0, 2),
159
+
160
/* The xregs array is a little awkward because element 1 (FPSCR)
161
* requires a specific accessor, so we have to split it up in
162
* the vmstate:
163
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/translate-a64.c
166
+++ b/target/arm/translate-a64.c
167
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
168
{
169
int offs = 0;
170
#ifdef HOST_WORDS_BIGENDIAN
171
- /* This is complicated slightly because vfp.regs[2n] is
172
- * still the low half and vfp.regs[2n+1] the high half
173
+ /* This is complicated slightly because vfp.zregs[n].d[0] is
174
+ * still the low half and vfp.zregs[n].d[1] the high half
175
* of the 128 bit vector, even on big endian systems.
176
* Calculate the offset assuming a fully bigendian 128 bits,
177
* then XOR to account for the order of the two 64 bit halves.
178
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
179
#else
180
offs += element * (1 << size);
181
#endif
182
- offs += offsetof(CPUARMState, vfp.regs[regno * 2]);
183
+ offs += offsetof(CPUARMState, vfp.zregs[regno]);
184
assert_fp_access_checked(s);
185
return offs;
186
}
187
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
188
static inline int vec_full_reg_offset(DisasContext *s, int regno)
189
{
190
assert_fp_access_checked(s);
191
- return offsetof(CPUARMState, vfp.regs[regno * 2]);
192
+ return offsetof(CPUARMState, vfp.zregs[regno]);
193
}
194
195
/* Return a newly allocated pointer to the vector register. */
196
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
197
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
198
--- a/target/arm/translate.c
16
--- a/target/arm/translate.c
199
+++ b/target/arm/translate.c
17
+++ b/target/arm/translate.c
200
@@ -XXX,XX +XXX,XX @@ static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
201
}
19
{0, 0, 0, 0}, /* VMLSL */
202
}
20
{0, 0, 0, 9}, /* VQDMLSL */
203
21
{0, 0, 0, 0}, /* Integer VMULL */
204
-static inline long
22
- {0, 0, 0, 1}, /* VQDMULL */
205
-vfp_reg_offset (int dp, int reg)
23
+ {0, 0, 0, 9}, /* VQDMULL */
206
+static inline long vfp_reg_offset(bool dp, unsigned reg)
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
207
{
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
208
if (dp) {
26
};
209
- return offsetof(CPUARMState, vfp.regs[reg]);
210
+ return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
211
} else {
212
- long ofs = offsetof(CPUARMState, vfp.regs[reg >> 1]);
213
+ long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
214
if (reg & 1) {
215
ofs += offsetof(CPU_DoubleU, l.upper);
216
} else {
217
--
27
--
218
2.16.1
28
2.20.1
219
29
220
30
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
By using the TYPE_* definitions for devices, we can:
4
- quickly find where devices are used with 'git-grep'
5
- easily rename a device (one-line change).
6
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/mps2-tz.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
18
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
20
exit(EXIT_FAILURE);
21
}
22
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
25
sizeof(mms->iotkit), mmc->armsse_type);
26
iotkitdev = DEVICE(&mms->iotkit);
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
2
2
TLB. However we never actually use the TLB -- all stage 2 lookups
3
Define ZCR_EL[1-3].
3
are done by direct calls to get_phys_addr_lpae() followed by a
4
4
physical address load via address_space_ld*().
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
7
Message-id: 20180123035349.24538-5-richard.henderson@linaro.org
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
8
MMU indexes.
9
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
12
permission bits to the stage 2 descriptors which define execute
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
18
In the process of updating the comment on our MMU index use,
19
fix a couple of other minor errors:
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
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
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
9
---
28
---
10
target/arm/cpu.h | 5 ++
29
target/arm/cpu-param.h | 2 +-
11
target/arm/helper.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++
30
target/arm/cpu.h | 21 +++++---
12
2 files changed, 136 insertions(+)
31
target/arm/helper.c | 112 ++++-------------------------------------
13
32
3 files changed, 27 insertions(+), 108 deletions(-)
33
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
37
+++ b/target/arm/cpu-param.h
38
@@ -XXX,XX +XXX,XX @@
39
# define TARGET_PAGE_BITS_MIN 10
40
#endif
41
42
-#define NB_MMU_MODES 12
43
+#define NB_MMU_MODES 11
44
45
#endif
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
48
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
19
*/
51
* handling via the TLB. The only way to do a stage 1 translation without
20
float_status fp_status;
52
* the immediate stage 2 translation is via the ATS or AT system insns,
21
float_status standard_fp_status;
53
* which can be slow-pathed and always do a page table walk.
22
+
54
+ * The only use of stage 2 translations is either as part of an s1+2
23
+ /* ZCR_EL[1-3] */
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
24
+ uint64_t zcr_el[4];
56
+ * and in both those cases we don't use the TLB.
25
} vfp;
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
26
uint64_t exclusive_addr;
58
* translation regimes, because they map reasonably well to each other
27
uint64_t exclusive_val;
59
* and they can't both be active at the same time.
28
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
29
#define CPTR_TCPAC (1U << 31)
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
30
#define CPTR_TTA (1U << 20)
62
* NS EL1 EL1&0 stage 1+2 +PAN
31
#define CPTR_TFP (1U << 10)
63
* NS EL0 EL2&0
32
+#define CPTR_TZ (1U << 8) /* CPTR_EL2 */
64
+ * NS EL2 EL2&0
33
+#define CPTR_EZ (1U << 8) /* CPTR_EL3 */
65
* NS EL2 EL2&0 +PAN
34
66
* NS EL2 (aka NS PL2)
35
#define MDCR_EPMAD (1U << 21)
67
* S EL0 EL1&0 (aka S PL0)
36
#define MDCR_EDAD (1U << 20)
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),
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
121
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
122
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
123
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
42
REGINFO_SENTINEL
125
tlb_flush_by_mmuidx(cs,
43
};
126
ARMMMUIdxBit_E10_1 |
44
127
ARMMMUIdxBit_E10_1_PAN |
45
+/* Return the exception level to which SVE-disabled exceptions should
128
- ARMMMUIdxBit_E10_0 |
46
+ * be taken, or 0 if SVE is enabled.
129
- ARMMMUIdxBit_Stage2);
47
+ */
130
+ ARMMMUIdxBit_E10_0);
48
+static int sve_exception_el(CPUARMState *env)
131
}
49
+{
132
50
+#ifndef CONFIG_USER_ONLY
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
51
+ unsigned current_el = arm_current_el(env);
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
52
+
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
53
+ /* The CPACR.ZEN controls traps to EL1:
136
ARMMMUIdxBit_E10_1 |
54
+ * 0, 2 : trap EL0 and EL1 accesses
137
ARMMMUIdxBit_E10_1_PAN |
55
+ * 1 : trap only EL0 accesses
138
- ARMMMUIdxBit_E10_0 |
56
+ * 3 : trap no accesses
139
- ARMMMUIdxBit_Stage2);
57
+ */
140
+ ARMMMUIdxBit_E10_0);
58
+ switch (extract32(env->cp15.cpacr_el1, 16, 2)) {
141
}
59
+ default:
142
60
+ if (current_el <= 1) {
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
61
+ /* Trap to PL1, which might be EL1 or EL3 */
144
- uint64_t value)
62
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
145
-{
63
+ return 3;
146
- /* Invalidate by IPA. This has to invalidate any structures that
64
+ }
147
- * contain only stage 2 translation information, but does not need
65
+ return 1;
148
- * to apply to structures that contain combined stage 1 and stage 2
66
+ }
149
- * translation information.
67
+ break;
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
68
+ case 1:
151
- */
69
+ if (current_el == 0) {
152
- CPUState *cs = env_cpu(env);
70
+ return 1;
153
- uint64_t pageaddr;
71
+ }
154
-
72
+ break;
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
73
+ case 3:
156
- return;
74
+ break;
157
- }
75
+ }
158
-
76
+
159
- pageaddr = sextract64(value << 12, 0, 40);
77
+ /* Similarly for CPACR.FPEN, after having checked ZEN. */
160
-
78
+ switch (extract32(env->cp15.cpacr_el1, 20, 2)) {
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
79
+ default:
162
-}
80
+ if (current_el <= 1) {
163
-
81
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
82
+ return 3;
165
- uint64_t value)
83
+ }
166
-{
84
+ return 1;
167
- CPUState *cs = env_cpu(env);
85
+ }
168
- uint64_t pageaddr;
86
+ break;
169
-
87
+ case 1:
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
88
+ if (current_el == 0) {
171
- return;
89
+ return 1;
172
- }
90
+ }
173
-
91
+ break;
174
- pageaddr = sextract64(value << 12, 0, 40);
92
+ case 3:
175
-
93
+ break;
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
94
+ }
177
- ARMMMUIdxBit_Stage2);
95
+
178
-}
96
+ /* CPTR_EL2. Check both TZ and TFP. */
179
97
+ if (current_el <= 2
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
98
+ && (env->cp15.cptr_el[2] & (CPTR_TFP | CPTR_TZ))
181
uint64_t value)
99
+ && !arm_is_secure_below_el3(env)) {
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
100
+ return 2;
183
tlb_flush_by_mmuidx(cs,
101
+ }
184
ARMMMUIdxBit_E10_1 |
102
+
185
ARMMMUIdxBit_E10_1_PAN |
103
+ /* CPTR_EL3. Check both EZ and TFP. */
186
- ARMMMUIdxBit_E10_0 |
104
+ if (!(env->cp15.cptr_el[3] & CPTR_EZ)
187
- ARMMMUIdxBit_Stage2);
105
+ || (env->cp15.cptr_el[3] & CPTR_TFP)) {
188
+ ARMMMUIdxBit_E10_0);
106
+ return 3;
189
raw_write(env, ri, value);
107
+ }
190
}
108
+#endif
191
}
109
+ return 0;
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
110
+}
193
return ARMMMUIdxBit_SE10_1 |
111
+
194
ARMMMUIdxBit_SE10_1_PAN |
112
+static CPAccessResult zcr_access(CPUARMState *env, const ARMCPRegInfo *ri,
195
ARMMMUIdxBit_SE10_0;
113
+ bool isread)
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
114
+{
197
- return ARMMMUIdxBit_E10_1 |
115
+ switch (sve_exception_el(env)) {
198
- ARMMMUIdxBit_E10_1_PAN |
116
+ case 3:
199
- ARMMMUIdxBit_E10_0 |
117
+ return CP_ACCESS_TRAP_EL3;
200
- ARMMMUIdxBit_Stage2;
118
+ case 2:
201
} else {
119
+ return CP_ACCESS_TRAP_EL2;
202
return ARMMMUIdxBit_E10_1 |
120
+ case 1:
203
ARMMMUIdxBit_E10_1_PAN |
121
+ return CP_ACCESS_TRAP;
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
122
+ }
205
ARMMMUIdxBit_SE3);
123
+ return CP_ACCESS_OK;
206
}
124
+}
207
125
+
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
126
+static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
209
- uint64_t value)
127
+ uint64_t value)
210
-{
128
+{
211
- /* Invalidate by IPA. This has to invalidate any structures that
129
+ /* Bits other than [3:0] are RAZ/WI. */
212
- * contain only stage 2 translation information, but does not need
130
+ raw_write(env, ri, value & 0xf);
213
- * to apply to structures that contain combined stage 1 and stage 2
131
+}
214
- * translation information.
132
+
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
133
+static const ARMCPRegInfo zcr_el1_reginfo = {
216
- */
134
+ .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
217
- ARMCPU *cpu = env_archcpu(env);
135
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
218
- CPUState *cs = CPU(cpu);
136
+ .access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
219
- uint64_t pageaddr;
137
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
220
-
138
+ .writefn = zcr_write, .raw_writefn = raw_write
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
139
+};
222
- return;
140
+
223
- }
141
+static const ARMCPRegInfo zcr_el2_reginfo = {
224
-
142
+ .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
225
- pageaddr = sextract64(value << 12, 0, 48);
143
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
226
-
144
+ .access = PL2_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
145
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
228
-}
146
+ .writefn = zcr_write, .raw_writefn = raw_write
229
-
147
+};
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
148
+
231
- uint64_t value)
149
+static const ARMCPRegInfo zcr_no_el2_reginfo = {
232
-{
150
+ .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
233
- CPUState *cs = env_cpu(env);
151
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
234
- uint64_t pageaddr;
152
+ .access = PL2_RW, .type = ARM_CP_64BIT,
235
-
153
+ .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
154
+};
237
- return;
155
+
238
- }
156
+static const ARMCPRegInfo zcr_el3_reginfo = {
239
-
157
+ .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
240
- pageaddr = sextract64(value << 12, 0, 48);
158
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
241
-
159
+ .access = PL3_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
160
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
243
- ARMMMUIdxBit_Stage2);
161
+ .writefn = zcr_write, .raw_writefn = raw_write
244
-}
162
+};
245
-
163
+
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
164
void hw_watchpoint_update(ARMCPU *cpu, int n)
247
bool isread)
165
{
248
{
166
CPUARMState *env = &cpu->env;
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
167
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
250
.writefn = tlbi_aa64_vae1_write },
168
}
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
169
define_one_arm_cp_reg(cpu, &sctlr);
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
170
}
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
171
+
254
- .writefn = tlbi_aa64_ipas2e1is_write },
172
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
255
+ .access = PL2_W, .type = ARM_CP_NOP },
173
+ define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
174
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
175
+ define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
176
+ } else {
259
- .writefn = tlbi_aa64_ipas2e1is_write },
177
+ define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
260
+ .access = PL2_W, .type = ARM_CP_NOP },
178
+ }
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
179
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
180
+ define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
181
+ }
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
182
+ }
265
.writefn = tlbi_aa64_alle1is_write },
183
}
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
184
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
185
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
269
- .writefn = tlbi_aa64_ipas2e1_write },
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 },
186
--
304
--
187
2.16.1
305
2.20.1
188
306
189
307
diff view generated by jsdifflib
1
The memory writes done to push registers on the stack
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
2
on exception entry in M profile CPUs are supposed to
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
3
go via MPU permissions checks, which may cause us to
3
call it in S1_ptw_translate().
4
take a derived exception instead of the original one of
5
the MPU lookup fails. We were implementing these as
6
always-succeeds direct writes to physical memory.
7
Rewrite v7m_push_stack() to do the necessary checks.
8
4
9
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>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 1517324542-6607-5-git-send-email-peter.maydell@linaro.org
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.org
12
---
9
---
13
target/arm/helper.c | 103 ++++++++++++++++++++++++++++++++++++++++++++--------
10
target/arm/helper.c | 5 +++--
14
1 file changed, 87 insertions(+), 16 deletions(-)
11
1 file changed, 3 insertions(+), 2 deletions(-)
15
12
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
21
return target_el;
18
pcacheattrs = &cacheattrs;
22
}
19
}
23
20
24
-static void v7m_push(CPUARMState *env, uint32_t val)
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
25
+static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
26
+ ARMMMUIdx mmu_idx, bool ignfault)
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
27
{
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
28
- CPUState *cs = CPU(arm_env_get_cpu(env));
25
+ pcacheattrs);
29
+ CPUState *cs = CPU(cpu);
26
if (ret) {
30
+ CPUARMState *env = &cpu->env;
27
assert(fi->type != ARMFault_None);
31
+ MemTxAttrs attrs = {};
28
fi->s2addr = addr;
32
+ MemTxResult txres;
33
+ target_ulong page_size;
34
+ hwaddr physaddr;
35
+ int prot;
36
+ ARMMMUFaultInfo fi;
37
+ bool secure = mmu_idx & ARM_MMU_IDX_M_S;
38
+ int exc;
39
+ bool exc_secure;
40
41
- env->regs[13] -= 4;
42
- stl_phys(cs->as, env->regs[13], val);
43
+ if (get_phys_addr(env, addr, MMU_DATA_STORE, mmu_idx, &physaddr,
44
+ &attrs, &prot, &page_size, &fi, NULL)) {
45
+ /* MPU/SAU lookup failed */
46
+ if (fi.type == ARMFault_QEMU_SFault) {
47
+ qemu_log_mask(CPU_LOG_INT,
48
+ "...SecureFault with SFSR.AUVIOL during stacking\n");
49
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
50
+ env->v7m.sfar = addr;
51
+ exc = ARMV7M_EXCP_SECURE;
52
+ exc_secure = false;
53
+ } else {
54
+ qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
55
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
56
+ exc = ARMV7M_EXCP_MEM;
57
+ exc_secure = secure;
58
+ }
59
+ goto pend_fault;
60
+ }
61
+ address_space_stl_le(arm_addressspace(cs, attrs), physaddr, value,
62
+ attrs, &txres);
63
+ if (txres != MEMTX_OK) {
64
+ /* BusFault trying to write the data */
65
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
66
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
67
+ exc = ARMV7M_EXCP_BUS;
68
+ exc_secure = false;
69
+ goto pend_fault;
70
+ }
71
+ return true;
72
+
73
+pend_fault:
74
+ /* By pending the exception at this point we are making
75
+ * the IMPDEF choice "overridden exceptions pended" (see the
76
+ * MergeExcInfo() pseudocode). The other choice would be to not
77
+ * pend them now and then make a choice about which to throw away
78
+ * later if we have two derived exceptions.
79
+ * The only case when we must not pend the exception but instead
80
+ * throw it away is if we are doing the push of the callee registers
81
+ * and we've already generated a derived exception. Even in this
82
+ * case we will still update the fault status registers.
83
+ */
84
+ if (!ignfault) {
85
+ armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
86
+ }
87
+ return false;
88
}
89
90
/* Return true if we're using the process stack pointer (not the MSP) */
91
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
92
* should ignore further stack faults trying to process
93
* that derived exception.)
94
*/
95
+ bool stacked_ok;
96
CPUARMState *env = &cpu->env;
97
uint32_t xpsr = xpsr_read(env);
98
+ uint32_t frameptr = env->regs[13];
99
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
100
101
/* Align stack pointer if the guest wants that */
102
- if ((env->regs[13] & 4) &&
103
+ if ((frameptr & 4) &&
104
(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKALIGN_MASK)) {
105
- env->regs[13] -= 4;
106
+ frameptr -= 4;
107
xpsr |= XPSR_SPREALIGN;
108
}
109
- /* Switch to the handler mode. */
110
- v7m_push(env, xpsr);
111
- v7m_push(env, env->regs[15]);
112
- v7m_push(env, env->regs[14]);
113
- v7m_push(env, env->regs[12]);
114
- v7m_push(env, env->regs[3]);
115
- v7m_push(env, env->regs[2]);
116
- v7m_push(env, env->regs[1]);
117
- v7m_push(env, env->regs[0]);
118
119
- return false;
120
+ frameptr -= 0x20;
121
+
122
+ /* Write as much of the stack frame as we can. If we fail a stack
123
+ * write this will result in a derived exception being pended
124
+ * (which may be taken in preference to the one we started with
125
+ * if it has higher priority).
126
+ */
127
+ stacked_ok =
128
+ v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
129
+ v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
130
+ v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
131
+ v7m_stack_write(cpu, frameptr + 12, env->regs[3], mmu_idx, false) &&
132
+ v7m_stack_write(cpu, frameptr + 16, env->regs[12], mmu_idx, false) &&
133
+ v7m_stack_write(cpu, frameptr + 20, env->regs[14], mmu_idx, false) &&
134
+ v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
135
+ v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
136
+
137
+ /* Update SP regardless of whether any of the stack accesses failed.
138
+ * When we implement v8M stack limit checking then this attempt to
139
+ * update SP might also fail and result in a derived exception.
140
+ */
141
+ env->regs[13] = frameptr;
142
+
143
+ return !stacked_ok;
144
}
145
146
static void do_v7m_exception_exit(ARMCPU *cpu)
147
--
29
--
148
2.16.1
30
2.20.1
149
31
150
32
diff view generated by jsdifflib
1
In the v8M architecture, if the process of taking an exception
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
2
results in a further exception this is called a derived exception
2
whether the stage 1 access is for EL0 or not, because whether
3
(for example, an MPU exception when writing the exception frame to
3
exec permission is given can depend on whether this is an EL0
4
memory). If the derived exception happens while pushing the initial
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
5
stack frame, we must ignore any subsequent possible exception
5
the call sites can pass this information in.
6
pushing the callee-saves registers.
7
6
8
In preparation for making the stack writes check for exceptions,
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
9
add a return value from v7m_push_stack() and a new parameter to
8
add one so we have a place to put the documentation of the
10
v7m_exception_taken(), so that the former can tell the latter that
9
semantics of the new s1_is_el0 argument.
11
it needs to ignore failures to write to the stack. We also plumb
12
the argument through to v7m_push_callee_stack(), which is where
13
the code to ignore the failures will be.
14
15
(Note that the v8M ARM pseudocode structures this slightly differently:
16
derived exceptions cause the attempt to process the original
17
exception to be abandoned; then at the top level it calls
18
DerivedLateArrival to prioritize the derived exception and call
19
TakeException from there. We choose to let the NVIC do the prioritization
20
and continue forward with a call to TakeException which will then
21
take either the original or the derived exception. The effect is
22
the same, but this structure works better for QEMU because we don't
23
have a convenient top level place to do the abandon-and-retry logic.)
24
10
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 1517324542-6607-4-git-send-email-peter.maydell@linaro.org
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
28
---
15
---
29
target/arm/helper.c | 35 +++++++++++++++++++++++------------
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
30
1 file changed, 23 insertions(+), 12 deletions(-)
17
1 file changed, 28 insertions(+), 1 deletion(-)
31
18
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
21
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
22
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
23
@@ -XXX,XX +XXX,XX @@
37
return addr;
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
};
38
}
41
}
39
42
40
-static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain)
43
+/**
41
+static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
42
+ bool ignore_faults)
45
+ *
43
{
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
44
/* For v8M, push the callee-saves register part of the stack frame.
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
45
* Compare the v8M pseudocode PushCalleeStack().
48
+ * information on why the translation aborted, in the format of a long-format
46
@@ -XXX,XX +XXX,XX @@ static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain)
49
+ * DFSR/IFSR fault register, with the following caveats:
47
*frame_sp_p = frameptr;
50
+ * * the WnR bit is never set (the caller must do this).
48
}
51
+ *
49
52
+ * @env: CPUARMState
50
-static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
53
+ * @address: virtual address to get physical address for
51
+static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
52
+ bool ignore_stackfaults)
55
+ * @mmu_idx: MMU index indicating required translation regime
53
{
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
54
/* Do the "take the exception" parts of exception entry,
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
55
* but not the pushing of state to the stack. This is
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
56
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
57
*/
60
+ * @attrs: set to the memory transaction attributes to use
58
if (lr & R_V7M_EXCRET_DCRS_MASK &&
61
+ * @prot: set to the permissions for the page containing phys_ptr
59
!(dotailchain && (lr & R_V7M_EXCRET_ES_MASK))) {
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
60
- v7m_push_callee_stack(cpu, lr, dotailchain);
63
+ * @fi: set to fault info if the translation fails
61
+ v7m_push_callee_stack(cpu, lr, dotailchain,
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
62
+ ignore_stackfaults);
65
+ */
63
}
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
64
lr |= R_V7M_EXCRET_DCRS_MASK;
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
65
}
68
+ bool s1_is_el0,
66
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
67
env->thumb = addr & 1;
70
target_ulong *page_size_ptr,
68
}
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
69
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
70
-static void v7m_push_stack(ARMCPU *cpu)
73
71
+static bool v7m_push_stack(ARMCPU *cpu)
74
/* S1 is done. Now do S2 translation. */
72
{
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
73
/* Do the "set up stack frame" part of exception entry,
76
+ mmu_idx == ARMMMUIdx_E10_0,
74
* similar to pseudocode PushStack().
77
phys_ptr, attrs, &s2_prot,
75
+ * Return true if we generate a derived exception (and so
78
page_size, fi,
76
+ * should ignore further stack faults trying to process
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
77
+ * that derived exception.)
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
78
*/
79
CPUARMState *env = &cpu->env;
80
uint32_t xpsr = xpsr_read(env);
81
@@ -XXX,XX +XXX,XX @@ static void v7m_push_stack(ARMCPU *cpu)
82
v7m_push(env, env->regs[2]);
83
v7m_push(env, env->regs[1]);
84
v7m_push(env, env->regs[0]);
85
+
86
+ return false;
87
}
88
89
static void do_v7m_exception_exit(ARMCPU *cpu)
90
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
91
if (sfault) {
92
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
93
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
94
- v7m_exception_taken(cpu, excret, true);
95
+ v7m_exception_taken(cpu, excret, true, false);
96
qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
97
"stackframe: failed EXC_RETURN.ES validity check\n");
98
return;
99
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
100
*/
101
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
102
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
103
- v7m_exception_taken(cpu, excret, true);
104
+ v7m_exception_taken(cpu, excret, true, false);
105
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
106
"stackframe: failed exception return integrity check\n");
107
return;
108
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
109
/* Take a SecureFault on the current stack */
110
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
111
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
112
- v7m_exception_taken(cpu, excret, true);
113
+ v7m_exception_taken(cpu, excret, true, false);
114
qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
115
"stackframe: failed exception return integrity "
116
"signature check\n");
117
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
118
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
119
env->v7m.secure);
120
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
121
- v7m_exception_taken(cpu, excret, true);
122
+ v7m_exception_taken(cpu, excret, true, false);
123
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
124
"stackframe: failed exception return integrity "
125
"check\n");
126
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
127
/* Take an INVPC UsageFault by pushing the stack again;
128
* we know we're v7M so this is never a Secure UsageFault.
129
*/
130
+ bool ignore_stackfaults;
131
+
132
assert(!arm_feature(env, ARM_FEATURE_V8));
133
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, false);
134
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
135
- v7m_push_stack(cpu);
136
- v7m_exception_taken(cpu, excret, false);
137
+ ignore_stackfaults = v7m_push_stack(cpu);
138
+ v7m_exception_taken(cpu, excret, false, ignore_stackfaults);
139
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on new stackframe: "
140
"failed exception return integrity check\n");
141
return;
142
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
143
ARMCPU *cpu = ARM_CPU(cs);
144
CPUARMState *env = &cpu->env;
145
uint32_t lr;
146
+ bool ignore_stackfaults;
147
148
arm_log_exception(cs->exception_index);
149
150
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
151
lr |= R_V7M_EXCRET_MODE_MASK;
152
}
81
}
153
82
154
- v7m_push_stack(cpu);
83
if (regime_using_lpae_format(env, mmu_idx)) {
155
- v7m_exception_taken(cpu, lr, false);
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
156
+ ignore_stackfaults = v7m_push_stack(cpu);
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
157
+ v7m_exception_taken(cpu, lr, false, ignore_stackfaults);
86
phys_ptr, attrs, prot, page_size,
158
qemu_log_mask(CPU_LOG_INT, "... as %d\n", env->v7m.exception);
87
fi, cacheattrs);
159
}
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
160
161
--
89
--
162
2.16.1
90
2.20.1
163
91
164
92
diff view generated by jsdifflib
1
Currently armv7m_nvic_acknowledge_irq() does three things:
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
2
* make the current highest priority pending interrupt active
2
translation table descriptors from just bit [54] to bits [54:53],
3
* return a bool indicating whether that interrupt is targeting
3
allowing stage 2 to control execution permissions separately for EL0
4
Secure or NonSecure state
4
and EL1. Implement the new semantics of the XN field and enable
5
* implicitly tell the caller which is the highest priority
5
the feature for our 'max' CPU.
6
pending interrupt by setting env->v7m.exception
7
8
We need to split these jobs, because v7m_exception_taken()
9
needs to know whether the pending interrupt targets Secure so
10
it can choose to stack callee-saves registers or not, but it
11
must not make the interrupt active until after it has done
12
that stacking, in case the stacking causes a derived exception.
13
Similarly, it needs to know the number of the pending interrupt
14
so it can read the correct vector table entry before the
15
interrupt is made active, because vector table reads might
16
also cause a derived exception.
17
18
Create a new armv7m_nvic_get_pending_irq_info() function which simply
19
returns information about the highest priority pending interrupt, and
20
use it to rearrange the v7m_exception_taken() code so we don't
21
acknowledge the exception until we've done all the things which could
22
possibly cause a derived exception.
23
6
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
27
Message-id: 1517324542-6607-3-git-send-email-peter.maydell@linaro.org
28
---
11
---
29
target/arm/cpu.h | 19 ++++++++++++++++---
12
target/arm/cpu.h | 15 +++++++++++++++
30
hw/intc/armv7m_nvic.c | 30 +++++++++++++++++++++++-------
13
target/arm/cpu.c | 1 +
31
target/arm/helper.c | 16 ++++++++++++----
14
target/arm/cpu64.c | 2 ++
32
hw/intc/trace-events | 3 ++-
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
33
4 files changed, 53 insertions(+), 15 deletions(-)
16
4 files changed, 49 insertions(+), 6 deletions(-)
34
17
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
38
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
39
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
40
* a different exception).
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
41
*/
42
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
43
+/**
44
+ * armv7m_nvic_get_pending_irq_info: return highest priority pending
45
+ * exception, and whether it targets Secure state
46
+ * @opaque: the NVIC
47
+ * @pirq: set to pending exception number
48
+ * @ptargets_secure: set to whether pending exception targets Secure
49
+ *
50
+ * This function writes the number of the highest priority pending
51
+ * exception (the one which would be made active by
52
+ * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
53
+ * to true if the current highest priority pending exception should
54
+ * be taken to Secure state, false for NS.
55
+ */
56
+void armv7m_nvic_get_pending_irq_info(void *opaque, int *pirq,
57
+ bool *ptargets_secure);
58
/**
59
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
60
* @opaque: the NVIC
61
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
62
* Move the current highest priority pending exception from the pending
63
* state to the active state, and update v7m.exception to indicate that
64
* it is the exception currently being handled.
65
- *
66
- * Returns: true if exception should be taken to Secure state, false for NS
67
*/
68
-bool armv7m_nvic_acknowledge_irq(void *opaque);
69
+void armv7m_nvic_acknowledge_irq(void *opaque);
70
/**
71
* armv7m_nvic_complete_irq: complete specified interrupt or exception
72
* @opaque: the NVIC
73
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/intc/armv7m_nvic.c
76
+++ b/hw/intc/armv7m_nvic.c
77
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
78
}
24
}
79
25
80
/* Make pending IRQ active. */
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
81
-bool armv7m_nvic_acknowledge_irq(void *opaque)
27
+{
82
+void armv7m_nvic_acknowledge_irq(void *opaque)
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
83
{
84
NVICState *s = (NVICState *)opaque;
85
CPUARMState *env = &s->cpu->env;
86
const int pending = s->vectpending;
87
const int running = nvic_exec_prio(s);
88
VecInfo *vec;
89
- bool targets_secure;
90
91
assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
92
93
if (s->vectpending_is_s_banked) {
94
vec = &s->sec_vectors[pending];
95
- targets_secure = true;
96
} else {
97
vec = &s->vectors[pending];
98
- targets_secure = !exc_is_banked(s->vectpending) &&
99
- exc_targets_secure(s, s->vectpending);
100
}
101
102
assert(vec->enabled);
103
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_acknowledge_irq(void *opaque)
104
105
assert(s->vectpending_prio < running);
106
107
- trace_nvic_acknowledge_irq(pending, s->vectpending_prio, targets_secure);
108
+ trace_nvic_acknowledge_irq(pending, s->vectpending_prio);
109
110
vec->active = 1;
111
vec->pending = 0;
112
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_acknowledge_irq(void *opaque)
113
write_v7m_exception(env, s->vectpending);
114
115
nvic_irq_update(s);
116
+}
29
+}
117
+
30
+
118
+void armv7m_nvic_get_pending_irq_info(void *opaque,
31
/*
119
+ int *pirq, bool *ptargets_secure)
32
* 64-bit feature tests via id registers.
33
*/
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
36
}
37
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
120
+{
39
+{
121
+ NVICState *s = (NVICState *)opaque;
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
122
+ const int pending = s->vectpending;
41
+}
123
+ bool targets_secure;
124
+
42
+
125
+ assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
43
/*
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
45
*/
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
48
}
49
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
51
+{
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
53
+}
126
+
54
+
127
+ if (s->vectpending_is_s_banked) {
55
/*
128
+ targets_secure = true;
56
* Forward to the above feature tests given an ARMCPU pointer.
129
+ } else {
57
*/
130
+ targets_secure = !exc_is_banked(pending) &&
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
131
+ exc_targets_secure(s, pending);
59
index XXXXXXX..XXXXXXX 100644
132
+ }
60
--- a/target/arm/cpu.c
133
+
61
+++ b/target/arm/cpu.c
134
+ trace_nvic_get_pending_irq_info(pending, targets_secure);
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
135
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
136
- return targets_secure;
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
137
+ *ptargets_secure = targets_secure;
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
138
+ *pirq = pending;
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
139
}
67
cpu->isar.id_mmfr4 = t;
140
68
}
141
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
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;
142
diff --git a/target/arm/helper.c b/target/arm/helper.c
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
143
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
144
--- a/target/arm/helper.c
92
--- a/target/arm/helper.c
145
+++ b/target/arm/helper.c
93
+++ b/target/arm/helper.c
146
@@ -XXX,XX +XXX,XX @@ static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
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
{
105
int prot = 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;
147
}
110
}
148
}
111
- if (!xn) {
149
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
150
-static uint32_t arm_v7m_load_vector(ARMCPU *cpu, bool targets_secure)
113
+
151
+static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
152
{
115
+ switch (xn) {
153
CPUState *cs = CPU(cpu);
116
+ case 0:
154
CPUARMState *env = &cpu->env;
117
prot |= PAGE_EXEC;
155
MemTxResult result;
118
+ break;
156
- hwaddr vec = env->v7m.vecbase[targets_secure] + env->v7m.exception * 4;
119
+ case 1:
157
+ hwaddr vec = env->v7m.vecbase[targets_secure] + exc * 4;
120
+ if (s1_is_el0) {
158
uint32_t addr;
121
+ prot |= PAGE_EXEC;
159
122
+ }
160
addr = address_space_ldl(cs->as, vec,
123
+ break;
161
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
124
+ case 2:
162
CPUARMState *env = &cpu->env;
125
+ break;
163
uint32_t addr;
126
+ case 3:
164
bool targets_secure;
127
+ if (!s1_is_el0) {
165
+ int exc;
128
+ prot |= PAGE_EXEC;
166
129
+ }
167
- targets_secure = armv7m_nvic_acknowledge_irq(env->nvic);
130
+ break;
168
+ armv7m_nvic_get_pending_irq_info(env->nvic, &exc, &targets_secure);
131
+ default:
169
132
+ g_assert_not_reached();
170
if (arm_feature(env, ARM_FEATURE_V8)) {
133
+ }
171
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
134
+ } else {
172
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
135
+ if (!extract32(xn, 1, 1)) {
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
137
+ prot |= PAGE_EXEC;
138
+ }
173
}
139
}
174
}
140
}
175
141
return prot;
176
+ addr = arm_v7m_load_vector(cpu, exc, targets_secure);
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
177
+
143
}
178
+ /* Now we've done everything that might cause a derived exception
144
179
+ * we can go ahead and activate whichever exception we're going to
145
ap = extract32(attrs, 4, 2);
180
+ * take (which might now be the derived exception).
146
- xn = extract32(attrs, 12, 1);
181
+ */
147
182
+ armv7m_nvic_acknowledge_irq(env->nvic);
148
if (mmu_idx == ARMMMUIdx_Stage2) {
183
+
149
ns = true;
184
/* Switch to target security state -- must do this before writing SPSEL */
150
- *prot = get_S2prot(env, ap, xn);
185
switch_v7m_security_state(env, targets_secure);
151
+ xn = extract32(attrs, 11, 2);
186
write_v7m_control_spsel(env, 0);
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
187
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
153
} else {
188
/* Clear IT bits */
154
ns = extract32(attrs, 3, 1);
189
env->condexec_bits = 0;
155
+ xn = extract32(attrs, 12, 1);
190
env->regs[14] = lr;
156
pxn = extract32(attrs, 11, 1);
191
- addr = arm_v7m_load_vector(cpu, targets_secure);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
192
env->regs[15] = addr & 0xfffffffe;
158
}
193
env->thumb = addr & 1;
194
}
195
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
196
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/intc/trace-events
198
+++ b/hw/intc/trace-events
199
@@ -XXX,XX +XXX,XX @@ nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
200
nvic_set_pending(int irq, bool secure, bool derived, int en, int prio) "NVIC set pending irq %d secure-bank %d derived %d (enabled: %d priority %d)"
201
nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
202
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
203
-nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)"
204
+nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (prio %d)"
205
+nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d"
206
nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)"
207
nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d"
208
nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
209
--
159
--
210
2.16.1
160
2.20.1
211
161
212
162
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
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.
2
9
3
Add support for the new ARMv8.2 SHA-3, SM3, SM4 and SHA-512 instructions to
10
Use the right-sized variable.
4
AArch64 user mode emulation.
5
11
6
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
12
Fixes: 3bec78447a958d481991
7
Message-id: 20180207111729.15737-6-ard.biesheuvel@linaro.org
8
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>
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
10
---
17
---
11
linux-user/elfload.c | 19 +++++++++++++++++++
18
target/arm/cpu64.c | 6 +++---
12
target/arm/cpu64.c | 4 ++++
19
1 file changed, 3 insertions(+), 3 deletions(-)
13
2 files changed, 23 insertions(+)
14
20
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
18
+++ b/linux-user/elfload.c
19
@@ -XXX,XX +XXX,XX @@ enum {
20
ARM_HWCAP_A64_SHA1 = 1 << 5,
21
ARM_HWCAP_A64_SHA2 = 1 << 6,
22
ARM_HWCAP_A64_CRC32 = 1 << 7,
23
+ ARM_HWCAP_A64_ATOMICS = 1 << 8,
24
+ ARM_HWCAP_A64_FPHP = 1 << 9,
25
+ ARM_HWCAP_A64_ASIMDHP = 1 << 10,
26
+ ARM_HWCAP_A64_CPUID = 1 << 11,
27
+ ARM_HWCAP_A64_ASIMDRDM = 1 << 12,
28
+ ARM_HWCAP_A64_JSCVT = 1 << 13,
29
+ ARM_HWCAP_A64_FCMA = 1 << 14,
30
+ ARM_HWCAP_A64_LRCPC = 1 << 15,
31
+ ARM_HWCAP_A64_DCPOP = 1 << 16,
32
+ ARM_HWCAP_A64_SHA3 = 1 << 17,
33
+ ARM_HWCAP_A64_SM3 = 1 << 18,
34
+ ARM_HWCAP_A64_SM4 = 1 << 19,
35
+ ARM_HWCAP_A64_ASIMDDP = 1 << 20,
36
+ ARM_HWCAP_A64_SHA512 = 1 << 21,
37
+ ARM_HWCAP_A64_SVE = 1 << 22,
38
};
39
40
#define ELF_HWCAP get_elf_hwcap()
41
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
42
GET_FEATURE(ARM_FEATURE_V8_SHA1, ARM_HWCAP_A64_SHA1);
43
GET_FEATURE(ARM_FEATURE_V8_SHA256, ARM_HWCAP_A64_SHA2);
44
GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP_A64_CRC32);
45
+ GET_FEATURE(ARM_FEATURE_V8_SHA3, ARM_HWCAP_A64_SHA3);
46
+ GET_FEATURE(ARM_FEATURE_V8_SM3, ARM_HWCAP_A64_SM3);
47
+ GET_FEATURE(ARM_FEATURE_V8_SM4, ARM_HWCAP_A64_SM4);
48
+ GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512);
49
#undef GET_FEATURE
50
51
return hwcaps;
52
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
53
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu64.c
23
--- a/target/arm/cpu64.c
55
+++ b/target/arm/cpu64.c
24
+++ b/target/arm/cpu64.c
56
@@ -XXX,XX +XXX,XX @@ static void aarch64_any_initfn(Object *obj)
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
57
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
58
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
27
cpu->isar.id_mmfr4 = u;
59
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
28
60
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
29
- u = cpu->isar.id_aa64dfr0;
61
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
62
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
31
- cpu->isar.id_aa64dfr0 = u;
63
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
32
+ t = cpu->isar.id_aa64dfr0;
64
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
65
set_feature(&cpu->env, ARM_FEATURE_CRC);
34
+ cpu->isar.id_aa64dfr0 = t;
66
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
35
36
u = cpu->isar.id_dfr0;
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
67
--
38
--
68
2.16.1
39
2.20.1
69
40
70
41
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
5
uint32_t.
6
7
This fixes an error when compiling with -Werror=conversion
8
because we were manipulating the register value using a
9
local uint64_t variable:
10
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
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]
13
628 | cpu->midr = t;
14
| ^
15
16
and future-proofs us against a possible future architecture
17
change using some of the top 32 bits.
18
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20180123035349.24538-3-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
26
---
9
target/arm/cpu.h | 12 ++++++++++++
27
target/arm/cpu.h | 2 +-
10
1 file changed, 12 insertions(+)
28
target/arm/cpu.c | 2 +-
29
2 files changed, 2 insertions(+), 2 deletions(-)
11
30
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
33
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
34
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVectorReg {
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
17
uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
36
uint64_t id_aa64dfr0;
18
} ARMVectorReg;
37
uint64_t id_aa64dfr1;
19
38
} isar;
20
+/* In AArch32 mode, predicate registers do not exist at all. */
39
- uint32_t midr;
21
+#ifdef TARGET_AARCH64
40
+ uint64_t midr;
22
+typedef struct ARMPredicateReg {
41
uint32_t revidr;
23
+ uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
42
uint32_t reset_fpsid;
24
+} ARMPredicateReg;
43
uint32_t ctr;
25
+#endif
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
+
45
index XXXXXXX..XXXXXXX 100644
27
46
--- a/target/arm/cpu.c
28
typedef struct CPUARMState {
47
+++ b/target/arm/cpu.c
29
/* Regs for current mode. */
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
49
static Property arm_cpu_properties[] = {
31
struct {
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
32
ARMVectorReg zregs[32];
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
33
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
34
+#ifdef TARGET_AARCH64
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
35
+ /* Store FFR as pregs[16] to make it easier to treat as any other. */
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
36
+ ARMPredicateReg pregs[17];
55
mp_affinity, ARM64_AFFINITY_INVALID),
37
+#endif
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
38
+
39
uint32_t xregs[16];
40
/* We store these fpcsr fields separately for convenience. */
41
int vec_len;
42
--
57
--
43
2.16.1
58
2.20.1
44
59
45
60
diff view generated by jsdifflib
New patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
2
3
Remove inclusion of arm_gicv3_common.h, this already gets
4
included via xlnx-versal.h.
5
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/xlnx-versal.c | 1 -
13
1 file changed, 1 deletion(-)
14
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
18
+++ b/hw/arm/xlnx-versal.c
19
@@ -XXX,XX +XXX,XX @@
20
#include "hw/arm/boot.h"
21
#include "kvm_arm.h"
22
#include "hw/misc/unimp.h"
23
-#include "hw/intc/arm_gicv3_common.h"
24
#include "hw/arm/xlnx-versal.h"
25
#include "hw/char/pl011.h"
26
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
New patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
2
3
Move misplaced comment.
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>
11
---
12
hw/arm/xlnx-versal.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
18
+++ b/hw/arm/xlnx-versal.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
20
21
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
22
if (!obj) {
23
- /* Secondary CPUs start in PSCI powered-down state */
24
error_report("Unable to create apu.cpu[%d] of type %s",
25
i, XLNX_VERSAL_ACPU_TYPE);
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
}
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Convert i.MX6 to use TYPE_IMX_USDHC since that's what real HW comes
3
Fix typo xlnx-ve -> xlnx-versal.
4
with.
5
4
6
Cc: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Cc: Jason Wang <jasowang@redhat.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
10
Cc: Michael S. Tsirkin <mst@redhat.com>
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
11
---
18
hw/arm/fsl-imx6.c | 2 +-
12
hw/arm/xlnx-versal-virt.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
20
14
21
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
22
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/fsl-imx6.c
17
--- a/hw/arm/xlnx-versal-virt.c
24
+++ b/hw/arm/fsl-imx6.c
18
+++ b/hw/arm/xlnx-versal-virt.c
25
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_init(Object *obj)
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
26
}
21
}
27
22
28
for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
29
- object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), TYPE_SYSBUS_SDHCI);
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
30
+ object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), TYPE_IMX_USDHC);
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
31
qdev_set_parent_bus(DEVICE(&s->esdhc[i]), sysbus_get_default());
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
32
snprintf(name, NAME_SIZE, "sdhc%d", i + 1);
27
"ddr", &error_abort);
33
object_property_add_child(obj, name, OBJECT(&s->esdhc[i]), NULL);
34
--
28
--
35
2.16.1
29
2.20.1
36
30
37
31
diff view generated by jsdifflib
New patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
2
3
Embed the UARTs into the SoC type.
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.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>
12
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
14
hw/arm/xlnx-versal.c | 12 ++++++------
15
2 files changed, 8 insertions(+), 7 deletions(-)
16
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/sysbus.h"
23
#include "hw/arm/boot.h"
24
#include "hw/intc/arm_gicv3.h"
25
+#include "hw/char/pl011.h"
26
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
MemoryRegion mr_ocm;
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
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@
43
#include "kvm_arm.h"
44
#include "hw/misc/unimp.h"
45
#include "hw/arm/xlnx-versal.h"
46
-#include "hw/char/pl011.h"
47
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
49
#define GEM_REVISION 0x40070106
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
51
DeviceState *dev;
52
MemoryRegion *mr;
53
54
- dev = qdev_create(NULL, TYPE_PL011);
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
56
+ sysbus_init_child_obj(OBJECT(s), name,
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
58
+ TYPE_PL011);
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
62
qdev_init_nofail(dev);
63
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
67
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
}
73
--
74
2.20.1
75
76
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Save the high parts of the Zregs and all of the Pregs.
3
Embed the GEMs into the SoC type.
4
The ZCR_ELx registers are migrated via the CP mechanism.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20180123035349.24538-4-richard.henderson@linaro.org
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
target/arm/machine.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
13
include/hw/arm/xlnx-versal.h | 3 ++-
13
1 file changed, 53 insertions(+)
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
15
2 files changed, 10 insertions(+), 8 deletions(-)
14
16
15
diff --git a/target/arm/machine.c b/target/arm/machine.c
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/machine.c
19
--- a/include/hw/arm/xlnx-versal.h
18
+++ b/target/arm/machine.c
20
+++ b/include/hw/arm/xlnx-versal.h
19
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_iwmmxt = {
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/arm/boot.h"
23
#include "hw/intc/arm_gicv3.h"
24
#include "hw/char/pl011.h"
25
+#include "hw/net/cadence_gem.h"
26
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
31
struct {
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
36
} iou;
37
} lpd;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
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);
20
}
74
}
21
};
75
}
22
23
+#ifdef TARGET_AARCH64
24
+/* The expression ARM_MAX_VQ - 2 is 0 for pure AArch32 build,
25
+ * and ARMPredicateReg is actively empty. This triggers errors
26
+ * in the expansion of the VMSTATE macros.
27
+ */
28
+
29
+static bool sve_needed(void *opaque)
30
+{
31
+ ARMCPU *cpu = opaque;
32
+ CPUARMState *env = &cpu->env;
33
+
34
+ return arm_feature(env, ARM_FEATURE_SVE);
35
+}
36
+
37
+/* The first two words of each Zreg is stored in VFP state. */
38
+static const VMStateDescription vmstate_zreg_hi_reg = {
39
+ .name = "cpu/sve/zreg_hi",
40
+ .version_id = 1,
41
+ .minimum_version_id = 1,
42
+ .fields = (VMStateField[]) {
43
+ VMSTATE_UINT64_SUB_ARRAY(d, ARMVectorReg, 2, ARM_MAX_VQ - 2),
44
+ VMSTATE_END_OF_LIST()
45
+ }
46
+};
47
+
48
+static const VMStateDescription vmstate_preg_reg = {
49
+ .name = "cpu/sve/preg",
50
+ .version_id = 1,
51
+ .minimum_version_id = 1,
52
+ .fields = (VMStateField[]) {
53
+ VMSTATE_UINT64_ARRAY(p, ARMPredicateReg, 2 * ARM_MAX_VQ / 8),
54
+ VMSTATE_END_OF_LIST()
55
+ }
56
+};
57
+
58
+static const VMStateDescription vmstate_sve = {
59
+ .name = "cpu/sve",
60
+ .version_id = 1,
61
+ .minimum_version_id = 1,
62
+ .needed = sve_needed,
63
+ .fields = (VMStateField[]) {
64
+ VMSTATE_STRUCT_ARRAY(env.vfp.zregs, ARMCPU, 32, 0,
65
+ vmstate_zreg_hi_reg, ARMVectorReg),
66
+ VMSTATE_STRUCT_ARRAY(env.vfp.pregs, ARMCPU, 17, 0,
67
+ vmstate_preg_reg, ARMPredicateReg),
68
+ VMSTATE_END_OF_LIST()
69
+ }
70
+};
71
+#endif /* AARCH64 */
72
+
73
static bool m_needed(void *opaque)
74
{
75
ARMCPU *cpu = opaque;
76
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
77
&vmstate_pmsav7,
78
&vmstate_pmsav8,
79
&vmstate_m_security,
80
+#ifdef TARGET_AARCH64
81
+ &vmstate_sve,
82
+#endif
83
NULL
84
}
85
};
86
--
76
--
87
2.16.1
77
2.20.1
88
78
89
79
diff view generated by jsdifflib
1
From: Christoffer Dall <christoffer.dall@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
KVM doesn't support emulating a GICv3 in userspace, only GICv2. We
3
Embed the ADMAs into the SoC type.
4
currently attempt this anyway, and as a result a KVM guest doesn't
5
receive interrupts and the user is left wondering why. Report an error
6
to the user if this particular combination is requested.
7
4
8
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20180201205307.30343-1-christoffer.dall@linaro.org
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
target/arm/kvm_arm.h | 4 ++++
13
include/hw/arm/xlnx-versal.h | 3 ++-
14
1 file changed, 4 insertions(+)
14
hw/arm/xlnx-versal.c | 14 +++++++-------
15
2 files changed, 9 insertions(+), 8 deletions(-)
15
16
16
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/kvm_arm.h
19
--- a/include/hw/arm/xlnx-versal.h
19
+++ b/target/arm/kvm_arm.h
20
+++ b/include/hw/arm/xlnx-versal.h
20
@@ -XXX,XX +XXX,XX @@ static inline const char *gicv3_class_name(void)
21
@@ -XXX,XX +XXX,XX @@
21
exit(1);
22
#include "hw/arm/boot.h"
22
#endif
23
#include "hw/intc/arm_gicv3.h"
23
} else {
24
#include "hw/char/pl011.h"
24
+ if (kvm_enabled()) {
25
+#include "hw/dma/xlnx-zdma.h"
25
+ error_report("Userspace GICv3 is not supported with KVM");
26
#include "hw/net/cadence_gem.h"
26
+ exit(1);
27
27
+ }
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
return "arm-gicv3";
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
struct {
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
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
43
DeviceState *dev;
44
MemoryRegion *mr;
45
46
- dev = qdev_create(NULL, "xlnx.zdma");
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
49
- &error_abort);
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
51
+ sysbus_init_child_obj(OBJECT(s), name,
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
53
+ TYPE_XLNX_ZDMA);
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
56
qdev_init_nofail(dev);
57
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
60
memory_region_add_subregion(&s->mr_ps,
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);
29
}
66
}
30
}
67
}
31
--
68
--
32
2.16.1
69
2.20.1
33
70
34
71
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Add minimal code needed to allow upstream Linux guest to boot.
3
Embed the APUs into the SoC type.
4
4
5
Cc: Peter Maydell <peter.maydell@linaro.org>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Cc: Jason Wang <jasowang@redhat.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
12
---
18
include/hw/timer/imx_gpt.h | 1 +
13
include/hw/arm/xlnx-versal.h | 2 +-
19
hw/timer/imx_gpt.c | 25 +++++++++++++++++++++++++
14
hw/arm/xlnx-versal-virt.c | 4 ++--
20
2 files changed, 26 insertions(+)
15
hw/arm/xlnx-versal.c | 19 +++++--------------
16
3 files changed, 8 insertions(+), 17 deletions(-)
21
17
22
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
23
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/timer/imx_gpt.h
20
--- a/include/hw/arm/xlnx-versal.h
25
+++ b/include/hw/timer/imx_gpt.h
21
+++ b/include/hw/arm/xlnx-versal.h
26
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
27
#define TYPE_IMX25_GPT "imx25.gpt"
23
struct {
28
#define TYPE_IMX31_GPT "imx31.gpt"
24
struct {
29
#define TYPE_IMX6_GPT "imx6.gpt"
25
MemoryRegion mr;
30
+#define TYPE_IMX7_GPT "imx7.gpt"
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
31
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
32
#define TYPE_IMX_GPT TYPE_IMX25_GPT
28
GICv3State gic;
33
29
} apu;
34
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
30
} fpd;
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
35
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/timer/imx_gpt.c
33
--- a/hw/arm/xlnx-versal-virt.c
37
+++ b/hw/timer/imx_gpt.c
34
+++ b/hw/arm/xlnx-versal-virt.c
38
@@ -XXX,XX +XXX,XX @@ static const IMXClk imx6_gpt_clocks[] = {
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
39
CLK_HIGH, /* 111 reference clock */
36
s->binfo.get_dtb = versal_virt_get_dtb;
40
};
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
41
38
if (machine->kernel_filename) {
42
+static const IMXClk imx7_gpt_clocks[] = {
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
43
+ CLK_NONE, /* 000 No clock source */
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
44
+ CLK_IPG, /* 001 ipg_clk, 532MHz*/
41
} else {
45
+ CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
46
+ CLK_EXT, /* 011 External clock */
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
47
+ CLK_32k, /* 100 ipg_clk_32k */
44
&s->binfo);
48
+ CLK_HIGH, /* 101 reference clock */
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
49
+ CLK_NONE, /* 110 not defined */
46
* Offset things by 4K. */
50
+ CLK_NONE, /* 111 not defined */
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
51
+};
48
index XXXXXXX..XXXXXXX 100644
52
+
49
--- a/hw/arm/xlnx-versal.c
53
static void imx_gpt_set_freq(IMXGPTState *s)
50
+++ b/hw/arm/xlnx-versal.c
54
{
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
55
uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
52
56
@@ -XXX,XX +XXX,XX @@ static void imx6_gpt_init(Object *obj)
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
57
s->clocks = imx6_gpt_clocks;
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
}
58
}
81
}
59
82
60
+static void imx7_gpt_init(Object *obj)
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
61
+{
84
}
62
+ IMXGPTState *s = IMX_GPT(obj);
85
63
+
86
for (i = 0; i < nr_apu_cpus; i++) {
64
+ s->clocks = imx7_gpt_clocks;
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
65
+}
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
66
+
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
67
static const TypeInfo imx25_gpt_info = {
90
qemu_irq maint_irq;
68
.name = TYPE_IMX25_GPT,
91
int ti;
69
.parent = TYPE_SYS_BUS_DEVICE,
70
@@ -XXX,XX +XXX,XX @@ static const TypeInfo imx6_gpt_info = {
71
.instance_init = imx6_gpt_init,
72
};
73
74
+static const TypeInfo imx7_gpt_info = {
75
+ .name = TYPE_IMX7_GPT,
76
+ .parent = TYPE_IMX25_GPT,
77
+ .instance_init = imx7_gpt_init,
78
+};
79
+
80
static void imx_gpt_register_types(void)
81
{
82
type_register_static(&imx25_gpt_info);
83
type_register_static(&imx31_gpt_info);
84
type_register_static(&imx6_gpt_info);
85
+ type_register_static(&imx7_gpt_info);
86
}
87
88
type_init(imx_gpt_register_types)
89
--
92
--
90
2.16.1
93
2.20.1
91
94
92
95
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Add code to emulate SNVS IP-block. Currently only the bits needed to
3
Add support for SD.
4
be able to emulate machine shutdown are implemented.
5
4
6
Cc: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Cc: Jason Wang <jasowang@redhat.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Cc: Michael S. Tsirkin <mst@redhat.com>
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
11
---
18
hw/misc/Makefile.objs | 1 +
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
19
include/hw/misc/imx7_snvs.h | 35 +++++++++++++++++++
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
20
hw/misc/imx7_snvs.c | 83 +++++++++++++++++++++++++++++++++++++++++++++
14
2 files changed, 43 insertions(+)
21
3 files changed, 119 insertions(+)
22
create mode 100644 include/hw/misc/imx7_snvs.h
23
create mode 100644 hw/misc/imx7_snvs.c
24
15
25
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/misc/Makefile.objs
18
--- a/include/hw/arm/xlnx-versal.h
28
+++ b/hw/misc/Makefile.objs
19
+++ b/include/hw/arm/xlnx-versal.h
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx6_ccm.o
30
obj-$(CONFIG_IMX) += imx6_src.o
31
obj-$(CONFIG_IMX) += imx7_ccm.o
32
obj-$(CONFIG_IMX) += imx2_wdt.o
33
+obj-$(CONFIG_IMX) += imx7_snvs.o
34
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
35
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
36
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
37
diff --git a/include/hw/misc/imx7_snvs.h b/include/hw/misc/imx7_snvs.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/misc/imx7_snvs.h
42
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
43
+/*
21
44
+ * Copyright (c) 2017, Impinj, Inc.
22
#include "hw/sysbus.h"
45
+ *
23
#include "hw/arm/boot.h"
46
+ * i.MX7 SNVS block emulation code
24
+#include "hw/sd/sdhci.h"
47
+ *
25
#include "hw/intc/arm_gicv3.h"
48
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
26
#include "hw/char/pl011.h"
49
+ *
27
#include "hw/dma/xlnx-zdma.h"
50
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
28
@@ -XXX,XX +XXX,XX @@
51
+ * See the COPYING file in the top-level directory.
29
#define XLNX_VERSAL_NR_UARTS 2
52
+ */
30
#define XLNX_VERSAL_NR_GEMS 2
31
#define XLNX_VERSAL_NR_ADMAS 8
32
+#define XLNX_VERSAL_NR_SDS 2
33
#define XLNX_VERSAL_NR_IRQS 192
34
35
typedef struct Versal {
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
37
} iou;
38
} lpd;
39
40
+ /* The Platform Management Controller subsystem. */
41
+ struct {
42
+ struct {
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
44
+ } iou;
45
+ } pmc;
53
+
46
+
54
+#ifndef IMX7_SNVS_H
47
struct {
55
+#define IMX7_SNVS_H
48
MemoryRegion *mr_ddr;
49
uint32_t psci_conduit;
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
51
#define VERSAL_GEM1_IRQ_0 58
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
53
#define VERSAL_ADMA_IRQ_0 60
54
+#define VERSAL_SD0_IRQ_0 126
55
56
/* Architecturally reserved IRQs suitable for virtualization. */
57
#define VERSAL_RSVD_IRQ_FIRST 111
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
59
#define MM_FPD_CRF 0xfd1a0000U
60
#define MM_FPD_CRF_SIZE 0x140000
61
62
+#define MM_PMC_SD0 0xf1040000U
63
+#define MM_PMC_SD0_SIZE 0x10000
64
#define MM_PMC_CRP 0xf1260000U
65
#define MM_PMC_CRP_SIZE 0x10000
66
#endif
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
68
index XXXXXXX..XXXXXXX 100644
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;
56
+
79
+
57
+#include "qemu/bitops.h"
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
58
+#include "hw/sysbus.h"
81
+ DeviceState *dev;
82
+ MemoryRegion *mr;
59
+
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]);
60
+
88
+
61
+enum IMX7SNVSRegisters {
89
+ object_property_set_uint(OBJECT(dev),
62
+ SNVS_LPCR = 0x38,
90
+ 3, "sd-spec-version", &error_fatal);
63
+ SNVS_LPCR_TOP = BIT(6),
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
64
+ SNVS_LPCR_DP_EN = BIT(5)
92
+ &error_fatal);
65
+};
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
94
+ qdev_init_nofail(dev);
66
+
95
+
67
+#define TYPE_IMX7_SNVS "imx7.snvs"
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
68
+#define IMX7_SNVS(obj) OBJECT_CHECK(IMX7SNVSState, (obj), TYPE_IMX7_SNVS)
97
+ memory_region_add_subregion(&s->mr_ps,
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
69
+
99
+
70
+typedef struct IMX7SNVSState {
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
71
+ /* <private> */
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
72
+ SysBusDevice parent_obj;
73
+
74
+ MemoryRegion mmio;
75
+} IMX7SNVSState;
76
+
77
+#endif /* IMX7_SNVS_H */
78
diff --git a/hw/misc/imx7_snvs.c b/hw/misc/imx7_snvs.c
79
new file mode 100644
80
index XXXXXXX..XXXXXXX
81
--- /dev/null
82
+++ b/hw/misc/imx7_snvs.c
83
@@ -XXX,XX +XXX,XX @@
84
+/*
85
+ * IMX7 Secure Non-Volatile Storage
86
+ *
87
+ * Copyright (c) 2018, Impinj, Inc.
88
+ *
89
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
90
+ *
91
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
92
+ * See the COPYING file in the top-level directory.
93
+ *
94
+ * Bare minimum emulation code needed to support being able to shut
95
+ * down linux guest gracefully.
96
+ */
97
+
98
+#include "qemu/osdep.h"
99
+#include "hw/misc/imx7_snvs.h"
100
+#include "qemu/log.h"
101
+#include "sysemu/sysemu.h"
102
+
103
+static uint64_t imx7_snvs_read(void *opaque, hwaddr offset, unsigned size)
104
+{
105
+ return 0;
106
+}
107
+
108
+static void imx7_snvs_write(void *opaque, hwaddr offset,
109
+ uint64_t v, unsigned size)
110
+{
111
+ const uint32_t value = v;
112
+ const uint32_t mask = SNVS_LPCR_TOP | SNVS_LPCR_DP_EN;
113
+
114
+ if (offset == SNVS_LPCR && ((value & mask) == mask)) {
115
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
116
+ }
102
+ }
117
+}
103
+}
118
+
104
+
119
+static const struct MemoryRegionOps imx7_snvs_ops = {
105
/* This takes the board allocated linear DDR memory and creates aliases
120
+ .read = imx7_snvs_read,
106
* for each split DDR range/aperture on the Versal address map.
121
+ .write = imx7_snvs_write,
107
*/
122
+ .endianness = DEVICE_NATIVE_ENDIAN,
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
123
+ .impl = {
109
versal_create_uarts(s, pic);
124
+ /*
110
versal_create_gems(s, pic);
125
+ * Our device would not work correctly if the guest was doing
111
versal_create_admas(s, pic);
126
+ * unaligned access. This might not be a limitation on the real
112
+ versal_create_sds(s, pic);
127
+ * device but in practice there is no reason for a guest to access
113
versal_map_ddr(s);
128
+ * this device unaligned.
114
versal_unimp(s);
129
+ */
115
130
+ .min_access_size = 4,
131
+ .max_access_size = 4,
132
+ .unaligned = false,
133
+ },
134
+};
135
+
136
+static void imx7_snvs_init(Object *obj)
137
+{
138
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
139
+ IMX7SNVSState *s = IMX7_SNVS(obj);
140
+
141
+ memory_region_init_io(&s->mmio, obj, &imx7_snvs_ops, s,
142
+ TYPE_IMX7_SNVS, 0x1000);
143
+
144
+ sysbus_init_mmio(sd, &s->mmio);
145
+}
146
+
147
+static void imx7_snvs_class_init(ObjectClass *klass, void *data)
148
+{
149
+ DeviceClass *dc = DEVICE_CLASS(klass);
150
+
151
+ dc->desc = "i.MX7 Secure Non-Volatile Storage Module";
152
+}
153
+
154
+static const TypeInfo imx7_snvs_info = {
155
+ .name = TYPE_IMX7_SNVS,
156
+ .parent = TYPE_SYS_BUS_DEVICE,
157
+ .instance_size = sizeof(IMX7SNVSState),
158
+ .instance_init = imx7_snvs_init,
159
+ .class_init = imx7_snvs_class_init,
160
+};
161
+
162
+static void imx7_snvs_register_type(void)
163
+{
164
+ type_register_static(&imx7_snvs_info);
165
+}
166
+type_init(imx7_snvs_register_type)
167
--
116
--
168
2.16.1
117
2.20.1
169
118
170
119
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Add minimal code needed to allow upstream Linux guest to boot.
3
hw/arm: versal: Add support for the RTC.
4
4
5
Cc: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Cc: Jason Wang <jasowang@redhat.com>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Cc: Michael S. Tsirkin <mst@redhat.com>
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
11
---
17
hw/misc/Makefile.objs | 1 +
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
18
include/hw/misc/imx7_ccm.h | 139 +++++++++++++++++++++++
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
19
hw/misc/imx7_ccm.c | 277 +++++++++++++++++++++++++++++++++++++++++++++
14
2 files changed, 29 insertions(+)
20
3 files changed, 417 insertions(+)
21
create mode 100644 include/hw/misc/imx7_ccm.h
22
create mode 100644 hw/misc/imx7_ccm.c
23
15
24
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/misc/Makefile.objs
18
--- a/include/hw/arm/xlnx-versal.h
27
+++ b/hw/misc/Makefile.objs
19
+++ b/include/hw/arm/xlnx-versal.h
28
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx31_ccm.o
29
obj-$(CONFIG_IMX) += imx25_ccm.o
30
obj-$(CONFIG_IMX) += imx6_ccm.o
31
obj-$(CONFIG_IMX) += imx6_src.o
32
+obj-$(CONFIG_IMX) += imx7_ccm.o
33
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
34
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
35
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
36
diff --git a/include/hw/misc/imx7_ccm.h b/include/hw/misc/imx7_ccm.h
37
new file mode 100644
38
index XXXXXXX..XXXXXXX
39
--- /dev/null
40
+++ b/include/hw/misc/imx7_ccm.h
41
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
42
+/*
21
#include "hw/char/pl011.h"
43
+ * Copyright (c) 2017, Impinj, Inc.
22
#include "hw/dma/xlnx-zdma.h"
44
+ *
23
#include "hw/net/cadence_gem.h"
45
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
46
+ *
25
47
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
48
+ *
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
50
+ * See the COPYING file in the top-level directory.
29
struct {
51
+ */
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
31
} iou;
52
+
32
+
53
+#ifndef IMX7_CCM_H
33
+ XlnxZynqMPRTC rtc;
54
+#define IMX7_CCM_H
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
57
--- a/hw/arm/xlnx-versal.c
58
+++ b/hw/arm/xlnx-versal.c
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
60
}
61
}
62
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
64
+{
65
+ SysBusDevice *sbd;
66
+ MemoryRegion *mr;
55
+
67
+
56
+#include "hw/misc/imx_ccm.h"
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
57
+#include "qemu/bitops.h"
69
+ TYPE_XLNX_ZYNQMP_RTC);
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
71
+ qdev_init_nofail(DEVICE(sbd));
58
+
72
+
59
+enum IMX7AnalogRegisters {
73
+ mr = sysbus_mmio_get_region(sbd, 0);
60
+ ANALOG_PLL_ARM,
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
61
+ ANALOG_PLL_ARM_SET,
62
+ ANALOG_PLL_ARM_CLR,
63
+ ANALOG_PLL_ARM_TOG,
64
+ ANALOG_PLL_DDR,
65
+ ANALOG_PLL_DDR_SET,
66
+ ANALOG_PLL_DDR_CLR,
67
+ ANALOG_PLL_DDR_TOG,
68
+ ANALOG_PLL_DDR_SS,
69
+ ANALOG_PLL_DDR_SS_SET,
70
+ ANALOG_PLL_DDR_SS_CLR,
71
+ ANALOG_PLL_DDR_SS_TOG,
72
+ ANALOG_PLL_DDR_NUM,
73
+ ANALOG_PLL_DDR_NUM_SET,
74
+ ANALOG_PLL_DDR_NUM_CLR,
75
+ ANALOG_PLL_DDR_NUM_TOG,
76
+ ANALOG_PLL_DDR_DENOM,
77
+ ANALOG_PLL_DDR_DENOM_SET,
78
+ ANALOG_PLL_DDR_DENOM_CLR,
79
+ ANALOG_PLL_DDR_DENOM_TOG,
80
+ ANALOG_PLL_480,
81
+ ANALOG_PLL_480_SET,
82
+ ANALOG_PLL_480_CLR,
83
+ ANALOG_PLL_480_TOG,
84
+ ANALOG_PLL_480A,
85
+ ANALOG_PLL_480A_SET,
86
+ ANALOG_PLL_480A_CLR,
87
+ ANALOG_PLL_480A_TOG,
88
+ ANALOG_PLL_480B,
89
+ ANALOG_PLL_480B_SET,
90
+ ANALOG_PLL_480B_CLR,
91
+ ANALOG_PLL_480B_TOG,
92
+ ANALOG_PLL_ENET,
93
+ ANALOG_PLL_ENET_SET,
94
+ ANALOG_PLL_ENET_CLR,
95
+ ANALOG_PLL_ENET_TOG,
96
+ ANALOG_PLL_AUDIO,
97
+ ANALOG_PLL_AUDIO_SET,
98
+ ANALOG_PLL_AUDIO_CLR,
99
+ ANALOG_PLL_AUDIO_TOG,
100
+ ANALOG_PLL_AUDIO_SS,
101
+ ANALOG_PLL_AUDIO_SS_SET,
102
+ ANALOG_PLL_AUDIO_SS_CLR,
103
+ ANALOG_PLL_AUDIO_SS_TOG,
104
+ ANALOG_PLL_AUDIO_NUM,
105
+ ANALOG_PLL_AUDIO_NUM_SET,
106
+ ANALOG_PLL_AUDIO_NUM_CLR,
107
+ ANALOG_PLL_AUDIO_NUM_TOG,
108
+ ANALOG_PLL_AUDIO_DENOM,
109
+ ANALOG_PLL_AUDIO_DENOM_SET,
110
+ ANALOG_PLL_AUDIO_DENOM_CLR,
111
+ ANALOG_PLL_AUDIO_DENOM_TOG,
112
+ ANALOG_PLL_VIDEO,
113
+ ANALOG_PLL_VIDEO_SET,
114
+ ANALOG_PLL_VIDEO_CLR,
115
+ ANALOG_PLL_VIDEO_TOG,
116
+ ANALOG_PLL_VIDEO_SS,
117
+ ANALOG_PLL_VIDEO_SS_SET,
118
+ ANALOG_PLL_VIDEO_SS_CLR,
119
+ ANALOG_PLL_VIDEO_SS_TOG,
120
+ ANALOG_PLL_VIDEO_NUM,
121
+ ANALOG_PLL_VIDEO_NUM_SET,
122
+ ANALOG_PLL_VIDEO_NUM_CLR,
123
+ ANALOG_PLL_VIDEO_NUM_TOG,
124
+ ANALOG_PLL_VIDEO_DENOM,
125
+ ANALOG_PLL_VIDEO_DENOM_SET,
126
+ ANALOG_PLL_VIDEO_DENOM_CLR,
127
+ ANALOG_PLL_VIDEO_DENOM_TOG,
128
+ ANALOG_PLL_MISC0,
129
+ ANALOG_PLL_MISC0_SET,
130
+ ANALOG_PLL_MISC0_CLR,
131
+ ANALOG_PLL_MISC0_TOG,
132
+
133
+ ANALOG_DIGPROG = 0x800 / sizeof(uint32_t),
134
+ ANALOG_MAX,
135
+
136
+ ANALOG_PLL_LOCK = BIT(31)
137
+};
138
+
139
+enum IMX7CCMRegisters {
140
+ CCM_MAX = 0xBE00 / sizeof(uint32_t) + 1,
141
+};
142
+
143
+enum IMX7PMURegisters {
144
+ PMU_MAX = 0x140 / sizeof(uint32_t),
145
+};
146
+
147
+#define TYPE_IMX7_CCM "imx7.ccm"
148
+#define IMX7_CCM(obj) OBJECT_CHECK(IMX7CCMState, (obj), TYPE_IMX7_CCM)
149
+
150
+typedef struct IMX7CCMState {
151
+ /* <private> */
152
+ IMXCCMState parent_obj;
153
+
154
+ /* <public> */
155
+ MemoryRegion iomem;
156
+
157
+ uint32_t ccm[CCM_MAX];
158
+} IMX7CCMState;
159
+
160
+
161
+#define TYPE_IMX7_ANALOG "imx7.analog"
162
+#define IMX7_ANALOG(obj) OBJECT_CHECK(IMX7AnalogState, (obj), TYPE_IMX7_ANALOG)
163
+
164
+typedef struct IMX7AnalogState {
165
+ /* <private> */
166
+ IMXCCMState parent_obj;
167
+
168
+ /* <public> */
169
+ struct {
170
+ MemoryRegion container;
171
+ MemoryRegion analog;
172
+ MemoryRegion digprog;
173
+ MemoryRegion pmu;
174
+ } mmio;
175
+
176
+ uint32_t analog[ANALOG_MAX];
177
+ uint32_t pmu[PMU_MAX];
178
+} IMX7AnalogState;
179
+
180
+#endif /* IMX7_CCM_H */
181
diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c
182
new file mode 100644
183
index XXXXXXX..XXXXXXX
184
--- /dev/null
185
+++ b/hw/misc/imx7_ccm.c
186
@@ -XXX,XX +XXX,XX @@
187
+/*
188
+ * Copyright (c) 2018, Impinj, Inc.
189
+ *
190
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
191
+ *
192
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
193
+ *
194
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
195
+ * See the COPYING file in the top-level directory.
196
+ */
197
+
198
+#include "qemu/osdep.h"
199
+#include "qemu/log.h"
200
+
201
+#include "hw/misc/imx7_ccm.h"
202
+
203
+static void imx7_analog_reset(DeviceState *dev)
204
+{
205
+ IMX7AnalogState *s = IMX7_ANALOG(dev);
206
+
207
+ memset(s->pmu, 0, sizeof(s->pmu));
208
+ memset(s->analog, 0, sizeof(s->analog));
209
+
210
+ s->analog[ANALOG_PLL_ARM] = 0x00002042;
211
+ s->analog[ANALOG_PLL_DDR] = 0x0060302c;
212
+ s->analog[ANALOG_PLL_DDR_SS] = 0x00000000;
213
+ s->analog[ANALOG_PLL_DDR_NUM] = 0x06aaac4d;
214
+ s->analog[ANALOG_PLL_DDR_DENOM] = 0x100003ec;
215
+ s->analog[ANALOG_PLL_480] = 0x00002000;
216
+ s->analog[ANALOG_PLL_480A] = 0x52605a56;
217
+ s->analog[ANALOG_PLL_480B] = 0x52525216;
218
+ s->analog[ANALOG_PLL_ENET] = 0x00001fc0;
219
+ s->analog[ANALOG_PLL_AUDIO] = 0x0001301b;
220
+ s->analog[ANALOG_PLL_AUDIO_SS] = 0x00000000;
221
+ s->analog[ANALOG_PLL_AUDIO_NUM] = 0x05f5e100;
222
+ s->analog[ANALOG_PLL_AUDIO_DENOM] = 0x2964619c;
223
+ s->analog[ANALOG_PLL_VIDEO] = 0x0008201b;
224
+ s->analog[ANALOG_PLL_VIDEO_SS] = 0x00000000;
225
+ s->analog[ANALOG_PLL_VIDEO_NUM] = 0x0000f699;
226
+ s->analog[ANALOG_PLL_VIDEO_DENOM] = 0x000f4240;
227
+ s->analog[ANALOG_PLL_MISC0] = 0x00000000;
228
+
229
+ /* all PLLs need to be locked */
230
+ s->analog[ANALOG_PLL_ARM] |= ANALOG_PLL_LOCK;
231
+ s->analog[ANALOG_PLL_DDR] |= ANALOG_PLL_LOCK;
232
+ s->analog[ANALOG_PLL_480] |= ANALOG_PLL_LOCK;
233
+ s->analog[ANALOG_PLL_480A] |= ANALOG_PLL_LOCK;
234
+ s->analog[ANALOG_PLL_480B] |= ANALOG_PLL_LOCK;
235
+ s->analog[ANALOG_PLL_ENET] |= ANALOG_PLL_LOCK;
236
+ s->analog[ANALOG_PLL_AUDIO] |= ANALOG_PLL_LOCK;
237
+ s->analog[ANALOG_PLL_VIDEO] |= ANALOG_PLL_LOCK;
238
+ s->analog[ANALOG_PLL_MISC0] |= ANALOG_PLL_LOCK;
239
+
75
+
240
+ /*
76
+ /*
241
+ * Since I couldn't find any info about this in the reference
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
242
+ * manual the value of this register is based strictly on matching
78
+ * supports them.
243
+ * what Linux kernel expects it to be.
244
+ */
79
+ */
245
+ s->analog[ANALOG_DIGPROG] = 0x720000;
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
246
+ /*
247
+ * Set revision to be 1.0 (Arbitrary choice, no particular
248
+ * reason).
249
+ */
250
+ s->analog[ANALOG_DIGPROG] |= 0x000010;
251
+}
81
+}
252
+
82
+
253
+static void imx7_ccm_reset(DeviceState *dev)
83
/* This takes the board allocated linear DDR memory and creates aliases
254
+{
84
* for each split DDR range/aperture on the Versal address map.
255
+ IMX7CCMState *s = IMX7_CCM(dev);
85
*/
256
+
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
257
+ memset(s->ccm, 0, sizeof(s->ccm));
87
versal_create_gems(s, pic);
258
+}
88
versal_create_admas(s, pic);
259
+
89
versal_create_sds(s, pic);
260
+#define CCM_INDEX(offset) (((offset) & ~(hwaddr)0xF) / sizeof(uint32_t))
90
+ versal_create_rtc(s, pic);
261
+#define CCM_BITOP(offset) ((offset) & (hwaddr)0xF)
91
versal_map_ddr(s);
262
+
92
versal_unimp(s);
263
+enum {
93
264
+ CCM_BITOP_NONE = 0x00,
265
+ CCM_BITOP_SET = 0x04,
266
+ CCM_BITOP_CLR = 0x08,
267
+ CCM_BITOP_TOG = 0x0C,
268
+};
269
+
270
+static uint64_t imx7_set_clr_tog_read(void *opaque, hwaddr offset,
271
+ unsigned size)
272
+{
273
+ const uint32_t *mmio = opaque;
274
+
275
+ return mmio[CCM_INDEX(offset)];
276
+}
277
+
278
+static void imx7_set_clr_tog_write(void *opaque, hwaddr offset,
279
+ uint64_t value, unsigned size)
280
+{
281
+ const uint8_t bitop = CCM_BITOP(offset);
282
+ const uint32_t index = CCM_INDEX(offset);
283
+ uint32_t *mmio = opaque;
284
+
285
+ switch (bitop) {
286
+ case CCM_BITOP_NONE:
287
+ mmio[index] = value;
288
+ break;
289
+ case CCM_BITOP_SET:
290
+ mmio[index] |= value;
291
+ break;
292
+ case CCM_BITOP_CLR:
293
+ mmio[index] &= ~value;
294
+ break;
295
+ case CCM_BITOP_TOG:
296
+ mmio[index] ^= value;
297
+ break;
298
+ };
299
+}
300
+
301
+static const struct MemoryRegionOps imx7_set_clr_tog_ops = {
302
+ .read = imx7_set_clr_tog_read,
303
+ .write = imx7_set_clr_tog_write,
304
+ .endianness = DEVICE_NATIVE_ENDIAN,
305
+ .impl = {
306
+ /*
307
+ * Our device would not work correctly if the guest was doing
308
+ * unaligned access. This might not be a limitation on the real
309
+ * device but in practice there is no reason for a guest to access
310
+ * this device unaligned.
311
+ */
312
+ .min_access_size = 4,
313
+ .max_access_size = 4,
314
+ .unaligned = false,
315
+ },
316
+};
317
+
318
+static const struct MemoryRegionOps imx7_digprog_ops = {
319
+ .read = imx7_set_clr_tog_read,
320
+ .endianness = DEVICE_NATIVE_ENDIAN,
321
+ .impl = {
322
+ .min_access_size = 4,
323
+ .max_access_size = 4,
324
+ .unaligned = false,
325
+ },
326
+};
327
+
328
+static void imx7_ccm_init(Object *obj)
329
+{
330
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
331
+ IMX7CCMState *s = IMX7_CCM(obj);
332
+
333
+ memory_region_init_io(&s->iomem,
334
+ obj,
335
+ &imx7_set_clr_tog_ops,
336
+ s->ccm,
337
+ TYPE_IMX7_CCM ".ccm",
338
+ sizeof(s->ccm));
339
+
340
+ sysbus_init_mmio(sd, &s->iomem);
341
+}
342
+
343
+static void imx7_analog_init(Object *obj)
344
+{
345
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
346
+ IMX7AnalogState *s = IMX7_ANALOG(obj);
347
+
348
+ memory_region_init(&s->mmio.container, obj, TYPE_IMX7_ANALOG,
349
+ 0x10000);
350
+
351
+ memory_region_init_io(&s->mmio.analog,
352
+ obj,
353
+ &imx7_set_clr_tog_ops,
354
+ s->analog,
355
+ TYPE_IMX7_ANALOG,
356
+ sizeof(s->analog));
357
+
358
+ memory_region_add_subregion(&s->mmio.container,
359
+ 0x60, &s->mmio.analog);
360
+
361
+ memory_region_init_io(&s->mmio.pmu,
362
+ obj,
363
+ &imx7_set_clr_tog_ops,
364
+ s->pmu,
365
+ TYPE_IMX7_ANALOG ".pmu",
366
+ sizeof(s->pmu));
367
+
368
+ memory_region_add_subregion(&s->mmio.container,
369
+ 0x200, &s->mmio.pmu);
370
+
371
+ memory_region_init_io(&s->mmio.digprog,
372
+ obj,
373
+ &imx7_digprog_ops,
374
+ &s->analog[ANALOG_DIGPROG],
375
+ TYPE_IMX7_ANALOG ".digprog",
376
+ sizeof(uint32_t));
377
+
378
+ memory_region_add_subregion_overlap(&s->mmio.container,
379
+ 0x800, &s->mmio.digprog, 10);
380
+
381
+
382
+ sysbus_init_mmio(sd, &s->mmio.container);
383
+}
384
+
385
+static const VMStateDescription vmstate_imx7_ccm = {
386
+ .name = TYPE_IMX7_CCM,
387
+ .version_id = 1,
388
+ .minimum_version_id = 1,
389
+ .fields = (VMStateField[]) {
390
+ VMSTATE_UINT32_ARRAY(ccm, IMX7CCMState, CCM_MAX),
391
+ VMSTATE_END_OF_LIST()
392
+ },
393
+};
394
+
395
+static uint32_t imx7_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
396
+{
397
+ /*
398
+ * This function is "consumed" by GPT emulation code, however on
399
+ * i.MX7 each GPT block can have their own clock root. This means
400
+ * that this functions needs somehow to know requester's identity
401
+ * and the way to pass it: be it via additional IMXClk constants
402
+ * or by adding another argument to this method needs to be
403
+ * figured out
404
+ */
405
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Not implemented\n",
406
+ TYPE_IMX7_CCM, __func__);
407
+ return 0;
408
+}
409
+
410
+static void imx7_ccm_class_init(ObjectClass *klass, void *data)
411
+{
412
+ DeviceClass *dc = DEVICE_CLASS(klass);
413
+ IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
414
+
415
+ dc->reset = imx7_ccm_reset;
416
+ dc->vmsd = &vmstate_imx7_ccm;
417
+ dc->desc = "i.MX7 Clock Control Module";
418
+
419
+ ccm->get_clock_frequency = imx7_ccm_get_clock_frequency;
420
+}
421
+
422
+static const TypeInfo imx7_ccm_info = {
423
+ .name = TYPE_IMX7_CCM,
424
+ .parent = TYPE_IMX_CCM,
425
+ .instance_size = sizeof(IMX7CCMState),
426
+ .instance_init = imx7_ccm_init,
427
+ .class_init = imx7_ccm_class_init,
428
+};
429
+
430
+static const VMStateDescription vmstate_imx7_analog = {
431
+ .name = TYPE_IMX7_ANALOG,
432
+ .version_id = 1,
433
+ .minimum_version_id = 1,
434
+ .fields = (VMStateField[]) {
435
+ VMSTATE_UINT32_ARRAY(analog, IMX7AnalogState, ANALOG_MAX),
436
+ VMSTATE_UINT32_ARRAY(pmu, IMX7AnalogState, PMU_MAX),
437
+ VMSTATE_END_OF_LIST()
438
+ },
439
+};
440
+
441
+static void imx7_analog_class_init(ObjectClass *klass, void *data)
442
+{
443
+ DeviceClass *dc = DEVICE_CLASS(klass);
444
+
445
+ dc->reset = imx7_analog_reset;
446
+ dc->vmsd = &vmstate_imx7_analog;
447
+ dc->desc = "i.MX7 Analog Module";
448
+}
449
+
450
+static const TypeInfo imx7_analog_info = {
451
+ .name = TYPE_IMX7_ANALOG,
452
+ .parent = TYPE_SYS_BUS_DEVICE,
453
+ .instance_size = sizeof(IMX7AnalogState),
454
+ .instance_init = imx7_analog_init,
455
+ .class_init = imx7_analog_class_init,
456
+};
457
+
458
+static void imx7_ccm_register_type(void)
459
+{
460
+ type_register_static(&imx7_ccm_info);
461
+ type_register_static(&imx7_analog_info);
462
+}
463
+type_init(imx7_ccm_register_type)
464
--
94
--
465
2.16.1
95
2.20.1
466
96
467
97
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Add code to emulate Chipidea USB IP (used in i.MX SoCs). Tested to
3
Add support for SD.
4
work against:
5
4
6
-usb -drive if=none,id=stick,file=usb.img,format=raw -device \
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
usb-storage,bus=usb-bus.0,drive=stick
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Cc: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
10
Cc: Jason Wang <jasowang@redhat.com>
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
13
Cc: Michael S. Tsirkin <mst@redhat.com>
14
Cc: qemu-devel@nongnu.org
15
Cc: qemu-arm@nongnu.org
16
Cc: yurovsky@gmail.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
hw/usb/Makefile.objs | 1 +
11
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
22
include/hw/usb/chipidea.h | 16 +++++
12
1 file changed, 46 insertions(+)
23
hw/usb/chipidea.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++
24
3 files changed, 193 insertions(+)
25
create mode 100644 include/hw/usb/chipidea.h
26
create mode 100644 hw/usb/chipidea.c
27
13
28
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
29
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/usb/Makefile.objs
16
--- a/hw/arm/xlnx-versal-virt.c
31
+++ b/hw/usb/Makefile.objs
17
+++ b/hw/arm/xlnx-versal-virt.c
32
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o
33
common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
34
35
obj-$(CONFIG_TUSB6010) += tusb6010.o
36
+obj-$(CONFIG_IMX) += chipidea.o
37
38
# emulated usb devices
39
common-obj-$(CONFIG_USB) += dev-hub.o
40
diff --git a/include/hw/usb/chipidea.h b/include/hw/usb/chipidea.h
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/include/hw/usb/chipidea.h
45
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
46
+#ifndef CHIPIDEA_H
19
#include "hw/arm/sysbus-fdt.h"
47
+#define CHIPIDEA_H
20
#include "hw/arm/fdt.h"
48
+
21
#include "cpu.h"
49
+#include "hw/usb/hcd-ehci.h"
22
+#include "hw/qdev-properties.h"
50
+
23
#include "hw/arm/xlnx-versal.h"
51
+typedef struct ChipideaState {
24
52
+ /*< private >*/
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
53
+ EHCISysBusState parent_obj;
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
54
+
27
}
55
+ MemoryRegion iomem[3];
28
}
56
+} ChipideaState;
29
57
+
30
+static void fdt_add_sd_nodes(VersalVirt *s)
58
+#define TYPE_CHIPIDEA "usb-chipidea"
59
+#define CHIPIDEA(obj) OBJECT_CHECK(ChipideaState, (obj), TYPE_CHIPIDEA)
60
+
61
+#endif /* CHIPIDEA_H */
62
diff --git a/hw/usb/chipidea.c b/hw/usb/chipidea.c
63
new file mode 100644
64
index XXXXXXX..XXXXXXX
65
--- /dev/null
66
+++ b/hw/usb/chipidea.c
67
@@ -XXX,XX +XXX,XX @@
68
+/*
69
+ * Copyright (c) 2018, Impinj, Inc.
70
+ *
71
+ * Chipidea USB block emulation code
72
+ *
73
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
74
+ *
75
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
76
+ * See the COPYING file in the top-level directory.
77
+ */
78
+
79
+#include "qemu/osdep.h"
80
+#include "hw/usb/hcd-ehci.h"
81
+#include "hw/usb/chipidea.h"
82
+#include "qemu/log.h"
83
+
84
+enum {
85
+ CHIPIDEA_USBx_DCIVERSION = 0x000,
86
+ CHIPIDEA_USBx_DCCPARAMS = 0x004,
87
+ CHIPIDEA_USBx_DCCPARAMS_HC = BIT(8),
88
+};
89
+
90
+static uint64_t chipidea_read(void *opaque, hwaddr offset,
91
+ unsigned size)
92
+{
31
+{
93
+ return 0;
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
94
+}
33
+ const char compat[] = "arasan,sdhci-8.9a";
95
+
96
+static void chipidea_write(void *opaque, hwaddr offset,
97
+ uint64_t value, unsigned size)
98
+{
99
+}
100
+
101
+static const struct MemoryRegionOps chipidea_ops = {
102
+ .read = chipidea_read,
103
+ .write = chipidea_write,
104
+ .endianness = DEVICE_NATIVE_ENDIAN,
105
+ .impl = {
106
+ /*
107
+ * Our device would not work correctly if the guest was doing
108
+ * unaligned access. This might not be a limitation on the
109
+ * real device but in practice there is no reason for a guest
110
+ * to access this device unaligned.
111
+ */
112
+ .min_access_size = 4,
113
+ .max_access_size = 4,
114
+ .unaligned = false,
115
+ },
116
+};
117
+
118
+static uint64_t chipidea_dc_read(void *opaque, hwaddr offset,
119
+ unsigned size)
120
+{
121
+ switch (offset) {
122
+ case CHIPIDEA_USBx_DCIVERSION:
123
+ return 0x1;
124
+ case CHIPIDEA_USBx_DCCPARAMS:
125
+ /*
126
+ * Real hardware (at least i.MX7) will also report the
127
+ * controller as "Device Capable" (and 8 supported endpoints),
128
+ * but there doesn't seem to be much point in doing so, since
129
+ * we don't emulate that part.
130
+ */
131
+ return CHIPIDEA_USBx_DCCPARAMS_HC;
132
+ }
133
+
134
+ return 0;
135
+}
136
+
137
+static void chipidea_dc_write(void *opaque, hwaddr offset,
138
+ uint64_t value, unsigned size)
139
+{
140
+}
141
+
142
+static const struct MemoryRegionOps chipidea_dc_ops = {
143
+ .read = chipidea_dc_read,
144
+ .write = chipidea_dc_write,
145
+ .endianness = DEVICE_NATIVE_ENDIAN,
146
+ .impl = {
147
+ /*
148
+ * Our device would not work correctly if the guest was doing
149
+ * unaligned access. This might not be a limitation on the real
150
+ * device but in practice there is no reason for a guest to access
151
+ * this device unaligned.
152
+ */
153
+ .min_access_size = 4,
154
+ .max_access_size = 4,
155
+ .unaligned = false,
156
+ },
157
+};
158
+
159
+static void chipidea_init(Object *obj)
160
+{
161
+ EHCIState *ehci = &SYS_BUS_EHCI(obj)->ehci;
162
+ ChipideaState *ci = CHIPIDEA(obj);
163
+ int i;
34
+ int i;
164
+
35
+
165
+ for (i = 0; i < ARRAY_SIZE(ci->iomem); i++) {
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
166
+ const struct {
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
167
+ const char *name;
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
168
+ hwaddr offset;
169
+ uint64_t size;
170
+ const struct MemoryRegionOps *ops;
171
+ } regions[ARRAY_SIZE(ci->iomem)] = {
172
+ /*
173
+ * Registers located between offsets 0x000 and 0xFC
174
+ */
175
+ {
176
+ .name = TYPE_CHIPIDEA ".misc",
177
+ .offset = 0x000,
178
+ .size = 0x100,
179
+ .ops = &chipidea_ops,
180
+ },
181
+ /*
182
+ * Registers located between offsets 0x1A4 and 0x1DC
183
+ */
184
+ {
185
+ .name = TYPE_CHIPIDEA ".endpoints",
186
+ .offset = 0x1A4,
187
+ .size = 0x1DC - 0x1A4 + 4,
188
+ .ops = &chipidea_ops,
189
+ },
190
+ /*
191
+ * USB_x_DCIVERSION and USB_x_DCCPARAMS
192
+ */
193
+ {
194
+ .name = TYPE_CHIPIDEA ".dc",
195
+ .offset = 0x120,
196
+ .size = 8,
197
+ .ops = &chipidea_dc_ops,
198
+ },
199
+ };
200
+
39
+
201
+ memory_region_init_io(&ci->iomem[i],
40
+ qemu_fdt_add_subnode(s->fdt, name);
202
+ obj,
203
+ regions[i].ops,
204
+ ci,
205
+ regions[i].name,
206
+ regions[i].size);
207
+
41
+
208
+ memory_region_add_subregion(&ehci->mem,
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
209
+ regions[i].offset,
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
210
+ &ci->iomem[i]);
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);
211
+ }
53
+ }
212
+}
54
+}
213
+
55
+
214
+static void chipidea_class_init(ObjectClass *klass, void *data)
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
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)
215
+{
64
+{
216
+ DeviceClass *dc = DEVICE_CLASS(klass);
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
217
+ SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(klass);
66
+ DeviceState *card;
218
+
67
+
219
+ /*
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
220
+ * Offsets used were taken from i.MX7Dual Applications Processor
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
221
+ * Reference Manual, Rev 0.1, p. 3177, Table 11-59
70
+ &error_fatal);
222
+ */
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
223
+ sec->capsbase = 0x100;
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
224
+ sec->opregbase = 0x140;
225
+ sec->portnr = 1;
226
+
227
+ set_bit(DEVICE_CATEGORY_USB, dc->categories);
228
+ dc->desc = "Chipidea USB Module";
229
+}
73
+}
230
+
74
+
231
+static const TypeInfo chipidea_info = {
75
static void versal_virt_init(MachineState *machine)
232
+ .name = TYPE_CHIPIDEA,
76
{
233
+ .parent = TYPE_SYS_BUS_EHCI,
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
234
+ .instance_size = sizeof(ChipideaState),
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
235
+ .instance_init = chipidea_init,
79
+ int i;
236
+ .class_init = chipidea_class_init,
80
237
+};
81
/*
82
* If the user provides an Operating System to be loaded, we expect them
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
84
fdt_add_gic_nodes(s);
85
fdt_add_timer_nodes(s);
86
fdt_add_zdma_nodes(s);
87
+ fdt_add_sd_nodes(s);
88
fdt_add_cpu_nodes(s, psci_conduit);
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
92
memory_region_add_subregion_overlap(get_system_memory(),
93
0, &s->soc.fpd.apu.mr, 0);
94
95
+ /* Plugin SD cards. */
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
98
+ }
238
+
99
+
239
+static void chipidea_register_type(void)
100
s->binfo.ram_size = machine->ram_size;
240
+{
101
s->binfo.loader_start = 0x0;
241
+ type_register_static(&chipidea_info);
102
s->binfo.get_dtb = versal_virt_get_dtb;
242
+}
243
+type_init(chipidea_register_type)
244
--
103
--
245
2.16.1
104
2.20.1
246
105
247
106
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Add enough code to emulate i.MX2 watchdog IP block so it would be
3
Add support for the RTC.
4
possible to reboot the machine running Linux Guest.
5
4
6
Cc: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Cc: Jason Wang <jasowang@redhat.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
10
Cc: Michael S. Tsirkin <mst@redhat.com>
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
hw/misc/Makefile.objs | 1 +
11
hw/arm/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
20
include/hw/misc/imx2_wdt.h | 33 +++++++++++++++++
12
1 file changed, 22 insertions(+)
21
hw/misc/imx2_wdt.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++
22
3 files changed, 123 insertions(+)
23
create mode 100644 include/hw/misc/imx2_wdt.h
24
create mode 100644 hw/misc/imx2_wdt.c
25
13
26
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/misc/Makefile.objs
16
--- a/hw/arm/xlnx-versal-virt.c
29
+++ b/hw/misc/Makefile.objs
17
+++ b/hw/arm/xlnx-versal-virt.c
30
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx25_ccm.o
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
31
obj-$(CONFIG_IMX) += imx6_ccm.o
19
}
32
obj-$(CONFIG_IMX) += imx6_src.o
20
}
33
obj-$(CONFIG_IMX) += imx7_ccm.o
21
34
+obj-$(CONFIG_IMX) += imx2_wdt.o
22
+static void fdt_add_rtc_node(VersalVirt *s)
35
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
23
+{
36
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
24
+ const char compat[] = "xlnx,zynqmp-rtc";
37
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
25
+ const char interrupt_names[] = "alarm\0sec";
38
diff --git a/include/hw/misc/imx2_wdt.h b/include/hw/misc/imx2_wdt.h
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
39
new file mode 100644
40
index XXXXXXX..XXXXXXX
41
--- /dev/null
42
+++ b/include/hw/misc/imx2_wdt.h
43
@@ -XXX,XX +XXX,XX @@
44
+/*
45
+ * Copyright (c) 2017, Impinj, Inc.
46
+ *
47
+ * i.MX2 Watchdog IP block
48
+ *
49
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
50
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
53
+ */
54
+
27
+
55
+#ifndef IMX2_WDT_H
28
+ qemu_fdt_add_subnode(s->fdt, name);
56
+#define IMX2_WDT_H
57
+
29
+
58
+#include "hw/sysbus.h"
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
59
+
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
60
+#define TYPE_IMX2_WDT "imx2.wdt"
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
61
+#define IMX2_WDT(obj) OBJECT_CHECK(IMX2WdtState, (obj), TYPE_IMX2_WDT)
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
62
+
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
63
+enum IMX2WdtRegisters {
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
64
+ IMX2_WDT_WCR = 0x0000,
36
+ interrupt_names, sizeof(interrupt_names));
65
+ IMX2_WDT_REG_NUM = 0x0008 / sizeof(uint16_t) + 1,
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
66
+};
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
67
+
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
68
+
40
+ g_free(name);
69
+typedef struct IMX2WdtState {
70
+ /* <private> */
71
+ SysBusDevice parent_obj;
72
+
73
+ MemoryRegion mmio;
74
+} IMX2WdtState;
75
+
76
+#endif /* IMX7_SNVS_H */
77
diff --git a/hw/misc/imx2_wdt.c b/hw/misc/imx2_wdt.c
78
new file mode 100644
79
index XXXXXXX..XXXXXXX
80
--- /dev/null
81
+++ b/hw/misc/imx2_wdt.c
82
@@ -XXX,XX +XXX,XX @@
83
+/*
84
+ * Copyright (c) 2018, Impinj, Inc.
85
+ *
86
+ * i.MX2 Watchdog IP block
87
+ *
88
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
89
+ *
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
91
+ * See the COPYING file in the top-level directory.
92
+ */
93
+
94
+#include "qemu/osdep.h"
95
+#include "qemu/bitops.h"
96
+#include "sysemu/watchdog.h"
97
+
98
+#include "hw/misc/imx2_wdt.h"
99
+
100
+#define IMX2_WDT_WCR_WDA BIT(5) /* -> External Reset WDOG_B */
101
+#define IMX2_WDT_WCR_SRS BIT(4) /* -> Software Reset Signal */
102
+
103
+static uint64_t imx2_wdt_read(void *opaque, hwaddr addr,
104
+ unsigned int size)
105
+{
106
+ return 0;
107
+}
41
+}
108
+
42
+
109
+static void imx2_wdt_write(void *opaque, hwaddr addr,
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
110
+ uint64_t value, unsigned int size)
44
{
111
+{
45
Error *err = NULL;
112
+ if (addr == IMX2_WDT_WCR &&
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
113
+ (value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) {
47
fdt_add_timer_nodes(s);
114
+ watchdog_perform_action();
48
fdt_add_zdma_nodes(s);
115
+ }
49
fdt_add_sd_nodes(s);
116
+}
50
+ fdt_add_rtc_node(s);
117
+
51
fdt_add_cpu_nodes(s, psci_conduit);
118
+static const MemoryRegionOps imx2_wdt_ops = {
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
119
+ .read = imx2_wdt_read,
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
120
+ .write = imx2_wdt_write,
121
+ .endianness = DEVICE_NATIVE_ENDIAN,
122
+ .impl = {
123
+ /*
124
+ * Our device would not work correctly if the guest was doing
125
+ * unaligned access. This might not be a limitation on the
126
+ * real device but in practice there is no reason for a guest
127
+ * to access this device unaligned.
128
+ */
129
+ .min_access_size = 4,
130
+ .max_access_size = 4,
131
+ .unaligned = false,
132
+ },
133
+};
134
+
135
+static void imx2_wdt_realize(DeviceState *dev, Error **errp)
136
+{
137
+ IMX2WdtState *s = IMX2_WDT(dev);
138
+
139
+ memory_region_init_io(&s->mmio, OBJECT(dev),
140
+ &imx2_wdt_ops, s,
141
+ TYPE_IMX2_WDT".mmio",
142
+ IMX2_WDT_REG_NUM * sizeof(uint16_t));
143
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
144
+}
145
+
146
+static void imx2_wdt_class_init(ObjectClass *klass, void *data)
147
+{
148
+ DeviceClass *dc = DEVICE_CLASS(klass);
149
+
150
+ dc->realize = imx2_wdt_realize;
151
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
152
+}
153
+
154
+static const TypeInfo imx2_wdt_info = {
155
+ .name = TYPE_IMX2_WDT,
156
+ .parent = TYPE_SYS_BUS_DEVICE,
157
+ .instance_size = sizeof(IMX2WdtState),
158
+ .class_init = imx2_wdt_class_init,
159
+};
160
+
161
+static WatchdogTimerModel model = {
162
+ .wdt_name = "imx2-watchdog",
163
+ .wdt_description = "i.MX2 Watchdog",
164
+};
165
+
166
+static void imx2_wdt_register_type(void)
167
+{
168
+ watchdog_add_model(&model);
169
+ type_register_static(&imx2_wdt_info);
170
+}
171
+type_init(imx2_wdt_register_type)
172
--
54
--
173
2.16.1
55
2.20.1
174
56
175
57
diff view generated by jsdifflib
1
Make v7m_push_callee_stack() honour the MPU by using the
1
Somewhere along theline we accidentally added a duplicate
2
new v7m_stack_write() function. We return a flag to indicate
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
3
whether the pushes failed, which we can then use in
3
(probably an artifact of a patchseries rebase). Remove it.
4
v7m_exception_taken() to cause us to handle the derived
5
exception correctly.
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 1517324542-6607-6-git-send-email-peter.maydell@linaro.org
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
11
---
9
---
12
target/arm/helper.c | 64 ++++++++++++++++++++++++++++++++++++++++-------------
10
target/arm/translate-vfp.inc.c | 6 ------
13
1 file changed, 49 insertions(+), 15 deletions(-)
11
1 file changed, 6 deletions(-)
14
12
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
15
--- a/target/arm/translate-vfp.inc.c
18
+++ b/target/arm/helper.c
16
+++ b/target/arm/translate-vfp.inc.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
20
return addr;
18
return false;
21
}
22
23
-static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
24
+static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
25
bool ignore_faults)
26
{
27
/* For v8M, push the callee-saves register part of the stack frame.
28
@@ -XXX,XX +XXX,XX @@ static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
29
* In the tailchaining case this may not be the current stack.
30
*/
31
CPUARMState *env = &cpu->env;
32
- CPUState *cs = CPU(cpu);
33
uint32_t *frame_sp_p;
34
uint32_t frameptr;
35
+ ARMMMUIdx mmu_idx;
36
+ bool stacked_ok;
37
38
if (dotailchain) {
39
- frame_sp_p = get_v7m_sp_ptr(env, true,
40
- lr & R_V7M_EXCRET_MODE_MASK,
41
+ bool mode = lr & R_V7M_EXCRET_MODE_MASK;
42
+ bool priv = !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_NPRIV_MASK) ||
43
+ !mode;
44
+
45
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, M_REG_S, priv);
46
+ frame_sp_p = get_v7m_sp_ptr(env, M_REG_S, mode,
47
lr & R_V7M_EXCRET_SPSEL_MASK);
48
} else {
49
+ mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
50
frame_sp_p = &env->regs[13];
51
}
19
}
52
20
53
frameptr = *frame_sp_p - 0x28;
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
54
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
55
- stl_phys(cs->as, frameptr, 0xfefa125b);
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
56
- stl_phys(cs->as, frameptr + 0x8, env->regs[4]);
24
- return false;
57
- stl_phys(cs->as, frameptr + 0xc, env->regs[5]);
25
- }
58
- stl_phys(cs->as, frameptr + 0x10, env->regs[6]);
26
-
59
- stl_phys(cs->as, frameptr + 0x14, env->regs[7]);
27
if (!vfp_access_check(s)) {
60
- stl_phys(cs->as, frameptr + 0x18, env->regs[8]);
28
return true;
61
- stl_phys(cs->as, frameptr + 0x1c, env->regs[9]);
62
- stl_phys(cs->as, frameptr + 0x20, env->regs[10]);
63
- stl_phys(cs->as, frameptr + 0x24, env->regs[11]);
64
+ /* Write as much of the stack frame as we can. A write failure may
65
+ * cause us to pend a derived exception.
66
+ */
67
+ stacked_ok =
68
+ v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
69
+ v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
70
+ ignore_faults) &&
71
+ v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
72
+ ignore_faults) &&
73
+ v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx,
74
+ ignore_faults) &&
75
+ v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx,
76
+ ignore_faults) &&
77
+ v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx,
78
+ ignore_faults) &&
79
+ v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx,
80
+ ignore_faults) &&
81
+ v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx,
82
+ ignore_faults) &&
83
+ v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx,
84
+ ignore_faults);
85
86
+ /* Update SP regardless of whether any of the stack accesses failed.
87
+ * When we implement v8M stack limit checking then this attempt to
88
+ * update SP might also fail and result in a derived exception.
89
+ */
90
*frame_sp_p = frameptr;
91
+
92
+ return !stacked_ok;
93
}
94
95
static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
96
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
97
uint32_t addr;
98
bool targets_secure;
99
int exc;
100
+ bool push_failed = false;
101
102
armv7m_nvic_get_pending_irq_info(env->nvic, &exc, &targets_secure);
103
104
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
105
*/
106
if (lr & R_V7M_EXCRET_DCRS_MASK &&
107
!(dotailchain && (lr & R_V7M_EXCRET_ES_MASK))) {
108
- v7m_push_callee_stack(cpu, lr, dotailchain,
109
- ignore_stackfaults);
110
+ push_failed = v7m_push_callee_stack(cpu, lr, dotailchain,
111
+ ignore_stackfaults);
112
}
113
lr |= R_V7M_EXCRET_DCRS_MASK;
114
}
115
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
116
}
117
}
29
}
118
119
+ if (push_failed && !ignore_stackfaults) {
120
+ /* Derived exception on callee-saves register stacking:
121
+ * we might now want to take a different exception which
122
+ * targets a different security state, so try again from the top.
123
+ */
124
+ v7m_exception_taken(cpu, lr, true, true);
125
+ return;
126
+ }
127
+
128
addr = arm_v7m_load_vector(cpu, exc, targets_secure);
129
130
/* Now we've done everything that might cause a derived exception
131
--
30
--
132
2.16.1
31
2.20.1
133
32
134
33
diff view generated by jsdifflib
1
The code where we added the TT instruction was accidentally
1
We were accidentally permitting decode of Thumb Neon insns even if
2
missing a 'break', which meant that after generating the code
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
3
to execute the TT we would fall through to 'goto illegal_op'
3
check was being done before the call to disas_neon_data_insn() and
4
and generate code to take an UNDEF insn.
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
5
Thumb decoder. Push the feature bit check down into the called
6
functions so it is done for both Arm and Thumb encodings.
5
7
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180206103941.13985-1-peter.maydell@linaro.org
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
9
---
12
---
10
target/arm/translate.c | 1 +
13
target/arm/translate.c | 16 ++++++++--------
11
1 file changed, 1 insertion(+)
14
1 file changed, 8 insertions(+), 8 deletions(-)
12
15
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
18
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
19
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
18
tcg_temp_free_i32(addr);
21
TCGv_i32 tmp2;
19
tcg_temp_free_i32(op);
22
TCGv_i64 tmp64;
20
store_reg(s, rd, ttresp);
23
21
+ break;
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
22
}
25
+ return 1;
23
goto illegal_op;
26
+ }
24
}
27
+
28
/* FIXME: this access check should not take precedence over UNDEF
29
* for invalid encodings; we will generate incorrect syndrome information
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
32
TCGv_ptr ptr1, ptr2, ptr3;
33
TCGv_i64 tmp64;
34
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
36
+ return 1;
37
+ }
38
+
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
}
25
--
64
--
26
2.16.1
65
2.20.1
27
66
28
67
diff view generated by jsdifflib
1
Make the load of the exception vector from the vector table honour
1
Add the infrastructure for building and invoking a decodetree decoder
2
the SAU and any bus error on the load (possibly provoking a derived
2
for the AArch32 Neon encodings. At the moment the new decoder covers
3
exception), rather than simply aborting if the load fails.
3
nothing, so we always fall back to the existing hand-written decode.
4
5
We follow the same pattern we did for the VFP decodetree conversion
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
8
which we #include into translate.c.
9
10
In order to share the decode files between A32 and T32, we
11
split Neon into 3 parts:
12
* data-processing
13
* load-store
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.
4
20
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 1517324542-6607-7-git-send-email-peter.maydell@linaro.org
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
8
---
24
---
9
target/arm/helper.c | 71 +++++++++++++++++++++++++++++++++++++++++------------
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
10
1 file changed, 55 insertions(+), 16 deletions(-)
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
11
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
30
target/arm/Makefile.objs | 18 +++++++++++++++++
31
6 files changed, 169 insertions(+), 2 deletions(-)
32
create mode 100644 target/arm/neon-dp.decode
33
create mode 100644 target/arm/neon-ls.decode
34
create mode 100644 target/arm/neon-shared.decode
35
create mode 100644 target/arm/translate-neon.inc.c
36
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/target/arm/neon-dp.decode
42
@@ -XXX,XX +XXX,XX @@
43
+# AArch32 Neon data-processing instruction descriptions
44
+#
45
+# Copyright (c) 2020 Linaro, Ltd
46
+#
47
+# This library is free software; you can redistribute it and/or
48
+# modify it under the terms of the GNU Lesser General Public
49
+# License as published by the Free Software Foundation; either
50
+# version 2 of the License, or (at your option) any later version.
51
+#
52
+# This library is distributed in the hope that it will be useful,
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
55
+# Lesser General Public License for more details.
56
+#
57
+# You should have received a copy of the GNU Lesser General Public
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
59
+
60
+#
61
+# This file is processed by scripts/decodetree.py
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
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
77
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
79
+#
80
+# Copyright (c) 2020 Linaro, Ltd
81
+#
82
+# This library is free software; you can redistribute it and/or
83
+# modify it under the terms of the GNU Lesser General Public
84
+# License as published by the Free Software Foundation; either
85
+# version 2 of the License, or (at your option) any later version.
86
+#
87
+# This library is distributed in the hope that it will be useful,
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90
+# Lesser General Public License for more details.
91
+#
92
+# You should have received a copy of the GNU Lesser General Public
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
94
+
95
+#
96
+# This file is processed by scripts/decodetree.py
97
+#
98
+
99
+# Encodings for Neon load/store instructions where the T32 encoding
100
+# is a simple transformation of the A32 encoding.
101
+# More specifically, this file covers instructions where the A32 encoding is
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
103
+# and the T32 encoding is
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
105
+# This file works on the A32 encoding only; calling code for T32 has to
106
+# transform the insn into the A32 version first.
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
112
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
114
+#
115
+# Copyright (c) 2020 Linaro, Ltd
116
+#
117
+# This library is free software; you can redistribute it and/or
118
+# modify it under the terms of the GNU Lesser General Public
119
+# License as published by the Free Software Foundation; either
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
13
index XXXXXXX..XXXXXXX 100644
179
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
180
--- a/target/arm/translate.c
15
+++ b/target/arm/helper.c
181
+++ b/target/arm/translate.c
16
@@ -XXX,XX +XXX,XX @@ static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
183
184
#define ARM_CP_RW_BIT (1 << 20)
185
186
-/* Include the VFP decoder */
187
+/* Include the VFP and Neon decoders */
188
#include "translate-vfp.inc.c"
189
+#include "translate-neon.inc.c"
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);
17
}
207
}
18
}
208
19
209
+ if ((insn & 0xef000000) == 0xef000000) {
20
-static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
210
+ /*
21
+static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
22
+ uint32_t *pvec)
212
+ * transform into
23
{
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
24
CPUState *cs = CPU(cpu);
214
+ */
25
CPUARMState *env = &cpu->env;
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
26
MemTxResult result;
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
27
- hwaddr vec = env->v7m.vecbase[targets_secure] + exc * 4;
217
+
28
- uint32_t addr;
218
+ if (disas_neon_dp(s, a32_insn)) {
29
+ uint32_t addr = env->v7m.vecbase[targets_secure] + exc * 4;
219
+ return;
30
+ uint32_t vector_entry;
31
+ MemTxAttrs attrs = {};
32
+ ARMMMUIdx mmu_idx;
33
+ bool exc_secure;
34
+
35
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targets_secure, true);
36
37
- addr = address_space_ldl(cs->as, vec,
38
- MEMTXATTRS_UNSPECIFIED, &result);
39
+ /* We don't do a get_phys_addr() here because the rules for vector
40
+ * loads are special: they always use the default memory map, and
41
+ * the default memory map permits reads from all addresses.
42
+ * Since there's no easy way to pass through to pmsav8_mpu_lookup()
43
+ * that we want this special case which would always say "yes",
44
+ * we just do the SAU lookup here followed by a direct physical load.
45
+ */
46
+ attrs.secure = targets_secure;
47
+ attrs.user = false;
48
+
49
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
50
+ V8M_SAttributes sattrs = {};
51
+
52
+ v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx, &sattrs);
53
+ if (sattrs.ns) {
54
+ attrs.secure = false;
55
+ } else if (!targets_secure) {
56
+ /* NS access to S memory */
57
+ goto load_fail;
58
+ }
220
+ }
59
+ }
221
+ }
60
+
222
+
61
+ vector_entry = address_space_ldl(arm_addressspace(cs, attrs), addr,
223
+ if ((insn & 0xff100000) == 0xf9000000) {
62
+ attrs, &result);
224
+ /*
63
if (result != MEMTX_OK) {
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
64
- /* Architecturally this should cause a HardFault setting HSFR.VECTTBL,
226
+ * transform into
65
- * which would then be immediately followed by our failing to load
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
66
- * the entry vector for that HardFault, which is a Lockup case.
228
+ */
67
- * Since we don't model Lockup, we just report this guest error
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
68
- * via cpu_abort().
230
+
69
- */
231
+ if (disas_neon_ls(s, a32_insn)) {
70
- cpu_abort(cs, "Failed to read from %s exception vector table "
232
+ return;
71
- "entry %08x\n", targets_secure ? "secure" : "nonsecure",
233
+ }
72
- (unsigned)vec);
234
+ }
73
+ goto load_fail;
235
+
74
}
236
/*
75
- return addr;
237
* TODO: Perhaps merge these into one decodetree output file.
76
+ *pvec = vector_entry;
238
* Note disas_vfp is written for a32 with cond field in the
77
+ return true;
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
78
+
240
*/
79
+load_fail:
241
if (disas_t32(s, insn) ||
80
+ /* All vector table fetch fails are reported as HardFault, with
242
disas_vfp_uncond(s, insn) ||
81
+ * HFSR.VECTTBL and .FORCED set. (FORCED is set because
243
+ disas_neon_shared(s, insn) ||
82
+ * technically the underlying exception is a MemManage or BusFault
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
83
+ * that is escalated to HardFault.) This is a terminal exception,
84
+ * so we will either take the HardFault immediately or else enter
85
+ * lockup (the latter case is handled in armv7m_nvic_set_pending_derived()).
86
+ */
87
+ exc_secure = targets_secure ||
88
+ !(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK);
89
+ env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK | R_V7M_HFSR_FORCED_MASK;
90
+ armv7m_nvic_set_pending_derived(env->nvic, ARMV7M_EXCP_HARD, exc_secure);
91
+ return false;
92
}
93
94
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
95
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
96
return;
245
return;
97
}
246
}
98
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
99
- addr = arm_v7m_load_vector(cpu, exc, targets_secure);
248
index XXXXXXX..XXXXXXX 100644
100
+ if (!arm_v7m_load_vector(cpu, exc, targets_secure, &addr)) {
249
--- a/target/arm/Makefile.objs
101
+ /* Vector load failed: derived exception */
250
+++ b/target/arm/Makefile.objs
102
+ v7m_exception_taken(cpu, lr, true, true);
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
103
+ return;
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
104
+ }
253
     "GEN", $(TARGET_DIR)$@)
105
254
106
/* Now we've done everything that might cause a derived exception
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
107
* we can go ahead and activate whichever exception we're going to
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
108
--
283
--
109
2.16.1
284
2.20.1
110
285
111
286
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
Convert the VCMLA (vector) insns in the 3same extension group to
2
decodetree.
2
3
3
This implements emulation of the new SHA-3 instructions that have
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
been added as an optional extensions to the ARMv8 Crypto Extensions
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
in ARM v8.2.
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 11 ++++++++++
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 11 +---------
11
3 files changed, 49 insertions(+), 10 deletions(-)
6
12
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
8
Message-id: 20180207111729.15737-3-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 1 +
13
target/arm/translate-a64.c | 148 +++++++++++++++++++++++++++++++++++++++++++--
14
2 files changed, 145 insertions(+), 4 deletions(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
15
--- a/target/arm/neon-shared.decode
19
+++ b/target/arm/cpu.h
16
+++ b/target/arm/neon-shared.decode
20
@@ -XXX,XX +XXX,XX @@ enum arm_features {
17
@@ -XXX,XX +XXX,XX @@
21
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
18
# More specifically, this covers:
22
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
23
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
24
+ ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
21
+
25
};
22
+# VFP/Neon register fields; same as vfp.decode
26
23
+%vm_dp 5:1 0:4
27
static inline int arm_feature(CPUARMState *env, int feature)
24
+%vm_sp 0:4 5:1
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
25
+%vn_dp 7:1 16:4
26
+%vn_sp 16:4 7:1
27
+%vd_dp 22:1 12:4
28
+%vd_sp 12:4 22:1
29
+
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
29
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
34
--- a/target/arm/translate-neon.inc.c
31
+++ b/target/arm/translate-a64.c
35
+++ b/target/arm/translate-neon.inc.c
32
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
36
@@ -XXX,XX +XXX,XX @@
33
feature = ARM_FEATURE_V8_SHA512;
37
#include "decode-neon-dp.inc.c"
34
genfn = gen_helper_crypto_sha512su1;
38
#include "decode-neon-ls.inc.c"
35
break;
39
#include "decode-neon-shared.inc.c"
36
- default:
37
- unallocated_encoding(s);
38
- return;
39
+ case 3: /* RAX1 */
40
+ feature = ARM_FEATURE_V8_SHA3;
41
+ genfn = NULL;
42
+ break;
43
}
44
} else {
45
unallocated_encoding(s);
46
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
47
tcg_temp_free_ptr(tcg_rn_ptr);
48
tcg_temp_free_ptr(tcg_rm_ptr);
49
} else {
50
- g_assert_not_reached();
51
+ TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
52
+ int pass;
53
+
40
+
54
+ tcg_op1 = tcg_temp_new_i64();
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
55
+ tcg_op2 = tcg_temp_new_i64();
42
+{
56
+ tcg_res[0] = tcg_temp_new_i64();
43
+ int opr_sz;
57
+ tcg_res[1] = tcg_temp_new_i64();
44
+ TCGv_ptr fpst;
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
58
+
46
+
59
+ for (pass = 0; pass < 2; pass++) {
47
+ if (!dc_isar_feature(aa32_vcma, s)
60
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
61
+ read_vec_element(s, tcg_op2, rm, pass, MO_64);
49
+ return false;
62
+
63
+ tcg_gen_rotli_i64(tcg_res[pass], tcg_op2, 1);
64
+ tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
65
+ }
66
+ write_vec_element(s, tcg_res[0], rd, 0, MO_64);
67
+ write_vec_element(s, tcg_res[1], rd, 1, MO_64);
68
+
69
+ tcg_temp_free_i64(tcg_op1);
70
+ tcg_temp_free_i64(tcg_op2);
71
+ tcg_temp_free_i64(tcg_res[0]);
72
+ tcg_temp_free_i64(tcg_res[1]);
73
}
74
}
75
76
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
77
tcg_temp_free_ptr(tcg_rn_ptr);
78
}
79
80
+/* Crypto four-register
81
+ * 31 23 22 21 20 16 15 14 10 9 5 4 0
82
+ * +-------------------+-----+------+---+------+------+------+
83
+ * | 1 1 0 0 1 1 1 0 0 | Op0 | Rm | 0 | Ra | Rn | Rd |
84
+ * +-------------------+-----+------+---+------+------+------+
85
+ */
86
+static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
87
+{
88
+ int op0 = extract32(insn, 21, 2);
89
+ int rm = extract32(insn, 16, 5);
90
+ int ra = extract32(insn, 10, 5);
91
+ int rn = extract32(insn, 5, 5);
92
+ int rd = extract32(insn, 0, 5);
93
+ int feature;
94
+
95
+ switch (op0) {
96
+ case 0: /* EOR3 */
97
+ case 1: /* BCAX */
98
+ feature = ARM_FEATURE_V8_SHA3;
99
+ break;
100
+ default:
101
+ unallocated_encoding(s);
102
+ return;
103
+ }
50
+ }
104
+
51
+
105
+ if (!arm_dc_feature(s, feature)) {
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
106
+ unallocated_encoding(s);
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
107
+ return;
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
55
+ return false;
108
+ }
56
+ }
109
+
57
+
110
+ if (!fp_access_check(s)) {
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
111
+ return;
59
+ return false;
112
+ }
60
+ }
113
+
61
+
114
+ if (op0 < 2) {
62
+ if (!vfp_access_check(s)) {
115
+ TCGv_i64 tcg_op1, tcg_op2, tcg_op3, tcg_res[2];
63
+ return true;
116
+ int pass;
117
+
118
+ tcg_op1 = tcg_temp_new_i64();
119
+ tcg_op2 = tcg_temp_new_i64();
120
+ tcg_op3 = tcg_temp_new_i64();
121
+ tcg_res[0] = tcg_temp_new_i64();
122
+ tcg_res[1] = tcg_temp_new_i64();
123
+
124
+ for (pass = 0; pass < 2; pass++) {
125
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
126
+ read_vec_element(s, tcg_op2, rm, pass, MO_64);
127
+ read_vec_element(s, tcg_op3, ra, pass, MO_64);
128
+
129
+ if (op0 == 0) {
130
+ /* EOR3 */
131
+ tcg_gen_xor_i64(tcg_res[pass], tcg_op2, tcg_op3);
132
+ } else {
133
+ /* BCAX */
134
+ tcg_gen_andc_i64(tcg_res[pass], tcg_op2, tcg_op3);
135
+ }
136
+ tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
137
+ }
138
+ write_vec_element(s, tcg_res[0], rd, 0, MO_64);
139
+ write_vec_element(s, tcg_res[1], rd, 1, MO_64);
140
+
141
+ tcg_temp_free_i64(tcg_op1);
142
+ tcg_temp_free_i64(tcg_op2);
143
+ tcg_temp_free_i64(tcg_op3);
144
+ tcg_temp_free_i64(tcg_res[0]);
145
+ tcg_temp_free_i64(tcg_res[1]);
146
+ } else {
147
+ g_assert_not_reached();
148
+ }
149
+}
150
+
151
+/* Crypto XAR
152
+ * 31 21 20 16 15 10 9 5 4 0
153
+ * +-----------------------+------+--------+------+------+
154
+ * | 1 1 0 0 1 1 1 0 1 0 0 | Rm | imm6 | Rn | Rd |
155
+ * +-----------------------+------+--------+------+------+
156
+ */
157
+static void disas_crypto_xar(DisasContext *s, uint32_t insn)
158
+{
159
+ int rm = extract32(insn, 16, 5);
160
+ int imm6 = extract32(insn, 10, 6);
161
+ int rn = extract32(insn, 5, 5);
162
+ int rd = extract32(insn, 0, 5);
163
+ TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
164
+ int pass;
165
+
166
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA3)) {
167
+ unallocated_encoding(s);
168
+ return;
169
+ }
64
+ }
170
+
65
+
171
+ if (!fp_access_check(s)) {
66
+ opr_sz = (1 + a->q) * 8;
172
+ return;
67
+ fpst = get_fpstatus_ptr(1);
173
+ }
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
174
+
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
175
+ tcg_op1 = tcg_temp_new_i64();
70
+ vfp_reg_offset(1, a->vn),
176
+ tcg_op2 = tcg_temp_new_i64();
71
+ vfp_reg_offset(1, a->vm),
177
+ tcg_res[0] = tcg_temp_new_i64();
72
+ fpst, opr_sz, opr_sz, a->rot,
178
+ tcg_res[1] = tcg_temp_new_i64();
73
+ fn_gvec_ptr);
179
+
74
+ tcg_temp_free_ptr(fpst);
180
+ for (pass = 0; pass < 2; pass++) {
75
+ return true;
181
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
182
+ read_vec_element(s, tcg_op2, rm, pass, MO_64);
183
+
184
+ tcg_gen_xor_i64(tcg_res[pass], tcg_op1, tcg_op2);
185
+ tcg_gen_rotri_i64(tcg_res[pass], tcg_res[pass], imm6);
186
+ }
187
+ write_vec_element(s, tcg_res[0], rd, 0, MO_64);
188
+ write_vec_element(s, tcg_res[1], rd, 1, MO_64);
189
+
190
+ tcg_temp_free_i64(tcg_op1);
191
+ tcg_temp_free_i64(tcg_op2);
192
+ tcg_temp_free_i64(tcg_res[0]);
193
+ tcg_temp_free_i64(tcg_res[1]);
194
+}
76
+}
195
+
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
196
/* C3.6 Data processing - SIMD, inc Crypto
78
index XXXXXXX..XXXXXXX 100644
197
*
79
--- a/target/arm/translate.c
198
* As the decode gets a little complex we are using a table based
80
+++ b/target/arm/translate.c
199
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
200
{ 0x5e280800, 0xff3e0c00, disas_crypto_two_reg_sha },
82
bool is_long = false, q = extract32(insn, 6, 1);
201
{ 0xce608000, 0xffe0b000, disas_crypto_three_reg_sha512 },
83
bool ptr_is_env = false;
202
{ 0xcec08000, 0xfffff000, disas_crypto_two_reg_sha512 },
84
203
+ { 0xce000000, 0xff808000, disas_crypto_four_reg },
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
204
+ { 0xce800000, 0xffe00000, disas_crypto_xar },
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
205
{ 0x00000000, 0x00000000, NULL }
87
- int size = extract32(insn, 20, 1);
206
};
88
- data = extract32(insn, 23, 2); /* rot */
207
89
- if (!dc_isar_feature(aa32_vcma, s)
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
91
- return 1;
92
- }
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
97
int size = extract32(insn, 20, 1);
98
data = extract32(insn, 24, 1); /* rot */
208
--
99
--
209
2.16.1
100
2.20.1
210
101
211
102
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
Convert the VCADD (vector) insns to decodetree.
2
2
3
IP block found on several generations of i.MX family does not use
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
vanilla SDHCI implementation and it comes with a number of quirks.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 3 +++
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 11 +---------
10
3 files changed, 41 insertions(+), 10 deletions(-)
5
11
6
Introduce i.MX SDHCI subtype of SDHCI block to add code necessary to
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
7
support unmodified Linux guest driver.
8
9
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Jason Wang <jasowang@redhat.com>
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
13
Cc: Michael S. Tsirkin <mst@redhat.com>
14
Cc: qemu-devel@nongnu.org
15
Cc: qemu-arm@nongnu.org
16
Cc: yurovsky@gmail.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
19
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
[PMM: define and use ESDHC_UNDOCUMENTED_REG27]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/sd/sdhci-internal.h | 23 +++++
24
include/hw/sd/sdhci.h | 13 +++
25
hw/sd/sdhci.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++-
26
3 files changed, 265 insertions(+), 1 deletion(-)
27
28
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
29
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/sd/sdhci-internal.h
14
--- a/target/arm/neon-shared.decode
31
+++ b/hw/sd/sdhci-internal.h
15
+++ b/target/arm/neon-shared.decode
32
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
33
17
34
/* R/W Host control Register 0x0 */
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
35
#define SDHC_HOSTCTL 0x28
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
36
+#define SDHC_CTRL_LED 0x01
37
#define SDHC_CTRL_DMA_CHECK_MASK 0x18
38
#define SDHC_CTRL_SDMA 0x00
39
#define SDHC_CTRL_ADMA1_32 0x08
40
#define SDHC_CTRL_ADMA2_32 0x10
41
#define SDHC_CTRL_ADMA2_64 0x18
42
#define SDHC_DMA_TYPE(x) ((x) & SDHC_CTRL_DMA_CHECK_MASK)
43
+#define SDHC_CTRL_4BITBUS 0x02
44
+#define SDHC_CTRL_8BITBUS 0x20
45
+#define SDHC_CTRL_CDTEST_INS 0x40
46
+#define SDHC_CTRL_CDTEST_EN 0x80
47
+
20
+
48
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
49
/* R/W Power Control Register 0x0 */
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
50
#define SDHC_PWRCON 0x29
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
51
@@ -XXX,XX +XXX,XX @@ enum {
24
index XXXXXXX..XXXXXXX 100644
52
sdhc_gap_write = 2 /* SDHC stopped at block gap during write operation */
25
--- a/target/arm/translate-neon.inc.c
53
};
26
+++ b/target/arm/translate-neon.inc.c
54
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
55
+extern const VMStateDescription sdhci_vmstate;
28
tcg_temp_free_ptr(fpst);
29
return true;
30
}
56
+
31
+
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
33
+{
34
+ int opr_sz;
35
+ TCGv_ptr fpst;
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
57
+
37
+
58
+#define ESDHC_MIX_CTRL 0x48
38
+ if (!dc_isar_feature(aa32_vcma, s)
59
+#define ESDHC_VENDOR_SPEC 0xc0
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
60
+#define ESDHC_DLL_CTRL 0x60
40
+ return false;
61
+
62
+#define ESDHC_TUNING_CTRL 0xcc
63
+#define ESDHC_TUNE_CTRL_STATUS 0x68
64
+#define ESDHC_WTMK_LVL 0x44
65
+
66
+/* Undocumented register used by guests working around erratum ERR004536 */
67
+#define ESDHC_UNDOCUMENTED_REG27 0x6c
68
+
69
+#define ESDHC_CTRL_4BITBUS (0x1 << 1)
70
+#define ESDHC_CTRL_8BITBUS (0x2 << 1)
71
+
72
#endif
73
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
74
index XXXXXXX..XXXXXXX 100644
75
--- a/include/hw/sd/sdhci.h
76
+++ b/include/hw/sd/sdhci.h
77
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
78
AddressSpace sysbus_dma_as;
79
AddressSpace *dma_as;
80
MemoryRegion *dma_mr;
81
+ const MemoryRegionOps *io_ops;
82
83
QEMUTimer *insert_timer; /* timer for 'changing' sd card. */
84
QEMUTimer *transfer_timer;
85
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
86
87
/* Configurable properties */
88
bool pending_insert_quirk; /* Quirk for Raspberry Pi card insert int */
89
+ uint32_t quirks;
90
} SDHCIState;
91
92
+/*
93
+ * Controller does not provide transfer-complete interrupt when not
94
+ * busy.
95
+ *
96
+ * NOTE: This definition is taken out of Linux kernel and so the
97
+ * original bit number is preserved
98
+ */
99
+#define SDHCI_QUIRK_NO_BUSY_IRQ BIT(14)
100
+
101
#define TYPE_PCI_SDHCI "sdhci-pci"
102
#define PCI_SDHCI(obj) OBJECT_CHECK(SDHCIState, (obj), TYPE_PCI_SDHCI)
103
104
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
105
#define SYSBUS_SDHCI(obj) \
106
OBJECT_CHECK(SDHCIState, (obj), TYPE_SYSBUS_SDHCI)
107
108
+#define TYPE_IMX_USDHC "imx-usdhc"
109
+
110
#endif /* SDHCI_H */
111
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/hw/sd/sdhci.c
114
+++ b/hw/sd/sdhci.c
115
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
116
}
117
}
118
119
- if ((s->norintstsen & SDHC_NISEN_TRSCMP) &&
120
+ if (!(s->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
121
+ (s->norintstsen & SDHC_NISEN_TRSCMP) &&
122
(s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) {
123
s->norintsts |= SDHC_NIS_TRSCMP;
124
}
125
@@ -XXX,XX +XXX,XX @@ static void sdhci_initfn(SDHCIState *s)
126
127
s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
128
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
129
+
130
+ s->io_ops = &sdhci_mmio_ops;
131
}
132
133
static void sdhci_uninitfn(SDHCIState *s)
134
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
135
}
136
137
sysbus_init_irq(sbd, &s->irq);
138
+
139
+ memory_region_init_io(&s->iomem, OBJECT(s), s->io_ops, s, "sdhci",
140
+ SDHC_REGISTERS_MAP_SIZE);
141
+
142
sysbus_init_mmio(sbd, &s->iomem);
143
}
144
145
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sdhci_bus_info = {
146
.class_init = sdhci_bus_class_init,
147
};
148
149
+static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
150
+{
151
+ SDHCIState *s = SYSBUS_SDHCI(opaque);
152
+ uint32_t ret;
153
+ uint16_t hostctl;
154
+
155
+ switch (offset) {
156
+ default:
157
+ return sdhci_read(opaque, offset, size);
158
+
159
+ case SDHC_HOSTCTL:
160
+ /*
161
+ * For a detailed explanation on the following bit
162
+ * manipulation code see comments in a similar part of
163
+ * usdhc_write()
164
+ */
165
+ hostctl = SDHC_DMA_TYPE(s->hostctl) << (8 - 3);
166
+
167
+ if (s->hostctl & SDHC_CTRL_8BITBUS) {
168
+ hostctl |= ESDHC_CTRL_8BITBUS;
169
+ }
170
+
171
+ if (s->hostctl & SDHC_CTRL_4BITBUS) {
172
+ hostctl |= ESDHC_CTRL_4BITBUS;
173
+ }
174
+
175
+ ret = hostctl;
176
+ ret |= (uint32_t)s->blkgap << 16;
177
+ ret |= (uint32_t)s->wakcon << 24;
178
+
179
+ break;
180
+
181
+ case ESDHC_DLL_CTRL:
182
+ case ESDHC_TUNE_CTRL_STATUS:
183
+ case ESDHC_UNDOCUMENTED_REG27:
184
+ case ESDHC_TUNING_CTRL:
185
+ case ESDHC_VENDOR_SPEC:
186
+ case ESDHC_MIX_CTRL:
187
+ case ESDHC_WTMK_LVL:
188
+ ret = 0;
189
+ break;
190
+ }
41
+ }
191
+
42
+
192
+ return ret;
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
50
+ return false;
51
+ }
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;
193
+}
67
+}
194
+
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
195
+static void
69
index XXXXXXX..XXXXXXX 100644
196
+usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
70
--- a/target/arm/translate.c
197
+{
71
+++ b/target/arm/translate.c
198
+ SDHCIState *s = SYSBUS_SDHCI(opaque);
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
199
+ uint8_t hostctl;
73
bool is_long = false, q = extract32(insn, 6, 1);
200
+ uint32_t value = (uint32_t)val;
74
bool ptr_is_env = false;
201
+
75
202
+ switch (offset) {
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
203
+ case ESDHC_DLL_CTRL:
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
204
+ case ESDHC_TUNE_CTRL_STATUS:
78
- int size = extract32(insn, 20, 1);
205
+ case ESDHC_UNDOCUMENTED_REG27:
79
- data = extract32(insn, 24, 1); /* rot */
206
+ case ESDHC_TUNING_CTRL:
80
- if (!dc_isar_feature(aa32_vcma, s)
207
+ case ESDHC_WTMK_LVL:
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
208
+ case ESDHC_VENDOR_SPEC:
82
- return 1;
209
+ break;
83
- }
210
+
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
211
+ case SDHC_HOSTCTL:
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
212
+ /*
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
213
+ * Here's What ESDHCI has at offset 0x28 (SDHC_HOSTCTL)
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
214
+ *
88
bool u = extract32(insn, 4, 1);
215
+ * 7 6 5 4 3 2 1 0
89
if (!dc_isar_feature(aa32_dp, s)) {
216
+ * |-----------+--------+--------+-----------+----------+---------|
217
+ * | Card | Card | Endian | DATA3 | Data | Led |
218
+ * | Detect | Detect | Mode | as Card | Transfer | Control |
219
+ * | Signal | Test | | Detection | Width | |
220
+ * | Selection | Level | | Pin | | |
221
+ * |-----------+--------+--------+-----------+----------+---------|
222
+ *
223
+ * and 0x29
224
+ *
225
+ * 15 10 9 8
226
+ * |----------+------|
227
+ * | Reserved | DMA |
228
+ * | | Sel. |
229
+ * | | |
230
+ * |----------+------|
231
+ *
232
+ * and here's what SDCHI spec expects those offsets to be:
233
+ *
234
+ * 0x28 (Host Control Register)
235
+ *
236
+ * 7 6 5 4 3 2 1 0
237
+ * |--------+--------+----------+------+--------+----------+---------|
238
+ * | Card | Card | Extended | DMA | High | Data | LED |
239
+ * | Detect | Detect | Data | Sel. | Speed | Transfer | Control |
240
+ * | Signal | Test | Transfer | | Enable | Width | |
241
+ * | Sel. | Level | Width | | | | |
242
+ * |--------+--------+----------+------+--------+----------+---------|
243
+ *
244
+ * and 0x29 (Power Control Register)
245
+ *
246
+ * |----------------------------------|
247
+ * | Power Control Register |
248
+ * | |
249
+ * | Description omitted, |
250
+ * | since it has no analog in ESDHCI |
251
+ * | |
252
+ * |----------------------------------|
253
+ *
254
+ * Since offsets 0x2A and 0x2B should be compatible between
255
+ * both IP specs we only need to reconcile least 16-bit of the
256
+ * word we've been given.
257
+ */
258
+
259
+ /*
260
+ * First, save bits 7 6 and 0 since they are identical
261
+ */
262
+ hostctl = value & (SDHC_CTRL_LED |
263
+ SDHC_CTRL_CDTEST_INS |
264
+ SDHC_CTRL_CDTEST_EN);
265
+ /*
266
+ * Second, split "Data Transfer Width" from bits 2 and 1 in to
267
+ * bits 5 and 1
268
+ */
269
+ if (value & ESDHC_CTRL_8BITBUS) {
270
+ hostctl |= SDHC_CTRL_8BITBUS;
271
+ }
272
+
273
+ if (value & ESDHC_CTRL_4BITBUS) {
274
+ hostctl |= ESDHC_CTRL_4BITBUS;
275
+ }
276
+
277
+ /*
278
+ * Third, move DMA select from bits 9 and 8 to bits 4 and 3
279
+ */
280
+ hostctl |= SDHC_DMA_TYPE(value >> (8 - 3));
281
+
282
+ /*
283
+ * Now place the corrected value into low 16-bit of the value
284
+ * we are going to give standard SDHCI write function
285
+ *
286
+ * NOTE: This transformation should be the inverse of what can
287
+ * be found in drivers/mmc/host/sdhci-esdhc-imx.c in Linux
288
+ * kernel
289
+ */
290
+ value &= ~UINT16_MAX;
291
+ value |= hostctl;
292
+ value |= (uint16_t)s->pwrcon << 8;
293
+
294
+ sdhci_write(opaque, offset, value, size);
295
+ break;
296
+
297
+ case ESDHC_MIX_CTRL:
298
+ /*
299
+ * So, when SD/MMC stack in Linux tries to write to "Transfer
300
+ * Mode Register", ESDHC i.MX quirk code will translate it
301
+ * into a write to ESDHC_MIX_CTRL, so we do the opposite in
302
+ * order to get where we started
303
+ *
304
+ * Note that Auto CMD23 Enable bit is located in a wrong place
305
+ * on i.MX, but since it is not used by QEMU we do not care.
306
+ *
307
+ * We don't want to call sdhci_write(.., SDHC_TRNMOD, ...)
308
+ * here becuase it will result in a call to
309
+ * sdhci_send_command(s) which we don't want.
310
+ *
311
+ */
312
+ s->trnmod = value & UINT16_MAX;
313
+ break;
314
+ case SDHC_TRNMOD:
315
+ /*
316
+ * Similar to above, but this time a write to "Command
317
+ * Register" will be translated into a 4-byte write to
318
+ * "Transfer Mode register" where lower 16-bit of value would
319
+ * be set to zero. So what we do is fill those bits with
320
+ * cached value from s->trnmod and let the SDHCI
321
+ * infrastructure handle the rest
322
+ */
323
+ sdhci_write(opaque, offset, val | s->trnmod, size);
324
+ break;
325
+ case SDHC_BLKSIZE:
326
+ /*
327
+ * ESDHCI does not implement "Host SDMA Buffer Boundary", and
328
+ * Linux driver will try to zero this field out which will
329
+ * break the rest of SDHCI emulation.
330
+ *
331
+ * Linux defaults to maximum possible setting (512K boundary)
332
+ * and it seems to be the only option that i.MX IP implements,
333
+ * so we artificially set it to that value.
334
+ */
335
+ val |= 0x7 << 12;
336
+ /* FALLTHROUGH */
337
+ default:
338
+ sdhci_write(opaque, offset, val, size);
339
+ break;
340
+ }
341
+}
342
+
343
+
344
+static const MemoryRegionOps usdhc_mmio_ops = {
345
+ .read = usdhc_read,
346
+ .write = usdhc_write,
347
+ .valid = {
348
+ .min_access_size = 1,
349
+ .max_access_size = 4,
350
+ .unaligned = false
351
+ },
352
+ .endianness = DEVICE_LITTLE_ENDIAN,
353
+};
354
+
355
+static void imx_usdhc_init(Object *obj)
356
+{
357
+ SDHCIState *s = SYSBUS_SDHCI(obj);
358
+
359
+ s->io_ops = &usdhc_mmio_ops;
360
+ s->quirks = SDHCI_QUIRK_NO_BUSY_IRQ;
361
+}
362
+
363
+static const TypeInfo imx_usdhc_info = {
364
+ .name = TYPE_IMX_USDHC,
365
+ .parent = TYPE_SYSBUS_SDHCI,
366
+ .instance_init = imx_usdhc_init,
367
+};
368
+
369
static void sdhci_register_types(void)
370
{
371
type_register_static(&sdhci_pci_info);
372
type_register_static(&sdhci_sysbus_info);
373
type_register_static(&sdhci_bus_info);
374
+ type_register_static(&imx_usdhc_info);
375
}
376
377
type_init(sdhci_register_types)
378
--
90
--
379
2.16.1
91
2.20.1
380
92
381
93
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
Convert the V[US]DOT (vector) insns to decodetree.
2
2
3
This implements emulation of the new SM4 instructions that have
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
been added as an optional extension to the ARMv8 Crypto Extensions
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
in ARM v8.2.
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 4 ++++
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 9 +--------
10
3 files changed, 37 insertions(+), 8 deletions(-)
6
11
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
8
Message-id: 20180207111729.15737-5-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 1 +
13
target/arm/helper.h | 3 ++
14
target/arm/crypto_helper.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++
15
target/arm/translate-a64.c | 8 ++++
16
4 files changed, 103 insertions(+)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
14
--- a/target/arm/neon-shared.decode
21
+++ b/target/arm/cpu.h
15
+++ b/target/arm/neon-shared.decode
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
23
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
17
24
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
25
ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
26
+ ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
20
+
27
};
21
+# VUDOT and VSDOT
28
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
29
static inline int arm_feature(CPUARMState *env, int feature)
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.h
26
--- a/target/arm/translate-neon.inc.c
33
+++ b/target/arm/helper.h
27
+++ b/target/arm/translate-neon.inc.c
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
35
DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
29
tcg_temp_free_ptr(fpst);
36
DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
30
return true;
37
38
+DEF_HELPER_FLAGS_2(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr)
39
+DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
40
+
41
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
42
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
43
DEF_HELPER_2(dc_zva, void, env, i64)
44
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/crypto_helper.c
47
+++ b/target/arm/crypto_helper.c
48
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
49
rd[0] = d.l[0];
50
rd[1] = d.l[1];
51
}
31
}
52
+
32
+
53
+static uint8_t const sm4_sbox[] = {
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
54
+ 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
34
+{
55
+ 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
35
+ int opr_sz;
56
+ 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
36
+ gen_helper_gvec_3 *fn_gvec;
57
+ 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
58
+ 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
59
+ 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
60
+ 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
61
+ 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
62
+ 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
63
+ 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
64
+ 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
65
+ 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
66
+ 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
67
+ 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
68
+ 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
69
+ 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
70
+ 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
71
+ 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
72
+ 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
73
+ 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
74
+ 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
75
+ 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
76
+ 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
77
+ 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
78
+ 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
79
+ 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
80
+ 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
81
+ 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
82
+ 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
83
+ 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
84
+ 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
85
+ 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
86
+};
87
+
37
+
88
+void HELPER(crypto_sm4e)(void *vd, void *vn)
38
+ if (!dc_isar_feature(aa32_dp, s)) {
89
+{
39
+ return false;
90
+ uint64_t *rd = vd;
91
+ uint64_t *rn = vn;
92
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
93
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
94
+ uint32_t t, i;
95
+
96
+ for (i = 0; i < 4; i++) {
97
+ t = CR_ST_WORD(d, (i + 1) % 4) ^
98
+ CR_ST_WORD(d, (i + 2) % 4) ^
99
+ CR_ST_WORD(d, (i + 3) % 4) ^
100
+ CR_ST_WORD(n, i);
101
+
102
+ t = sm4_sbox[t & 0xff] |
103
+ sm4_sbox[(t >> 8) & 0xff] << 8 |
104
+ sm4_sbox[(t >> 16) & 0xff] << 16 |
105
+ sm4_sbox[(t >> 24) & 0xff] << 24;
106
+
107
+ CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
108
+ rol32(t, 24);
109
+ }
40
+ }
110
+
41
+
111
+ rd[0] = d.l[0];
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
112
+ rd[1] = d.l[1];
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
113
+}
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
114
+
45
+ return false;
115
+void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm)
116
+{
117
+ uint64_t *rd = vd;
118
+ uint64_t *rn = vn;
119
+ uint64_t *rm = vm;
120
+ union CRYPTO_STATE d;
121
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
122
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
123
+ uint32_t t, i;
124
+
125
+ d = n;
126
+ for (i = 0; i < 4; i++) {
127
+ t = CR_ST_WORD(d, (i + 1) % 4) ^
128
+ CR_ST_WORD(d, (i + 2) % 4) ^
129
+ CR_ST_WORD(d, (i + 3) % 4) ^
130
+ CR_ST_WORD(m, i);
131
+
132
+ t = sm4_sbox[t & 0xff] |
133
+ sm4_sbox[(t >> 8) & 0xff] << 8 |
134
+ sm4_sbox[(t >> 16) & 0xff] << 16 |
135
+ sm4_sbox[(t >> 24) & 0xff] << 24;
136
+
137
+ CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
138
+ }
46
+ }
139
+
47
+
140
+ rd[0] = d.l[0];
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
141
+ rd[1] = d.l[1];
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;
142
+}
63
+}
143
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
144
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
145
--- a/target/arm/translate-a64.c
66
--- a/target/arm/translate.c
146
+++ b/target/arm/translate-a64.c
67
+++ b/target/arm/translate.c
147
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
148
feature = ARM_FEATURE_V8_SM3;
69
bool is_long = false, q = extract32(insn, 6, 1);
149
genfn = gen_helper_crypto_sm3partw2;
70
bool ptr_is_env = false;
150
break;
71
151
+ case 2: /* SM4EKEY */
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
152
+ feature = ARM_FEATURE_V8_SM4;
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
153
+ genfn = gen_helper_crypto_sm4ekey;
74
- bool u = extract32(insn, 4, 1);
154
+ break;
75
- if (!dc_isar_feature(aa32_dp, s)) {
155
default:
76
- return 1;
156
unallocated_encoding(s);
77
- }
157
return;
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
158
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
159
feature = ARM_FEATURE_V8_SHA512;
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
160
genfn = gen_helper_crypto_sha512su0;
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
161
break;
82
int is_s = extract32(insn, 23, 1);
162
+ case 1: /* SM4E */
83
if (!dc_isar_feature(aa32_fhm, s)) {
163
+ feature = ARM_FEATURE_V8_SM4;
164
+ genfn = gen_helper_crypto_sm4e;
165
+ break;
166
default:
167
unallocated_encoding(s);
168
return;
169
--
84
--
170
2.16.1
85
2.20.1
171
86
172
87
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
2
insn in the legacy decoder for the 3same_ext group, so we can
3
delete the legacy decoder function for the group entirely.
2
4
3
Move virt's PSCI DT fixup code to arm/boot.c and set this fixup to
5
Note that in disas_thumb2_insn() the parts of this encoding space
4
happen automatically for every board that doesn't mark "psci-conduit"
6
where the decodetree decoder returns false will correctly be directed
5
as disabled. This way emulated boards other than "virt" that rely on
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
6
PSIC for SMP could benefit from that code.
8
into disas_coproc_insn() by mistake.
7
9
8
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Cc: Jason Wang <jasowang@redhat.com>
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
12
Cc: Michael S. Tsirkin <mst@redhat.com>
13
Cc: qemu-devel@nongnu.org
14
Cc: qemu-arm@nongnu.org
15
Cc: yurovsky@gmail.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
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
20
---
13
---
21
hw/arm/boot.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14
target/arm/neon-shared.decode | 6 +++
22
hw/arm/virt.c | 61 -------------------------------------------------------
15
target/arm/translate-neon.inc.c | 31 +++++++++++
23
2 files changed, 65 insertions(+), 61 deletions(-)
16
target/arm/translate.c | 92 +--------------------------------
17
3 files changed, 38 insertions(+), 91 deletions(-)
24
18
25
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
26
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/boot.c
21
--- a/target/arm/neon-shared.decode
28
+++ b/hw/arm/boot.c
22
+++ b/target/arm/neon-shared.decode
29
@@ -XXX,XX +XXX,XX @@ static void set_kernel_args_old(const struct arm_boot_info *info)
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
30
}
24
# VUDOT and VSDOT
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
+
28
+# VFM[AS]L
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
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
35
--- a/target/arm/translate-neon.inc.c
36
+++ b/target/arm/translate-neon.inc.c
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
38
opr_sz, opr_sz, 0, fn_gvec);
39
return true;
31
}
40
}
32
41
+
33
+static void fdt_add_psci_node(void *fdt)
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
34
+{
43
+{
35
+ uint32_t cpu_suspend_fn;
44
+ int opr_sz;
36
+ uint32_t cpu_off_fn;
37
+ uint32_t cpu_on_fn;
38
+ uint32_t migrate_fn;
39
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
40
+ const char *psci_method;
41
+ int64_t psci_conduit;
42
+
45
+
43
+ psci_conduit = object_property_get_int(OBJECT(armcpu),
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
44
+ "psci-conduit",
47
+ return false;
45
+ &error_abort);
46
+ switch (psci_conduit) {
47
+ case QEMU_PSCI_CONDUIT_DISABLED:
48
+ return;
49
+ case QEMU_PSCI_CONDUIT_HVC:
50
+ psci_method = "hvc";
51
+ break;
52
+ case QEMU_PSCI_CONDUIT_SMC:
53
+ psci_method = "smc";
54
+ break;
55
+ default:
56
+ g_assert_not_reached();
57
+ }
48
+ }
58
+
49
+
59
+ qemu_fdt_add_subnode(fdt, "/psci");
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
60
+ if (armcpu->psci_version == 2) {
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
61
+ const char comp[] = "arm,psci-0.2\0arm,psci";
52
+ (a->vd & 0x10)) {
62
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
53
+ return false;
63
+
64
+ cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
65
+ if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
66
+ cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
67
+ cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
68
+ migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
69
+ } else {
70
+ cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
71
+ cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
72
+ migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
73
+ }
74
+ } else {
75
+ qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
76
+
77
+ cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
78
+ cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
79
+ cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
80
+ migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
81
+ }
54
+ }
82
+
55
+
83
+ /* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
56
+ if (a->vd & a->q) {
84
+ * to the instruction that should be used to invoke PSCI functions.
57
+ return false;
85
+ * However, the device tree binding uses 'method' instead, so that is
58
+ }
86
+ * what we should use here.
87
+ */
88
+ qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
89
+
59
+
90
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
60
+ if (!vfp_access_check(s)) {
91
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
61
+ return true;
92
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
62
+ }
93
+ qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
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;
94
+}
71
+}
95
+
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
96
/**
97
* load_dtb() - load a device tree binary image into memory
98
* @addr: the address to load the image at
99
@@ -XXX,XX +XXX,XX @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
100
}
101
}
102
103
+ fdt_add_psci_node(fdt);
104
+
105
if (binfo->modify_dtb) {
106
binfo->modify_dtb(binfo, fdt);
107
}
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
109
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/virt.c
74
--- a/target/arm/translate.c
111
+++ b/hw/arm/virt.c
75
+++ b/target/arm/translate.c
112
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
113
}
77
return 0;
114
}
78
}
115
79
116
-static void fdt_add_psci_node(const VirtMachineState *vms)
80
-/* Advanced SIMD three registers of the same length extension.
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
85
- */
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
117
-{
87
-{
118
- uint32_t cpu_suspend_fn;
88
- gen_helper_gvec_3 *fn_gvec = NULL;
119
- uint32_t cpu_off_fn;
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
120
- uint32_t cpu_on_fn;
90
- int rd, rn, rm, opr_sz;
121
- uint32_t migrate_fn;
91
- int data = 0;
122
- void *fdt = vms->fdt;
92
- int off_rn, off_rm;
123
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
93
- bool is_long = false, q = extract32(insn, 6, 1);
124
- const char *psci_method;
94
- bool ptr_is_env = false;
125
-
95
-
126
- switch (vms->psci_conduit) {
96
- if ((insn & 0xff300f10) == 0xfc200810) {
127
- case QEMU_PSCI_CONDUIT_DISABLED:
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
128
- return;
98
- int is_s = extract32(insn, 23, 1);
129
- case QEMU_PSCI_CONDUIT_HVC:
99
- if (!dc_isar_feature(aa32_fhm, s)) {
130
- psci_method = "hvc";
100
- return 1;
131
- break;
101
- }
132
- case QEMU_PSCI_CONDUIT_SMC:
102
- is_long = true;
133
- psci_method = "smc";
103
- data = is_s; /* is_2 == 0 */
134
- break;
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
135
- default:
105
- ptr_is_env = true;
136
- g_assert_not_reached();
106
- } else {
107
- return 1;
137
- }
108
- }
138
-
109
-
139
- qemu_fdt_add_subnode(fdt, "/psci");
110
- VFP_DREG_D(rd, insn);
140
- if (armcpu->psci_version == 2) {
111
- if (rd & q) {
141
- const char comp[] = "arm,psci-0.2\0arm,psci";
112
- return 1;
142
- qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
113
- }
114
- if (q || !is_long) {
115
- VFP_DREG_N(rn, insn);
116
- VFP_DREG_M(rm, insn);
117
- if ((rn | rm) & q & !is_long) {
118
- return 1;
119
- }
120
- off_rn = vfp_reg_offset(1, rn);
121
- off_rm = vfp_reg_offset(1, rm);
122
- } else {
123
- rn = VFP_SREG_N(insn);
124
- rm = VFP_SREG_M(insn);
125
- off_rn = vfp_reg_offset(0, rn);
126
- off_rm = vfp_reg_offset(0, rm);
127
- }
143
-
128
-
144
- cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
129
- if (s->fp_excp_el) {
145
- if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
146
- cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
147
- cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
132
- return 0;
148
- migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
133
- }
134
- if (!s->vfp_enabled) {
135
- return 1;
136
- }
137
-
138
- opr_sz = (1 + q) * 8;
139
- if (fn_gvec_ptr) {
140
- TCGv_ptr ptr;
141
- if (ptr_is_env) {
142
- ptr = cpu_env;
149
- } else {
143
- } else {
150
- cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
144
- ptr = get_fpstatus_ptr(1);
151
- cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
145
- }
152
- migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
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);
153
- }
150
- }
154
- } else {
151
- } else {
155
- qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
156
-
153
- opr_sz, opr_sz, data, fn_gvec);
157
- cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
158
- cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
159
- cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
160
- migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
161
- }
154
- }
162
-
155
- return 0;
163
- /* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
164
- * to the instruction that should be used to invoke PSCI functions.
165
- * However, the device tree binding uses 'method' instead, so that is
166
- * what we should use here.
167
- */
168
- qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
169
-
170
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
171
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
172
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
173
- qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
174
-}
156
-}
175
-
157
-
176
static void fdt_add_timer_nodes(const VirtMachineState *vms)
158
/* Advanced SIMD two registers and a scalar extension.
177
{
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
178
/* On real hardware these interrupts are level-triggered.
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
179
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
180
}
162
}
181
fdt_add_timer_nodes(vms);
163
}
182
fdt_add_cpu_nodes(vms);
164
}
183
- fdt_add_psci_node(vms);
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
184
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
185
memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
167
- if (disas_neon_insn_3same_ext(s, insn)) {
186
machine->ram_size);
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;
177
}
178
- if ((insn & 0xfe000a00) == 0xfc000800
179
+ if ((insn & 0xff000a00) == 0xfe000800
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
181
/* The Thumb2 and ARM encodings are identical. */
182
- if (disas_neon_insn_3same_ext(s, insn)) {
183
- goto illegal_op;
184
- }
185
- } else if ((insn & 0xff000a00) == 0xfe000800
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
187
- /* The Thumb2 and ARM encodings are identical. */
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
189
goto illegal_op;
190
}
187
--
191
--
188
2.16.1
192
2.20.1
189
193
190
194
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
2
2
3
This implements emulation of the new SM3 instructions that have
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
been added as an optional extension to the ARMv8 Crypto Extensions
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
in ARM v8.2.
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 5 +++++
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 26 +--------------------
10
3 files changed, 46 insertions(+), 25 deletions(-)
6
11
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
8
Message-id: 20180207111729.15737-4-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 1 +
13
target/arm/helper.h | 4 ++
14
target/arm/crypto_helper.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++
15
target/arm/translate-a64.c | 88 ++++++++++++++++++++++++++++++++++++++++--
16
4 files changed, 186 insertions(+), 3 deletions(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
14
--- a/target/arm/neon-shared.decode
21
+++ b/target/arm/cpu.h
15
+++ b/target/arm/neon-shared.decode
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
23
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
24
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
25
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
26
+ ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
20
+
27
};
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
28
22
+ vn=%vn_dp vd=%vd_dp size=0
29
static inline int arm_feature(CPUARMState *env, int feature)
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
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
31
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.h
27
--- a/target/arm/translate-neon.inc.c
33
+++ b/target/arm/helper.h
28
+++ b/target/arm/translate-neon.inc.c
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
35
DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr)
30
gen_helper_gvec_fmlal_a32);
36
DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
31
return true;
37
38
+DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
39
+DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
40
+DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
41
+
42
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
43
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
44
DEF_HELPER_2(dc_zva, void, env, i64)
45
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/crypto_helper.c
48
+++ b/target/arm/crypto_helper.c
49
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
50
rd[0] += s1_512(rn[0]) + rm[0];
51
rd[1] += s1_512(rn[1]) + rm[1];
52
}
32
}
53
+
33
+
54
+void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
55
+{
35
+{
56
+ uint64_t *rd = vd;
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
57
+ uint64_t *rn = vn;
37
+ int opr_sz;
58
+ uint64_t *rm = vm;
38
+ TCGv_ptr fpst;
59
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
60
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
61
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
62
+ uint32_t t;
63
+
39
+
64
+ t = CR_ST_WORD(d, 0) ^ CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 1), 17);
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
65
+ CR_ST_WORD(d, 0) = t ^ ror32(t, 17) ^ ror32(t, 9);
41
+ return false;
66
+
42
+ }
67
+ t = CR_ST_WORD(d, 1) ^ CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 2), 17);
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
68
+ CR_ST_WORD(d, 1) = t ^ ror32(t, 17) ^ ror32(t, 9);
44
+ return false;
69
+
70
+ t = CR_ST_WORD(d, 2) ^ CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 3), 17);
71
+ CR_ST_WORD(d, 2) = t ^ ror32(t, 17) ^ ror32(t, 9);
72
+
73
+ t = CR_ST_WORD(d, 3) ^ CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 0), 17);
74
+ CR_ST_WORD(d, 3) = t ^ ror32(t, 17) ^ ror32(t, 9);
75
+
76
+ rd[0] = d.l[0];
77
+ rd[1] = d.l[1];
78
+}
79
+
80
+void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
81
+{
82
+ uint64_t *rd = vd;
83
+ uint64_t *rn = vn;
84
+ uint64_t *rm = vm;
85
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
86
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
87
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
88
+ uint32_t t = CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 0), 25);
89
+
90
+ CR_ST_WORD(d, 0) ^= t;
91
+ CR_ST_WORD(d, 1) ^= CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 1), 25);
92
+ CR_ST_WORD(d, 2) ^= CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 2), 25);
93
+ CR_ST_WORD(d, 3) ^= CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(m, 3), 25) ^
94
+ ror32(t, 17) ^ ror32(t, 2) ^ ror32(t, 26);
95
+
96
+ rd[0] = d.l[0];
97
+ rd[1] = d.l[1];
98
+}
99
+
100
+void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
101
+ uint32_t opcode)
102
+{
103
+ uint64_t *rd = vd;
104
+ uint64_t *rn = vn;
105
+ uint64_t *rm = vm;
106
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
107
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
108
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
109
+ uint32_t t;
110
+
111
+ assert(imm2 < 4);
112
+
113
+ if (opcode == 0 || opcode == 2) {
114
+ /* SM3TT1A, SM3TT2A */
115
+ t = par(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
116
+ } else if (opcode == 1) {
117
+ /* SM3TT1B */
118
+ t = maj(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
119
+ } else if (opcode == 3) {
120
+ /* SM3TT2B */
121
+ t = cho(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
122
+ } else {
123
+ g_assert_not_reached();
124
+ }
45
+ }
125
+
46
+
126
+ t += CR_ST_WORD(d, 0) + CR_ST_WORD(m, imm2);
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
127
+
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
128
+ CR_ST_WORD(d, 0) = CR_ST_WORD(d, 1);
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
129
+
50
+ return false;
130
+ if (opcode < 2) {
131
+ /* SM3TT1A, SM3TT1B */
132
+ t += CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 3), 20);
133
+
134
+ CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 23);
135
+ } else {
136
+ /* SM3TT2A, SM3TT2B */
137
+ t += CR_ST_WORD(n, 3);
138
+ t ^= rol32(t, 9) ^ rol32(t, 17);
139
+
140
+ CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 13);
141
+ }
51
+ }
142
+
52
+
143
+ CR_ST_WORD(d, 2) = CR_ST_WORD(d, 3);
53
+ if ((a->vd | a->vn) & a->q) {
144
+ CR_ST_WORD(d, 3) = t;
54
+ return false;
145
+
146
+ rd[0] = d.l[0];
147
+ rd[1] = d.l[1];
148
+}
149
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-a64.c
152
+++ b/target/arm/translate-a64.c
153
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
154
break;
155
}
156
} else {
157
- unallocated_encoding(s);
158
- return;
159
+ switch (opcode) {
160
+ case 0: /* SM3PARTW1 */
161
+ feature = ARM_FEATURE_V8_SM3;
162
+ genfn = gen_helper_crypto_sm3partw1;
163
+ break;
164
+ case 1: /* SM3PARTW2 */
165
+ feature = ARM_FEATURE_V8_SM3;
166
+ genfn = gen_helper_crypto_sm3partw2;
167
+ break;
168
+ default:
169
+ unallocated_encoding(s);
170
+ return;
171
+ }
172
}
173
174
if (!arm_dc_feature(s, feature)) {
175
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
176
case 1: /* BCAX */
177
feature = ARM_FEATURE_V8_SHA3;
178
break;
179
+ case 2: /* SM3SS1 */
180
+ feature = ARM_FEATURE_V8_SM3;
181
+ break;
182
default:
183
unallocated_encoding(s);
184
return;
185
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
186
tcg_temp_free_i64(tcg_res[0]);
187
tcg_temp_free_i64(tcg_res[1]);
188
} else {
189
- g_assert_not_reached();
190
+ TCGv_i32 tcg_op1, tcg_op2, tcg_op3, tcg_res, tcg_zero;
191
+
192
+ tcg_op1 = tcg_temp_new_i32();
193
+ tcg_op2 = tcg_temp_new_i32();
194
+ tcg_op3 = tcg_temp_new_i32();
195
+ tcg_res = tcg_temp_new_i32();
196
+ tcg_zero = tcg_const_i32(0);
197
+
198
+ read_vec_element_i32(s, tcg_op1, rn, 3, MO_32);
199
+ read_vec_element_i32(s, tcg_op2, rm, 3, MO_32);
200
+ read_vec_element_i32(s, tcg_op3, ra, 3, MO_32);
201
+
202
+ tcg_gen_rotri_i32(tcg_res, tcg_op1, 20);
203
+ tcg_gen_add_i32(tcg_res, tcg_res, tcg_op2);
204
+ tcg_gen_add_i32(tcg_res, tcg_res, tcg_op3);
205
+ tcg_gen_rotri_i32(tcg_res, tcg_res, 25);
206
+
207
+ write_vec_element_i32(s, tcg_zero, rd, 0, MO_32);
208
+ write_vec_element_i32(s, tcg_zero, rd, 1, MO_32);
209
+ write_vec_element_i32(s, tcg_zero, rd, 2, MO_32);
210
+ write_vec_element_i32(s, tcg_res, rd, 3, MO_32);
211
+
212
+ tcg_temp_free_i32(tcg_op1);
213
+ tcg_temp_free_i32(tcg_op2);
214
+ tcg_temp_free_i32(tcg_op3);
215
+ tcg_temp_free_i32(tcg_res);
216
+ tcg_temp_free_i32(tcg_zero);
217
}
218
}
219
220
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_xar(DisasContext *s, uint32_t insn)
221
tcg_temp_free_i64(tcg_res[1]);
222
}
223
224
+/* Crypto three-reg imm2
225
+ * 31 21 20 16 15 14 13 12 11 10 9 5 4 0
226
+ * +-----------------------+------+-----+------+--------+------+------+
227
+ * | 1 1 0 0 1 1 1 0 0 1 0 | Rm | 1 0 | imm2 | opcode | Rn | Rd |
228
+ * +-----------------------+------+-----+------+--------+------+------+
229
+ */
230
+static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn)
231
+{
232
+ int opcode = extract32(insn, 10, 2);
233
+ int imm2 = extract32(insn, 12, 2);
234
+ int rm = extract32(insn, 16, 5);
235
+ int rn = extract32(insn, 5, 5);
236
+ int rd = extract32(insn, 0, 5);
237
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
238
+ TCGv_i32 tcg_imm2, tcg_opcode;
239
+
240
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_SM3)) {
241
+ unallocated_encoding(s);
242
+ return;
243
+ }
55
+ }
244
+
56
+
245
+ if (!fp_access_check(s)) {
57
+ if (!vfp_access_check(s)) {
246
+ return;
58
+ return true;
247
+ }
59
+ }
248
+
60
+
249
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
250
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
62
+ : gen_helper_gvec_fcmlah_idx);
251
+ tcg_rm_ptr = vec_full_reg_ptr(s, rm);
63
+ opr_sz = (1 + a->q) * 8;
252
+ tcg_imm2 = tcg_const_i32(imm2);
64
+ fpst = get_fpstatus_ptr(1);
253
+ tcg_opcode = tcg_const_i32(opcode);
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
254
+
66
+ vfp_reg_offset(1, a->vn),
255
+ gen_helper_crypto_sm3tt(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr, tcg_imm2,
67
+ vfp_reg_offset(1, a->vm),
256
+ tcg_opcode);
68
+ fpst, opr_sz, opr_sz,
257
+
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
258
+ tcg_temp_free_ptr(tcg_rd_ptr);
70
+ tcg_temp_free_ptr(fpst);
259
+ tcg_temp_free_ptr(tcg_rn_ptr);
71
+ return true;
260
+ tcg_temp_free_ptr(tcg_rm_ptr);
261
+ tcg_temp_free_i32(tcg_imm2);
262
+ tcg_temp_free_i32(tcg_opcode);
263
+}
72
+}
264
+
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
265
/* C3.6 Data processing - SIMD, inc Crypto
74
index XXXXXXX..XXXXXXX 100644
266
*
75
--- a/target/arm/translate.c
267
* As the decode gets a little complex we are using a table based
76
+++ b/target/arm/translate.c
268
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
269
{ 0xcec08000, 0xfffff000, disas_crypto_two_reg_sha512 },
78
bool is_long = false, q = extract32(insn, 6, 1);
270
{ 0xce000000, 0xff808000, disas_crypto_four_reg },
79
bool ptr_is_env = false;
271
{ 0xce800000, 0xffe00000, disas_crypto_xar },
80
272
+ { 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
81
- if ((insn & 0xff000f10) == 0xfe000800) {
273
{ 0x00000000, 0x00000000, NULL }
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
274
};
83
- int rot = extract32(insn, 20, 2);
84
- int size = extract32(insn, 23, 1);
85
- int index;
86
-
87
- if (!dc_isar_feature(aa32_vcma, s)) {
88
- return 1;
89
- }
90
- if (size == 0) {
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
92
- return 1;
93
- }
94
- /* For fp16, rm is just Vm, and index is M. */
95
- rm = extract32(insn, 0, 4);
96
- index = extract32(insn, 5, 1);
97
- } else {
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
99
- VFP_DREG_M(rm, insn);
100
- index = 0;
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);
275
109
276
--
110
--
277
2.16.1
111
2.20.1
278
112
279
113
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
2
to decodetree.
2
3
3
This implements emulation of the new SHA-512 instructions that have
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
been added as an optional extensions to the ARMv8 Crypto Extensions
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
in ARM v8.2.
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 3 +++
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 13 +-----------
11
3 files changed, 39 insertions(+), 12 deletions(-)
6
12
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
8
Message-id: 20180207111729.15737-2-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 1 +
13
target/arm/helper.h | 5 +++
14
target/arm/crypto_helper.c | 90 ++++++++++++++++++++++++++++++++++++-
15
target/arm/translate-a64.c | 110 +++++++++++++++++++++++++++++++++++++++++++++
16
4 files changed, 205 insertions(+), 1 deletion(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
15
--- a/target/arm/neon-shared.decode
21
+++ b/target/arm/cpu.h
16
+++ b/target/arm/neon-shared.decode
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
23
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
18
vn=%vn_dp vd=%vd_dp size=0
24
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
25
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
26
+ ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
21
+
27
};
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
28
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
29
static inline int arm_feature(CPUARMState *env, int feature)
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
31
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.h
26
--- a/target/arm/translate-neon.inc.c
33
+++ b/target/arm/helper.h
27
+++ b/target/arm/translate-neon.inc.c
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
35
DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr)
29
tcg_temp_free_ptr(fpst);
36
DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
30
return true;
37
38
+DEF_HELPER_FLAGS_3(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
39
+DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
40
+DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr)
41
+DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
42
+
43
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
44
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
45
DEF_HELPER_2(dc_zva, void, env, i64)
46
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/crypto_helper.c
49
+++ b/target/arm/crypto_helper.c
50
@@ -XXX,XX +XXX,XX @@
51
/*
52
* crypto_helper.c - emulate v8 Crypto Extensions instructions
53
*
54
- * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
55
+ * Copyright (C) 2013 - 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
56
*
57
* This library is free software; you can redistribute it and/or
58
* modify it under the terms of the GNU Lesser General Public
59
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
60
rd[0] = d.l[0];
61
rd[1] = d.l[1];
62
}
31
}
63
+
32
+
64
+/*
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
65
+ * The SHA-512 logical functions (same as above but using 64-bit operands)
34
+{
66
+ */
35
+ gen_helper_gvec_3 *fn_gvec;
36
+ int opr_sz;
37
+ TCGv_ptr fpst;
67
+
38
+
68
+static uint64_t cho512(uint64_t x, uint64_t y, uint64_t z)
39
+ if (!dc_isar_feature(aa32_dp, s)) {
69
+{
40
+ return false;
70
+ return (x & (y ^ z)) ^ z;
71
+}
72
+
73
+static uint64_t maj512(uint64_t x, uint64_t y, uint64_t z)
74
+{
75
+ return (x & y) | ((x | y) & z);
76
+}
77
+
78
+static uint64_t S0_512(uint64_t x)
79
+{
80
+ return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
81
+}
82
+
83
+static uint64_t S1_512(uint64_t x)
84
+{
85
+ return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
86
+}
87
+
88
+static uint64_t s0_512(uint64_t x)
89
+{
90
+ return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
91
+}
92
+
93
+static uint64_t s1_512(uint64_t x)
94
+{
95
+ return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
96
+}
97
+
98
+void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
99
+{
100
+ uint64_t *rd = vd;
101
+ uint64_t *rn = vn;
102
+ uint64_t *rm = vm;
103
+ uint64_t d0 = rd[0];
104
+ uint64_t d1 = rd[1];
105
+
106
+ d1 += S1_512(rm[1]) + cho512(rm[1], rn[0], rn[1]);
107
+ d0 += S1_512(d1 + rm[0]) + cho512(d1 + rm[0], rm[1], rn[0]);
108
+
109
+ rd[0] = d0;
110
+ rd[1] = d1;
111
+}
112
+
113
+void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
114
+{
115
+ uint64_t *rd = vd;
116
+ uint64_t *rn = vn;
117
+ uint64_t *rm = vm;
118
+ uint64_t d0 = rd[0];
119
+ uint64_t d1 = rd[1];
120
+
121
+ d1 += S0_512(rm[0]) + maj512(rn[0], rm[1], rm[0]);
122
+ d0 += S0_512(d1) + maj512(d1, rm[0], rm[1]);
123
+
124
+ rd[0] = d0;
125
+ rd[1] = d1;
126
+}
127
+
128
+void HELPER(crypto_sha512su0)(void *vd, void *vn)
129
+{
130
+ uint64_t *rd = vd;
131
+ uint64_t *rn = vn;
132
+ uint64_t d0 = rd[0];
133
+ uint64_t d1 = rd[1];
134
+
135
+ d0 += s0_512(rd[1]);
136
+ d1 += s0_512(rn[0]);
137
+
138
+ rd[0] = d0;
139
+ rd[1] = d1;
140
+}
141
+
142
+void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
143
+{
144
+ uint64_t *rd = vd;
145
+ uint64_t *rn = vn;
146
+ uint64_t *rm = vm;
147
+
148
+ rd[0] += s1_512(rn[0]) + rm[0];
149
+ rd[1] += s1_512(rn[1]) + rm[1];
150
+}
151
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/target/arm/translate-a64.c
154
+++ b/target/arm/translate-a64.c
155
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
156
tcg_temp_free_ptr(tcg_rn_ptr);
157
}
158
159
+/* Crypto three-reg SHA512
160
+ * 31 21 20 16 15 14 13 12 11 10 9 5 4 0
161
+ * +-----------------------+------+---+---+-----+--------+------+------+
162
+ * | 1 1 0 0 1 1 1 0 0 1 1 | Rm | 1 | O | 0 0 | opcode | Rn | Rd |
163
+ * +-----------------------+------+---+---+-----+--------+------+------+
164
+ */
165
+static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
166
+{
167
+ int opcode = extract32(insn, 10, 2);
168
+ int o = extract32(insn, 14, 1);
169
+ int rm = extract32(insn, 16, 5);
170
+ int rn = extract32(insn, 5, 5);
171
+ int rd = extract32(insn, 0, 5);
172
+ int feature;
173
+ CryptoThreeOpFn *genfn;
174
+
175
+ if (o == 0) {
176
+ switch (opcode) {
177
+ case 0: /* SHA512H */
178
+ feature = ARM_FEATURE_V8_SHA512;
179
+ genfn = gen_helper_crypto_sha512h;
180
+ break;
181
+ case 1: /* SHA512H2 */
182
+ feature = ARM_FEATURE_V8_SHA512;
183
+ genfn = gen_helper_crypto_sha512h2;
184
+ break;
185
+ case 2: /* SHA512SU1 */
186
+ feature = ARM_FEATURE_V8_SHA512;
187
+ genfn = gen_helper_crypto_sha512su1;
188
+ break;
189
+ default:
190
+ unallocated_encoding(s);
191
+ return;
192
+ }
193
+ } else {
194
+ unallocated_encoding(s);
195
+ return;
196
+ }
41
+ }
197
+
42
+
198
+ if (!arm_dc_feature(s, feature)) {
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
199
+ unallocated_encoding(s);
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
200
+ return;
45
+ ((a->vd | a->vn) & 0x10)) {
46
+ return false;
201
+ }
47
+ }
202
+
48
+
203
+ if (!fp_access_check(s)) {
49
+ if ((a->vd | a->vn) & a->q) {
204
+ return;
50
+ return false;
205
+ }
51
+ }
206
+
52
+
207
+ if (genfn) {
53
+ if (!vfp_access_check(s)) {
208
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
54
+ return true;
209
+
210
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
211
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
212
+ tcg_rm_ptr = vec_full_reg_ptr(s, rm);
213
+
214
+ genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr);
215
+
216
+ tcg_temp_free_ptr(tcg_rd_ptr);
217
+ tcg_temp_free_ptr(tcg_rn_ptr);
218
+ tcg_temp_free_ptr(tcg_rm_ptr);
219
+ } else {
220
+ g_assert_not_reached();
221
+ }
222
+}
223
+
224
+/* Crypto two-reg SHA512
225
+ * 31 12 11 10 9 5 4 0
226
+ * +-----------------------------------------+--------+------+------+
227
+ * | 1 1 0 0 1 1 1 0 1 1 0 0 0 0 0 0 1 0 0 0 | opcode | Rn | Rd |
228
+ * +-----------------------------------------+--------+------+------+
229
+ */
230
+static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
231
+{
232
+ int opcode = extract32(insn, 10, 2);
233
+ int rn = extract32(insn, 5, 5);
234
+ int rd = extract32(insn, 0, 5);
235
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
236
+ int feature;
237
+ CryptoTwoOpFn *genfn;
238
+
239
+ switch (opcode) {
240
+ case 0: /* SHA512SU0 */
241
+ feature = ARM_FEATURE_V8_SHA512;
242
+ genfn = gen_helper_crypto_sha512su0;
243
+ break;
244
+ default:
245
+ unallocated_encoding(s);
246
+ return;
247
+ }
55
+ }
248
+
56
+
249
+ if (!arm_dc_feature(s, feature)) {
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
250
+ unallocated_encoding(s);
58
+ opr_sz = (1 + a->q) * 8;
251
+ return;
59
+ fpst = get_fpstatus_ptr(1);
252
+ }
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
253
+
61
+ vfp_reg_offset(1, a->vn),
254
+ if (!fp_access_check(s)) {
62
+ vfp_reg_offset(1, a->rm),
255
+ return;
63
+ opr_sz, opr_sz, a->index, fn_gvec);
256
+ }
64
+ tcg_temp_free_ptr(fpst);
257
+
65
+ return true;
258
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
259
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
260
+
261
+ genfn(tcg_rd_ptr, tcg_rn_ptr);
262
+
263
+ tcg_temp_free_ptr(tcg_rd_ptr);
264
+ tcg_temp_free_ptr(tcg_rn_ptr);
265
+}
66
+}
266
+
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
267
/* C3.6 Data processing - SIMD, inc Crypto
68
index XXXXXXX..XXXXXXX 100644
268
*
69
--- a/target/arm/translate.c
269
* As the decode gets a little complex we are using a table based
70
+++ b/target/arm/translate.c
270
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
271
{ 0x4e280800, 0xff3e0c00, disas_crypto_aes },
72
bool is_long = false, q = extract32(insn, 6, 1);
272
{ 0x5e000000, 0xff208c00, disas_crypto_three_reg_sha },
73
bool ptr_is_env = false;
273
{ 0x5e280800, 0xff3e0c00, disas_crypto_two_reg_sha },
74
274
+ { 0xce608000, 0xffe0b000, disas_crypto_three_reg_sha512 },
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
275
+ { 0xcec08000, 0xfffff000, disas_crypto_two_reg_sha512 },
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
276
{ 0x00000000, 0x00000000, NULL }
77
- int u = extract32(insn, 4, 1);
277
};
78
-
278
79
- if (!dc_isar_feature(aa32_dp, s)) {
80
- return 1;
81
- }
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
83
- /* rm is just Vm, and index is M. */
84
- data = extract32(insn, 5, 1); /* index */
85
- rm = extract32(insn, 0, 4);
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
89
int is_s = extract32(insn, 20, 1);
90
int vm20 = extract32(insn, 0, 3);
279
--
91
--
280
2.16.1
92
2.20.1
281
93
282
94
diff view generated by jsdifflib
New patch
1
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
2
to decodetree. These are the last ones in the group so we can remove
3
all the legacy decode for the group.
4
5
Note that in disas_thumb2_insn() the parts of this encoding space
6
where the decodetree decoder returns false will correctly be directed
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
10
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
---
14
target/arm/neon-shared.decode | 7 +++
15
target/arm/translate-neon.inc.c | 32 ++++++++++
16
target/arm/translate.c | 107 +-------------------------------
17
3 files changed, 40 insertions(+), 106 deletions(-)
18
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
22
+++ b/target/arm/neon-shared.decode
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
24
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
+
28
+%vfml_scalar_q0_rm 0:3 5:1
29
+%vfml_scalar_q1_index 5:1 3:1
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
37
+++ b/target/arm/translate-neon.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
39
tcg_temp_free_ptr(fpst);
40
return true;
41
}
42
+
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
44
+{
45
+ int opr_sz;
46
+
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
48
+ return false;
49
+ }
50
+
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
54
+ return false;
55
+ }
56
+
57
+ if (a->vd & a->q) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ opr_sz = (1 + a->q) * 8;
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
67
+ vfp_reg_offset(a->q, a->vn),
68
+ vfp_reg_offset(a->q, a->rm),
69
+ cpu_env, opr_sz, opr_sz,
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
71
+ gen_helper_gvec_fmlal_idx_a32);
72
+ return true;
73
+}
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/translate.c
77
+++ b/target/arm/translate.c
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
79
}
80
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
82
-#define VFP_SREG(insn, bigbit, smallbit) \
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
86
reg = (((insn) >> (bigbit)) & 0x0f) \
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
88
reg = ((insn) >> (bigbit)) & 0x0f; \
89
}} while (0)
90
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
97
98
static void gen_neon_dup_low16(TCGv_i32 var)
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
100
return 0;
101
}
102
103
-/* Advanced SIMD two registers and a scalar extension.
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
108
- *
109
- */
110
-
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
112
-{
113
- gen_helper_gvec_3 *fn_gvec = NULL;
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
115
- int rd, rn, rm, opr_sz, data;
116
- int off_rn, off_rm;
117
- bool is_long = false, q = extract32(insn, 6, 1);
118
- bool ptr_is_env = false;
119
-
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
122
- int is_s = extract32(insn, 20, 1);
123
- int vm20 = extract32(insn, 0, 3);
124
- int vm3 = extract32(insn, 3, 1);
125
- int m = extract32(insn, 5, 1);
126
- int index;
127
-
128
- if (!dc_isar_feature(aa32_fhm, s)) {
129
- return 1;
130
- }
131
- if (q) {
132
- rm = vm20;
133
- index = m * 2 + vm3;
134
- } else {
135
- rm = vm20 * 2 + m;
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;
189
-}
190
-
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
192
{
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
195
}
196
}
197
}
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
201
- goto illegal_op;
202
- }
203
- return;
204
}
205
goto illegal_op;
206
}
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
208
}
209
break;
210
}
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
--
223
2.20.1
224
225
diff view generated by jsdifflib
New patch
1
1
Convert the Neon "load/store multiple structures" insns to decodetree.
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
6
---
7
target/arm/neon-ls.decode | 7 ++
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 91 +----------------------
10
3 files changed, 133 insertions(+), 89 deletions(-)
11
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-ls.decode
15
+++ b/target/arm/neon-ls.decode
16
@@ -XXX,XX +XXX,XX @@
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
18
# This file works on the A32 encoding only; calling code for T32 has to
19
# transform the insn into the A32 version first.
20
+
21
+%vd_dp 22:1 12:4
22
+
23
+# Neon load/store multiple structures
24
+
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
26
+ vd=%vd_dp
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
32
gen_helper_gvec_fmlal_idx_a32);
33
return true;
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
+};
53
+
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
55
+ int stride)
56
+{
57
+ if (rm != 15) {
58
+ TCGv_i32 base;
59
+
60
+ base = load_reg(s, rn);
61
+ if (rm == 13) {
62
+ tcg_gen_addi_i32(base, base, stride);
63
+ } else {
64
+ TCGv_i32 index;
65
+ index = load_reg(s, rm);
66
+ tcg_gen_add_i32(base, base, index);
67
+ tcg_temp_free_i32(index);
68
+ }
69
+ store_reg(s, rn, base);
70
+ }
71
+}
72
+
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
74
+{
75
+ /* Neon load/store multiple structures */
76
+ int nregs, interleave, spacing, reg, n;
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
+ }
100
+ break;
101
+ case 8:
102
+ if (a->align == 3) {
103
+ return false;
104
+ }
105
+ break;
106
+ default:
107
+ break;
108
+ }
109
+ nregs = neon_ls_element_type[a->itype].nregs;
110
+ interleave = neon_ls_element_type[a->itype].interleave;
111
+ spacing = neon_ls_element_type[a->itype].spacing;
112
+ if (size == 3 && (interleave | spacing) != 1) {
113
+ return false;
114
+ }
115
+
116
+ if (!vfp_access_check(s)) {
117
+ return true;
118
+ }
119
+
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
+ }
151
+ }
152
+ tcg_temp_free_i32(addr);
153
+ tcg_temp_free_i32(tmp);
154
+ tcg_temp_free_i64(tmp64);
155
+
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
157
+ return true;
158
+}
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate.c
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
--
283
2.20.1
284
285
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
Convert the Neon "load single structure to all lanes" insns to
2
decodetree.
2
3
3
Add minimal code needed to allow upstream Linux guest to boot.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
7
---
8
target/arm/neon-ls.decode | 5 +++
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 55 +------------------------
11
3 files changed, 80 insertions(+), 53 deletions(-)
4
12
5
Cc: Peter Maydell <peter.maydell@linaro.org>
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
6
Cc: Jason Wang <jasowang@redhat.com>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/intc/Makefile.objs | 2 +-
18
include/hw/intc/imx_gpcv2.h | 22 ++++++++
19
hw/intc/imx_gpcv2.c | 125 ++++++++++++++++++++++++++++++++++++++++++++
20
3 files changed, 148 insertions(+), 1 deletion(-)
21
create mode 100644 include/hw/intc/imx_gpcv2.h
22
create mode 100644 hw/intc/imx_gpcv2.c
23
24
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
25
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/intc/Makefile.objs
15
--- a/target/arm/neon-ls.decode
27
+++ b/hw/intc/Makefile.objs
16
+++ b/target/arm/neon-ls.decode
28
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XILINX) += xilinx_intc.o
29
common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-pmu-iomod-intc.o
30
common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-ipi.o
31
common-obj-$(CONFIG_ETRAXFS) += etraxfs_pic.o
32
-common-obj-$(CONFIG_IMX) += imx_avic.o
33
+common-obj-$(CONFIG_IMX) += imx_avic.o imx_gpcv2.o
34
common-obj-$(CONFIG_LM32) += lm32_pic.o
35
common-obj-$(CONFIG_REALVIEW) += realview_gic.o
36
common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
37
diff --git a/include/hw/intc/imx_gpcv2.h b/include/hw/intc/imx_gpcv2.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/imx_gpcv2.h
42
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
43
+#ifndef IMX_GPCV2_H
18
44
+#define IMX_GPCV2_H
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
20
vd=%vd_dp
45
+
21
+
46
+#include "hw/sysbus.h"
22
+# Neon load single element to all lanes
47
+
23
+
48
+enum IMXGPCv2Registers {
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
49
+ GPC_NUM = 0xE00 / sizeof(uint32_t),
25
+ vd=%vd_dp
50
+};
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-neon.inc.c
29
+++ b/target/arm/translate-neon.inc.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
32
return true;
33
}
51
+
34
+
52
+typedef struct IMXGPCv2State {
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
53
+ /*< private >*/
36
+{
54
+ SysBusDevice parent_obj;
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;
55
+
43
+
56
+ /*< public >*/
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
57
+ MemoryRegion iomem;
45
+ return false;
58
+ uint32_t regs[GPC_NUM];
46
+ }
59
+} IMXGPCv2State;
60
+
47
+
61
+#define TYPE_IMX_GPCV2 "imx-gpcv2"
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
62
+#define IMX_GPCV2(obj) OBJECT_CHECK(IMXGPCv2State, (obj), TYPE_IMX_GPCV2)
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
50
+ return false;
51
+ }
63
+
52
+
64
+#endif /* IMX_GPCV2_H */
53
+ if (size == 3) {
65
diff --git a/hw/intc/imx_gpcv2.c b/hw/intc/imx_gpcv2.c
54
+ if (nregs != 4 || a->a == 0) {
66
new file mode 100644
55
+ return false;
67
index XXXXXXX..XXXXXXX
56
+ }
68
--- /dev/null
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
69
+++ b/hw/intc/imx_gpcv2.c
58
+ size = 2;
70
@@ -XXX,XX +XXX,XX @@
59
+ }
71
+/*
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
72
+ * Copyright (c) 2018, Impinj, Inc.
61
+ return false;
73
+ *
62
+ }
74
+ * i.MX7 GPCv2 block emulation code
63
+ if (nregs == 3 && a->a == 1) {
75
+ *
64
+ return false;
76
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
65
+ }
77
+ *
78
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
79
+ * See the COPYING file in the top-level directory.
80
+ */
81
+
66
+
82
+#include "qemu/osdep.h"
67
+ if (!vfp_access_check(s)) {
83
+#include "hw/intc/imx_gpcv2.h"
68
+ return true;
84
+#include "qemu/log.h"
69
+ }
85
+
86
+#define GPC_PU_PGC_SW_PUP_REQ 0x0f8
87
+#define GPC_PU_PGC_SW_PDN_REQ 0x104
88
+
89
+#define USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
90
+#define USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
91
+#define USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
92
+#define PCIE_PHY_SW_Pxx_REQ BIT(1)
93
+#define MIPI_PHY_SW_Pxx_REQ BIT(0)
94
+
95
+
96
+static void imx_gpcv2_reset(DeviceState *dev)
97
+{
98
+ IMXGPCv2State *s = IMX_GPCV2(dev);
99
+
100
+ memset(s->regs, 0, sizeof(s->regs));
101
+}
102
+
103
+static uint64_t imx_gpcv2_read(void *opaque, hwaddr offset,
104
+ unsigned size)
105
+{
106
+ IMXGPCv2State *s = opaque;
107
+
108
+ return s->regs[offset / sizeof(uint32_t)];
109
+}
110
+
111
+static void imx_gpcv2_write(void *opaque, hwaddr offset,
112
+ uint64_t value, unsigned size)
113
+{
114
+ IMXGPCv2State *s = opaque;
115
+ const size_t idx = offset / sizeof(uint32_t);
116
+
117
+ s->regs[idx] = value;
118
+
70
+
119
+ /*
71
+ /*
120
+ * Real HW will clear those bits once as a way to indicate that
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
121
+ * power up request is complete
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
122
+ */
74
+ */
123
+ if (offset == GPC_PU_PGC_SW_PUP_REQ ||
75
+ stride = a->t ? 2 : 1;
124
+ offset == GPC_PU_PGC_SW_PDN_REQ) {
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
125
+ s->regs[idx] &= ~(USB_HSIC_PHY_SW_Pxx_REQ |
77
+
126
+ USB_OTG2_PHY_SW_Pxx_REQ |
78
+ tmp = tcg_temp_new_i32();
127
+ USB_OTG1_PHY_SW_Pxx_REQ |
79
+ addr = tcg_temp_new_i32();
128
+ PCIE_PHY_SW_Pxx_REQ |
80
+ load_reg_var(s, addr, a->rn);
129
+ MIPI_PHY_SW_Pxx_REQ);
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
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
98
+ vd += stride;
130
+ }
99
+ }
100
+ tcg_temp_free_i32(tmp);
101
+ tcg_temp_free_i32(addr);
102
+
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
104
+
105
+ return true;
131
+}
106
+}
132
+
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
133
+static const struct MemoryRegionOps imx_gpcv2_ops = {
108
index XXXXXXX..XXXXXXX 100644
134
+ .read = imx_gpcv2_read,
109
--- a/target/arm/translate.c
135
+ .write = imx_gpcv2_write,
110
+++ b/target/arm/translate.c
136
+ .endianness = DEVICE_NATIVE_ENDIAN,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
137
+ .impl = {
112
int size;
138
+ /*
113
int reg;
139
+ * Our device would not work correctly if the guest was doing
114
int load;
140
+ * unaligned access. This might not be a limitation on the real
115
- int vec_size;
141
+ * device but in practice there is no reason for a guest to access
116
TCGv_i32 addr;
142
+ * this device unaligned.
117
TCGv_i32 tmp;
143
+ */
118
144
+ .min_access_size = 4,
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
145
+ .max_access_size = 4,
120
} else {
146
+ .unaligned = false,
121
size = (insn >> 10) & 3;
147
+ },
122
if (size == 3) {
148
+};
123
- /* Load single element to all lanes. */
149
+
124
- int a = (insn >> 4) & 1;
150
+static void imx_gpcv2_init(Object *obj)
125
- if (!load) {
151
+{
126
- return 1;
152
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
127
- }
153
+ IMXGPCv2State *s = IMX_GPCV2(obj);
128
- size = (insn >> 6) & 3;
154
+
129
- nregs = ((insn >> 8) & 3) + 1;
155
+ memory_region_init_io(&s->iomem,
130
-
156
+ obj,
131
- if (size == 3) {
157
+ &imx_gpcv2_ops,
132
- if (nregs != 4 || a == 0) {
158
+ s,
133
- return 1;
159
+ TYPE_IMX_GPCV2 ".iomem",
134
- }
160
+ sizeof(s->regs));
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
161
+ sysbus_init_mmio(sd, &s->iomem);
136
- size = 2;
162
+}
137
- }
163
+
138
- if (nregs == 1 && a == 1 && size == 0) {
164
+static const VMStateDescription vmstate_imx_gpcv2 = {
139
- return 1;
165
+ .name = TYPE_IMX_GPCV2,
140
- }
166
+ .version_id = 1,
141
- if (nregs == 3 && a == 1) {
167
+ .minimum_version_id = 1,
142
- return 1;
168
+ .fields = (VMStateField[]) {
143
- }
169
+ VMSTATE_UINT32_ARRAY(regs, IMXGPCv2State, GPC_NUM),
144
- addr = tcg_temp_new_i32();
170
+ VMSTATE_END_OF_LIST()
145
- load_reg_var(s, addr, rn);
171
+ },
146
-
172
+};
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
173
+
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
174
+static void imx_gpcv2_class_init(ObjectClass *klass, void *data)
149
- */
175
+{
150
- stride = (insn & (1 << 5)) ? 2 : 1;
176
+ DeviceClass *dc = DEVICE_CLASS(klass);
151
- vec_size = nregs == 1 ? stride * 8 : 8;
177
+
152
-
178
+ dc->reset = imx_gpcv2_reset;
153
- tmp = tcg_temp_new_i32();
179
+ dc->vmsd = &vmstate_imx_gpcv2;
154
- for (reg = 0; reg < nregs; reg++) {
180
+ dc->desc = "i.MX GPCv2 Module";
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
181
+}
156
- s->be_data | size);
182
+
157
- if ((rd & 1) && vec_size == 16) {
183
+static const TypeInfo imx_gpcv2_info = {
158
- /* We cannot write 16 bytes at once because the
184
+ .name = TYPE_IMX_GPCV2,
159
- * destination is unaligned.
185
+ .parent = TYPE_SYS_BUS_DEVICE,
160
- */
186
+ .instance_size = sizeof(IMXGPCv2State),
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
187
+ .instance_init = imx_gpcv2_init,
162
- 8, 8, tmp);
188
+ .class_init = imx_gpcv2_class_init,
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
189
+};
164
- neon_reg_offset(rd, 0), 8, 8);
190
+
165
- } else {
191
+static void imx_gpcv2_register_type(void)
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
192
+{
167
- vec_size, vec_size, tmp);
193
+ type_register_static(&imx_gpcv2_info);
168
- }
194
+}
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
195
+type_init(imx_gpcv2_register_type)
170
- rd += stride;
171
- }
172
- tcg_temp_free_i32(tmp);
173
- tcg_temp_free_i32(addr);
174
- stride = (1 << size) * nregs;
175
+ /* Load single element to all lanes -- handled by decodetree */
176
+ return 1;
177
} else {
178
/* Single element. */
179
int idx = (insn >> 4) & 0xf;
196
--
180
--
197
2.16.1
181
2.20.1
198
182
199
183
diff view generated by jsdifflib
New patch
1
1
Convert the Neon "load/store single structure to one lane" insns to
2
decodetree.
3
4
As this is the last set of insns in the neon load/store group,
5
we can remove the whole disas_neon_ls_insn() function.
6
7
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
---
11
target/arm/neon-ls.decode | 11 +++
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
13
target/arm/translate.c | 147 --------------------------------
14
3 files changed, 100 insertions(+), 147 deletions(-)
15
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-ls.decode
19
+++ b/target/arm/neon-ls.decode
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
21
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
23
vd=%vd_dp
24
+
25
+# Neon load/store single structure to one lane
26
+%imm1_5_p1 5:1 !function=plus1
27
+%imm1_6_p1 6:1 !function=plus1
28
+
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
37
--- a/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@
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;
54
}
55
+
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
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;
106
+ }
107
+
108
+ if (!vfp_access_check(s)) {
109
+ return true;
110
+ }
111
+
112
+ tmp = tcg_temp_new_i32();
113
+ addr = tcg_temp_new_i32();
114
+ load_reg_var(s, addr, a->rn);
115
+ /*
116
+ * TODO: if we implemented alignment exceptions, we should check
117
+ * addr against the alignment encoded in a->align here.
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);
134
+
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
136
+
137
+ return true;
138
+}
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
142
+++ b/target/arm/translate.c
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
144
tcg_temp_free_i32(rd);
145
}
146
147
-
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
149
- instruction is invalid. */
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
151
-{
152
- int rd, rn, rm;
153
- int nregs;
154
- int stride;
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
--
312
2.20.1
313
314
diff view generated by jsdifflib
1
Handle possible MPU faults, SAU faults or bus errors when
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
2
popping register state off the stack during exception return.
2
3
Note that we don't need the neon_3r_sizes[op] check here because all
4
size values are OK for VADD and VSUB; we'll add this when we convert
5
the first insn that has size restrictions.
6
7
For this we need one of the GVecGen*Fn typedefs currently in
8
translate-a64.h; move them all to translate.h as a block so they
9
are visible to the 32-bit decoder.
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: 1517324542-6607-8-git-send-email-peter.maydell@linaro.org
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
7
---
14
---
8
target/arm/helper.c | 115 ++++++++++++++++++++++++++++++++++++++++++----------
15
target/arm/translate-a64.h | 9 --------
9
1 file changed, 94 insertions(+), 21 deletions(-)
16
target/arm/translate.h | 9 ++++++++
17
target/arm/neon-dp.decode | 17 +++++++++++++++
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
19
target/arm/translate.c | 14 ++++--------
20
5 files changed, 68 insertions(+), 19 deletions(-)
10
21
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
12
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
24
--- a/target/arm/translate-a64.h
14
+++ b/target/arm/helper.c
25
+++ b/target/arm/translate-a64.h
15
@@ -XXX,XX +XXX,XX @@ pend_fault:
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
16
return false;
27
28
bool disas_sve(DisasContext *, uint32_t);
29
30
-/* Note that the gvec expanders operate on offsets + sizes. */
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
33
- uint32_t, uint32_t);
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
35
- uint32_t, uint32_t, uint32_t);
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
37
- uint32_t, uint32_t, uint32_t);
38
-
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate.h
43
+++ b/target/arm/translate.h
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
45
#define dc_isar_feature(name, ctx) \
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
47
48
+/* Note that the gvec expanders operate on offsets + sizes. */
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
51
+ uint32_t, uint32_t);
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
53
+ uint32_t, uint32_t, uint32_t);
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
55
+ uint32_t, uint32_t, uint32_t);
56
+
57
#endif /* TARGET_ARM_TRANSLATE_H */
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/neon-dp.decode
61
+++ b/target/arm/neon-dp.decode
62
@@ -XXX,XX +XXX,XX @@
63
#
64
# This file is processed by scripts/decodetree.py
65
#
66
+# VFP/Neon register fields; same as vfp.decode
67
+%vm_dp 5:1 0:4
68
+%vn_dp 7:1 16:4
69
+%vd_dp 22:1 12:4
70
71
# Encodings for Neon data processing instructions where the T32 encoding
72
# is a simple transformation of the A32 encoding.
73
@@ -XXX,XX +XXX,XX @@
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
75
# This file works on the A32 encoding only; calling code for T32 has to
76
# transform the insn into the A32 version first.
77
+
78
+######################################################################
79
+# 3-reg-same grouping:
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
81
+######################################################################
82
+
83
+&3same vm vn vd q size
84
+
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
87
+
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
93
+++ b/target/arm/translate-neon.inc.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
95
96
return true;
17
}
97
}
18
98
+
19
+static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
20
+ ARMMMUIdx mmu_idx)
21
+{
100
+{
22
+ CPUState *cs = CPU(cpu);
101
+ int vec_size = a->q ? 16 : 8;
23
+ CPUARMState *env = &cpu->env;
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
24
+ MemTxAttrs attrs = {};
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
25
+ MemTxResult txres;
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
26
+ target_ulong page_size;
27
+ hwaddr physaddr;
28
+ int prot;
29
+ ARMMMUFaultInfo fi;
30
+ bool secure = mmu_idx & ARM_MMU_IDX_M_S;
31
+ int exc;
32
+ bool exc_secure;
33
+ uint32_t value;
34
+
105
+
35
+ if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &physaddr,
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
36
+ &attrs, &prot, &page_size, &fi, NULL)) {
107
+ return false;
37
+ /* MPU/SAU lookup failed */
38
+ if (fi.type == ARMFault_QEMU_SFault) {
39
+ qemu_log_mask(CPU_LOG_INT,
40
+ "...SecureFault with SFSR.AUVIOL during unstack\n");
41
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
42
+ env->v7m.sfar = addr;
43
+ exc = ARMV7M_EXCP_SECURE;
44
+ exc_secure = false;
45
+ } else {
46
+ qemu_log_mask(CPU_LOG_INT,
47
+ "...MemManageFault with CFSR.MUNSTKERR\n");
48
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MUNSTKERR_MASK;
49
+ exc = ARMV7M_EXCP_MEM;
50
+ exc_secure = secure;
51
+ }
52
+ goto pend_fault;
53
+ }
108
+ }
54
+
109
+
55
+ value = address_space_ldl(arm_addressspace(cs, attrs), physaddr,
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
56
+ attrs, &txres);
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
57
+ if (txres != MEMTX_OK) {
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
58
+ /* BusFault trying to read the data */
113
+ return false;
59
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
60
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_UNSTKERR_MASK;
61
+ exc = ARMV7M_EXCP_BUS;
62
+ exc_secure = false;
63
+ goto pend_fault;
64
+ }
114
+ }
65
+
115
+
66
+ *dest = value;
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
117
+ return false;
118
+ }
119
+
120
+ if (!vfp_access_check(s)) {
121
+ return true;
122
+ }
123
+
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
67
+ return true;
125
+ return true;
68
+
69
+pend_fault:
70
+ /* By pending the exception at this point we are making
71
+ * the IMPDEF choice "overridden exceptions pended" (see the
72
+ * MergeExcInfo() pseudocode). The other choice would be to not
73
+ * pend them now and then make a choice about which to throw away
74
+ * later if we have two derived exceptions.
75
+ */
76
+ armv7m_nvic_set_pending(env->nvic, exc, exc_secure);
77
+ return false;
78
+}
126
+}
79
+
127
+
80
/* Return true if we're using the process stack pointer (not the MSP) */
128
+#define DO_3SAME(INSN, FUNC) \
81
static bool v7m_using_psp(CPUARMState *env)
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
82
{
130
+ { \
83
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
131
+ return do_3same(s, a, FUNC); \
84
!return_to_handler,
132
+ }
85
return_to_sp_process);
86
uint32_t frameptr = *frame_sp_p;
87
+ bool pop_ok = true;
88
+ ARMMMUIdx mmu_idx;
89
+
133
+
90
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, return_to_secure,
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
91
+ !return_to_handler);
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
92
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
93
if (!QEMU_IS_ALIGNED(frameptr, 8) &&
137
index XXXXXXX..XXXXXXX 100644
94
arm_feature(env, ARM_FEATURE_V8)) {
138
--- a/target/arm/translate.c
95
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
139
+++ b/target/arm/translate.c
96
return;
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
97
}
141
}
98
142
return 0;
99
- env->regs[4] = ldl_phys(cs->as, frameptr + 0x8);
143
100
- env->regs[5] = ldl_phys(cs->as, frameptr + 0xc);
144
- case NEON_3R_VADD_VSUB:
101
- env->regs[6] = ldl_phys(cs->as, frameptr + 0x10);
145
- if (u) {
102
- env->regs[7] = ldl_phys(cs->as, frameptr + 0x14);
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
103
- env->regs[8] = ldl_phys(cs->as, frameptr + 0x18);
147
- vec_size, vec_size);
104
- env->regs[9] = ldl_phys(cs->as, frameptr + 0x1c);
148
- } else {
105
- env->regs[10] = ldl_phys(cs->as, frameptr + 0x20);
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
106
- env->regs[11] = ldl_phys(cs->as, frameptr + 0x24);
150
- vec_size, vec_size);
107
+ pop_ok =
151
- }
108
+ v7m_stack_read(cpu, &env->regs[4], frameptr + 0x8, mmu_idx) &&
152
- return 0;
109
+ v7m_stack_read(cpu, &env->regs[4], frameptr + 0x8, mmu_idx) &&
153
-
110
+ v7m_stack_read(cpu, &env->regs[5], frameptr + 0xc, mmu_idx) &&
154
case NEON_3R_VQADD:
111
+ v7m_stack_read(cpu, &env->regs[6], frameptr + 0x10, mmu_idx) &&
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
112
+ v7m_stack_read(cpu, &env->regs[7], frameptr + 0x14, mmu_idx) &&
156
rn_ofs, rm_ofs, vec_size, vec_size,
113
+ v7m_stack_read(cpu, &env->regs[8], frameptr + 0x18, mmu_idx) &&
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
114
+ v7m_stack_read(cpu, &env->regs[9], frameptr + 0x1c, mmu_idx) &&
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
115
+ v7m_stack_read(cpu, &env->regs[10], frameptr + 0x20, mmu_idx) &&
159
u ? &ushl_op[size] : &sshl_op[size]);
116
+ v7m_stack_read(cpu, &env->regs[11], frameptr + 0x24, mmu_idx);
160
return 0;
117
161
+
118
frameptr += 0x28;
162
+ case NEON_3R_VADD_VSUB:
163
+ /* Already handled by decodetree */
164
+ return 1;
119
}
165
}
120
166
121
- /* Pop registers. TODO: make these accesses use the correct
167
if (size == 3) {
122
- * attributes and address space (S/NS, priv/unpriv) and handle
123
- * memory transaction failures.
124
- */
125
- env->regs[0] = ldl_phys(cs->as, frameptr);
126
- env->regs[1] = ldl_phys(cs->as, frameptr + 0x4);
127
- env->regs[2] = ldl_phys(cs->as, frameptr + 0x8);
128
- env->regs[3] = ldl_phys(cs->as, frameptr + 0xc);
129
- env->regs[12] = ldl_phys(cs->as, frameptr + 0x10);
130
- env->regs[14] = ldl_phys(cs->as, frameptr + 0x14);
131
- env->regs[15] = ldl_phys(cs->as, frameptr + 0x18);
132
+ /* Pop registers */
133
+ pop_ok = pop_ok &&
134
+ v7m_stack_read(cpu, &env->regs[0], frameptr, mmu_idx) &&
135
+ v7m_stack_read(cpu, &env->regs[1], frameptr + 0x4, mmu_idx) &&
136
+ v7m_stack_read(cpu, &env->regs[2], frameptr + 0x8, mmu_idx) &&
137
+ v7m_stack_read(cpu, &env->regs[3], frameptr + 0xc, mmu_idx) &&
138
+ v7m_stack_read(cpu, &env->regs[12], frameptr + 0x10, mmu_idx) &&
139
+ v7m_stack_read(cpu, &env->regs[14], frameptr + 0x14, mmu_idx) &&
140
+ v7m_stack_read(cpu, &env->regs[15], frameptr + 0x18, mmu_idx) &&
141
+ v7m_stack_read(cpu, &xpsr, frameptr + 0x1c, mmu_idx);
142
+
143
+ if (!pop_ok) {
144
+ /* v7m_stack_read() pended a fault, so take it (as a tail
145
+ * chained exception on the same stack frame)
146
+ */
147
+ v7m_exception_taken(cpu, excret, true, false);
148
+ return;
149
+ }
150
151
/* Returning from an exception with a PC with bit 0 set is defined
152
* behaviour on v8M (bit 0 is ignored), but for v7M it was specified
153
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
154
}
155
}
156
157
- xpsr = ldl_phys(cs->as, frameptr + 0x1c);
158
-
159
if (arm_feature(env, ARM_FEATURE_V8)) {
160
/* For v8M we have to check whether the xPSR exception field
161
* matches the EXCRET value for return to handler/thread
162
--
168
--
163
2.16.1
169
2.20.1
164
170
165
171
diff view generated by jsdifflib
New patch
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
2
Note that for the logic ops the 'size' field forms part of their
3
decode and the actual operations are always bitwise.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
8
---
9
target/arm/neon-dp.decode | 12 +++++++++++
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
11
target/arm/translate.c | 38 +--------------------------------
12
3 files changed, 32 insertions(+), 37 deletions(-)
13
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
17
+++ b/target/arm/neon-dp.decode
18
@@ -XXX,XX +XXX,XX @@
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
21
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
24
+
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
33
+
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
39
+++ b/target/arm/translate-neon.inc.c
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
41
42
DO_3SAME(VADD, tcg_gen_gvec_add)
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
49
+
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
54
+ uint32_t oprsz, uint32_t maxsz) \
55
+ { \
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
57
+ } \
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
59
+
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.c
66
+++ b/target/arm/translate.c
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
68
}
69
return 1;
70
71
- case NEON_3R_LOGIC: /* Logic ops. */
72
- switch ((u << 2) | size) {
73
- case 0: /* VAND */
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
75
- vec_size, vec_size);
76
- break;
77
- case 1: /* VBIC */
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
79
- vec_size, vec_size);
80
- break;
81
- case 2: /* VORR */
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
83
- vec_size, vec_size);
84
- break;
85
- case 3: /* VORN */
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
87
- vec_size, vec_size);
88
- break;
89
- case 4: /* VEOR */
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
91
- vec_size, vec_size);
92
- break;
93
- case 5: /* VBSL */
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
95
- vec_size, vec_size);
96
- break;
97
- case 6: /* VBIT */
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
99
- vec_size, vec_size);
100
- break;
101
- case 7: /* VBIF */
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
103
- vec_size, vec_size);
104
- break;
105
- }
106
- return 0;
107
-
108
case NEON_3R_VQADD:
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
110
rn_ofs, rm_ofs, vec_size, vec_size,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
114
case NEON_3R_VADD_VSUB:
115
+ case NEON_3R_LOGIC:
116
/* Already handled by decodetree */
117
return 1;
118
}
119
--
120
2.20.1
121
122
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
2
2
3
Add minimal code needed to allow upstream Linux guest to boot.
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
6
---
7
target/arm/neon-dp.decode | 5 +++++
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
9
target/arm/translate.c | 21 ++-------------------
10
3 files changed, 21 insertions(+), 19 deletions(-)
4
11
5
Cc: Peter Maydell <peter.maydell@linaro.org>
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
6
Cc: Jason Wang <jasowang@redhat.com>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
hw/misc/Makefile.objs | 1 +
19
include/hw/misc/imx7_gpr.h | 28 ++++++++++
20
hw/misc/imx7_gpr.c | 124 +++++++++++++++++++++++++++++++++++++++++++++
21
hw/misc/trace-events | 4 ++
22
4 files changed, 157 insertions(+)
23
create mode 100644 include/hw/misc/imx7_gpr.h
24
create mode 100644 hw/misc/imx7_gpr.c
25
26
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
27
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/misc/Makefile.objs
14
--- a/target/arm/neon-dp.decode
29
+++ b/hw/misc/Makefile.objs
15
+++ b/target/arm/neon-dp.decode
30
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx6_src.o
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
31
obj-$(CONFIG_IMX) += imx7_ccm.o
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
32
obj-$(CONFIG_IMX) += imx2_wdt.o
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
33
obj-$(CONFIG_IMX) += imx7_snvs.o
19
34
+obj-$(CONFIG_IMX) += imx7_gpr.o
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
35
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
36
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
37
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
38
diff --git a/include/hw/misc/imx7_gpr.h b/include/hw/misc/imx7_gpr.h
39
new file mode 100644
40
index XXXXXXX..XXXXXXX
41
--- /dev/null
42
+++ b/include/hw/misc/imx7_gpr.h
43
@@ -XXX,XX +XXX,XX @@
44
+/*
45
+ * Copyright (c) 2017, Impinj, Inc.
46
+ *
47
+ * i.MX7 GPR IP block emulation code
48
+ *
49
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
50
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
53
+ */
54
+
24
+
55
+#ifndef IMX7_GPR_H
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
56
+#define IMX7_GPR_H
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
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)
57
+
35
+
58
+#include "qemu/bitops.h"
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
59
+#include "hw/sysbus.h"
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
60
+
38
+ { \
61
+#define TYPE_IMX7_GPR "imx7.gpr"
39
+ if (a->size == 3) { \
62
+#define IMX7_GPR(obj) OBJECT_CHECK(IMX7GPRState, (obj), TYPE_IMX7_GPR)
40
+ return false; \
63
+
41
+ } \
64
+typedef struct IMX7GPRState {
42
+ return do_3same(s, a, FUNC); \
65
+ /* <private> */
66
+ SysBusDevice parent_obj;
67
+
68
+ MemoryRegion mmio;
69
+} IMX7GPRState;
70
+
71
+#endif /* IMX7_GPR_H */
72
diff --git a/hw/misc/imx7_gpr.c b/hw/misc/imx7_gpr.c
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/hw/misc/imx7_gpr.c
77
@@ -XXX,XX +XXX,XX @@
78
+/*
79
+ * Copyright (c) 2018, Impinj, Inc.
80
+ *
81
+ * i.MX7 GPR IP block emulation code
82
+ *
83
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
84
+ *
85
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
86
+ * See the COPYING file in the top-level directory.
87
+ *
88
+ * Bare minimum emulation code needed to support being able to shut
89
+ * down linux guest gracefully.
90
+ */
91
+
92
+#include "qemu/osdep.h"
93
+#include "hw/misc/imx7_gpr.h"
94
+#include "qemu/log.h"
95
+#include "sysemu/sysemu.h"
96
+
97
+#include "trace.h"
98
+
99
+enum IMX7GPRRegisters {
100
+ IOMUXC_GPR0 = 0x00,
101
+ IOMUXC_GPR1 = 0x04,
102
+ IOMUXC_GPR2 = 0x08,
103
+ IOMUXC_GPR3 = 0x0c,
104
+ IOMUXC_GPR4 = 0x10,
105
+ IOMUXC_GPR5 = 0x14,
106
+ IOMUXC_GPR6 = 0x18,
107
+ IOMUXC_GPR7 = 0x1c,
108
+ IOMUXC_GPR8 = 0x20,
109
+ IOMUXC_GPR9 = 0x24,
110
+ IOMUXC_GPR10 = 0x28,
111
+ IOMUXC_GPR11 = 0x2c,
112
+ IOMUXC_GPR12 = 0x30,
113
+ IOMUXC_GPR13 = 0x34,
114
+ IOMUXC_GPR14 = 0x38,
115
+ IOMUXC_GPR15 = 0x3c,
116
+ IOMUXC_GPR16 = 0x40,
117
+ IOMUXC_GPR17 = 0x44,
118
+ IOMUXC_GPR18 = 0x48,
119
+ IOMUXC_GPR19 = 0x4c,
120
+ IOMUXC_GPR20 = 0x50,
121
+ IOMUXC_GPR21 = 0x54,
122
+ IOMUXC_GPR22 = 0x58,
123
+};
124
+
125
+#define IMX7D_GPR1_IRQ_MASK BIT(12)
126
+#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK BIT(13)
127
+#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK BIT(14)
128
+#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK (0x3 << 13)
129
+#define IMX7D_GPR1_ENET1_CLK_DIR_MASK BIT(17)
130
+#define IMX7D_GPR1_ENET2_CLK_DIR_MASK BIT(18)
131
+#define IMX7D_GPR1_ENET_CLK_DIR_MASK (0x3 << 17)
132
+
133
+#define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI BIT(4)
134
+#define IMX7D_GPR12_PCIE_PHY_REFCLK_SEL BIT(5)
135
+#define IMX7D_GPR22_PCIE_PHY_PLL_LOCKED BIT(31)
136
+
137
+
138
+static uint64_t imx7_gpr_read(void *opaque, hwaddr offset, unsigned size)
139
+{
140
+ trace_imx7_gpr_read(offset);
141
+
142
+ if (offset == IOMUXC_GPR22) {
143
+ return IMX7D_GPR22_PCIE_PHY_PLL_LOCKED;
144
+ }
43
+ }
145
+
44
+
146
+ return 0;
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
147
+}
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
148
+
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
149
+static void imx7_gpr_write(void *opaque, hwaddr offset,
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
150
+ uint64_t v, unsigned size)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
151
+{
152
+ trace_imx7_gpr_write(offset, v);
153
+}
154
+
155
+static const struct MemoryRegionOps imx7_gpr_ops = {
156
+ .read = imx7_gpr_read,
157
+ .write = imx7_gpr_write,
158
+ .endianness = DEVICE_NATIVE_ENDIAN,
159
+ .impl = {
160
+ /*
161
+ * Our device would not work correctly if the guest was doing
162
+ * unaligned access. This might not be a limitation on the
163
+ * real device but in practice there is no reason for a guest
164
+ * to access this device unaligned.
165
+ */
166
+ .min_access_size = 4,
167
+ .max_access_size = 4,
168
+ .unaligned = false,
169
+ },
170
+};
171
+
172
+static void imx7_gpr_init(Object *obj)
173
+{
174
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
175
+ IMX7GPRState *s = IMX7_GPR(obj);
176
+
177
+ memory_region_init_io(&s->mmio, obj, &imx7_gpr_ops, s,
178
+ TYPE_IMX7_GPR, 64 * 1024);
179
+ sysbus_init_mmio(sd, &s->mmio);
180
+}
181
+
182
+static void imx7_gpr_class_init(ObjectClass *klass, void *data)
183
+{
184
+ DeviceClass *dc = DEVICE_CLASS(klass);
185
+
186
+ dc->desc = "i.MX7 General Purpose Registers Module";
187
+}
188
+
189
+static const TypeInfo imx7_gpr_info = {
190
+ .name = TYPE_IMX7_GPR,
191
+ .parent = TYPE_SYS_BUS_DEVICE,
192
+ .instance_size = sizeof(IMX7GPRState),
193
+ .instance_init = imx7_gpr_init,
194
+ .class_init = imx7_gpr_class_init,
195
+};
196
+
197
+static void imx7_gpr_register_type(void)
198
+{
199
+ type_register_static(&imx7_gpr_info);
200
+}
201
+type_init(imx7_gpr_register_type)
202
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
203
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
204
--- a/hw/misc/trace-events
51
--- a/target/arm/translate.c
205
+++ b/hw/misc/trace-events
52
+++ b/target/arm/translate.c
206
@@ -XXX,XX +XXX,XX @@ mps2_scc_cfg_read(unsigned function, unsigned device, uint32_t value) "MPS2 SCC
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
207
msf2_sysreg_write(uint64_t offset, uint32_t val, uint32_t prev) "msf2-sysreg write: addr 0x%08" HWADDR_PRIx " data 0x%" PRIx32 " prev 0x%" PRIx32
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
208
msf2_sysreg_read(uint64_t offset, uint32_t val) "msf2-sysreg read: addr 0x%08" HWADDR_PRIx " data 0x%08" PRIx32
55
return 0;
209
msf2_sysreg_write_pll_status(void) "Invalid write to read only PLL status register"
56
210
+
57
- case NEON_3R_VMAX:
211
+#hw/misc/imx7_gpr.c
58
- if (u) {
212
+imx7_gpr_read(uint64_t offset) "addr 0x%08" HWADDR_PRIx
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
213
+imx7_gpr_write(uint64_t offset, uint64_t value) "addr 0x%08" HWADDR_PRIx "value 0x%08" HWADDR_PRIx
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
}
214
--
88
--
215
2.16.1
89
2.20.1
216
90
217
91
diff view generated by jsdifflib
New patch
1
Convert the Neon comparison ops in the 3-reg-same grouping
2
to decodetree.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 8 ++++++++
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
10
target/arm/translate.c | 23 +++--------------------
11
3 files changed, 33 insertions(+), 20 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
20
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
25
+
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
30
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
33
+
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
39
+++ b/target/arm/translate-neon.inc.c
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
44
+
45
+#define DO_3SAME_CMP(INSN, COND) \
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
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
--
108
2.20.1
109
110
diff view generated by jsdifflib
1
The documentation for the generic loader claims that you can
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
2
set the PC for a CPU with an option of the form
2
to decodetree.
3
-device loader,cpu-num=0,addr=0x10000004
4
5
However if you try this QEMU complains:
6
cpu_num must be specified when setting a program counter
7
8
This is because we were testing against 0 rather than CPU_NONE.
9
3
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
13
Message-id: 20180205150426.20542-1-peter.maydell@linaro.org
14
---
7
---
15
hw/core/generic-loader.c | 2 +-
8
target/arm/neon-dp.decode | 6 ++++++
16
1 file changed, 1 insertion(+), 1 deletion(-)
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
10
target/arm/translate.c | 14 ++------------
11
3 files changed, 23 insertions(+), 12 deletions(-)
17
12
18
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/core/generic-loader.c
15
--- a/target/arm/neon-dp.decode
21
+++ b/hw/core/generic-loader.c
16
+++ b/target/arm/neon-dp.decode
22
@@ -XXX,XX +XXX,XX @@ static void generic_loader_realize(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@
23
error_setg(errp, "data can not be specified when setting a "
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
24
"program counter");
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
25
return;
20
26
- } else if (!s->cpu_num) {
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
27
+ } else if (s->cpu_num == CPU_NONE) {
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
28
error_setg(errp, "cpu_num must be specified when setting a "
23
+
29
"program counter");
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
30
return;
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
}
31
--
92
--
32
2.16.1
93
2.20.1
33
94
34
95
diff view generated by jsdifflib
1
In order to support derived exceptions (exceptions generated in
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
2
the course of trying to take an exception), we need to be able
2
3-reg-same grouping to decodetree.
3
to handle prioritizing whether to take the original exception
4
or the derived exception.
5
6
We do this by introducing a new function
7
armv7m_nvic_set_pending_derived() which the exception-taking code in
8
helper.c will call when a derived exception occurs. Derived
9
exceptions are dealt with mostly like normal pending exceptions, so
10
we share the implementation with the armv7m_nvic_set_pending()
11
function.
12
13
Note that the way we structure this is significantly different
14
from the v8M Arm ARM pseudocode: that does all the prioritization
15
logic in the DerivedLateArrival() function, whereas we choose to
16
let the existing "identify highest priority exception" logic
17
do the prioritization for us. The effect is the same, though.
18
3
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 1517324542-6607-2-git-send-email-peter.maydell@linaro.org
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
22
---
7
---
23
target/arm/cpu.h | 13 ++++++++++
8
target/arm/neon-dp.decode | 9 +++++++
24
hw/intc/armv7m_nvic.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++--
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
25
hw/intc/trace-events | 2 +-
10
target/arm/translate.c | 28 +++------------------
26
3 files changed, 80 insertions(+), 3 deletions(-)
11
3 files changed, 56 insertions(+), 25 deletions(-)
27
12
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
29
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
15
--- a/target/arm/neon-dp.decode
31
+++ b/target/arm/cpu.h
16
+++ b/target/arm/neon-dp.decode
32
@@ -XXX,XX +XXX,XX @@ static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
33
* of architecturally banked exceptions.
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
34
*/
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
35
void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
20
36
+/**
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
37
+ * armv7m_nvic_set_pending_derived: mark this derived exception as pending
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
38
+ * @opaque: the NVIC
23
+
39
+ * @irq: the exception number to mark pending
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
40
+ * @secure: false for non-banked exceptions or for the nonsecure
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
41
+ * version of a banked exception, true for the secure version of a banked
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
42
+ * exception.
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
43
+ *
28
44
+ * Similar to armv7m_nvic_set_pending(), but specifically for derived
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
45
+ * exceptions (exceptions generated in the course of trying to take
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
46
+ * a different exception).
31
+
47
+ */
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
48
+void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
49
/**
34
+
50
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
51
* @opaque: the NVIC
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
52
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
53
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/intc/armv7m_nvic.c
39
--- a/target/arm/translate-neon.inc.c
55
+++ b/hw/intc/armv7m_nvic.c
40
+++ b/target/arm/translate-neon.inc.c
56
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_clear_pending(void *opaque, int irq, bool secure)
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
57
}
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
58
}
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
59
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
60
-void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
61
+static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
46
62
+ bool derived)
47
#define DO_3SAME_CMP(INSN, COND) \
63
{
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
64
+ /* Pend an exception, including possibly escalating it to HardFault.
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
65
+ *
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
66
+ * This function handles both "normal" pending of interrupts and
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
67
+ * exceptions, and also derived exceptions (ones which occur as
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
68
+ * a result of trying to take some other exception).
69
+ *
70
+ * If derived == true, the caller guarantees that we are part way through
71
+ * trying to take an exception (but have not yet called
72
+ * armv7m_nvic_acknowledge_irq() to make it active), and so:
73
+ * - s->vectpending is the "original exception" we were trying to take
74
+ * - irq is the "derived exception"
75
+ * - nvic_exec_prio(s) gives the priority before exception entry
76
+ * Here we handle the prioritization logic which the pseudocode puts
77
+ * in the DerivedLateArrival() function.
78
+ */
79
+
53
+
80
NVICState *s = (NVICState *)opaque;
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
81
bool banked = exc_is_banked(irq);
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
82
VecInfo *vec;
83
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
84
85
vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
86
87
- trace_nvic_set_pending(irq, secure, vec->enabled, vec->prio);
88
+ trace_nvic_set_pending(irq, secure, derived, vec->enabled, vec->prio);
89
+
90
+ if (derived) {
91
+ /* Derived exceptions are always synchronous. */
92
+ assert(irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV);
93
+
94
+ if (irq == ARMV7M_EXCP_DEBUG &&
95
+ exc_group_prio(s, vec->prio, secure) >= nvic_exec_prio(s)) {
96
+ /* DebugMonitorFault, but its priority is lower than the
97
+ * preempted exception priority: just ignore it.
98
+ */
99
+ return;
100
+ }
101
+
102
+ if (irq == ARMV7M_EXCP_HARD && vec->prio >= s->vectpending_prio) {
103
+ /* If this is a terminal exception (one which means we cannot
104
+ * take the original exception, like a failure to read its
105
+ * vector table entry), then we must take the derived exception.
106
+ * If the derived exception can't take priority over the
107
+ * original exception, then we go into Lockup.
108
+ *
109
+ * For QEMU, we rely on the fact that a derived exception is
110
+ * terminal if and only if it's reported to us as HardFault,
111
+ * which saves having to have an extra argument is_terminal
112
+ * that we'd only use in one place.
113
+ */
114
+ cpu_abort(&s->cpu->parent_obj,
115
+ "Lockup: can't take terminal derived exception "
116
+ "(original exception priority %d)\n",
117
+ s->vectpending_prio);
118
+ }
119
+ /* We now continue with the same code as for a normal pending
120
+ * exception, which will cause us to pend the derived exception.
121
+ * We'll then take either the original or the derived exception
122
+ * based on which is higher priority by the usual mechanism
123
+ * for selecting the highest priority pending interrupt.
124
+ */
125
+ }
126
127
if (irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV) {
128
/* If a synchronous exception is pending then it may be
129
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
130
}
131
}
132
133
+void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
134
+{
56
+{
135
+ do_armv7m_nvic_set_pending(opaque, irq, secure, false);
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
58
+ 0, gen_helper_gvec_pmul_b);
136
+}
59
+}
137
+
60
+
138
+void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
139
+{
62
+{
140
+ do_armv7m_nvic_set_pending(opaque, irq, secure, true);
63
+ if (a->size != 0) {
64
+ return false;
65
+ }
66
+ return do_3same(s, a, gen_VMUL_p_3s);
141
+}
67
+}
142
+
68
+
143
/* Make pending IRQ active. */
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
144
bool armv7m_nvic_acknowledge_irq(void *opaque)
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
145
{
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
146
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
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
147
index XXXXXXX..XXXXXXX 100644
97
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/intc/trace-events
98
--- a/target/arm/translate.c
149
+++ b/hw/intc/trace-events
99
+++ b/target/arm/translate.c
150
@@ -XXX,XX +XXX,XX @@ nvic_set_prio(int irq, bool secure, uint8_t prio) "NVIC set irq %d secure-bank %
100
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
151
nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d"
101
}
152
nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d"
102
return 1;
153
nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
103
154
-nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending irq %d secure-bank %d (enabled: %d priority %d)"
104
- case NEON_3R_VMUL: /* VMUL */
155
+nvic_set_pending(int irq, bool secure, bool derived, int en, int prio) "NVIC set pending irq %d secure-bank %d derived %d (enabled: %d priority %d)"
105
- if (u) {
156
nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
106
- /* Polynomial case allows only P8. */
157
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
107
- if (size != 0) {
158
nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)"
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
}
159
--
142
--
160
2.16.1
143
2.20.1
161
144
162
145
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
We're going to want at least some of the NeonGen* typedefs
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.
2
5
3
Add both SVE exception state and vector length.
6
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
---
10
target/arm/translate.h | 17 +++++++++++++++++
11
target/arm/translate-a64.c | 17 -----------------
12
2 files changed, 17 insertions(+), 17 deletions(-)
4
13
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180123035349.24538-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu.h | 8 ++++++++
11
target/arm/translate.h | 2 ++
12
target/arm/helper.c | 25 ++++++++++++++++++++++++-
13
target/arm/translate-a64.c | 2 ++
14
4 files changed, 36 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
21
#define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT)
22
#define ARM_TBFLAG_TBI1_SHIFT 1 /* TBI1 for EL0/1 */
23
#define ARM_TBFLAG_TBI1_MASK (0x1ull << ARM_TBFLAG_TBI1_SHIFT)
24
+#define ARM_TBFLAG_SVEEXC_EL_SHIFT 2
25
+#define ARM_TBFLAG_SVEEXC_EL_MASK (0x3 << ARM_TBFLAG_SVEEXC_EL_SHIFT)
26
+#define ARM_TBFLAG_ZCR_LEN_SHIFT 4
27
+#define ARM_TBFLAG_ZCR_LEN_MASK (0xf << ARM_TBFLAG_ZCR_LEN_SHIFT)
28
29
/* some convenience accessor macros */
30
#define ARM_TBFLAG_AARCH64_STATE(F) \
31
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
32
(((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT)
33
#define ARM_TBFLAG_TBI1(F) \
34
(((F) & ARM_TBFLAG_TBI1_MASK) >> ARM_TBFLAG_TBI1_SHIFT)
35
+#define ARM_TBFLAG_SVEEXC_EL(F) \
36
+ (((F) & ARM_TBFLAG_SVEEXC_EL_MASK) >> ARM_TBFLAG_SVEEXC_EL_SHIFT)
37
+#define ARM_TBFLAG_ZCR_LEN(F) \
38
+ (((F) & ARM_TBFLAG_ZCR_LEN_MASK) >> ARM_TBFLAG_ZCR_LEN_SHIFT)
39
40
static inline bool bswap_code(bool sctlr_b)
41
{
42
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
43
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/translate.h
16
--- a/target/arm/translate.h
45
+++ b/target/arm/translate.h
17
+++ b/target/arm/translate.h
46
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
47
bool tbi1; /* TBI1 for EL0/1, not used for EL2/3 */
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
48
bool ns; /* Use non-secure CPREG bank on access */
20
uint32_t, uint32_t, uint32_t);
49
int fp_excp_el; /* FP exception EL or 0 if enabled */
21
50
+ int sve_excp_el; /* SVE exception EL or 0 if enabled */
22
+/* Function prototype for gen_ functions for calling Neon helpers */
51
+ int sve_len; /* SVE vector length in bytes */
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
52
/* Flag indicating that exceptions from secure mode are routed to EL3. */
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
53
bool secure_routed_to_el3;
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
54
bool vfp_enabled; /* FP enabled via FPSCR.EN */
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
55
diff --git a/target/arm/helper.c b/target/arm/helper.c
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
56
index XXXXXXX..XXXXXXX 100644
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
57
--- a/target/arm/helper.c
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
58
+++ b/target/arm/helper.c
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
59
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
60
target_ulong *cs_base, uint32_t *pflags)
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
61
{
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
62
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
63
+ int fp_el = fp_exception_el(env);
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
64
uint32_t flags;
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
65
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
66
if (is_a64(env)) {
67
+ int sve_el = sve_exception_el(env);
68
+ uint32_t zcr_len;
69
+
38
+
70
*pc = env->pc;
39
#endif /* TARGET_ARM_TRANSLATE_H */
71
flags = ARM_TBFLAG_AARCH64_STATE_MASK;
72
/* Get control bits for tagged addresses */
73
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
74
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
75
+ flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
76
+
77
+ /* If SVE is disabled, but FP is enabled,
78
+ then the effective len is 0. */
79
+ if (sve_el != 0 && fp_el == 0) {
80
+ zcr_len = 0;
81
+ } else {
82
+ int current_el = arm_current_el(env);
83
+
84
+ zcr_len = env->vfp.zcr_el[current_el <= 1 ? 1 : current_el];
85
+ zcr_len &= 0xf;
86
+ if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
87
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
88
+ }
89
+ if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
90
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
91
+ }
92
+ }
93
+ flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
94
} else {
95
*pc = env->regs[15];
96
flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
97
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
98
if (arm_cpu_data_is_big_endian(env)) {
99
flags |= ARM_TBFLAG_BE_DATA_MASK;
100
}
101
- flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
102
+ flags |= fp_el << ARM_TBFLAG_FPEXC_EL_SHIFT;
103
104
if (arm_v7m_is_handler_mode(env)) {
105
flags |= ARM_TBFLAG_HANDLER_MASK;
106
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
107
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-a64.c
42
--- a/target/arm/translate-a64.c
109
+++ b/target/arm/translate-a64.c
43
+++ b/target/arm/translate-a64.c
110
@@ -XXX,XX +XXX,XX @@ static int aarch64_tr_init_disas_context(DisasContextBase *dcbase,
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
111
dc->user = (dc->current_el == 0);
45
AArch64DecodeFn *disas_fn;
112
#endif
46
} AArch64DecodeTable;
113
dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
47
114
+ dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
48
-/* Function prototype for gen_ functions for calling Neon helpers */
115
+ dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
116
dc->vec_len = 0;
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
117
dc->vec_stride = 0;
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
118
dc->cp_regs = arm_cpu->cp_regs;
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
64
-
65
/* initialize TCG globals. */
66
void a64_translate_init(void)
67
{
119
--
68
--
120
2.16.1
69
2.20.1
121
70
122
71
diff view generated by jsdifflib