1
Latest arm queue, half minor code cleanups and half minor
1
Nothing too exciting, but does include the last bits of v8.1M support work.
2
bug fixes.
3
2
4
-- PMM
3
-- PMM
5
4
6
The following changes since commit 5d0e5694470d2952b4f257bc985cac8c89b4fd92:
5
The following changes since commit e79de63ab1bd1f6550e7b915e433bec1ad1a870a:
7
6
8
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2019-06-17 11:55:14 +0100)
7
Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-tcg-20210107' into staging (2021-01-07 20:34:05 +0000)
9
8
10
are available in the Git repository at:
9
are available in the Git repository at:
11
10
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190617
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210108
13
12
14
for you to fetch changes up to 1120827fa182f0e76226df7ffe7a86598d1df54f:
13
for you to fetch changes up to c9f8511ea8d2b80723af0fea1f716d752c1b5208:
15
14
16
target/arm: Only implement doubles if the FPU supports them (2019-06-17 15:15:06 +0100)
15
docs/system: arm: Add sabrelite board description (2021-01-08 15:13:39 +0000)
17
16
18
----------------------------------------------------------------
17
----------------------------------------------------------------
19
target-arm queue:
18
target-arm queue:
20
* support large kernel images in bootloader (by avoiding
19
* intc/arm_gic: Fix gic_irq_signaling_enabled() for vCPUs
21
putting the initrd over the top of them)
20
* target/arm: Fix MTE0_ACTIVE
22
* correctly disable FPU/DSP in the CPU for the mps2-an521, musca-a boards
21
* target/arm: Implement v8.1M and Cortex-M55 model
23
* arm_gicv3: Fix decoding of ID register range
22
* hw/arm/highbank: Drop dead KVM support code
24
* arm_gicv3: GICD_TYPER.SecurityExtn is RAZ if GICD_CTLR.DS == 1
23
* util/qemu-timer: Make timer_free() imply timer_del()
25
* some code cleanups following on from the VFP decodetree conversion
24
* various devices: Use ptimer_free() in finalize function
26
* Only implement doubles if the FPU supports them
25
* docs/system: arm: Add sabrelite board description
27
(so we now correctly model Cortex-M4, -M33 as single precision only)
26
* sabrelite: Minor fixes to allow booting U-Boot
28
27
29
----------------------------------------------------------------
28
----------------------------------------------------------------
30
Peter Maydell (24):
29
Andrew Jones (1):
31
hw/arm/boot: Don't assume RAM starts at address zero
30
hw/arm/virt: Remove virt machine state 'smp_cpus'
32
hw/arm/boot: Diagnose layouts that put initrd or DTB off the end of RAM
33
hw/arm/boot: Avoid placing the initrd on top of the kernel
34
hw/arm/boot: Honour image size field in AArch64 Image format kernels
35
target/arm: Allow VFP and Neon to be disabled via a CPU property
36
target/arm: Allow M-profile CPUs to disable the DSP extension via CPU property
37
hw/arm/armv7m: Forward "vfp" and "dsp" properties to CPU
38
hw/arm: Correctly disable FPU/DSP for some ARMSSE-based boards
39
hw/intc/arm_gicv3: Fix decoding of ID register range
40
hw/intc/arm_gicv3: GICD_TYPER.SecurityExtn is RAZ if GICD_CTLR.DS == 1
41
target/arm: Move vfp_expand_imm() to translate.[ch]
42
target/arm: Use vfp_expand_imm() for AArch32 VFP VMOV_imm
43
target/arm: Stop using cpu_F0s for NEON_2RM_VABS_F
44
target/arm: Stop using cpu_F0s for NEON_2RM_VNEG_F
45
target/arm: Stop using cpu_F0s for NEON_2RM_VRINT*
46
target/arm: Stop using cpu_F0s for NEON_2RM_VCVT[ANPM][US]
47
target/arm: Stop using cpu_F0s for NEON_2RM_VRECPE_F and NEON_2RM_VRSQRTE_F
48
target/arm: Stop using cpu_F0s for Neon f32/s32 VCVT
49
target/arm: Stop using cpu_F0s in Neon VCVT fixed-point ops
50
target/arm: stop using deprecated functions in NEON_2RM_VCVT_F16_F32
51
target/arm: Stop using deprecated functions in NEON_2RM_VCVT_F32_F16
52
target/arm: Remove unused cpu_F0s, cpu_F0d, cpu_F1s, cpu_F1d
53
target/arm: Fix typos in trans function prototypes
54
target/arm: Only implement doubles if the FPU supports them
55
31
56
include/hw/arm/armsse.h | 7 ++
32
Bin Meng (4):
57
include/hw/arm/armv7m.h | 4 +
33
hw/misc: imx6_ccm: Update PMU_MISC0 reset value
58
target/arm/cpu.h | 12 +++
34
hw/msic: imx6_ccm: Correct register value for silicon type
59
target/arm/translate-a64.h | 1 -
35
hw/arm: sabrelite: Connect the Ethernet PHY at address 6
60
target/arm/translate.h | 7 ++
36
docs/system: arm: Add sabrelite board description
61
hw/arm/armsse.c | 58 +++++++---
62
hw/arm/armv7m.c | 18 ++++
63
hw/arm/boot.c | 83 ++++++++++----
64
hw/arm/musca.c | 8 ++
65
hw/intc/arm_gicv3_dist.c | 12 ++-
66
hw/intc/arm_gicv3_redist.c | 4 +-
67
target/arm/cpu.c | 179 ++++++++++++++++++++++++++++--
68
target/arm/translate-a64.c | 32 ------
69
target/arm/translate-vfp.inc.c | 173 ++++++++++++++++++++++-------
70
target/arm/translate.c | 240 ++++++++++++++---------------------------
71
target/arm/vfp.decode | 10 +-
72
16 files changed, 572 insertions(+), 276 deletions(-)
73
37
38
Edgar E. Iglesias (1):
39
intc/arm_gic: Fix gic_irq_signaling_enabled() for vCPUs
40
41
Gan Qixin (7):
42
digic-timer: Use ptimer_free() in the finalize function to avoid memleaks
43
allwinner-a10-pit: Use ptimer_free() in the finalize function to avoid memleaks
44
exynos4210_rtc: Use ptimer_free() in the finalize function to avoid memleaks
45
exynos4210_pwm: Use ptimer_free() in the finalize function to avoid memleaks
46
mss-timer: Use ptimer_free() in the finalize function to avoid memleaks
47
musicpal: Use ptimer_free() in the finalize function to avoid memleaks
48
exynos4210_mct: Use ptimer_free() in the finalize function to avoid memleaks
49
50
Peter Maydell (9):
51
hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN
52
target/arm: Correct store of FPSCR value via FPCXT_S
53
target/arm: Implement FPCXT_NS fp system register
54
target/arm: Implement Cortex-M55 model
55
hw/arm/highbank: Drop dead KVM support code
56
util/qemu-timer: Make timer_free() imply timer_del()
57
scripts/coccinelle: New script to remove unnecessary timer_del() calls
58
Remove superfluous timer_del() calls
59
target/arm: Remove timer_del()/timer_deinit() before timer_free()
60
61
Richard Henderson (1):
62
target/arm: Fix MTE0_ACTIVE
63
64
docs/system/arm/sabrelite.rst | 119 ++++++++++++++++++++++++++
65
docs/system/target-arm.rst | 1 +
66
scripts/coccinelle/timer-del-timer-free.cocci | 18 ++++
67
include/hw/arm/virt.h | 3 +-
68
include/qemu/timer.h | 24 +++---
69
block/iscsi.c | 2 -
70
block/nbd.c | 1 -
71
block/qcow2.c | 1 -
72
hw/arm/highbank.c | 14 +--
73
hw/arm/musicpal.c | 12 +++
74
hw/arm/sabrelite.c | 4 +
75
hw/arm/virt-acpi-build.c | 9 +-
76
hw/arm/virt.c | 21 +++--
77
hw/block/nvme.c | 2 -
78
hw/char/serial.c | 2 -
79
hw/char/virtio-serial-bus.c | 2 -
80
hw/ide/core.c | 1 -
81
hw/input/hid.c | 1 -
82
hw/intc/apic.c | 1 -
83
hw/intc/arm_gic.c | 4 +-
84
hw/intc/armv7m_nvic.c | 15 ++++
85
hw/intc/ioapic.c | 1 -
86
hw/ipmi/ipmi_bmc_extern.c | 1 -
87
hw/misc/imx6_ccm.c | 4 +-
88
hw/net/e1000.c | 3 -
89
hw/net/e1000e_core.c | 8 --
90
hw/net/pcnet-pci.c | 1 -
91
hw/net/rtl8139.c | 1 -
92
hw/net/spapr_llan.c | 1 -
93
hw/net/virtio-net.c | 2 -
94
hw/rtc/exynos4210_rtc.c | 9 ++
95
hw/s390x/s390-pci-inst.c | 1 -
96
hw/sd/sd.c | 1 -
97
hw/sd/sdhci.c | 2 -
98
hw/timer/allwinner-a10-pit.c | 11 +++
99
hw/timer/digic-timer.c | 8 ++
100
hw/timer/exynos4210_mct.c | 14 +++
101
hw/timer/exynos4210_pwm.c | 11 +++
102
hw/timer/mss-timer.c | 13 +++
103
hw/usb/dev-hub.c | 1 -
104
hw/usb/hcd-ehci.c | 1 -
105
hw/usb/hcd-ohci-pci.c | 1 -
106
hw/usb/hcd-uhci.c | 1 -
107
hw/usb/hcd-xhci.c | 1 -
108
hw/usb/redirect.c | 1 -
109
hw/vfio/display.c | 1 -
110
hw/virtio/vhost-vsock-common.c | 1 -
111
hw/virtio/virtio-balloon.c | 1 -
112
hw/virtio/virtio-rng.c | 1 -
113
hw/watchdog/wdt_diag288.c | 1 -
114
hw/watchdog/wdt_i6300esb.c | 1 -
115
migration/colo.c | 1 -
116
monitor/hmp-cmds.c | 1 -
117
net/announce.c | 1 -
118
net/colo-compare.c | 1 -
119
net/slirp.c | 1 -
120
replay/replay-debugging.c | 1 -
121
target/arm/cpu.c | 2 -
122
target/arm/cpu_tcg.c | 42 +++++++++
123
target/arm/helper.c | 2 +-
124
target/s390x/cpu.c | 2 -
125
ui/console.c | 1 -
126
ui/spice-core.c | 1 -
127
util/throttle.c | 1 -
128
target/arm/translate-vfp.c.inc | 114 ++++++++++++++++++++++--
129
65 files changed, 421 insertions(+), 111 deletions(-)
130
create mode 100644 docs/system/arm/sabrelite.rst
131
create mode 100644 scripts/coccinelle/timer-del-timer-free.cocci
132
diff view generated by jsdifflib
Deleted patch
1
In the Arm kernel/initrd loading code, in some places we make the
2
incorrect assumption that info->ram_size can be treated as the
3
address of the end of RAM, as for instance when we calculate the
4
available space for the initrd using "info->ram_size - info->initrd_start".
5
This is wrong, because many Arm boards (including "virt") specify
6
a non-zero info->loader_start to indicate that their RAM area
7
starts at a non-zero physical address.
8
1
9
Correct the places which make this incorrect assumption.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Tested-by: Mark Rutland <mark.rutland@arm.com>
14
Message-id: 20190516144733.32399-2-peter.maydell@linaro.org
15
---
16
hw/arm/boot.c | 9 ++++-----
17
1 file changed, 4 insertions(+), 5 deletions(-)
18
19
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/boot.c
22
+++ b/hw/arm/boot.c
23
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
24
int elf_machine;
25
hwaddr entry;
26
static const ARMInsnFixup *primary_loader;
27
+ uint64_t ram_end = info->loader_start + info->ram_size;
28
29
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
30
primary_loader = bootloader_aarch64;
31
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
32
/* 32-bit ARM */
33
entry = info->loader_start + KERNEL_LOAD_ADDR;
34
kernel_size = load_image_targphys_as(info->kernel_filename, entry,
35
- info->ram_size - KERNEL_LOAD_ADDR,
36
- as);
37
+ ram_end - KERNEL_LOAD_ADDR, as);
38
is_linux = 1;
39
}
40
if (kernel_size < 0) {
41
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
42
if (info->initrd_filename) {
43
initrd_size = load_ramdisk_as(info->initrd_filename,
44
info->initrd_start,
45
- info->ram_size - info->initrd_start,
46
- as);
47
+ ram_end - info->initrd_start, as);
48
if (initrd_size < 0) {
49
initrd_size = load_image_targphys_as(info->initrd_filename,
50
info->initrd_start,
51
- info->ram_size -
52
+ ram_end -
53
info->initrd_start,
54
as);
55
}
56
--
57
2.20.1
58
59
diff view generated by jsdifflib
1
The architecture permits FPUs which have only single-precision
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
support, not double-precision; Cortex-M4 and Cortex-M33 are
3
both like that. Add the necessary checks on the MVFR0 FPDP
4
field so that we UNDEF any double-precision instructions on
5
CPUs like this.
6
2
7
Note that even if FPDP==0 the insns like VMOV-to/from-gpreg,
3
Correct the indexing into s->cpu_ctlr for vCPUs.
8
VLDM/VSTM, VLDR/VSTR which take double precision registers
9
still exist.
10
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20201214222154.3480243-2-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190614104457.24703-3-peter.maydell@linaro.org
14
---
10
---
15
target/arm/cpu.h | 6 +++
11
hw/intc/arm_gic.c | 4 +++-
16
target/arm/translate-vfp.inc.c | 84 ++++++++++++++++++++++++++++++++++
12
1 file changed, 3 insertions(+), 1 deletion(-)
17
2 files changed, 90 insertions(+)
18
13
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
16
--- a/hw/intc/arm_gic.c
22
+++ b/target/arm/cpu.h
17
+++ b/hw/intc/arm_gic.c
23
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
18
@@ -XXX,XX +XXX,XX @@ static inline void gic_get_best_virq(GICState *s, int cpu,
24
return FIELD_EX64(id->mvfr0, MVFR0, FPSHVEC) > 0;
19
static inline bool gic_irq_signaling_enabled(GICState *s, int cpu, bool virt,
25
}
20
int group_mask)
26
21
{
27
+static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
22
+ int cpu_iface = virt ? (cpu + GIC_NCPU) : cpu;
28
+{
29
+ /* Return true if CPU supports double precision floating point */
30
+ return FIELD_EX64(id->mvfr0, MVFR0, FPDP) > 0;
31
+}
32
+
23
+
33
/*
24
if (!virt && !(s->ctlr & group_mask)) {
34
* We always set the FP and SIMD FP16 fields to indicate identical
35
* levels of support (assuming SIMD is implemented at all), so
36
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-vfp.inc.c
39
+++ b/target/arm/translate-vfp.inc.c
40
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
41
((a->vm | a->vn | a->vd) & 0x10)) {
42
return false;
25
return false;
43
}
26
}
44
+
27
@@ -XXX,XX +XXX,XX @@ static inline bool gic_irq_signaling_enabled(GICState *s, int cpu, bool virt,
45
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
46
+ return false;
47
+ }
48
+
49
rd = a->vd;
50
rn = a->vn;
51
rm = a->vm;
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
53
((a->vm | a->vn | a->vd) & 0x10)) {
54
return false;
28
return false;
55
}
29
}
56
+
30
57
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
31
- if (!(s->cpu_ctlr[cpu] & group_mask)) {
58
+ return false;
32
+ if (!(s->cpu_ctlr[cpu_iface] & group_mask)) {
59
+ }
60
+
61
rd = a->vd;
62
rn = a->vn;
63
rm = a->vm;
64
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
65
((a->vm | a->vd) & 0x10)) {
66
return false;
33
return false;
67
}
34
}
68
+
35
69
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
70
+ return false;
71
+ }
72
+
73
rd = a->vd;
74
rm = a->vm;
75
76
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
77
if (dp && !dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
78
return false;
79
}
80
+
81
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
82
+ return false;
83
+ }
84
+
85
rd = a->vd;
86
rm = a->vm;
87
88
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
89
return false;
90
}
91
92
+ if (!dc_isar_feature(aa32_fpdp, s)) {
93
+ return false;
94
+ }
95
+
96
if (!dc_isar_feature(aa32_fpshvec, s) &&
97
(veclen != 0 || s->vec_stride != 0)) {
98
return false;
99
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
100
return false;
101
}
102
103
+ if (!dc_isar_feature(aa32_fpdp, s)) {
104
+ return false;
105
+ }
106
+
107
if (!dc_isar_feature(aa32_fpshvec, s) &&
108
(veclen != 0 || s->vec_stride != 0)) {
109
return false;
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
111
return false;
112
}
113
114
+ if (!dc_isar_feature(aa32_fpdp, s)) {
115
+ return false;
116
+ }
117
+
118
if (!vfp_access_check(s)) {
119
return true;
120
}
121
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
122
return false;
123
}
124
125
+ if (!dc_isar_feature(aa32_fpdp, s)) {
126
+ return false;
127
+ }
128
+
129
if (!dc_isar_feature(aa32_fpshvec, s) &&
130
(veclen != 0 || s->vec_stride != 0)) {
131
return false;
132
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
133
return false;
134
}
135
136
+ if (!dc_isar_feature(aa32_fpdp, s)) {
137
+ return false;
138
+ }
139
+
140
if (!vfp_access_check(s)) {
141
return true;
142
}
143
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
144
return false;
145
}
146
147
+ if (!dc_isar_feature(aa32_fpdp, s)) {
148
+ return false;
149
+ }
150
+
151
if (!vfp_access_check(s)) {
152
return true;
153
}
154
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
155
return false;
156
}
157
158
+ if (!dc_isar_feature(aa32_fpdp, s)) {
159
+ return false;
160
+ }
161
+
162
if (!vfp_access_check(s)) {
163
return true;
164
}
165
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
166
return false;
167
}
168
169
+ if (!dc_isar_feature(aa32_fpdp, s)) {
170
+ return false;
171
+ }
172
+
173
if (!vfp_access_check(s)) {
174
return true;
175
}
176
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
177
return false;
178
}
179
180
+ if (!dc_isar_feature(aa32_fpdp, s)) {
181
+ return false;
182
+ }
183
+
184
if (!vfp_access_check(s)) {
185
return true;
186
}
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
188
return false;
189
}
190
191
+ if (!dc_isar_feature(aa32_fpdp, s)) {
192
+ return false;
193
+ }
194
+
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
199
return false;
200
}
201
202
+ if (!dc_isar_feature(aa32_fpdp, s)) {
203
+ return false;
204
+ }
205
+
206
if (!vfp_access_check(s)) {
207
return true;
208
}
209
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
210
return false;
211
}
212
213
+ if (!dc_isar_feature(aa32_fpdp, s)) {
214
+ return false;
215
+ }
216
+
217
if (!vfp_access_check(s)) {
218
return true;
219
}
220
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
221
return false;
222
}
223
224
+ if (!dc_isar_feature(aa32_fpdp, s)) {
225
+ return false;
226
+ }
227
+
228
if (!vfp_access_check(s)) {
229
return true;
230
}
231
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
232
return false;
233
}
234
235
+ if (!dc_isar_feature(aa32_fpdp, s)) {
236
+ return false;
237
+ }
238
+
239
if (!vfp_access_check(s)) {
240
return true;
241
}
242
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
243
return false;
244
}
245
246
+ if (!dc_isar_feature(aa32_fpdp, s)) {
247
+ return false;
248
+ }
249
+
250
if (!vfp_access_check(s)) {
251
return true;
252
}
253
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
254
return false;
255
}
256
257
+ if (!dc_isar_feature(aa32_fpdp, s)) {
258
+ return false;
259
+ }
260
+
261
if (!vfp_access_check(s)) {
262
return true;
263
}
264
--
36
--
265
2.20.1
37
2.20.1
266
38
267
39
diff view generated by jsdifflib
1
Remove some old constructns from NEON_2RM_VCVT_F16_F32 code:
1
From: Andrew Jones <drjones@redhat.com>
2
* don't use CPU_F0s
3
* don't use tcg_gen_st_f32
4
2
3
virt machine's 'smp_cpus' and machine->smp.cpus must always have the
4
same value. And, anywhere we have virt machine state we have machine
5
state. So let's remove the redundancy. Also, to make it easier to see
6
that machine->smp is the true source for "smp_cpus" and "max_cpus",
7
avoid passing them in function parameters, preferring instead to get
8
them from the state.
9
10
No functional change intended.
11
12
Signed-off-by: Andrew Jones <drjones@redhat.com>
13
Reviewed-by: David Edmondson <david.edmondson@oracle.com>
14
Reviewed-by: Ying Fang <fangying1@huawei.com>
15
Message-id: 20201215174815.51520-1-drjones@redhat.com
16
[PMM: minor formatting tweak to smp_cpus variable declaration]
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-12-peter.maydell@linaro.org
9
---
18
---
10
target/arm/translate.c | 26 +++++++++++---------------
19
include/hw/arm/virt.h | 3 +--
11
1 file changed, 11 insertions(+), 15 deletions(-)
20
hw/arm/virt-acpi-build.c | 9 +++++----
21
hw/arm/virt.c | 21 ++++++++++-----------
22
3 files changed, 16 insertions(+), 17 deletions(-)
12
23
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
24
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
26
--- a/include/hw/arm/virt.h
16
+++ b/target/arm/translate.c
27
+++ b/include/hw/arm/virt.h
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
28
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
18
return ret;
29
MemMapEntry *memmap;
30
char *pciehb_nodename;
31
const int *irqmap;
32
- int smp_cpus;
33
void *fdt;
34
int fdt_size;
35
uint32_t clock_phandle;
36
@@ -XXX,XX +XXX,XX @@ static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
37
38
assert(vms->gic_version == VIRT_GIC_VERSION_3);
39
40
- return vms->smp_cpus > redist0_capacity ? 2 : 1;
41
+ return MACHINE(vms)->smp.cpus > redist0_capacity ? 2 : 1;
19
}
42
}
20
43
21
-#define tcg_gen_st_f32 tcg_gen_st_i32
44
#endif /* QEMU_ARM_VIRT_H */
45
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/virt-acpi-build.c
48
+++ b/hw/arm/virt-acpi-build.c
49
@@ -XXX,XX +XXX,XX @@
50
51
#define ACPI_BUILD_TABLE_SIZE 0x20000
52
53
-static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
54
+static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms)
55
{
56
+ MachineState *ms = MACHINE(vms);
57
uint16_t i;
58
59
- for (i = 0; i < smp_cpus; i++) {
60
+ for (i = 0; i < ms->smp.cpus; i++) {
61
Aml *dev = aml_device("C%.03X", i);
62
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
63
aml_append(dev, aml_name_decl("_UID", aml_int(i)));
64
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
65
gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base);
66
gicd->version = vms->gic_version;
67
68
- for (i = 0; i < vms->smp_cpus; i++) {
69
+ for (i = 0; i < MACHINE(vms)->smp.cpus; i++) {
70
AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data,
71
sizeof(*gicc));
72
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
73
@@ -XXX,XX +XXX,XX @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
74
* the RTC ACPI device at all when using UEFI.
75
*/
76
scope = aml_scope("\\_SB");
77
- acpi_dsdt_add_cpus(scope, vms->smp_cpus);
78
+ acpi_dsdt_add_cpus(scope, vms);
79
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
80
(irqmap[VIRT_UART] + ARM_SPI_BASE));
81
if (vmc->acpi_expose_flash) {
82
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/arm/virt.c
85
+++ b/hw/arm/virt.c
86
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
87
if (vms->gic_version == VIRT_GIC_VERSION_2) {
88
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
89
GIC_FDT_IRQ_PPI_CPU_WIDTH,
90
- (1 << vms->smp_cpus) - 1);
91
+ (1 << MACHINE(vms)->smp.cpus) - 1);
92
}
93
94
qemu_fdt_add_subnode(vms->fdt, "/timer");
95
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
96
int cpu;
97
int addr_cells = 1;
98
const MachineState *ms = MACHINE(vms);
99
+ int smp_cpus = ms->smp.cpus;
100
101
/*
102
* From Documentation/devicetree/bindings/arm/cpus.txt
103
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
104
* The simplest way to go is to examine affinity IDs of all our CPUs. If
105
* at least one of them has Aff3 populated, we set #address-cells to 2.
106
*/
107
- for (cpu = 0; cpu < vms->smp_cpus; cpu++) {
108
+ for (cpu = 0; cpu < smp_cpus; cpu++) {
109
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
110
111
if (armcpu->mp_affinity & ARM_AFF3_MASK) {
112
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
113
qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#address-cells", addr_cells);
114
qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#size-cells", 0x0);
115
116
- for (cpu = vms->smp_cpus - 1; cpu >= 0; cpu--) {
117
+ for (cpu = smp_cpus - 1; cpu >= 0; cpu--) {
118
char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
119
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
120
CPUState *cs = CPU(armcpu);
121
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
122
qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
123
armcpu->dtb_compatible);
124
125
- if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED
126
- && vms->smp_cpus > 1) {
127
+ if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED && smp_cpus > 1) {
128
qemu_fdt_setprop_string(vms->fdt, nodename,
129
"enable-method", "psci");
130
}
131
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
132
if (vms->gic_version == VIRT_GIC_VERSION_2) {
133
irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
134
GIC_FDT_IRQ_PPI_CPU_WIDTH,
135
- (1 << vms->smp_cpus) - 1);
136
+ (1 << MACHINE(vms)->smp.cpus) - 1);
137
}
138
139
qemu_fdt_add_subnode(vms->fdt, "/pmu");
140
@@ -XXX,XX +XXX,XX @@ static void finalize_gic_version(VirtMachineState *vms)
141
* virt_cpu_post_init() must be called after the CPUs have
142
* been realized and the GIC has been created.
143
*/
144
-static void virt_cpu_post_init(VirtMachineState *vms, int max_cpus,
145
- MemoryRegion *sysmem)
146
+static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem)
147
{
148
+ int max_cpus = MACHINE(vms)->smp.max_cpus;
149
bool aarch64, pmu, steal_time;
150
CPUState *cpu;
151
152
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
153
exit(1);
154
}
155
156
- vms->smp_cpus = smp_cpus;
22
-
157
-
23
#define ARM_CP_RW_BIT (1 << 20)
158
if (vms->virt && kvm_enabled()) {
24
159
error_report("mach-virt: KVM does not support providing "
25
/* Include the VFP decoder */
160
"Virtualization extensions to the guest CPU");
26
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
161
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
27
tmp = neon_load_reg(rm, 0);
162
create_fdt(vms);
28
tmp2 = neon_load_reg(rm, 1);
163
29
tcg_gen_ext16u_i32(tmp3, tmp);
164
possible_cpus = mc->possible_cpu_arch_ids(machine);
30
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
165
+ assert(possible_cpus->len == max_cpus);
31
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
166
for (n = 0; n < possible_cpus->len; n++) {
32
- tcg_gen_shri_i32(tmp3, tmp, 16);
167
Object *cpuobj;
33
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
168
CPUState *cs;
34
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
169
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
35
- tcg_temp_free_i32(tmp);
170
36
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
171
create_gic(vms);
37
+ neon_store_reg(rd, 0, tmp3);
172
38
+ tcg_gen_shri_i32(tmp, tmp, 16);
173
- virt_cpu_post_init(vms, possible_cpus->len, sysmem);
39
+ gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
174
+ virt_cpu_post_init(vms, sysmem);
40
+ neon_store_reg(rd, 1, tmp);
175
41
+ tmp3 = tcg_temp_new_i32();
176
fdt_add_pmu_nodes(vms);
42
tcg_gen_ext16u_i32(tmp3, tmp2);
177
43
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
44
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
45
- tcg_gen_shri_i32(tmp3, tmp2, 16);
46
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
47
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
48
- tcg_temp_free_i32(tmp2);
49
- tcg_temp_free_i32(tmp3);
50
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
51
+ neon_store_reg(rd, 2, tmp3);
52
+ tcg_gen_shri_i32(tmp2, tmp2, 16);
53
+ gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
54
+ neon_store_reg(rd, 3, tmp2);
55
tcg_temp_free_i32(ahp);
56
tcg_temp_free_ptr(fpst);
57
break;
58
--
178
--
59
2.20.1
179
2.20.1
60
180
61
181
diff view generated by jsdifflib
1
Remove some old constructs from NEON_2RM_VCVT_F16_F32 code:
1
From: Richard Henderson <richard.henderson@linaro.org>
2
* don't use cpu_F0s
3
* don't use tcg_gen_ld_f32
4
2
3
In 50244cc76abc we updated mte_check_fail to match the ARM
4
pseudocode, using the correct EL to select the TCF field.
5
But we failed to update MTE0_ACTIVE the same way, which led
6
to g_assert_not_reached().
7
8
Cc: qemu-stable@nongnu.org
9
Buglink: https://bugs.launchpad.net/bugs/1907137
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20201221204426.88514-1-richard.henderson@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-11-peter.maydell@linaro.org
9
---
14
---
10
target/arm/translate.c | 27 ++++++++++++---------------
15
target/arm/helper.c | 2 +-
11
1 file changed, 12 insertions(+), 15 deletions(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
12
17
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
20
--- a/target/arm/helper.c
16
+++ b/target/arm/translate.c
21
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
22
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
18
return ret;
23
if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
19
}
24
&& tbid
20
25
&& !(env->pstate & PSTATE_TCO)
21
-#define tcg_gen_ld_f32 tcg_gen_ld_i32
26
- && (sctlr & SCTLR_TCF0)
22
#define tcg_gen_st_f32 tcg_gen_st_i32
27
+ && (sctlr & SCTLR_TCF)
23
28
&& allocation_tag_access_enabled(env, 0, sctlr)) {
24
#define ARM_CP_RW_BIT (1 << 20)
29
flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
30
}
26
q || (rm & 1)) {
27
return 1;
28
}
29
- tmp = tcg_temp_new_i32();
30
- tmp2 = tcg_temp_new_i32();
31
fpst = get_fpstatus_ptr(true);
32
ahp = get_ahp_flag();
33
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
34
- gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
35
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
36
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
37
+ tmp = neon_load_reg(rm, 0);
38
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
39
+ tmp2 = neon_load_reg(rm, 1);
40
+ gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
41
tcg_gen_shli_i32(tmp2, tmp2, 16);
42
tcg_gen_or_i32(tmp2, tmp2, tmp);
43
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
44
- gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
45
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
46
+ tcg_temp_free_i32(tmp);
47
+ tmp = neon_load_reg(rm, 2);
48
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
49
+ tmp3 = neon_load_reg(rm, 3);
50
neon_store_reg(rd, 0, tmp2);
51
- tmp2 = tcg_temp_new_i32();
52
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
53
- tcg_gen_shli_i32(tmp2, tmp2, 16);
54
- tcg_gen_or_i32(tmp2, tmp2, tmp);
55
- neon_store_reg(rd, 1, tmp2);
56
+ gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
57
+ tcg_gen_shli_i32(tmp3, tmp3, 16);
58
+ tcg_gen_or_i32(tmp3, tmp3, tmp);
59
+ neon_store_reg(rd, 1, tmp3);
60
tcg_temp_free_i32(tmp);
61
tcg_temp_free_i32(ahp);
62
tcg_temp_free_ptr(fpst);
63
--
31
--
64
2.20.1
32
2.20.1
65
33
66
34
diff view generated by jsdifflib
1
Stop using cpu_F0s in the Neon VCVT fixed-point operations.
1
The CCR is a register most of whose bits are banked between security
2
states but where BFHFNMIGN is not, and we keep it in the non-secure
3
entry of the v7m.ccr[] array. The logic which tries to handle this
4
bit fails to implement the "RAZ/WI from Nonsecure if AIRCR.BFHFNMINS
5
is zero" requirement; correct the omission.
2
6
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20201210201433.26262-2-peter.maydell@linaro.org
6
Message-id: 20190613163917.28589-10-peter.maydell@linaro.org
7
---
10
---
8
target/arm/translate.c | 62 +++++++++++++++++++-----------------------
11
hw/intc/armv7m_nvic.c | 15 +++++++++++++++
9
1 file changed, 28 insertions(+), 34 deletions(-)
12
1 file changed, 15 insertions(+)
10
13
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
16
--- a/hw/intc/armv7m_nvic.c
14
+++ b/target/arm/translate.c
17
+++ b/hw/intc/armv7m_nvic.c
15
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
18
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
16
/* Function prototypes for gen_ functions calling Neon helpers. */
19
*/
17
typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
20
val = cpu->env.v7m.ccr[attrs.secure];
18
TCGv_i32, TCGv_i32);
21
val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
19
+/* Function prototypes for gen_ functions for fix point conversions */
22
+ /* BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0 */
20
+typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
23
+ if (!attrs.secure) {
21
24
+ if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
22
/* initialize TCG globals. */
25
+ val &= ~R_V7M_CCR_BFHFNMIGN_MASK;
23
void arm_translate_init(void)
26
+ }
24
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
27
+ }
25
return statusptr;
28
return val;
26
}
29
case 0xd24: /* System Handler Control and State (SHCSR) */
27
30
if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) {
28
-#define VFP_GEN_FIX(name, round) \
31
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
29
-static inline void gen_vfp_##name(int dp, int shift, int neon) \
32
(cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK)
30
-{ \
33
| (value & R_V7M_CCR_BFHFNMIGN_MASK);
31
- TCGv_i32 tmp_shift = tcg_const_i32(shift); \
34
value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
32
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
35
+ } else {
33
- if (dp) { \
36
+ /*
34
- gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
37
+ * BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0, so
35
- statusptr); \
38
+ * preserve the state currently in the NS element of the array
36
- } else { \
39
+ */
37
- gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
40
+ if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
38
- statusptr); \
41
+ value &= ~R_V7M_CCR_BFHFNMIGN_MASK;
39
- } \
42
+ value |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
40
- tcg_temp_free_i32(tmp_shift); \
43
+ }
41
- tcg_temp_free_ptr(statusptr); \
44
}
42
-}
45
43
-VFP_GEN_FIX(tosl, _round_to_zero)
46
cpu->env.v7m.ccr[attrs.secure] = value;
44
-VFP_GEN_FIX(toul, _round_to_zero)
45
-VFP_GEN_FIX(slto, )
46
-VFP_GEN_FIX(ulto, )
47
-#undef VFP_GEN_FIX
48
-
49
static inline long vfp_reg_offset(bool dp, unsigned reg)
50
{
51
if (dp) {
52
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
53
}
54
} else if (op >= 14) {
55
/* VCVT fixed-point. */
56
+ TCGv_ptr fpst;
57
+ TCGv_i32 shiftv;
58
+ VFPGenFixPointFn *fn;
59
+
60
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
61
return 1;
62
}
63
+
64
+ if (!(op & 1)) {
65
+ if (u) {
66
+ fn = gen_helper_vfp_ultos;
67
+ } else {
68
+ fn = gen_helper_vfp_sltos;
69
+ }
70
+ } else {
71
+ if (u) {
72
+ fn = gen_helper_vfp_touls_round_to_zero;
73
+ } else {
74
+ fn = gen_helper_vfp_tosls_round_to_zero;
75
+ }
76
+ }
77
+
78
/* We have already masked out the must-be-1 top bit of imm6,
79
* hence this 32-shift where the ARM ARM has 64-imm6.
80
*/
81
shift = 32 - shift;
82
+ fpst = get_fpstatus_ptr(1);
83
+ shiftv = tcg_const_i32(shift);
84
for (pass = 0; pass < (q ? 4 : 2); pass++) {
85
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
86
- if (!(op & 1)) {
87
- if (u)
88
- gen_vfp_ulto(0, shift, 1);
89
- else
90
- gen_vfp_slto(0, shift, 1);
91
- } else {
92
- if (u)
93
- gen_vfp_toul(0, shift, 1);
94
- else
95
- gen_vfp_tosl(0, shift, 1);
96
- }
97
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
98
+ TCGv_i32 tmpf = neon_load_reg(rm, pass);
99
+ fn(tmpf, tmpf, shiftv, fpst);
100
+ neon_store_reg(rd, pass, tmpf);
101
}
102
+ tcg_temp_free_ptr(fpst);
103
+ tcg_temp_free_i32(shiftv);
104
} else {
105
return 1;
106
}
107
--
47
--
108
2.20.1
48
2.20.1
109
49
110
50
diff view generated by jsdifflib
1
Stop using cpu_F0s for the Neon f32/s32 VCVT operations.
1
In commit 64f863baeedc8659 we implemented the v8.1M FPCXT_S register,
2
Since this is the last user of cpu_F0s in the Neon 2rm-op
2
but we got the write behaviour wrong. On read, this register reads
3
loop, we can remove the handling code for it too.
3
bits [27:0] of FPSCR plus the CONTROL.SFPA bit. On write, it doesn't
4
just write back those bits -- it writes a value to the whole FPSCR,
5
whose upper 4 bits are zeroes.
6
7
We also incorrectly implemented the write-to-FPSCR as a simple store
8
to vfp.xregs; this skips the "update the softfloat flags" part of
9
the vfp_set_fpscr helper so the value would read back correctly but
10
not actually take effect.
11
12
Fix both of these things by doing a complete write to the FPSCR
13
using the helper function.
4
14
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Message-id: 20201210201433.26262-3-peter.maydell@linaro.org
8
Message-id: 20190613163917.28589-9-peter.maydell@linaro.org
9
---
18
---
10
target/arm/translate.c | 82 ++++++++++++------------------------------
19
target/arm/translate-vfp.c.inc | 12 ++++++------
11
1 file changed, 22 insertions(+), 60 deletions(-)
20
1 file changed, 6 insertions(+), 6 deletions(-)
12
21
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
22
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
24
--- a/target/arm/translate-vfp.c.inc
16
+++ b/target/arm/translate.c
25
+++ b/target/arm/translate-vfp.c.inc
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
26
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
18
return statusptr;
27
}
19
}
28
case ARM_VFP_FPCXT_S:
20
29
{
21
-#define VFP_GEN_ITOF(name) \
30
- TCGv_i32 sfpa, control, fpscr;
22
-static inline void gen_vfp_##name(int dp, int neon) \
31
- /* Set FPSCR[27:0] and CONTROL.SFPA from value */
23
-{ \
32
+ TCGv_i32 sfpa, control;
24
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
33
+ /*
25
- if (dp) { \
34
+ * Set FPSCR and CONTROL.SFPA from value; the new FPSCR takes
26
- gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
35
+ * bits [27:0] from value and zeroes bits [31:28].
27
- } else { \
36
+ */
28
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
37
tmp = loadfn(s, opaque);
29
- } \
38
sfpa = tcg_temp_new_i32();
30
- tcg_temp_free_ptr(statusptr); \
39
tcg_gen_shri_i32(sfpa, tmp, 31);
31
-}
40
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
32
-
41
tcg_gen_deposit_i32(control, control, sfpa,
33
-VFP_GEN_ITOF(uito)
42
R_V7M_CONTROL_SFPA_SHIFT, 1);
34
-VFP_GEN_ITOF(sito)
43
store_cpu_field(control, v7m.control[M_REG_S]);
35
-#undef VFP_GEN_ITOF
44
- fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
36
-
45
- tcg_gen_andi_i32(fpscr, fpscr, FPCR_NZCV_MASK);
37
-#define VFP_GEN_FTOI(name) \
46
tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK);
38
-static inline void gen_vfp_##name(int dp, int neon) \
47
- tcg_gen_or_i32(fpscr, fpscr, tmp);
39
-{ \
48
- store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
40
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
49
+ gen_helper_vfp_set_fpscr(cpu_env, tmp);
41
- if (dp) { \
50
tcg_temp_free_i32(tmp);
42
- gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
51
tcg_temp_free_i32(sfpa);
43
- } else { \
52
break;
44
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
45
- } \
46
- tcg_temp_free_ptr(statusptr); \
47
-}
48
-
49
-VFP_GEN_FTOI(touiz)
50
-VFP_GEN_FTOI(tosiz)
51
-#undef VFP_GEN_FTOI
52
-
53
#define VFP_GEN_FIX(name, round) \
54
static inline void gen_vfp_##name(int dp, int shift, int neon) \
55
{ \
56
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_3r_sizes[] = {
57
#define NEON_2RM_VCVT_SF 62
58
#define NEON_2RM_VCVT_UF 63
59
60
-static int neon_2rm_is_float_op(int op)
61
-{
62
- /*
63
- * Return true if this neon 2reg-misc op is float-to-float.
64
- * This is not a property of the operation but of our code --
65
- * what we are asking here is "does the code for this case in
66
- * the Neon for-each-pass loop use cpu_F0s?".
67
- */
68
- return op >= NEON_2RM_VCVT_FS;
69
-}
70
-
71
static bool neon_2rm_is_v8_op(int op)
72
{
73
/* Return true if this neon 2reg-misc op is ARMv8 and up */
74
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
75
default:
76
elementwise:
77
for (pass = 0; pass < (q ? 4 : 2); pass++) {
78
- if (neon_2rm_is_float_op(op)) {
79
- tcg_gen_ld_f32(cpu_F0s, cpu_env,
80
- neon_reg_offset(rm, pass));
81
- tmp = NULL;
82
- } else {
83
- tmp = neon_load_reg(rm, pass);
84
- }
85
+ tmp = neon_load_reg(rm, pass);
86
switch (op) {
87
case NEON_2RM_VREV32:
88
switch (size) {
89
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
90
break;
91
}
92
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
93
- gen_vfp_sito(0, 1);
94
+ {
95
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
96
+ gen_helper_vfp_sitos(tmp, tmp, fpstatus);
97
+ tcg_temp_free_ptr(fpstatus);
98
break;
99
+ }
100
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
101
- gen_vfp_uito(0, 1);
102
+ {
103
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
104
+ gen_helper_vfp_uitos(tmp, tmp, fpstatus);
105
+ tcg_temp_free_ptr(fpstatus);
106
break;
107
+ }
108
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
109
- gen_vfp_tosiz(0, 1);
110
+ {
111
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
112
+ gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
113
+ tcg_temp_free_ptr(fpstatus);
114
break;
115
+ }
116
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
117
- gen_vfp_touiz(0, 1);
118
+ {
119
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
120
+ gen_helper_vfp_touizs(tmp, tmp, fpstatus);
121
+ tcg_temp_free_ptr(fpstatus);
122
break;
123
+ }
124
default:
125
/* Reserved op values were caught by the
126
* neon_2rm_sizes[] check earlier.
127
*/
128
abort();
129
}
130
- if (neon_2rm_is_float_op(op)) {
131
- tcg_gen_st_f32(cpu_F0s, cpu_env,
132
- neon_reg_offset(rd, pass));
133
- } else {
134
- neon_store_reg(rd, pass, tmp);
135
- }
136
+ neon_store_reg(rd, pass, tmp);
137
}
138
break;
139
}
140
--
53
--
141
2.20.1
54
2.20.1
142
55
143
56
diff view generated by jsdifflib
1
In several places cut and paste errors meant we were using the wrong
1
Implement the v8.1M FPCXT_NS floating-point system register. This is
2
type for the 'arg' struct in trans_ functions called by the
2
a little more complicated than FPCXT_S, because it has specific
3
decodetree decoder, because we were using the _sp version of the
3
handling for "current FP state is inactive", and it only wants to do
4
struct in the _dp function. These were harmless, because the two
4
PreserveFPState(), not the full set of actions done by
5
structs were identical and so decodetree made them typedefs of the
5
ExecuteFPCheck() which vfp_access_check() implements.
6
same underlying structure (and we'd have had a compile error if they
7
were not harmless), but we should clean them up anyway.
8
6
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190614104457.24703-2-peter.maydell@linaro.org
9
Message-id: 20201210201433.26262-4-peter.maydell@linaro.org
12
---
10
---
13
target/arm/translate-vfp.inc.c | 28 ++++++++++++++--------------
11
target/arm/translate-vfp.c.inc | 102 ++++++++++++++++++++++++++++++++-
14
1 file changed, 14 insertions(+), 14 deletions(-)
12
1 file changed, 99 insertions(+), 3 deletions(-)
15
13
16
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
14
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-vfp.inc.c
16
--- a/target/arm/translate-vfp.c.inc
19
+++ b/target/arm/translate-vfp.inc.c
17
+++ b/target/arm/translate-vfp.c.inc
20
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
18
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
19
}
20
break;
21
case ARM_VFP_FPCXT_S:
22
+ case ARM_VFP_FPCXT_NS:
23
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
24
return false;
25
}
26
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
27
return FPSysRegCheckFailed;
28
}
29
30
- if (!vfp_access_check(s)) {
31
+ /*
32
+ * FPCXT_NS is a special case: it has specific handling for
33
+ * "current FP state is inactive", and must do the PreserveFPState()
34
+ * but not the usual full set of actions done by ExecuteFPCheck().
35
+ * So we don't call vfp_access_check() and the callers must handle this.
36
+ */
37
+ if (regno != ARM_VFP_FPCXT_NS && !vfp_access_check(s)) {
38
return FPSysRegCheckDone;
39
}
40
-
41
return FPSysRegCheckContinue;
42
}
43
44
+static void gen_branch_fpInactive(DisasContext *s, TCGCond cond,
45
+ TCGLabel *label)
46
+{
47
+ /*
48
+ * FPCXT_NS is a special case: it has specific handling for
49
+ * "current FP state is inactive", and must do the PreserveFPState()
50
+ * but not the usual full set of actions done by ExecuteFPCheck().
51
+ * We don't have a TB flag that matches the fpInactive check, so we
52
+ * do it at runtime as we don't expect FPCXT_NS accesses to be frequent.
53
+ *
54
+ * Emit code that checks fpInactive and does a conditional
55
+ * branch to label based on it:
56
+ * if cond is TCG_COND_NE then branch if fpInactive != 0 (ie if inactive)
57
+ * if cond is TCG_COND_EQ then branch if fpInactive == 0 (ie if active)
58
+ */
59
+ assert(cond == TCG_COND_EQ || cond == TCG_COND_NE);
60
+
61
+ /* fpInactive = FPCCR_NS.ASPEN == 1 && CONTROL.FPCA == 0 */
62
+ TCGv_i32 aspen, fpca;
63
+ aspen = load_cpu_field(v7m.fpccr[M_REG_NS]);
64
+ fpca = load_cpu_field(v7m.control[M_REG_S]);
65
+ tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
66
+ tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
67
+ tcg_gen_andi_i32(fpca, fpca, R_V7M_CONTROL_FPCA_MASK);
68
+ tcg_gen_or_i32(fpca, fpca, aspen);
69
+ tcg_gen_brcondi_i32(tcg_invert_cond(cond), fpca, 0, label);
70
+ tcg_temp_free_i32(aspen);
71
+ tcg_temp_free_i32(fpca);
72
+}
73
+
74
static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
75
76
fp_sysreg_loadfn *loadfn,
77
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
78
{
79
/* Do a write to an M-profile floating point system register */
80
TCGv_i32 tmp;
81
+ TCGLabel *lab_end = NULL;
82
83
switch (fp_sysreg_checks(s, regno)) {
84
case FPSysRegCheckFailed:
85
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
86
tcg_temp_free_i32(tmp);
87
break;
88
}
89
+ case ARM_VFP_FPCXT_NS:
90
+ lab_end = gen_new_label();
91
+ /* fpInactive case: write is a NOP, so branch to end */
92
+ gen_branch_fpInactive(s, TCG_COND_NE, lab_end);
93
+ /* !fpInactive: PreserveFPState(), and reads same as FPCXT_S */
94
+ gen_preserve_fp_state(s);
95
+ /* fall through */
96
case ARM_VFP_FPCXT_S:
97
{
98
TCGv_i32 sfpa, control;
99
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
100
default:
101
g_assert_not_reached();
102
}
103
+ if (lab_end) {
104
+ gen_set_label(lab_end);
105
+ }
21
return true;
106
return true;
22
}
107
}
23
108
24
-static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_sp *a)
109
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
25
+static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
26
{
110
{
111
/* Do a read from an M-profile floating point system register */
27
TCGv_i32 tmp;
112
TCGv_i32 tmp;
28
113
+ TCGLabel *lab_end = NULL;
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
114
+ bool lookup_tb = false;
115
116
switch (fp_sysreg_checks(s, regno)) {
117
case FPSysRegCheckFailed:
118
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
119
fpscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
120
gen_helper_vfp_set_fpscr(cpu_env, fpscr);
121
tcg_temp_free_i32(fpscr);
122
- gen_lookup_tb(s);
123
+ lookup_tb = true;
124
+ break;
125
+ }
126
+ case ARM_VFP_FPCXT_NS:
127
+ {
128
+ TCGv_i32 control, sfpa, fpscr, fpdscr, zero;
129
+ TCGLabel *lab_active = gen_new_label();
130
+
131
+ lookup_tb = true;
132
+
133
+ gen_branch_fpInactive(s, TCG_COND_EQ, lab_active);
134
+ /* fpInactive case: reads as FPDSCR_NS */
135
+ TCGv_i32 tmp = load_cpu_field(v7m.fpdscr[M_REG_NS]);
136
+ storefn(s, opaque, tmp);
137
+ lab_end = gen_new_label();
138
+ tcg_gen_br(lab_end);
139
+
140
+ gen_set_label(lab_active);
141
+ /* !fpInactive: Reads the same as FPCXT_S, but side effects differ */
142
+ gen_preserve_fp_state(s);
143
+ tmp = tcg_temp_new_i32();
144
+ sfpa = tcg_temp_new_i32();
145
+ fpscr = tcg_temp_new_i32();
146
+ gen_helper_vfp_get_fpscr(fpscr, cpu_env);
147
+ tcg_gen_andi_i32(tmp, fpscr, ~FPCR_NZCV_MASK);
148
+ control = load_cpu_field(v7m.control[M_REG_S]);
149
+ tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK);
150
+ tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT);
151
+ tcg_gen_or_i32(tmp, tmp, sfpa);
152
+ tcg_temp_free_i32(control);
153
+ /* Store result before updating FPSCR, in case it faults */
154
+ storefn(s, opaque, tmp);
155
+ /* If SFPA is zero then set FPSCR from FPDSCR_NS */
156
+ fpdscr = load_cpu_field(v7m.fpdscr[M_REG_NS]);
157
+ zero = tcg_const_i32(0);
158
+ tcg_gen_movcond_i32(TCG_COND_EQ, fpscr, sfpa, zero, fpdscr, fpscr);
159
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
160
+ tcg_temp_free_i32(zero);
161
+ tcg_temp_free_i32(sfpa);
162
+ tcg_temp_free_i32(fpdscr);
163
+ tcg_temp_free_i32(fpscr);
164
break;
165
}
166
default:
167
g_assert_not_reached();
168
}
169
+
170
+ if (lab_end) {
171
+ gen_set_label(lab_end);
172
+ }
173
+ if (lookup_tb) {
174
+ gen_lookup_tb(s);
175
+ }
30
return true;
176
return true;
31
}
177
}
32
178
33
-static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_sp *a)
34
+static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
35
{
36
uint32_t offset;
37
TCGv_i32 addr;
38
@@ -XXX,XX +XXX,XX @@ static void gen_VMLA_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
39
tcg_temp_free_i64(tmp);
40
}
41
42
-static bool trans_VMLA_dp(DisasContext *s, arg_VMLA_sp *a)
43
+static bool trans_VMLA_dp(DisasContext *s, arg_VMLA_dp *a)
44
{
45
return do_vfp_3op_dp(s, gen_VMLA_dp, a->vd, a->vn, a->vm, true);
46
}
47
@@ -XXX,XX +XXX,XX @@ static void gen_VMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
48
tcg_temp_free_i64(tmp);
49
}
50
51
-static bool trans_VMLS_dp(DisasContext *s, arg_VMLS_sp *a)
52
+static bool trans_VMLS_dp(DisasContext *s, arg_VMLS_dp *a)
53
{
54
return do_vfp_3op_dp(s, gen_VMLS_dp, a->vd, a->vn, a->vm, true);
55
}
56
@@ -XXX,XX +XXX,XX @@ static void gen_VNMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
57
tcg_temp_free_i64(tmp);
58
}
59
60
-static bool trans_VNMLS_dp(DisasContext *s, arg_VNMLS_sp *a)
61
+static bool trans_VNMLS_dp(DisasContext *s, arg_VNMLS_dp *a)
62
{
63
return do_vfp_3op_dp(s, gen_VNMLS_dp, a->vd, a->vn, a->vm, true);
64
}
65
@@ -XXX,XX +XXX,XX @@ static void gen_VNMLA_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
66
tcg_temp_free_i64(tmp);
67
}
68
69
-static bool trans_VNMLA_dp(DisasContext *s, arg_VNMLA_sp *a)
70
+static bool trans_VNMLA_dp(DisasContext *s, arg_VNMLA_dp *a)
71
{
72
return do_vfp_3op_dp(s, gen_VNMLA_dp, a->vd, a->vn, a->vm, true);
73
}
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_sp(DisasContext *s, arg_VMUL_sp *a)
75
return do_vfp_3op_sp(s, gen_helper_vfp_muls, a->vd, a->vn, a->vm, false);
76
}
77
78
-static bool trans_VMUL_dp(DisasContext *s, arg_VMUL_sp *a)
79
+static bool trans_VMUL_dp(DisasContext *s, arg_VMUL_dp *a)
80
{
81
return do_vfp_3op_dp(s, gen_helper_vfp_muld, a->vd, a->vn, a->vm, false);
82
}
83
@@ -XXX,XX +XXX,XX @@ static void gen_VNMUL_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
84
gen_helper_vfp_negd(vd, vd);
85
}
86
87
-static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_sp *a)
88
+static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_dp *a)
89
{
90
return do_vfp_3op_dp(s, gen_VNMUL_dp, a->vd, a->vn, a->vm, false);
91
}
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VADD_sp(DisasContext *s, arg_VADD_sp *a)
93
return do_vfp_3op_sp(s, gen_helper_vfp_adds, a->vd, a->vn, a->vm, false);
94
}
95
96
-static bool trans_VADD_dp(DisasContext *s, arg_VADD_sp *a)
97
+static bool trans_VADD_dp(DisasContext *s, arg_VADD_dp *a)
98
{
99
return do_vfp_3op_dp(s, gen_helper_vfp_addd, a->vd, a->vn, a->vm, false);
100
}
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VSUB_sp(DisasContext *s, arg_VSUB_sp *a)
102
return do_vfp_3op_sp(s, gen_helper_vfp_subs, a->vd, a->vn, a->vm, false);
103
}
104
105
-static bool trans_VSUB_dp(DisasContext *s, arg_VSUB_sp *a)
106
+static bool trans_VSUB_dp(DisasContext *s, arg_VSUB_dp *a)
107
{
108
return do_vfp_3op_dp(s, gen_helper_vfp_subd, a->vd, a->vn, a->vm, false);
109
}
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VDIV_sp(DisasContext *s, arg_VDIV_sp *a)
111
return do_vfp_3op_sp(s, gen_helper_vfp_divs, a->vd, a->vn, a->vm, false);
112
}
113
114
-static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_sp *a)
115
+static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_dp *a)
116
{
117
return do_vfp_3op_dp(s, gen_helper_vfp_divd, a->vd, a->vn, a->vm, false);
118
}
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
120
return true;
121
}
122
123
-static bool trans_VFM_dp(DisasContext *s, arg_VFM_sp *a)
124
+static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
125
{
126
/*
127
* VFNMA : fd = muladd(-fd, fn, fm)
128
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
129
return true;
130
}
131
132
-static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_sp *a)
133
+static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
134
{
135
TCGv_ptr fpst;
136
TCGv_i64 tmp;
137
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
138
return true;
139
}
140
141
-static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_sp *a)
142
+static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
143
{
144
TCGv_ptr fpst;
145
TCGv_i64 tmp;
146
--
179
--
147
2.20.1
180
2.20.1
148
181
149
182
diff view generated by jsdifflib
1
Stop using cpu_F0s for NEON_2RM_VRECPE_F and NEON_2RM_VRSQRTE_F.
1
Now that we have implemented all the features needed by the v8.1M
2
architecture, we can add the model of the Cortex-M55. This is the
3
configuration without MVE support; we'll add MVE later.
2
4
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20201210201433.26262-5-peter.maydell@linaro.org
6
Message-id: 20190613163917.28589-8-peter.maydell@linaro.org
7
---
8
---
8
target/arm/translate.c | 6 +++---
9
target/arm/cpu_tcg.c | 42 ++++++++++++++++++++++++++++++++++++++++++
9
1 file changed, 3 insertions(+), 3 deletions(-)
10
1 file changed, 42 insertions(+)
10
11
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
14
--- a/target/arm/cpu_tcg.c
14
+++ b/target/arm/translate.c
15
+++ b/target/arm/cpu_tcg.c
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
16
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
16
* what we are asking here is "does the code for this case in
17
cpu->ctr = 0x8000c000;
17
* the Neon for-each-pass loop use cpu_F0s?".
18
*/
19
- return op >= NEON_2RM_VRECPE_F;
20
+ return op >= NEON_2RM_VCVT_FS;
21
}
18
}
22
19
23
static bool neon_2rm_is_v8_op(int op)
20
+static void cortex_m55_initfn(Object *obj)
24
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
21
+{
25
case NEON_2RM_VRECPE_F:
22
+ ARMCPU *cpu = ARM_CPU(obj);
26
{
23
+
27
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
24
+ set_feature(&cpu->env, ARM_FEATURE_V8);
28
- gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
25
+ set_feature(&cpu->env, ARM_FEATURE_V8_1M);
29
+ gen_helper_recpe_f32(tmp, tmp, fpstatus);
26
+ set_feature(&cpu->env, ARM_FEATURE_M);
30
tcg_temp_free_ptr(fpstatus);
27
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
31
break;
28
+ set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
32
}
29
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
33
case NEON_2RM_VRSQRTE_F:
30
+ cpu->midr = 0x410fd221; /* r0p1 */
34
{
31
+ cpu->revidr = 0;
35
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
32
+ cpu->pmsav7_dregion = 16;
36
- gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
33
+ cpu->sau_sregion = 8;
37
+ gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
34
+ /*
38
tcg_temp_free_ptr(fpstatus);
35
+ * These are the MVFR* values for the FPU, no MVE configuration;
39
break;
36
+ * we will update them later when we implement MVE
40
}
37
+ */
38
+ cpu->isar.mvfr0 = 0x10110221;
39
+ cpu->isar.mvfr1 = 0x12100011;
40
+ cpu->isar.mvfr2 = 0x00000040;
41
+ cpu->isar.id_pfr0 = 0x20000030;
42
+ cpu->isar.id_pfr1 = 0x00000230;
43
+ cpu->isar.id_dfr0 = 0x10200000;
44
+ cpu->id_afr0 = 0x00000000;
45
+ cpu->isar.id_mmfr0 = 0x00111040;
46
+ cpu->isar.id_mmfr1 = 0x00000000;
47
+ cpu->isar.id_mmfr2 = 0x01000000;
48
+ cpu->isar.id_mmfr3 = 0x00000011;
49
+ cpu->isar.id_isar0 = 0x01103110;
50
+ cpu->isar.id_isar1 = 0x02212000;
51
+ cpu->isar.id_isar2 = 0x20232232;
52
+ cpu->isar.id_isar3 = 0x01111131;
53
+ cpu->isar.id_isar4 = 0x01310132;
54
+ cpu->isar.id_isar5 = 0x00000000;
55
+ cpu->isar.id_isar6 = 0x00000000;
56
+ cpu->clidr = 0x00000000; /* caches not implemented */
57
+ cpu->ctr = 0x8303c003;
58
+}
59
+
60
static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
61
/* Dummy the TCM region regs for the moment */
62
{ .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
64
.class_init = arm_v7m_class_init },
65
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
66
.class_init = arm_v7m_class_init },
67
+ { .name = "cortex-m55", .initfn = cortex_m55_initfn,
68
+ .class_init = arm_v7m_class_init },
69
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
70
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
71
{ .name = "ti925t", .initfn = ti925t_initfn },
41
--
72
--
42
2.20.1
73
2.20.1
43
74
44
75
diff view generated by jsdifflib
1
Remove the now unused TCG globals cpu_F0s, cpu_F0d, cpu_F1s, cpu_F1d.
1
Support for running KVM on 32-bit Arm hosts was removed in commit
2
2
82bf7ae84ce739e. You can still run a 32-bit guest on a 64-bit Arm
3
cpu_M0 is still used by the iwmmxt code, and cpu_V0 and
3
host CPU, but because Arm KVM requires the host and guest CPU types
4
cpu_V1 are used by both iwmmxt and Neon.
4
to match, it is not possible to run a guest that requires a Cortex-A9
5
or Cortex-A15 CPU there. That means that the code in the
6
highbank/midway board models to support KVM is no longer used, and we
7
can delete it.
5
8
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20190613163917.28589-13-peter.maydell@linaro.org
12
Message-id: 20201215144215.28482-1-peter.maydell@linaro.org
10
---
13
---
11
target/arm/translate.c | 12 ++----------
14
hw/arm/highbank.c | 14 ++++----------
12
1 file changed, 2 insertions(+), 10 deletions(-)
15
1 file changed, 4 insertions(+), 10 deletions(-)
13
16
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
19
--- a/hw/arm/highbank.c
17
+++ b/target/arm/translate.c
20
+++ b/hw/arm/highbank.c
18
@@ -XXX,XX +XXX,XX @@ TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
21
@@ -XXX,XX +XXX,XX @@
19
TCGv_i64 cpu_exclusive_addr;
22
#include "hw/arm/boot.h"
20
TCGv_i64 cpu_exclusive_val;
23
#include "hw/loader.h"
21
24
#include "net/net.h"
22
-/* FIXME: These should be removed. */
25
-#include "sysemu/kvm.h"
23
-static TCGv_i32 cpu_F0s, cpu_F1s;
26
#include "sysemu/runstate.h"
24
-static TCGv_i64 cpu_F0d, cpu_F1d;
27
#include "sysemu/sysemu.h"
25
-
28
#include "hw/boards.h"
26
#include "exec/gen-icount.h"
29
@@ -XXX,XX +XXX,XX @@
27
30
#include "hw/cpu/a15mpcore.h"
28
static const char * const regnames[] =
31
#include "qemu/log.h"
29
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
32
#include "qom/object.h"
30
dc->base.max_insns = MIN(dc->base.max_insns, bound);
33
+#include "cpu.h"
31
}
34
32
35
#define SMP_BOOT_ADDR 0x100
33
- cpu_F0s = tcg_temp_new_i32();
36
#define SMP_BOOT_REG 0x40
34
- cpu_F1s = tcg_temp_new_i32();
37
@@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id)
35
- cpu_F0d = tcg_temp_new_i64();
38
highbank_binfo.loader_start = 0;
36
- cpu_F1d = tcg_temp_new_i64();
39
highbank_binfo.write_secondary_boot = hb_write_secondary;
37
- cpu_V0 = cpu_F0d;
40
highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
38
- cpu_V1 = cpu_F1d;
41
- if (!kvm_enabled()) {
39
+ cpu_V0 = tcg_temp_new_i64();
42
- highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
40
+ cpu_V1 = tcg_temp_new_i64();
43
- highbank_binfo.write_board_setup = hb_write_board_setup;
41
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
44
- highbank_binfo.secure_board_setup = true;
42
cpu_M0 = tcg_temp_new_i64();
45
- } else {
46
- warn_report("cannot load built-in Monitor support "
47
- "if KVM is enabled. Some guests (such as Linux) "
48
- "may not boot.");
49
- }
50
+ highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR;
51
+ highbank_binfo.write_board_setup = hb_write_board_setup;
52
+ highbank_binfo.secure_board_setup = true;
53
54
arm_load_kernel(ARM_CPU(first_cpu), machine, &highbank_binfo);
43
}
55
}
44
--
56
--
45
2.20.1
57
2.20.1
46
58
47
59
diff view generated by jsdifflib
1
The GIC ID registers cover an area 0x30 bytes in size
1
Currently timer_free() is a simple wrapper for g_free(). This means
2
(12 registers, 4 bytes each). We were incorrectly decoding
2
that the timer being freed must not be currently active, as otherwise
3
only the first 0x20 bytes.
3
QEMU might crash later when the active list is processed and still
4
has a pointer to freed memory on it. As a result almost all calls to
5
timer_free() are preceded by a timer_del() call, as can be seen in
6
the output of
7
git grep -B1 '\<timer_free\>'
8
9
This is unfortunate API design as it makes it easy to accidentally
10
misuse (by forgetting the timer_del()), and the correct use is
11
annoyingly verbose.
12
13
Make timer_free() imply a timer_del().
4
14
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20190524124248.28394-2-peter.maydell@linaro.org
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20201215154107.3255-2-peter.maydell@linaro.org
8
---
19
---
9
hw/intc/arm_gicv3_dist.c | 4 ++--
20
include/qemu/timer.h | 24 +++++++++++++-----------
10
hw/intc/arm_gicv3_redist.c | 4 ++--
21
1 file changed, 13 insertions(+), 11 deletions(-)
11
2 files changed, 4 insertions(+), 4 deletions(-)
12
22
13
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
23
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
14
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/arm_gicv3_dist.c
25
--- a/include/qemu/timer.h
16
+++ b/hw/intc/arm_gicv3_dist.c
26
+++ b/include/qemu/timer.h
17
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset,
27
@@ -XXX,XX +XXX,XX @@ static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
18
}
28
*/
19
return MEMTX_OK;
29
void timer_deinit(QEMUTimer *ts);
20
}
30
21
- case GICD_IDREGS ... GICD_IDREGS + 0x1f:
31
-/**
22
+ case GICD_IDREGS ... GICD_IDREGS + 0x2f:
32
- * timer_free:
23
/* ID registers */
33
- * @ts: the timer
24
*data = gicv3_idreg(offset - GICD_IDREGS);
34
- *
25
return MEMTX_OK;
35
- * Free a timer (it must not be on the active list)
26
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_writel(GICv3State *s, hwaddr offset,
36
- */
27
gicd_write_irouter(s, attrs, irq, r);
37
-static inline void timer_free(QEMUTimer *ts)
28
return MEMTX_OK;
38
-{
29
}
39
- g_free(ts);
30
- case GICD_IDREGS ... GICD_IDREGS + 0x1f:
40
-}
31
+ case GICD_IDREGS ... GICD_IDREGS + 0x2f:
41
-
32
case GICD_TYPER:
42
/**
33
case GICD_IIDR:
43
* timer_del:
34
/* RO registers, ignore the write */
44
* @ts: the timer
35
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
45
@@ -XXX,XX +XXX,XX @@ static inline void timer_free(QEMUTimer *ts)
36
index XXXXXXX..XXXXXXX 100644
46
*/
37
--- a/hw/intc/arm_gicv3_redist.c
47
void timer_del(QEMUTimer *ts);
38
+++ b/hw/intc/arm_gicv3_redist.c
48
39
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset,
49
+/**
40
}
50
+ * timer_free:
41
*data = cs->gicr_nsacr;
51
+ * @ts: the timer
42
return MEMTX_OK;
52
+ *
43
- case GICR_IDREGS ... GICR_IDREGS + 0x1f:
53
+ * Free a timer. This will call timer_del() for you to remove
44
+ case GICR_IDREGS ... GICR_IDREGS + 0x2f:
54
+ * the timer from the active list if it was still active.
45
*data = gicv3_idreg(offset - GICR_IDREGS);
55
+ */
46
return MEMTX_OK;
56
+static inline void timer_free(QEMUTimer *ts)
47
default:
57
+{
48
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
58
+ timer_del(ts);
49
return MEMTX_OK;
59
+ g_free(ts);
50
case GICR_IIDR:
60
+}
51
case GICR_TYPER:
61
+
52
- case GICR_IDREGS ... GICR_IDREGS + 0x1f:
62
/**
53
+ case GICR_IDREGS ... GICR_IDREGS + 0x2f:
63
* timer_mod_ns:
54
/* RO registers, ignore the write */
64
* @ts: the timer
55
qemu_log_mask(LOG_GUEST_ERROR,
56
"%s: invalid guest write to RO register at offset "
57
--
65
--
58
2.20.1
66
2.20.1
59
67
60
68
diff view generated by jsdifflib
1
The GICv3 specification says that the GICD_TYPER.SecurityExtn bit
1
Now that timer_free() implicitly calls timer_del(), sequences
2
is RAZ if GICD_CTLR.DS is 1. We were incorrectly making it RAZ
2
timer_del(mytimer);
3
if the security extension is unsupported. "Security extension
3
timer_free(mytimer);
4
unsupported" always implies GICD_CTLR.DS == 1, but the guest can
4
5
also set DS on a GIC which does support the security extension.
5
can be simplified to just
6
Fix the condition to correctly check the GICD_CTLR.DS bit.
6
timer_free(mytimer);
7
8
Add a Coccinelle script to do this transformation.
7
9
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190524124248.28394-3-peter.maydell@linaro.org
11
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20201215154107.3255-3-peter.maydell@linaro.org
10
---
15
---
11
hw/intc/arm_gicv3_dist.c | 8 +++++++-
16
scripts/coccinelle/timer-del-timer-free.cocci | 18 ++++++++++++++++++
12
1 file changed, 7 insertions(+), 1 deletion(-)
17
1 file changed, 18 insertions(+)
18
create mode 100644 scripts/coccinelle/timer-del-timer-free.cocci
13
19
14
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
20
diff --git a/scripts/coccinelle/timer-del-timer-free.cocci b/scripts/coccinelle/timer-del-timer-free.cocci
15
index XXXXXXX..XXXXXXX 100644
21
new file mode 100644
16
--- a/hw/intc/arm_gicv3_dist.c
22
index XXXXXXX..XXXXXXX
17
+++ b/hw/intc/arm_gicv3_dist.c
23
--- /dev/null
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset,
24
+++ b/scripts/coccinelle/timer-del-timer-free.cocci
19
* ITLinesNumber == (num external irqs / 32) - 1
25
@@ -XXX,XX +XXX,XX @@
20
*/
26
+// Remove superfluous timer_del() calls
21
int itlinesnumber = ((s->num_irq - GIC_INTERNAL) / 32) - 1;
27
+//
22
+ /*
28
+// Copyright Linaro Limited 2020
23
+ * SecurityExtn must be RAZ if GICD_CTLR.DS == 1, and
29
+// This work is licensed under the terms of the GNU GPLv2 or later.
24
+ * "security extensions not supported" always implies DS == 1,
30
+//
25
+ * so we only need to check the DS bit.
31
+// spatch --macro-file scripts/cocci-macro-file.h \
26
+ */
32
+// --sp-file scripts/coccinelle/timer-del-timer-free.cocci \
27
+ bool sec_extn = !(s->gicd_ctlr & GICD_CTLR_DS);
33
+// --in-place --dir .
28
34
+//
29
- *data = (1 << 25) | (1 << 24) | (s->security_extn << 10) |
35
+// The timer_free() function now implicitly calls timer_del()
30
+ *data = (1 << 25) | (1 << 24) | (sec_extn << 10) |
36
+// for you, so calls to timer_del() immediately before the
31
(0xf << 19) | itlinesnumber;
37
+// timer_free() of the same timer can be deleted.
32
return MEMTX_OK;
38
+
33
}
39
+@@
40
+expression T;
41
+@@
42
+-timer_del(T);
43
+ timer_free(T);
34
--
44
--
35
2.20.1
45
2.20.1
36
46
37
47
diff view generated by jsdifflib
1
Allow VFP and neon to be disabled via a CPU property. As with
1
This commit is the result of running the timer-del-timer-free.cocci
2
the "pmu" property, we only allow these features to be removed
2
script on the whole source tree.
3
from CPUs which have it by default, not added to CPUs which
4
don't have it.
5
6
The primary motivation here is to be able to optionally
7
create Cortex-M33 CPUs with no FPU, but we provide switches
8
for both VFP and Neon because the two interact:
9
* AArch64 can't have one without the other
10
* Some ID register fields only change if both are disabled
11
3
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Acked-by: Corey Minyard <cminyard@mvista.com>
6
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190517174046.11146-2-peter.maydell@linaro.org
9
Message-id: 20201215154107.3255-4-peter.maydell@linaro.org
16
---
10
---
17
target/arm/cpu.h | 4 ++
11
block/iscsi.c | 2 --
18
target/arm/cpu.c | 150 +++++++++++++++++++++++++++++++++++++++++++++--
12
block/nbd.c | 1 -
19
2 files changed, 148 insertions(+), 6 deletions(-)
13
block/qcow2.c | 1 -
14
hw/block/nvme.c | 2 --
15
hw/char/serial.c | 2 --
16
hw/char/virtio-serial-bus.c | 2 --
17
hw/ide/core.c | 1 -
18
hw/input/hid.c | 1 -
19
hw/intc/apic.c | 1 -
20
hw/intc/ioapic.c | 1 -
21
hw/ipmi/ipmi_bmc_extern.c | 1 -
22
hw/net/e1000.c | 3 ---
23
hw/net/e1000e_core.c | 8 --------
24
hw/net/pcnet-pci.c | 1 -
25
hw/net/rtl8139.c | 1 -
26
hw/net/spapr_llan.c | 1 -
27
hw/net/virtio-net.c | 2 --
28
hw/s390x/s390-pci-inst.c | 1 -
29
hw/sd/sd.c | 1 -
30
hw/sd/sdhci.c | 2 --
31
hw/usb/dev-hub.c | 1 -
32
hw/usb/hcd-ehci.c | 1 -
33
hw/usb/hcd-ohci-pci.c | 1 -
34
hw/usb/hcd-uhci.c | 1 -
35
hw/usb/hcd-xhci.c | 1 -
36
hw/usb/redirect.c | 1 -
37
hw/vfio/display.c | 1 -
38
hw/virtio/vhost-vsock-common.c | 1 -
39
hw/virtio/virtio-balloon.c | 1 -
40
hw/virtio/virtio-rng.c | 1 -
41
hw/watchdog/wdt_diag288.c | 1 -
42
hw/watchdog/wdt_i6300esb.c | 1 -
43
migration/colo.c | 1 -
44
monitor/hmp-cmds.c | 1 -
45
net/announce.c | 1 -
46
net/colo-compare.c | 1 -
47
net/slirp.c | 1 -
48
replay/replay-debugging.c | 1 -
49
target/s390x/cpu.c | 2 --
50
ui/console.c | 1 -
51
ui/spice-core.c | 1 -
52
util/throttle.c | 1 -
53
42 files changed, 58 deletions(-)
20
54
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
55
diff --git a/block/iscsi.c b/block/iscsi.c
22
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
57
--- a/block/iscsi.c
24
+++ b/target/arm/cpu.h
58
+++ b/block/iscsi.c
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
59
@@ -XXX,XX +XXX,XX @@ static void iscsi_detach_aio_context(BlockDriverState *bs)
26
bool has_el3;
60
iscsilun->events = 0;
27
/* CPU has PMU (Performance Monitor Unit) */
61
28
bool has_pmu;
62
if (iscsilun->nop_timer) {
29
+ /* CPU has VFP */
63
- timer_del(iscsilun->nop_timer);
30
+ bool has_vfp;
64
timer_free(iscsilun->nop_timer);
31
+ /* CPU has Neon */
65
iscsilun->nop_timer = NULL;
32
+ bool has_neon;
66
}
33
67
if (iscsilun->event_timer) {
34
/* CPU has memory protection unit */
68
- timer_del(iscsilun->event_timer);
35
bool has_mpu;
69
timer_free(iscsilun->event_timer);
36
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
70
iscsilun->event_timer = NULL;
37
index XXXXXXX..XXXXXXX 100644
71
}
38
--- a/target/arm/cpu.c
72
diff --git a/block/nbd.c b/block/nbd.c
39
+++ b/target/arm/cpu.c
73
index XXXXXXX..XXXXXXX 100644
40
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_cfgend_property =
74
--- a/block/nbd.c
41
static Property arm_cpu_has_pmu_property =
75
+++ b/block/nbd.c
42
DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true);
76
@@ -XXX,XX +XXX,XX @@ static void nbd_recv_coroutines_wake_all(BDRVNBDState *s)
43
77
static void reconnect_delay_timer_del(BDRVNBDState *s)
44
+static Property arm_cpu_has_vfp_property =
78
{
45
+ DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true);
79
if (s->reconnect_delay_timer) {
46
+
80
- timer_del(s->reconnect_delay_timer);
47
+static Property arm_cpu_has_neon_property =
81
timer_free(s->reconnect_delay_timer);
48
+ DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
82
s->reconnect_delay_timer = NULL;
49
+
83
}
50
static Property arm_cpu_has_mpu_property =
84
diff --git a/block/qcow2.c b/block/qcow2.c
51
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
85
index XXXXXXX..XXXXXXX 100644
52
86
--- a/block/qcow2.c
53
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
87
+++ b/block/qcow2.c
54
if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
88
@@ -XXX,XX +XXX,XX @@ static void cache_clean_timer_del(BlockDriverState *bs)
55
set_feature(&cpu->env, ARM_FEATURE_PMSA);
89
{
56
}
90
BDRVQcow2State *s = bs->opaque;
57
+ /* Similarly for the VFP feature bits */
91
if (s->cache_clean_timer) {
58
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP4)) {
92
- timer_del(s->cache_clean_timer);
59
+ set_feature(&cpu->env, ARM_FEATURE_VFP3);
93
timer_free(s->cache_clean_timer);
60
+ }
94
s->cache_clean_timer = NULL;
61
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP3)) {
95
}
62
+ set_feature(&cpu->env, ARM_FEATURE_VFP);
96
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
63
+ }
97
index XXXXXXX..XXXXXXX 100644
64
98
--- a/hw/block/nvme.c
65
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
99
+++ b/hw/block/nvme.c
66
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
100
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest *req)
67
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
101
static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n)
68
&error_abort);
102
{
69
}
103
n->sq[sq->sqid] = NULL;
70
104
- timer_del(sq->timer);
71
+ /*
105
timer_free(sq->timer);
72
+ * Allow user to turn off VFP and Neon support, but only for TCG --
106
g_free(sq->io_req);
73
+ * KVM does not currently allow us to lie to the guest about its
107
if (sq->sqid) {
74
+ * ID/feature registers, so the guest always sees what the host has.
108
@@ -XXX,XX +XXX,XX @@ static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest *req)
75
+ */
109
static void nvme_free_cq(NvmeCQueue *cq, NvmeCtrl *n)
76
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
110
{
77
+ cpu->has_vfp = true;
111
n->cq[cq->cqid] = NULL;
78
+ if (!kvm_enabled()) {
112
- timer_del(cq->timer);
79
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property,
113
timer_free(cq->timer);
80
+ &error_abort);
114
msix_vector_unuse(&n->parent_obj, cq->vector);
81
+ }
115
if (cq->cqid) {
82
+ }
116
diff --git a/hw/char/serial.c b/hw/char/serial.c
83
+
117
index XXXXXXX..XXXXXXX 100644
84
+ if (arm_feature(&cpu->env, ARM_FEATURE_NEON)) {
118
--- a/hw/char/serial.c
85
+ cpu->has_neon = true;
119
+++ b/hw/char/serial.c
86
+ if (!kvm_enabled()) {
120
@@ -XXX,XX +XXX,XX @@ static void serial_unrealize(DeviceState *dev)
87
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_neon_property,
121
88
+ &error_abort);
122
qemu_chr_fe_deinit(&s->chr, false);
89
+ }
123
90
+ }
124
- timer_del(s->modem_status_poll);
91
+
125
timer_free(s->modem_status_poll);
92
if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
126
93
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
127
- timer_del(s->fifo_timeout_timer);
94
&error_abort);
128
timer_free(s->fifo_timeout_timer);
95
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
129
130
fifo8_destroy(&s->recv_fifo);
131
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/char/virtio-serial-bus.c
134
+++ b/hw/char/virtio-serial-bus.c
135
@@ -XXX,XX +XXX,XX @@ static void virtio_serial_post_load_timer_cb(void *opaque)
136
}
137
}
138
g_free(s->post_load->connected);
139
- timer_del(s->post_load->timer);
140
timer_free(s->post_load->timer);
141
g_free(s->post_load);
142
s->post_load = NULL;
143
@@ -XXX,XX +XXX,XX @@ static void virtio_serial_device_unrealize(DeviceState *dev)
144
g_free(vser->ports_map);
145
if (vser->post_load) {
146
g_free(vser->post_load->connected);
147
- timer_del(vser->post_load->timer);
148
timer_free(vser->post_load->timer);
149
g_free(vser->post_load);
150
}
151
diff --git a/hw/ide/core.c b/hw/ide/core.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/hw/ide/core.c
154
+++ b/hw/ide/core.c
155
@@ -XXX,XX +XXX,XX @@ void ide_init2(IDEBus *bus, qemu_irq irq)
156
157
void ide_exit(IDEState *s)
158
{
159
- timer_del(s->sector_write_timer);
160
timer_free(s->sector_write_timer);
161
qemu_vfree(s->smart_selftest_data);
162
qemu_vfree(s->io_buffer);
163
diff --git a/hw/input/hid.c b/hw/input/hid.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/hw/input/hid.c
166
+++ b/hw/input/hid.c
167
@@ -XXX,XX +XXX,XX @@ static void hid_idle_timer(void *opaque)
168
static void hid_del_idle_timer(HIDState *hs)
169
{
170
if (hs->idle_timer) {
171
- timer_del(hs->idle_timer);
172
timer_free(hs->idle_timer);
173
hs->idle_timer = NULL;
174
}
175
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
176
index XXXXXXX..XXXXXXX 100644
177
--- a/hw/intc/apic.c
178
+++ b/hw/intc/apic.c
179
@@ -XXX,XX +XXX,XX @@ static void apic_unrealize(DeviceState *dev)
180
{
181
APICCommonState *s = APIC(dev);
182
183
- timer_del(s->timer);
184
timer_free(s->timer);
185
local_apics[s->id] = NULL;
186
}
187
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
188
index XXXXXXX..XXXXXXX 100644
189
--- a/hw/intc/ioapic.c
190
+++ b/hw/intc/ioapic.c
191
@@ -XXX,XX +XXX,XX @@ static void ioapic_unrealize(DeviceState *dev)
192
{
193
IOAPICCommonState *s = IOAPIC_COMMON(dev);
194
195
- timer_del(s->delayed_ioapic_service_timer);
196
timer_free(s->delayed_ioapic_service_timer);
197
}
198
199
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/hw/ipmi/ipmi_bmc_extern.c
202
+++ b/hw/ipmi/ipmi_bmc_extern.c
203
@@ -XXX,XX +XXX,XX @@ static void ipmi_bmc_extern_finalize(Object *obj)
204
{
205
IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj);
206
207
- timer_del(ibe->extern_timer);
208
timer_free(ibe->extern_timer);
209
}
210
211
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/hw/net/e1000.c
214
+++ b/hw/net/e1000.c
215
@@ -XXX,XX +XXX,XX @@ pci_e1000_uninit(PCIDevice *dev)
216
{
217
E1000State *d = E1000(dev);
218
219
- timer_del(d->autoneg_timer);
220
timer_free(d->autoneg_timer);
221
- timer_del(d->mit_timer);
222
timer_free(d->mit_timer);
223
- timer_del(d->flush_queue_timer);
224
timer_free(d->flush_queue_timer);
225
qemu_del_nic(d->nic);
226
}
227
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/hw/net/e1000e_core.c
230
+++ b/hw/net/e1000e_core.c
231
@@ -XXX,XX +XXX,XX @@ e1000e_intrmgr_pci_unint(E1000ECore *core)
232
{
233
int i;
234
235
- timer_del(core->radv.timer);
236
timer_free(core->radv.timer);
237
- timer_del(core->rdtr.timer);
238
timer_free(core->rdtr.timer);
239
- timer_del(core->raid.timer);
240
timer_free(core->raid.timer);
241
242
- timer_del(core->tadv.timer);
243
timer_free(core->tadv.timer);
244
- timer_del(core->tidv.timer);
245
timer_free(core->tidv.timer);
246
247
- timer_del(core->itr.timer);
248
timer_free(core->itr.timer);
249
250
for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) {
251
- timer_del(core->eitr[i].timer);
252
timer_free(core->eitr[i].timer);
253
}
254
}
255
@@ -XXX,XX +XXX,XX @@ e1000e_core_pci_uninit(E1000ECore *core)
256
{
257
int i;
258
259
- timer_del(core->autoneg_timer);
260
timer_free(core->autoneg_timer);
261
262
e1000e_intrmgr_pci_unint(core);
263
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
264
index XXXXXXX..XXXXXXX 100644
265
--- a/hw/net/pcnet-pci.c
266
+++ b/hw/net/pcnet-pci.c
267
@@ -XXX,XX +XXX,XX @@ static void pci_pcnet_uninit(PCIDevice *dev)
268
PCIPCNetState *d = PCI_PCNET(dev);
269
270
qemu_free_irq(d->state.irq);
271
- timer_del(d->state.poll_timer);
272
timer_free(d->state.poll_timer);
273
qemu_del_nic(d->state.nic);
274
}
275
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
276
index XXXXXXX..XXXXXXX 100644
277
--- a/hw/net/rtl8139.c
278
+++ b/hw/net/rtl8139.c
279
@@ -XXX,XX +XXX,XX @@ static void pci_rtl8139_uninit(PCIDevice *dev)
280
281
g_free(s->cplus_txbuffer);
282
s->cplus_txbuffer = NULL;
283
- timer_del(s->timer);
284
timer_free(s->timer);
285
qemu_del_nic(s->nic);
286
}
287
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
288
index XXXXXXX..XXXXXXX 100644
289
--- a/hw/net/spapr_llan.c
290
+++ b/hw/net/spapr_llan.c
291
@@ -XXX,XX +XXX,XX @@ static void spapr_vlan_instance_finalize(Object *obj)
292
}
293
294
if (dev->rxp_timer) {
295
- timer_del(dev->rxp_timer);
296
timer_free(dev->rxp_timer);
297
}
298
}
299
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
300
index XXXXXXX..XXXXXXX 100644
301
--- a/hw/net/virtio-net.c
302
+++ b/hw/net/virtio-net.c
303
@@ -XXX,XX +XXX,XX @@ static void virtio_net_rsc_cleanup(VirtIONet *n)
304
g_free(seg);
305
}
306
307
- timer_del(chain->drain_timer);
308
timer_free(chain->drain_timer);
309
QTAILQ_REMOVE(&n->rsc_chains, chain, next);
310
g_free(chain);
311
@@ -XXX,XX +XXX,XX @@ static void virtio_net_del_queue(VirtIONet *n, int index)
312
313
virtio_del_queue(vdev, index * 2);
314
if (q->tx_timer) {
315
- timer_del(q->tx_timer);
316
timer_free(q->tx_timer);
317
q->tx_timer = NULL;
318
} else {
319
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
320
index XXXXXXX..XXXXXXX 100644
321
--- a/hw/s390x/s390-pci-inst.c
322
+++ b/hw/s390x/s390-pci-inst.c
323
@@ -XXX,XX +XXX,XX @@ void pci_dereg_ioat(S390PCIIOMMU *iommu)
324
void fmb_timer_free(S390PCIBusDevice *pbdev)
325
{
326
if (pbdev->fmb_timer) {
327
- timer_del(pbdev->fmb_timer);
328
timer_free(pbdev->fmb_timer);
329
pbdev->fmb_timer = NULL;
330
}
331
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
332
index XXXXXXX..XXXXXXX 100644
333
--- a/hw/sd/sd.c
334
+++ b/hw/sd/sd.c
335
@@ -XXX,XX +XXX,XX @@ static void sd_instance_finalize(Object *obj)
336
{
337
SDState *sd = SD_CARD(obj);
338
339
- timer_del(sd->ocr_power_timer);
340
timer_free(sd->ocr_power_timer);
341
}
342
343
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
344
index XXXXXXX..XXXXXXX 100644
345
--- a/hw/sd/sdhci.c
346
+++ b/hw/sd/sdhci.c
347
@@ -XXX,XX +XXX,XX @@ void sdhci_initfn(SDHCIState *s)
348
349
void sdhci_uninitfn(SDHCIState *s)
350
{
351
- timer_del(s->insert_timer);
352
timer_free(s->insert_timer);
353
- timer_del(s->transfer_timer);
354
timer_free(s->transfer_timer);
355
356
g_free(s->fifo_buffer);
357
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
358
index XXXXXXX..XXXXXXX 100644
359
--- a/hw/usb/dev-hub.c
360
+++ b/hw/usb/dev-hub.c
361
@@ -XXX,XX +XXX,XX @@ static void usb_hub_unrealize(USBDevice *dev)
362
&s->ports[i].port);
363
}
364
365
- timer_del(s->port_timer);
366
timer_free(s->port_timer);
367
}
368
369
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
370
index XXXXXXX..XXXXXXX 100644
371
--- a/hw/usb/hcd-ehci.c
372
+++ b/hw/usb/hcd-ehci.c
373
@@ -XXX,XX +XXX,XX @@ void usb_ehci_unrealize(EHCIState *s, DeviceState *dev)
374
trace_usb_ehci_unrealize();
375
376
if (s->frame_timer) {
377
- timer_del(s->frame_timer);
378
timer_free(s->frame_timer);
379
s->frame_timer = NULL;
380
}
381
diff --git a/hw/usb/hcd-ohci-pci.c b/hw/usb/hcd-ohci-pci.c
382
index XXXXXXX..XXXXXXX 100644
383
--- a/hw/usb/hcd-ohci-pci.c
384
+++ b/hw/usb/hcd-ohci-pci.c
385
@@ -XXX,XX +XXX,XX @@ static void usb_ohci_exit(PCIDevice *dev)
386
usb_bus_release(&s->bus);
387
}
388
389
- timer_del(s->eof_timer);
390
timer_free(s->eof_timer);
391
}
392
393
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
394
index XXXXXXX..XXXXXXX 100644
395
--- a/hw/usb/hcd-uhci.c
396
+++ b/hw/usb/hcd-uhci.c
397
@@ -XXX,XX +XXX,XX @@ static void usb_uhci_exit(PCIDevice *dev)
398
trace_usb_uhci_exit();
399
400
if (s->frame_timer) {
401
- timer_del(s->frame_timer);
402
timer_free(s->frame_timer);
403
s->frame_timer = NULL;
404
}
405
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
406
index XXXXXXX..XXXXXXX 100644
407
--- a/hw/usb/hcd-xhci.c
408
+++ b/hw/usb/hcd-xhci.c
409
@@ -XXX,XX +XXX,XX @@ static void usb_xhci_unrealize(DeviceState *dev)
410
}
411
412
if (xhci->mfwrap_timer) {
413
- timer_del(xhci->mfwrap_timer);
414
timer_free(xhci->mfwrap_timer);
415
xhci->mfwrap_timer = NULL;
416
}
417
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
418
index XXXXXXX..XXXXXXX 100644
419
--- a/hw/usb/redirect.c
420
+++ b/hw/usb/redirect.c
421
@@ -XXX,XX +XXX,XX @@ static void usbredir_unrealize(USBDevice *udev)
422
qemu_bh_delete(dev->chardev_close_bh);
423
qemu_bh_delete(dev->device_reject_bh);
424
425
- timer_del(dev->attach_timer);
426
timer_free(dev->attach_timer);
427
428
usbredir_cleanup_device_queues(dev);
429
diff --git a/hw/vfio/display.c b/hw/vfio/display.c
430
index XXXXXXX..XXXXXXX 100644
431
--- a/hw/vfio/display.c
432
+++ b/hw/vfio/display.c
433
@@ -XXX,XX +XXX,XX @@ static void vfio_display_edid_exit(VFIODisplay *dpy)
434
435
g_free(dpy->edid_regs);
436
g_free(dpy->edid_blob);
437
- timer_del(dpy->edid_link_timer);
438
timer_free(dpy->edid_link_timer);
439
}
440
441
diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c
442
index XXXXXXX..XXXXXXX 100644
443
--- a/hw/virtio/vhost-vsock-common.c
444
+++ b/hw/virtio/vhost-vsock-common.c
445
@@ -XXX,XX +XXX,XX @@ static void vhost_vsock_common_post_load_timer_cleanup(VHostVSockCommon *vvc)
96
return;
446
return;
97
}
447
}
98
448
99
+ if (arm_feature(env, ARM_FEATURE_AARCH64) &&
449
- timer_del(vvc->post_load_timer);
100
+ cpu->has_vfp != cpu->has_neon) {
450
timer_free(vvc->post_load_timer);
101
+ /*
451
vvc->post_load_timer = NULL;
102
+ * This is an architectural requirement for AArch64; AArch32 is
452
}
103
+ * more flexible and permits VFP-no-Neon and Neon-no-VFP.
453
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
104
+ */
454
index XXXXXXX..XXXXXXX 100644
105
+ error_setg(errp,
455
--- a/hw/virtio/virtio-balloon.c
106
+ "AArch64 CPUs must have both VFP and Neon or neither");
456
+++ b/hw/virtio/virtio-balloon.c
107
+ return;
457
@@ -XXX,XX +XXX,XX @@ static bool balloon_stats_enabled(const VirtIOBalloon *s)
108
+ }
458
static void balloon_stats_destroy_timer(VirtIOBalloon *s)
109
+
459
{
110
+ if (!cpu->has_vfp) {
460
if (balloon_stats_enabled(s)) {
111
+ uint64_t t;
461
- timer_del(s->stats_timer);
112
+ uint32_t u;
462
timer_free(s->stats_timer);
113
+
463
s->stats_timer = NULL;
114
+ unset_feature(env, ARM_FEATURE_VFP);
464
s->stats_poll_interval = 0;
115
+ unset_feature(env, ARM_FEATURE_VFP3);
465
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
116
+ unset_feature(env, ARM_FEATURE_VFP4);
466
index XXXXXXX..XXXXXXX 100644
117
+
467
--- a/hw/virtio/virtio-rng.c
118
+ t = cpu->isar.id_aa64isar1;
468
+++ b/hw/virtio/virtio-rng.c
119
+ t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0);
469
@@ -XXX,XX +XXX,XX @@ static void virtio_rng_device_unrealize(DeviceState *dev)
120
+ cpu->isar.id_aa64isar1 = t;
470
VirtIORNG *vrng = VIRTIO_RNG(dev);
121
+
471
122
+ t = cpu->isar.id_aa64pfr0;
472
qemu_del_vm_change_state_handler(vrng->vmstate);
123
+ t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf);
473
- timer_del(vrng->rate_limit_timer);
124
+ cpu->isar.id_aa64pfr0 = t;
474
timer_free(vrng->rate_limit_timer);
125
+
475
virtio_del_queue(vdev, 0);
126
+ u = cpu->isar.id_isar6;
476
virtio_cleanup(vdev);
127
+ u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0);
477
diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c
128
+ cpu->isar.id_isar6 = u;
478
index XXXXXXX..XXXXXXX 100644
129
+
479
--- a/hw/watchdog/wdt_diag288.c
130
+ u = cpu->isar.mvfr0;
480
+++ b/hw/watchdog/wdt_diag288.c
131
+ u = FIELD_DP32(u, MVFR0, FPSP, 0);
481
@@ -XXX,XX +XXX,XX @@ static void wdt_diag288_unrealize(DeviceState *dev)
132
+ u = FIELD_DP32(u, MVFR0, FPDP, 0);
482
{
133
+ u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
483
DIAG288State *diag288 = DIAG288(dev);
134
+ u = FIELD_DP32(u, MVFR0, FPDIVIDE, 0);
484
135
+ u = FIELD_DP32(u, MVFR0, FPSQRT, 0);
485
- timer_del(diag288->timer);
136
+ u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
486
timer_free(diag288->timer);
137
+ u = FIELD_DP32(u, MVFR0, FPROUND, 0);
487
}
138
+ cpu->isar.mvfr0 = u;
488
139
+
489
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
140
+ u = cpu->isar.mvfr1;
490
index XXXXXXX..XXXXXXX 100644
141
+ u = FIELD_DP32(u, MVFR1, FPFTZ, 0);
491
--- a/hw/watchdog/wdt_i6300esb.c
142
+ u = FIELD_DP32(u, MVFR1, FPDNAN, 0);
492
+++ b/hw/watchdog/wdt_i6300esb.c
143
+ u = FIELD_DP32(u, MVFR1, FPHP, 0);
493
@@ -XXX,XX +XXX,XX @@ static void i6300esb_exit(PCIDevice *dev)
144
+ cpu->isar.mvfr1 = u;
494
{
145
+
495
I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
146
+ u = cpu->isar.mvfr2;
496
147
+ u = FIELD_DP32(u, MVFR2, FPMISC, 0);
497
- timer_del(d->timer);
148
+ cpu->isar.mvfr2 = u;
498
timer_free(d->timer);
149
+ }
499
}
150
+
500
151
+ if (!cpu->has_neon) {
501
diff --git a/migration/colo.c b/migration/colo.c
152
+ uint64_t t;
502
index XXXXXXX..XXXXXXX 100644
153
+ uint32_t u;
503
--- a/migration/colo.c
154
+
504
+++ b/migration/colo.c
155
+ unset_feature(env, ARM_FEATURE_NEON);
505
@@ -XXX,XX +XXX,XX @@ out:
156
+
506
* error.
157
+ t = cpu->isar.id_aa64isar0;
507
*/
158
+ t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0);
508
colo_compare_unregister_notifier(&packets_compare_notifier);
159
+ cpu->isar.id_aa64isar0 = t;
509
- timer_del(s->colo_delay_timer);
160
+
510
timer_free(s->colo_delay_timer);
161
+ t = cpu->isar.id_aa64isar1;
511
qemu_event_destroy(&s->colo_checkpoint_event);
162
+ t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0);
512
163
+ cpu->isar.id_aa64isar1 = t;
513
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
164
+
514
index XXXXXXX..XXXXXXX 100644
165
+ t = cpu->isar.id_aa64pfr0;
515
--- a/monitor/hmp-cmds.c
166
+ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf);
516
+++ b/monitor/hmp-cmds.c
167
+ cpu->isar.id_aa64pfr0 = t;
517
@@ -XXX,XX +XXX,XX @@ static void hmp_migrate_status_cb(void *opaque)
168
+
518
error_report("%s", info->error_desc);
169
+ u = cpu->isar.id_isar5;
519
}
170
+ u = FIELD_DP32(u, ID_ISAR5, RDM, 0);
520
monitor_resume(status->mon);
171
+ u = FIELD_DP32(u, ID_ISAR5, VCMA, 0);
521
- timer_del(status->timer);
172
+ cpu->isar.id_isar5 = u;
522
timer_free(status->timer);
173
+
523
g_free(status);
174
+ u = cpu->isar.id_isar6;
524
}
175
+ u = FIELD_DP32(u, ID_ISAR6, DP, 0);
525
diff --git a/net/announce.c b/net/announce.c
176
+ u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
526
index XXXXXXX..XXXXXXX 100644
177
+ cpu->isar.id_isar6 = u;
527
--- a/net/announce.c
178
+
528
+++ b/net/announce.c
179
+ u = cpu->isar.mvfr1;
529
@@ -XXX,XX +XXX,XX @@ void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named)
180
+ u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
530
{
181
+ u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
531
bool free_timer = false;
182
+ u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
532
if (timer->tm) {
183
+ u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
533
- timer_del(timer->tm);
184
+ u = FIELD_DP32(u, MVFR1, SIMDFMAC, 0);
534
timer_free(timer->tm);
185
+ cpu->isar.mvfr1 = u;
535
timer->tm = NULL;
186
+
536
}
187
+ u = cpu->isar.mvfr2;
537
diff --git a/net/colo-compare.c b/net/colo-compare.c
188
+ u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
538
index XXXXXXX..XXXXXXX 100644
189
+ cpu->isar.mvfr2 = u;
539
--- a/net/colo-compare.c
190
+ }
540
+++ b/net/colo-compare.c
191
+
541
@@ -XXX,XX +XXX,XX @@ static void colo_compare_timer_init(CompareState *s)
192
+ if (!cpu->has_neon && !cpu->has_vfp) {
542
static void colo_compare_timer_del(CompareState *s)
193
+ uint64_t t;
543
{
194
+ uint32_t u;
544
if (s->packet_check_timer) {
195
+
545
- timer_del(s->packet_check_timer);
196
+ t = cpu->isar.id_aa64isar0;
546
timer_free(s->packet_check_timer);
197
+ t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 0);
547
s->packet_check_timer = NULL;
198
+ cpu->isar.id_aa64isar0 = t;
548
}
199
+
549
diff --git a/net/slirp.c b/net/slirp.c
200
+ t = cpu->isar.id_aa64isar1;
550
index XXXXXXX..XXXXXXX 100644
201
+ t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0);
551
--- a/net/slirp.c
202
+ cpu->isar.id_aa64isar1 = t;
552
+++ b/net/slirp.c
203
+
553
@@ -XXX,XX +XXX,XX @@ static void *net_slirp_timer_new(SlirpTimerCb cb,
204
+ u = cpu->isar.mvfr0;
554
205
+ u = FIELD_DP32(u, MVFR0, SIMDREG, 0);
555
static void net_slirp_timer_free(void *timer, void *opaque)
206
+ cpu->isar.mvfr0 = u;
556
{
207
+ }
557
- timer_del(timer);
208
+
558
timer_free(timer);
209
/* Some features automatically imply others: */
559
}
210
if (arm_feature(env, ARM_FEATURE_V8)) {
560
211
if (arm_feature(env, ARM_FEATURE_M)) {
561
diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c
212
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
562
index XXXXXXX..XXXXXXX 100644
213
if (arm_feature(env, ARM_FEATURE_V5)) {
563
--- a/replay/replay-debugging.c
214
set_feature(env, ARM_FEATURE_V4T);
564
+++ b/replay/replay-debugging.c
215
}
565
@@ -XXX,XX +XXX,XX @@ static void replay_delete_break(void)
216
- if (arm_feature(env, ARM_FEATURE_VFP4)) {
566
assert(replay_mutex_locked());
217
- set_feature(env, ARM_FEATURE_VFP3);
567
218
- }
568
if (replay_break_timer) {
219
- if (arm_feature(env, ARM_FEATURE_VFP3)) {
569
- timer_del(replay_break_timer);
220
- set_feature(env, ARM_FEATURE_VFP);
570
timer_free(replay_break_timer);
221
- }
571
replay_break_timer = NULL;
222
if (arm_feature(env, ARM_FEATURE_LPAE)) {
572
}
223
set_feature(env, ARM_FEATURE_V7MP);
573
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
224
set_feature(env, ARM_FEATURE_PXN);
574
index XXXXXXX..XXXXXXX 100644
575
--- a/target/s390x/cpu.c
576
+++ b/target/s390x/cpu.c
577
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_finalize(Object *obj)
578
#if !defined(CONFIG_USER_ONLY)
579
S390CPU *cpu = S390_CPU(obj);
580
581
- timer_del(cpu->env.tod_timer);
582
timer_free(cpu->env.tod_timer);
583
- timer_del(cpu->env.cpu_timer);
584
timer_free(cpu->env.cpu_timer);
585
586
qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu);
587
diff --git a/ui/console.c b/ui/console.c
588
index XXXXXXX..XXXXXXX 100644
589
--- a/ui/console.c
590
+++ b/ui/console.c
591
@@ -XXX,XX +XXX,XX @@ static void gui_setup_refresh(DisplayState *ds)
592
timer_mod(ds->gui_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
593
}
594
if (!need_timer && ds->gui_timer != NULL) {
595
- timer_del(ds->gui_timer);
596
timer_free(ds->gui_timer);
597
ds->gui_timer = NULL;
598
}
599
diff --git a/ui/spice-core.c b/ui/spice-core.c
600
index XXXXXXX..XXXXXXX 100644
601
--- a/ui/spice-core.c
602
+++ b/ui/spice-core.c
603
@@ -XXX,XX +XXX,XX @@ static void timer_cancel(SpiceTimer *timer)
604
605
static void timer_remove(SpiceTimer *timer)
606
{
607
- timer_del(timer->timer);
608
timer_free(timer->timer);
609
g_free(timer);
610
}
611
diff --git a/util/throttle.c b/util/throttle.c
612
index XXXXXXX..XXXXXXX 100644
613
--- a/util/throttle.c
614
+++ b/util/throttle.c
615
@@ -XXX,XX +XXX,XX @@ static void throttle_timer_destroy(QEMUTimer **timer)
616
{
617
assert(*timer != NULL);
618
619
- timer_del(*timer);
620
timer_free(*timer);
621
*timer = NULL;
622
}
225
--
623
--
226
2.20.1
624
2.20.1
227
625
228
626
diff view generated by jsdifflib
1
Allow the DSP extension to be disabled via a CPU property for
1
The Arm CPU finalize function uses a sequence of timer_del(), timer_deinit(),
2
M-profile CPUs. (A and R-profile CPUs don't have this extension
2
timer_free() to free the timer. The timer_deinit() step in this was always
3
as a defined separate optional architecture extension, so
3
unnecessary, and now the timer_del() is implied by timer_free(), so we can
4
they don't need the property.)
4
collapse this down to simply calling timer_free().
5
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190517174046.11146-3-peter.maydell@linaro.org
9
Message-id: 20201215154107.3255-5-peter.maydell@linaro.org
10
---
10
---
11
target/arm/cpu.h | 2 ++
11
target/arm/cpu.c | 2 --
12
target/arm/cpu.c | 29 +++++++++++++++++++++++++++++
12
1 file changed, 2 deletions(-)
13
2 files changed, 31 insertions(+)
14
13
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
20
bool has_vfp;
21
/* CPU has Neon */
22
bool has_neon;
23
+ /* CPU has M-profile DSP extension */
24
+ bool has_dsp;
25
26
/* CPU has memory protection unit */
27
bool has_mpu;
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.c
16
--- a/target/arm/cpu.c
31
+++ b/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
32
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_has_vfp_property =
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_finalizefn(Object *obj)
33
static Property arm_cpu_has_neon_property =
34
DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
35
36
+static Property arm_cpu_has_dsp_property =
37
+ DEFINE_PROP_BOOL("dsp", ARMCPU, has_dsp, true);
38
+
39
static Property arm_cpu_has_mpu_property =
40
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
41
42
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
43
}
44
}
19
}
45
20
#ifndef CONFIG_USER_ONLY
46
+ if (arm_feature(&cpu->env, ARM_FEATURE_M) &&
21
if (cpu->pmu_timer) {
47
+ arm_feature(&cpu->env, ARM_FEATURE_THUMB_DSP)) {
22
- timer_del(cpu->pmu_timer);
48
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_dsp_property,
23
- timer_deinit(cpu->pmu_timer);
49
+ &error_abort);
24
timer_free(cpu->pmu_timer);
50
+ }
51
+
52
if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
53
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
54
&error_abort);
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
56
cpu->isar.mvfr0 = u;
57
}
25
}
58
26
#endif
59
+ if (arm_feature(env, ARM_FEATURE_M) && !cpu->has_dsp) {
60
+ uint32_t u;
61
+
62
+ unset_feature(env, ARM_FEATURE_THUMB_DSP);
63
+
64
+ u = cpu->isar.id_isar1;
65
+ u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1);
66
+ cpu->isar.id_isar1 = u;
67
+
68
+ u = cpu->isar.id_isar2;
69
+ u = FIELD_DP32(u, ID_ISAR2, MULTU, 1);
70
+ u = FIELD_DP32(u, ID_ISAR2, MULTS, 1);
71
+ cpu->isar.id_isar2 = u;
72
+
73
+ u = cpu->isar.id_isar3;
74
+ u = FIELD_DP32(u, ID_ISAR3, SIMD, 1);
75
+ u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0);
76
+ cpu->isar.id_isar3 = u;
77
+ }
78
+
79
/* Some features automatically imply others: */
80
if (arm_feature(env, ARM_FEATURE_V8)) {
81
if (arm_feature(env, ARM_FEATURE_M)) {
82
--
27
--
83
2.20.1
28
2.20.1
84
29
85
30
diff view generated by jsdifflib
1
Switch NEON_2RM_VRINT* away from using cpu_F0s.
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
When running device-introspect-test, a memory leak occurred in the
4
digic_timer_init function, so use ptimer_free() in the finalize function to
5
avoid it.
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 288 byte(s) in 3 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf5b04084 in digic_timer_init /qemu/hw/timer/digic-timer.c:142
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564
16
#6 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547
17
#7 0xaaabf5b40e84 in digic_init /qemu/hw/arm/digic.c:46
18
#8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
19
#9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
20
#10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
21
#11 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
22
#12 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-6-peter.maydell@linaro.org
7
---
28
---
8
target/arm/translate.c | 8 +++-----
29
hw/timer/digic-timer.c | 8 ++++++++
9
1 file changed, 3 insertions(+), 5 deletions(-)
30
1 file changed, 8 insertions(+)
10
31
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
32
diff --git a/hw/timer/digic-timer.c b/hw/timer/digic-timer.c
12
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
34
--- a/hw/timer/digic-timer.c
14
+++ b/target/arm/translate.c
35
+++ b/hw/timer/digic-timer.c
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
36
@@ -XXX,XX +XXX,XX @@ static void digic_timer_init(Object *obj)
16
* what we are asking here is "does the code for this case in
37
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
17
* the Neon for-each-pass loop use cpu_F0s?".
18
*/
19
- return ((op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
20
- op == NEON_2RM_VRINTM ||
21
- (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
22
+ return ((op >= NEON_2RM_VCVTAU && op <= NEON_2RM_VCVTMS) ||
23
op >= NEON_2RM_VRECPE_F);
24
}
38
}
25
39
26
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
40
+static void digic_timer_finalize(Object *obj)
27
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
41
+{
28
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
42
+ DigicTimerState *s = DIGIC_TIMER(obj);
29
cpu_env);
43
+
30
- gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
44
+ ptimer_free(s->ptimer);
31
+ gen_helper_rints(tmp, tmp, fpstatus);
45
+}
32
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
46
+
33
cpu_env);
47
static void digic_timer_class_init(ObjectClass *klass, void *class_data)
34
tcg_temp_free_ptr(fpstatus);
48
{
35
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
49
DeviceClass *dc = DEVICE_CLASS(klass);
36
case NEON_2RM_VRINTX:
50
@@ -XXX,XX +XXX,XX @@ static const TypeInfo digic_timer_info = {
37
{
51
.parent = TYPE_SYS_BUS_DEVICE,
38
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
52
.instance_size = sizeof(DigicTimerState),
39
- gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
53
.instance_init = digic_timer_init,
40
+ gen_helper_rints_exact(tmp, tmp, fpstatus);
54
+ .instance_finalize = digic_timer_finalize,
41
tcg_temp_free_ptr(fpstatus);
55
.class_init = digic_timer_class_init,
42
break;
56
};
43
}
57
44
--
58
--
45
2.20.1
59
2.20.1
46
60
47
61
diff view generated by jsdifflib
1
We want to use vfp_expand_imm() in the AArch32 VFP decode;
1
From: Gan Qixin <ganqixin@huawei.com>
2
move it from the a64-only header/source file to the
3
AArch32 one (which is always compiled even for AArch64).
4
2
3
When running device-introspect-test, a memory leak occurred in the a10_pit_init
4
function, so use ptimer_free() in the finalize function to avoid it.
5
6
ASAN shows memory leak stack:
7
8
Indirect leak of 288 byte(s) in 6 object(s) allocated from:
9
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
10
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
11
#2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523
12
#3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544
13
#4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562
14
#5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433
15
#6 0xaaabf57415e8 in a10_pit_init /qemu/hw/timer/allwinner-a10-pit.c:278
16
#7 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
17
#8 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564
18
#9 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547
19
#10 0xaaabf5b94680 in aw_a10_init /qemu/hw/arm/allwinner-a10.c:49
20
#11 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
21
#12 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
22
23
Reported-by: Euler Robot <euler.robot@huawei.com>
24
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-2-peter.maydell@linaro.org
9
---
27
---
10
target/arm/translate-a64.h | 1 -
28
hw/timer/allwinner-a10-pit.c | 11 +++++++++++
11
target/arm/translate.h | 7 +++++++
29
1 file changed, 11 insertions(+)
12
target/arm/translate-a64.c | 32 --------------------------------
13
target/arm/translate-vfp.inc.c | 33 +++++++++++++++++++++++++++++++++
14
4 files changed, 40 insertions(+), 33 deletions(-)
15
30
16
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
31
diff --git a/hw/timer/allwinner-a10-pit.c b/hw/timer/allwinner-a10-pit.c
17
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.h
33
--- a/hw/timer/allwinner-a10-pit.c
19
+++ b/target/arm/translate-a64.h
34
+++ b/hw/timer/allwinner-a10-pit.c
20
@@ -XXX,XX +XXX,XX @@ void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v);
35
@@ -XXX,XX +XXX,XX @@ static void a10_pit_init(Object *obj)
21
TCGv_ptr get_fpstatus_ptr(bool);
22
bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
23
unsigned int imms, unsigned int immr);
24
-uint64_t vfp_expand_imm(int size, uint8_t imm8);
25
bool sve_access_check(DisasContext *s);
26
27
/* We should have at some point before trying to access an FP register
28
diff --git a/target/arm/translate.h b/target/arm/translate.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate.h
31
+++ b/target/arm/translate.h
32
@@ -XXX,XX +XXX,XX @@ static inline void gen_ss_advance(DisasContext *s)
33
}
36
}
34
}
37
}
35
38
36
+/*
39
+static void a10_pit_finalize(Object *obj)
37
+ * Given a VFP floating point constant encoded into an 8 bit immediate in an
40
+{
38
+ * instruction, expand it to the actual constant value of the specified
41
+ AwA10PITState *s = AW_A10_PIT(obj);
39
+ * size, as per the VFPExpandImm() pseudocode in the Arm ARM.
42
+ int i;
40
+ */
41
+uint64_t vfp_expand_imm(int size, uint8_t imm8);
42
+
43
+
43
/* Vector operations shared between ARM and AArch64. */
44
+ for (i = 0; i < AW_A10_PIT_TIMER_NR; i++) {
44
extern const GVecGen3 mla_op[4];
45
+ ptimer_free(s->timer[i]);
45
extern const GVecGen3 mls_op[4];
46
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate-a64.c
49
+++ b/target/arm/translate-a64.c
50
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
51
}
52
}
53
54
-/* The imm8 encodes the sign bit, enough bits to represent an exponent in
55
- * the range 01....1xx to 10....0xx, and the most significant 4 bits of
56
- * the mantissa; see VFPExpandImm() in the v8 ARM ARM.
57
- */
58
-uint64_t vfp_expand_imm(int size, uint8_t imm8)
59
-{
60
- uint64_t imm;
61
-
62
- switch (size) {
63
- case MO_64:
64
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
65
- (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
66
- extract32(imm8, 0, 6);
67
- imm <<= 48;
68
- break;
69
- case MO_32:
70
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
71
- (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
72
- (extract32(imm8, 0, 6) << 3);
73
- imm <<= 16;
74
- break;
75
- case MO_16:
76
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
77
- (extract32(imm8, 6, 1) ? 0x3000 : 0x4000) |
78
- (extract32(imm8, 0, 6) << 6);
79
- break;
80
- default:
81
- g_assert_not_reached();
82
- }
83
- return imm;
84
-}
85
-
86
/* Floating point immediate
87
* 31 30 29 28 24 23 22 21 20 13 12 10 9 5 4 0
88
* +---+---+---+-----------+------+---+------------+-------+------+------+
89
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/translate-vfp.inc.c
92
+++ b/target/arm/translate-vfp.inc.c
93
@@ -XXX,XX +XXX,XX @@
94
#include "decode-vfp.inc.c"
95
#include "decode-vfp-uncond.inc.c"
96
97
+/*
98
+ * The imm8 encodes the sign bit, enough bits to represent an exponent in
99
+ * the range 01....1xx to 10....0xx, and the most significant 4 bits of
100
+ * the mantissa; see VFPExpandImm() in the v8 ARM ARM.
101
+ */
102
+uint64_t vfp_expand_imm(int size, uint8_t imm8)
103
+{
104
+ uint64_t imm;
105
+
106
+ switch (size) {
107
+ case MO_64:
108
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
109
+ (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
110
+ extract32(imm8, 0, 6);
111
+ imm <<= 48;
112
+ break;
113
+ case MO_32:
114
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
115
+ (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
116
+ (extract32(imm8, 0, 6) << 3);
117
+ imm <<= 16;
118
+ break;
119
+ case MO_16:
120
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
121
+ (extract32(imm8, 6, 1) ? 0x3000 : 0x4000) |
122
+ (extract32(imm8, 0, 6) << 6);
123
+ break;
124
+ default:
125
+ g_assert_not_reached();
126
+ }
46
+ }
127
+ return imm;
128
+}
47
+}
129
+
48
+
130
/*
49
static void a10_pit_class_init(ObjectClass *klass, void *data)
131
* Return the offset of a 16-bit half of the specified VFP single-precision
50
{
132
* register. If top is true, returns the top 16 bits; otherwise the bottom
51
DeviceClass *dc = DEVICE_CLASS(klass);
52
@@ -XXX,XX +XXX,XX @@ static const TypeInfo a10_pit_info = {
53
.parent = TYPE_SYS_BUS_DEVICE,
54
.instance_size = sizeof(AwA10PITState),
55
.instance_init = a10_pit_init,
56
+ .instance_finalize = a10_pit_finalize,
57
.class_init = a10_pit_class_init,
58
};
59
133
--
60
--
134
2.20.1
61
2.20.1
135
62
136
63
diff view generated by jsdifflib
1
Stop using cpu_F0s for the NEON_2RM_VCVT[ANPM][US] ops.
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
When running device-introspect-test, a memory leak occurred in the
4
exynos4210_rtc_init function, so use ptimer_free() in the finalize function to
5
avoid it.
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 96 byte(s) in 1 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf57b3934 in exynos4210_rtc_init /qemu/hw/rtc/exynos4210_rtc.c:567
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
16
#6 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
17
#7 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
18
#8 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
19
#9 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136
20
#10 0xaaabf6552708 in aio_bh_poll /qemu/util/async.c:164
21
#11 0xaaabf655f19c in aio_dispatch /qemu/util/aio-posix.c:381
22
#12 0xaaabf65523f4 in aio_ctx_dispatch /qemu/util/async.c:306
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-7-peter.maydell@linaro.org
7
---
28
---
8
target/arm/translate.c | 7 +++----
29
hw/rtc/exynos4210_rtc.c | 9 +++++++++
9
1 file changed, 3 insertions(+), 4 deletions(-)
30
1 file changed, 9 insertions(+)
10
31
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
32
diff --git a/hw/rtc/exynos4210_rtc.c b/hw/rtc/exynos4210_rtc.c
12
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
34
--- a/hw/rtc/exynos4210_rtc.c
14
+++ b/target/arm/translate.c
35
+++ b/hw/rtc/exynos4210_rtc.c
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
36
@@ -XXX,XX +XXX,XX @@ static void exynos4210_rtc_init(Object *obj)
16
* what we are asking here is "does the code for this case in
37
sysbus_init_mmio(dev, &s->iomem);
17
* the Neon for-each-pass loop use cpu_F0s?".
18
*/
19
- return ((op >= NEON_2RM_VCVTAU && op <= NEON_2RM_VCVTMS) ||
20
- op >= NEON_2RM_VRECPE_F);
21
+ return op >= NEON_2RM_VRECPE_F;
22
}
38
}
23
39
24
static bool neon_2rm_is_v8_op(int op)
40
+static void exynos4210_rtc_finalize(Object *obj)
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
41
+{
26
cpu_env);
42
+ Exynos4210RTCState *s = EXYNOS4210_RTC(obj);
27
43
+
28
if (is_signed) {
44
+ ptimer_free(s->ptimer);
29
- gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
45
+ ptimer_free(s->ptimer_1Hz);
30
+ gen_helper_vfp_tosls(tmp, tmp,
46
+}
31
tcg_shift, fpst);
47
+
32
} else {
48
static void exynos4210_rtc_class_init(ObjectClass *klass, void *data)
33
- gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
49
{
34
+ gen_helper_vfp_touls(tmp, tmp,
50
DeviceClass *dc = DEVICE_CLASS(klass);
35
tcg_shift, fpst);
51
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_rtc_info = {
36
}
52
.parent = TYPE_SYS_BUS_DEVICE,
53
.instance_size = sizeof(Exynos4210RTCState),
54
.instance_init = exynos4210_rtc_init,
55
+ .instance_finalize = exynos4210_rtc_finalize,
56
.class_init = exynos4210_rtc_class_init,
57
};
37
58
38
--
59
--
39
2.20.1
60
2.20.1
40
61
41
62
diff view generated by jsdifflib
1
Switch NEON_2RM_VABS_F away from using cpu_F0s.
1
From: Gan Qixin <ganqixin@huawei.com>
2
2
3
When running device-introspect-test, a memory leak occurred in the
4
exynos4210_pwm_init function, so use ptimer_free() in the finalize function to
5
avoid it.
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 240 byte(s) in 5 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523
13
#3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544
14
#4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562
15
#5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433
16
#6 0xaaabf56a36cc in exynos4210_pwm_init /qemu/hw/timer/exynos4210_pwm.c:401
17
#7 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
18
#8 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
19
#9 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
20
#10 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
21
#11 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
22
#12 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-5-peter.maydell@linaro.org
7
---
28
---
8
target/arm/translate.c | 13 ++-----------
29
hw/timer/exynos4210_pwm.c | 11 +++++++++++
9
1 file changed, 2 insertions(+), 11 deletions(-)
30
1 file changed, 11 insertions(+)
10
31
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
32
diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c
12
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
34
--- a/hw/timer/exynos4210_pwm.c
14
+++ b/target/arm/translate.c
35
+++ b/hw/timer/exynos4210_pwm.c
15
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
36
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_init(Object *obj)
16
return statusptr;
37
sysbus_init_mmio(dev, &s->iomem);
17
}
38
}
18
39
19
-static inline void gen_vfp_neg(int dp)
40
+static void exynos4210_pwm_finalize(Object *obj)
20
-{
41
+{
21
- if (dp)
42
+ Exynos4210PWMState *s = EXYNOS4210_PWM(obj);
22
- gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
43
+ int i;
23
- else
44
+
24
- gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
45
+ for (i = 0; i < EXYNOS4210_PWM_TIMERS_NUM; i++) {
25
-}
46
+ ptimer_free(s->timer[i].ptimer);
26
-
47
+ }
27
#define VFP_GEN_ITOF(name) \
48
+}
28
static inline void gen_vfp_##name(int dp, int neon) \
49
+
29
{ \
50
static void exynos4210_pwm_class_init(ObjectClass *klass, void *data)
30
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
51
{
31
* what we are asking here is "does the code for this case in
52
DeviceClass *dc = DEVICE_CLASS(klass);
32
* the Neon for-each-pass loop use cpu_F0s?".
53
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_pwm_info = {
33
*/
54
.parent = TYPE_SYS_BUS_DEVICE,
34
- return (op == NEON_2RM_VNEG_F ||
55
.instance_size = sizeof(Exynos4210PWMState),
35
- (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
56
.instance_init = exynos4210_pwm_init,
36
+ return ((op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
57
+ .instance_finalize = exynos4210_pwm_finalize,
37
op == NEON_2RM_VRINTM ||
58
.class_init = exynos4210_pwm_class_init,
38
(op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
59
};
39
op >= NEON_2RM_VRECPE_F);
60
40
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
41
gen_helper_vfp_abss(tmp, tmp);
42
break;
43
case NEON_2RM_VNEG_F:
44
- gen_vfp_neg(0);
45
+ gen_helper_vfp_negs(tmp, tmp);
46
break;
47
case NEON_2RM_VSWP:
48
tmp2 = neon_load_reg(rd, pass);
49
--
61
--
50
2.20.1
62
2.20.1
51
63
52
64
diff view generated by jsdifflib
1
Where Neon instructions are floating point operations, we
1
From: Gan Qixin <ganqixin@huawei.com>
2
mostly use the old VFP utility functions like gen_vfp_abs()
3
which work on the TCG globals cpu_F0s and cpu_F1s. The
4
Neon for-each-element loop conditionally loads the inputs
5
into either a plain old TCG temporary for most operations
6
or into cpu_F0s for float operations, and similarly stores
7
back either cpu_F0s or the temporary.
8
2
9
Switch NEON_2RM_VABS_F away from using cpu_F0s, and
3
When running device-introspect-test, a memory leak occurred in the
10
update neon_2rm_is_float_op() accordingly.
4
mss_timer_init function, so use ptimer_free() in the finalize function to avoid
5
it.
11
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 192 byte(s) in 2 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf58a0010 in mss_timer_init /qemu/hw/timer/mss-timer.c:235
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564
16
#6 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547
17
#7 0xaaabf5b8316c in m2sxxx_soc_initfn /qemu/hw/arm/msf2-soc.c:70
18
#8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
19
#9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
20
#10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
21
#11 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
22
#12 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-id: 20190613163917.28589-4-peter.maydell@linaro.org
16
---
28
---
17
target/arm/translate.c | 19 ++++++++-----------
29
hw/timer/mss-timer.c | 13 +++++++++++++
18
1 file changed, 8 insertions(+), 11 deletions(-)
30
1 file changed, 13 insertions(+)
19
31
20
diff --git a/target/arm/translate.c b/target/arm/translate.c
32
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
21
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/translate.c
34
--- a/hw/timer/mss-timer.c
23
+++ b/target/arm/translate.c
35
+++ b/hw/timer/mss-timer.c
24
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
36
@@ -XXX,XX +XXX,XX @@ static void mss_timer_init(Object *obj)
25
return statusptr;
37
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &t->mmio);
26
}
38
}
27
39
28
-static inline void gen_vfp_abs(int dp)
40
+static void mss_timer_finalize(Object *obj)
29
-{
41
+{
30
- if (dp)
42
+ MSSTimerState *t = MSS_TIMER(obj);
31
- gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
43
+ int i;
32
- else
44
+
33
- gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
45
+ for (i = 0; i < NUM_TIMERS; i++) {
34
-}
46
+ struct Msf2Timer *st = &t->timers[i];
35
-
47
+
36
static inline void gen_vfp_neg(int dp)
48
+ ptimer_free(st->ptimer);
37
{
49
+ }
38
if (dp)
50
+}
39
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_3r_sizes[] = {
51
+
40
52
static const VMStateDescription vmstate_timers = {
41
static int neon_2rm_is_float_op(int op)
53
.name = "mss-timer-block",
42
{
54
.version_id = 1,
43
- /* Return true if this neon 2reg-misc op is float-to-float */
55
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mss_timer_info = {
44
- return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
56
.parent = TYPE_SYS_BUS_DEVICE,
45
+ /*
57
.instance_size = sizeof(MSSTimerState),
46
+ * Return true if this neon 2reg-misc op is float-to-float.
58
.instance_init = mss_timer_init,
47
+ * This is not a property of the operation but of our code --
59
+ .instance_finalize = mss_timer_finalize,
48
+ * what we are asking here is "does the code for this case in
60
.class_init = mss_timer_class_init,
49
+ * the Neon for-each-pass loop use cpu_F0s?".
61
};
50
+ */
62
51
+ return (op == NEON_2RM_VNEG_F ||
52
(op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
53
op == NEON_2RM_VRINTM ||
54
(op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
55
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
56
break;
57
}
58
case NEON_2RM_VABS_F:
59
- gen_vfp_abs(0);
60
+ gen_helper_vfp_abss(tmp, tmp);
61
break;
62
case NEON_2RM_VNEG_F:
63
gen_vfp_neg(0);
64
--
63
--
65
2.20.1
64
2.20.1
66
65
67
66
diff view generated by jsdifflib
1
The SSE-200 hardware has configurable integration settings which
1
From: Gan Qixin <ganqixin@huawei.com>
2
determine whether its two CPUs have the FPU and DSP:
3
* CPU0_FPU (default 0)
4
* CPU0_DSP (default 0)
5
* CPU1_FPU (default 1)
6
* CPU1_DSP (default 1)
7
2
8
Similarly, the IoTKit has settings for its single CPU:
3
When running device-introspect-test, a memory leak occurred in the
9
* CPU0_FPU (default 1)
4
mv88w8618_pit_init function, so use ptimer_free() in the finalize function to
10
* CPU0_DSP (default 1)
5
avoid it.
11
6
12
Of our four boards that use either the IoTKit or the SSE-200:
7
ASAN shows memory leak stack:
13
* mps2-an505, mps2-an521 and musca-a use the default settings
14
* musca-b1 enables FPU and DSP on both CPUs
15
8
16
Currently QEMU models all these boards using CPUs with
9
Indirect leak of 192 byte(s) in 4 object(s) allocated from:
17
both FPU and DSP enabled. This means that we are incorrect
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
18
for mps2-an521 and musca-a, which should not have FPU or DSP
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
19
on CPU0.
12
#2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523
13
#3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544
14
#4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562
15
#5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433
16
#6 0xaaabf5bb2290 in mv88w8618_timer_init /qemu/hw/arm/musicpal.c:862
17
#7 0xaaabf5bb2290 in mv88w8618_pit_init /qemu/hw/arm/musicpal.c:954
18
#8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
19
#9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
20
#10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
21
#11 0xaaabf5a95540 in qdev_device_help /qemu/softmmu/qdev-monitor.c:283
22
#12 0xaaabf5a96940 in qmp_device_add /qemu/softmmu/qdev-monitor.c:801
20
23
21
Create QOM properties on the ARMSSE devices corresponding to the
24
Reported-by: Euler Robot <euler.robot@huawei.com>
22
default h/w integration settings, and make the Musca-B1 board
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
23
enable FPU and DSP on both CPUs. This fixes the mps2-an521
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
and musca-a behaviour, and leaves the musca-b1 and mps2-an505
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
behaviour unchanged.
28
---
29
hw/arm/musicpal.c | 12 ++++++++++++
30
1 file changed, 12 insertions(+)
26
31
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
28
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
29
Message-id: 20190517174046.11146-5-peter.maydell@linaro.org
30
---
31
include/hw/arm/armsse.h | 7 +++++
32
hw/arm/armsse.c | 58 ++++++++++++++++++++++++++++++++---------
33
hw/arm/musca.c | 8 ++++++
34
3 files changed, 61 insertions(+), 12 deletions(-)
35
36
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
37
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/arm/armsse.h
34
--- a/hw/arm/musicpal.c
39
+++ b/include/hw/arm/armsse.h
35
+++ b/hw/arm/musicpal.c
40
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@ static void mv88w8618_pit_init(Object *obj)
41
* address of each SRAM bank (and thus the total amount of internal SRAM)
37
sysbus_init_mmio(dev, &s->iomem);
42
* + QOM property "init-svtor" sets the initial value of the CPU SVTOR register
38
}
43
* (where it expects to load the PC and SP from the vector table on reset)
39
44
+ * + QOM properties "CPU0_FPU", "CPU0_DSP", "CPU1_FPU" and "CPU1_DSP" which
40
+static void mv88w8618_pit_finalize(Object *obj)
45
+ * set whether the CPUs have the FPU and DSP features present. The default
41
+{
46
+ * (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an
42
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
47
+ * SSE-200 both are present; CPU0 in an SSE-200 has neither.
43
+ mv88w8618_pit_state *s = MV88W8618_PIT(dev);
48
+ * Since the IoTKit has only one CPU, it does not have the CPU1_* properties.
44
+ int i;
49
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
50
* which are wired to its NVIC lines 32 .. n+32
51
* + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
52
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
53
uint32_t mainclk_frq;
54
uint32_t sram_addr_width;
55
uint32_t init_svtor;
56
+ bool cpu_fpu[SSE_MAX_CPUS];
57
+ bool cpu_dsp[SSE_MAX_CPUS];
58
} ARMSSE;
59
60
typedef struct ARMSSEInfo ARMSSEInfo;
61
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/armsse.c
64
+++ b/hw/arm/armsse.c
65
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
66
bool has_cachectrl;
67
bool has_cpusecctrl;
68
bool has_cpuid;
69
+ Property *props;
70
+};
71
+
45
+
72
+static Property iotkit_properties[] = {
46
+ for (i = 0; i < 4; i++) {
73
+ DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
47
+ ptimer_free(s->timer[i].ptimer);
74
+ MemoryRegion *),
48
+ }
75
+ DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
49
+}
76
+ DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
77
+ DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
78
+ DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
79
+ DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
80
+ DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
81
+ DEFINE_PROP_END_OF_LIST()
82
+};
83
+
50
+
84
+static Property armsse_properties[] = {
51
static const VMStateDescription mv88w8618_timer_vmsd = {
85
+ DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
52
.name = "timer",
86
+ MemoryRegion *),
53
.version_id = 1,
87
+ DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mv88w8618_pit_info = {
88
+ DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
55
.parent = TYPE_SYS_BUS_DEVICE,
89
+ DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
56
.instance_size = sizeof(mv88w8618_pit_state),
90
+ DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
57
.instance_init = mv88w8618_pit_init,
91
+ DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
58
+ .instance_finalize = mv88w8618_pit_finalize,
92
+ DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
59
.class_init = mv88w8618_pit_class_init,
93
+ DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
94
+ DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
95
+ DEFINE_PROP_END_OF_LIST()
96
};
60
};
97
98
static const ARMSSEInfo armsse_variants[] = {
99
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
100
.has_cachectrl = false,
101
.has_cpusecctrl = false,
102
.has_cpuid = false,
103
+ .props = iotkit_properties,
104
},
105
{
106
.name = TYPE_SSE200,
107
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
108
.has_cachectrl = true,
109
.has_cpusecctrl = true,
110
.has_cpuid = true,
111
+ .props = armsse_properties,
112
},
113
};
114
115
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
116
return;
117
}
118
}
119
+ if (!s->cpu_fpu[i]) {
120
+ object_property_set_bool(cpuobj, false, "vfp", &err);
121
+ if (err) {
122
+ error_propagate(errp, err);
123
+ return;
124
+ }
125
+ }
126
+ if (!s->cpu_dsp[i]) {
127
+ object_property_set_bool(cpuobj, false, "dsp", &err);
128
+ if (err) {
129
+ error_propagate(errp, err);
130
+ return;
131
+ }
132
+ }
133
134
if (i > 0) {
135
memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
136
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription armsse_vmstate = {
137
}
138
};
139
140
-static Property armsse_properties[] = {
141
- DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
142
- MemoryRegion *),
143
- DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
144
- DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
145
- DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
146
- DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
147
- DEFINE_PROP_END_OF_LIST()
148
-};
149
-
150
static void armsse_reset(DeviceState *dev)
151
{
152
ARMSSE *s = ARMSSE(dev);
153
@@ -XXX,XX +XXX,XX @@ static void armsse_class_init(ObjectClass *klass, void *data)
154
DeviceClass *dc = DEVICE_CLASS(klass);
155
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
156
ARMSSEClass *asc = ARMSSE_CLASS(klass);
157
+ const ARMSSEInfo *info = data;
158
159
dc->realize = armsse_realize;
160
dc->vmsd = &armsse_vmstate;
161
- dc->props = armsse_properties;
162
+ dc->props = info->props;
163
dc->reset = armsse_reset;
164
iic->check = armsse_idau_check;
165
- asc->info = data;
166
+ asc->info = info;
167
}
168
169
static const TypeInfo armsse_info = {
170
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/hw/arm/musca.c
173
+++ b/hw/arm/musca.c
174
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
175
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
176
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
177
qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
178
+ /*
179
+ * Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
180
+ * CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
181
+ */
182
+ if (mmc->type == MUSCA_B1) {
183
+ qdev_prop_set_bit(ssedev, "CPU0_FPU", true);
184
+ qdev_prop_set_bit(ssedev, "CPU0_DSP", true);
185
+ }
186
object_property_set_bool(OBJECT(&mms->sse), true, "realized",
187
&error_fatal);
188
61
189
--
62
--
190
2.20.1
63
2.20.1
191
64
192
65
diff view generated by jsdifflib
1
Create "vfp" and "dsp" properties on the armv7m container object
1
From: Gan Qixin <ganqixin@huawei.com>
2
which will be forwarded to its CPU object, so that SoCs can
3
configure whether the CPU has these features.
4
2
3
When running device-introspect-test, a memory leak occurred in the
4
exynos4210_mct_init function, so use ptimer_free() in the finalize function to
5
avoid it.
6
7
ASAN shows memory leak stack:
8
9
Indirect leak of 96 byte(s) in 1 object(s) allocated from:
10
#0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0)
11
#1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800)
12
#2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432
13
#3 0xaaabf56b01a0 in exynos4210_mct_init /qemu/hw/timer/exynos4210_mct.c:1505
14
#4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515
15
#5 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729
16
#6 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153
17
#7 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59
18
#8 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110
19
#9 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136
20
#10 0xaaabf6552708 in aio_bh_poll /qemu/util/async.c:164
21
#11 0xaaabf655f19c in aio_dispatch /qemu/util/aio-posix.c:381
22
#12 0xaaabf65523f4 in aio_ctx_dispatch /qemu/util/async.c:306
23
24
Reported-by: Euler Robot <euler.robot@huawei.com>
25
Signed-off-by: Gan Qixin <ganqixin@huawei.com>
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20190517174046.11146-4-peter.maydell@linaro.org
9
---
28
---
10
include/hw/arm/armv7m.h | 4 ++++
29
hw/timer/exynos4210_mct.c | 14 ++++++++++++++
11
hw/arm/armv7m.c | 18 ++++++++++++++++++
30
1 file changed, 14 insertions(+)
12
2 files changed, 22 insertions(+)
13
31
14
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
32
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
15
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/armv7m.h
34
--- a/hw/timer/exynos4210_mct.c
17
+++ b/include/hw/arm/armv7m.h
35
+++ b/hw/timer/exynos4210_mct.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct {
36
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_init(Object *obj)
19
* devices will be automatically layered on top of this view.)
37
sysbus_init_mmio(dev, &s->iomem);
20
* + Property "idau": IDAU interface (forwarded to CPU object)
38
}
21
* + Property "init-svtor": secure VTOR reset value (forwarded to CPU object)
39
22
+ * + Property "vfp": enable VFP (forwarded to CPU object)
40
+static void exynos4210_mct_finalize(Object *obj)
23
+ * + Property "dsp": enable DSP (forwarded to CPU object)
41
+{
24
* + Property "enable-bitband": expose bitbanded IO
42
+ int i;
25
*/
43
+ Exynos4210MCTState *s = EXYNOS4210_MCT(obj);
26
typedef struct ARMv7MState {
44
+
27
@@ -XXX,XX +XXX,XX @@ typedef struct ARMv7MState {
45
+ ptimer_free(s->g_timer.ptimer_frc);
28
uint32_t init_svtor;
46
+
29
bool enable_bitband;
47
+ for (i = 0; i < 2; i++) {
30
bool start_powered_off;
48
+ ptimer_free(s->l_timer[i].tick_timer.ptimer_tick);
31
+ bool vfp;
49
+ ptimer_free(s->l_timer[i].ptimer_frc);
32
+ bool dsp;
33
} ARMv7MState;
34
35
#endif
36
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/armv7m.c
39
+++ b/hw/arm/armv7m.c
40
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
41
return;
42
}
43
}
44
+ if (object_property_find(OBJECT(s->cpu), "vfp", NULL)) {
45
+ object_property_set_bool(OBJECT(s->cpu), s->vfp,
46
+ "vfp", &err);
47
+ if (err != NULL) {
48
+ error_propagate(errp, err);
49
+ return;
50
+ }
51
+ }
50
+ }
52
+ if (object_property_find(OBJECT(s->cpu), "dsp", NULL)) {
51
+}
53
+ object_property_set_bool(OBJECT(s->cpu), s->dsp,
52
+
54
+ "dsp", &err);
53
static void exynos4210_mct_class_init(ObjectClass *klass, void *data)
55
+ if (err != NULL) {
54
{
56
+ error_propagate(errp, err);
55
DeviceClass *dc = DEVICE_CLASS(klass);
57
+ return;
56
@@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_mct_info = {
58
+ }
57
.parent = TYPE_SYS_BUS_DEVICE,
59
+ }
58
.instance_size = sizeof(Exynos4210MCTState),
60
59
.instance_init = exynos4210_mct_init,
61
/*
60
+ .instance_finalize = exynos4210_mct_finalize,
62
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
61
.class_init = exynos4210_mct_class_init,
63
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
64
DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
65
DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
66
false),
67
+ DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
68
+ DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
69
DEFINE_PROP_END_OF_LIST(),
70
};
62
};
71
63
72
--
64
--
73
2.20.1
65
2.20.1
74
66
75
67
diff view generated by jsdifflib
1
We currently put the initrd at the smaller of:
1
From: Bin Meng <bin.meng@windriver.com>
2
* 128MB into RAM
3
* halfway into the RAM
4
(with the dtb following it).
5
2
6
However for large kernels this might mean that the kernel
3
U-Boot expects PMU_MISC0 register bit 7 is set (see init_bandgap()
7
overlaps the initrd. For some kinds of kernel (self-decompressing
4
in arch/arm/mach-imx/mx6/soc.c) during boot. This bit indicates the
8
32-bit kernels, and ELF images with a BSS section at the end)
5
bandgap has stabilized.
9
we don't know the exact size, but even there we have a
10
minimum size. Put the initrd at least further into RAM than
11
that. For image formats that can give us an exact kernel size, this
12
will mean that we definitely avoid overlaying kernel and initrd.
13
6
7
With this change, the latest upstream U-Boot (v2021.01-rc3) for imx6
8
sabrelite board (mx6qsabrelite_defconfig), with a slight change made
9
by switching CONFIG_OF_SEPARATE to CONFIG_OF_EMBED, boots to U-Boot
10
shell on QEMU with the following command:
11
12
$ qemu-system-arm -M sabrelite -smp 4 -m 1G -kernel u-boot \
13
-display none -serial null -serial stdio
14
15
Boot log below:
16
17
U-Boot 2021.01-rc3 (Dec 12 2020 - 17:40:02 +0800)
18
19
CPU: Freescale i.MX?? rev1.0 at 792 MHz
20
Reset cause: POR
21
Model: Freescale i.MX6 Quad SABRE Lite Board
22
Board: SABRE Lite
23
I2C: ready
24
DRAM: 1 GiB
25
force_idle_bus: sda=0 scl=0 sda.gp=0x5c scl.gp=0x55
26
force_idle_bus: failed to clear bus, sda=0 scl=0
27
force_idle_bus: sda=0 scl=0 sda.gp=0x6d scl.gp=0x6c
28
force_idle_bus: failed to clear bus, sda=0 scl=0
29
force_idle_bus: sda=0 scl=0 sda.gp=0xcb scl.gp=0x5
30
force_idle_bus: failed to clear bus, sda=0 scl=0
31
MMC: FSL_SDHC: 0, FSL_SDHC: 1
32
Loading Environment from MMC... *** Warning - No block device, using default environment
33
34
In: serial
35
Out: serial
36
Err: serial
37
Net: Board Net Initialization Failed
38
No ethernet found.
39
starting USB...
40
Bus usb@2184000: usb dr_mode not found
41
USB EHCI 1.00
42
Bus usb@2184200: USB EHCI 1.00
43
scanning bus usb@2184000 for devices... 1 USB Device(s) found
44
scanning bus usb@2184200 for devices... 1 USB Device(s) found
45
scanning usb for storage devices... 0 Storage Device(s) found
46
scanning usb for ethernet devices... 0 Ethernet Device(s) found
47
Hit any key to stop autoboot: 0
48
=>
49
50
Signed-off-by: Bin Meng <bin.meng@windriver.com>
51
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
52
Message-id: 20210106063504.10841-2-bmeng.cn@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
53
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
Tested-by: Mark Rutland <mark.rutland@arm.com>
17
Message-id: 20190516144733.32399-4-peter.maydell@linaro.org
18
---
54
---
19
hw/arm/boot.c | 34 ++++++++++++++++++++--------------
55
hw/misc/imx6_ccm.c | 2 +-
20
1 file changed, 20 insertions(+), 14 deletions(-)
56
1 file changed, 1 insertion(+), 1 deletion(-)
21
57
22
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
58
diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
23
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/boot.c
60
--- a/hw/misc/imx6_ccm.c
25
+++ b/hw/arm/boot.c
61
+++ b/hw/misc/imx6_ccm.c
26
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
62
@@ -XXX,XX +XXX,XX @@ static void imx6_ccm_reset(DeviceState *dev)
27
if (info->nb_cpus == 0)
63
s->analog[PMU_REG_3P0] = 0x00000F74;
28
info->nb_cpus = 1;
64
s->analog[PMU_REG_2P5] = 0x00005071;
29
65
s->analog[PMU_REG_CORE] = 0x00402010;
30
- /*
66
- s->analog[PMU_MISC0] = 0x04000000;
31
- * We want to put the initrd far enough into RAM that when the
67
+ s->analog[PMU_MISC0] = 0x04000080;
32
- * kernel is uncompressed it will not clobber the initrd. However
68
s->analog[PMU_MISC1] = 0x00000000;
33
- * on boards without much RAM we must ensure that we still leave
69
s->analog[PMU_MISC2] = 0x00272727;
34
- * enough room for a decent sized initrd, and on boards with large
35
- * amounts of RAM we must avoid the initrd being so far up in RAM
36
- * that it is outside lowmem and inaccessible to the kernel.
37
- * So for boards with less than 256MB of RAM we put the initrd
38
- * halfway into RAM, and for boards with 256MB of RAM or more we put
39
- * the initrd at 128MB.
40
- */
41
- info->initrd_start = info->loader_start +
42
- MIN(info->ram_size / 2, 128 * 1024 * 1024);
43
-
44
/* Assume that raw images are linux kernels, and ELF images are not. */
45
kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
46
&elf_high_addr, elf_machine, as);
47
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
48
}
49
50
info->entry = entry;
51
+
52
+ /*
53
+ * We want to put the initrd far enough into RAM that when the
54
+ * kernel is uncompressed it will not clobber the initrd. However
55
+ * on boards without much RAM we must ensure that we still leave
56
+ * enough room for a decent sized initrd, and on boards with large
57
+ * amounts of RAM we must avoid the initrd being so far up in RAM
58
+ * that it is outside lowmem and inaccessible to the kernel.
59
+ * So for boards with less than 256MB of RAM we put the initrd
60
+ * halfway into RAM, and for boards with 256MB of RAM or more we put
61
+ * the initrd at 128MB.
62
+ * We also refuse to put the initrd somewhere that will definitely
63
+ * overlay the kernel we just loaded, though for kernel formats which
64
+ * don't tell us their exact size (eg self-decompressing 32-bit kernels)
65
+ * we might still make a bad choice here.
66
+ */
67
+ info->initrd_start = info->loader_start +
68
+ MAX(MIN(info->ram_size / 2, 128 * 1024 * 1024), kernel_size);
69
+ info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start);
70
+
71
if (is_linux) {
72
uint32_t fixupcontext[FIXUP_MAX];
73
70
74
--
71
--
75
2.20.1
72
2.20.1
76
73
77
74
diff view generated by jsdifflib
1
The AArch32 VMOV (immediate) instruction uses the same VFP encoded
1
From: Bin Meng <bin.meng@windriver.com>
2
immediate format we already handle in vfp_expand_imm(). Use that
3
function rather than hand-decoding it.
4
2
5
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
3
Currently when U-Boot boots, it prints "??" for i.MX processor:
4
5
CPU: Freescale i.MX?? rev1.0 at 792 MHz
6
7
The register that was used to determine the silicon type is
8
undocumented in the latest IMX6DQRM (Rev. 6, 05/2020), but we
9
can refer to get_cpu_rev() in arch/arm/mach-imx/mx6/soc.c in
10
the U-Boot source codes that USB_ANALOG_DIGPROG is used.
11
12
Update its reset value to indicate i.MX6Q.
13
14
Signed-off-by: Bin Meng <bin.meng@windriver.com>
15
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
Message-id: 20210106063504.10841-3-bmeng.cn@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190613163917.28589-3-peter.maydell@linaro.org
10
---
18
---
11
target/arm/translate-vfp.inc.c | 28 ++++------------------------
19
hw/misc/imx6_ccm.c | 2 +-
12
target/arm/vfp.decode | 10 ++++++----
20
1 file changed, 1 insertion(+), 1 deletion(-)
13
2 files changed, 10 insertions(+), 28 deletions(-)
14
21
15
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
22
diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-vfp.inc.c
24
--- a/hw/misc/imx6_ccm.c
18
+++ b/target/arm/translate-vfp.inc.c
25
+++ b/hw/misc/imx6_ccm.c
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
26
@@ -XXX,XX +XXX,XX @@ static void imx6_ccm_reset(DeviceState *dev)
20
uint32_t delta_d = 0;
27
s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x00000004;
21
int veclen = s->vec_len;
28
s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000;
22
TCGv_i32 fd;
29
s->analog[USB_ANALOG_USB2_MISC] = 0x00000002;
23
- uint32_t n, i, vd;
30
- s->analog[USB_ANALOG_DIGPROG] = 0x00000000;
24
+ uint32_t vd;
31
+ s->analog[USB_ANALOG_DIGPROG] = 0x00630000;
25
32
26
vd = a->vd;
33
/* all PLLs need to be locked */
27
34
s->analog[CCM_ANALOG_PLL_ARM] |= CCM_ANALOG_PLL_LOCK;
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
29
}
30
}
31
32
- n = (a->imm4h << 28) & 0x80000000;
33
- i = ((a->imm4h << 4) & 0x70) | a->imm4l;
34
- if (i & 0x40) {
35
- i |= 0x780;
36
- } else {
37
- i |= 0x800;
38
- }
39
- n |= i << 19;
40
-
41
- fd = tcg_temp_new_i32();
42
- tcg_gen_movi_i32(fd, n);
43
+ fd = tcg_const_i32(vfp_expand_imm(MO_32, a->imm));
44
45
for (;;) {
46
neon_store_reg32(fd, vd);
47
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
48
uint32_t delta_d = 0;
49
int veclen = s->vec_len;
50
TCGv_i64 fd;
51
- uint32_t n, i, vd;
52
+ uint32_t vd;
53
54
vd = a->vd;
55
56
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
57
}
58
}
59
60
- n = (a->imm4h << 28) & 0x80000000;
61
- i = ((a->imm4h << 4) & 0x70) | a->imm4l;
62
- if (i & 0x40) {
63
- i |= 0x3f80;
64
- } else {
65
- i |= 0x4000;
66
- }
67
- n |= i << 16;
68
-
69
- fd = tcg_temp_new_i64();
70
- tcg_gen_movi_i64(fd, ((uint64_t)n) << 32);
71
+ fd = tcg_const_i64(vfp_expand_imm(MO_64, a->imm));
72
73
for (;;) {
74
neon_store_reg64(fd, vd);
75
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/vfp.decode
78
+++ b/target/arm/vfp.decode
79
@@ -XXX,XX +XXX,XX @@
80
%vmov_idx_b 21:1 5:2
81
%vmov_idx_h 21:1 6:1
82
83
+%vmov_imm 16:4 0:4
84
+
85
# VMOV scalar to general-purpose register; note that this does
86
# include some Neon cases.
87
VMOV_to_gp ---- 1110 u:1 1. 1 .... rt:4 1011 ... 1 0000 \
88
@@ -XXX,XX +XXX,XX @@ VFM_sp ---- 1110 1.10 .... .... 1010 . o2:1 . 0 .... \
89
VFM_dp ---- 1110 1.10 .... .... 1011 . o2:1 . 0 .... \
90
vm=%vm_dp vn=%vn_dp vd=%vd_dp o1=2
91
92
-VMOV_imm_sp ---- 1110 1.11 imm4h:4 .... 1010 0000 imm4l:4 \
93
- vd=%vd_sp
94
-VMOV_imm_dp ---- 1110 1.11 imm4h:4 .... 1011 0000 imm4l:4 \
95
- vd=%vd_dp
96
+VMOV_imm_sp ---- 1110 1.11 .... .... 1010 0000 .... \
97
+ vd=%vd_sp imm=%vmov_imm
98
+VMOV_imm_dp ---- 1110 1.11 .... .... 1011 0000 .... \
99
+ vd=%vd_dp imm=%vmov_imm
100
101
VMOV_reg_sp ---- 1110 1.11 0000 .... 1010 01.0 .... \
102
vd=%vd_sp vm=%vm_sp
103
--
35
--
104
2.20.1
36
2.20.1
105
37
106
38
diff view generated by jsdifflib
1
Since Linux v3.17, the kernel's Image header includes a field image_size,
1
From: Bin Meng <bin.meng@windriver.com>
2
which gives the total size of the kernel including unpopulated data
3
sections such as the BSS). If this is present, then return it from
4
load_aarch64_image() as the true size of the kernel rather than
5
just using the size of the Image file itself. This allows the code
6
which calculates where to put the initrd to avoid putting it in
7
the kernel's BSS area.
8
2
9
This means that we should be able to reliably load kernel images
3
At present, when booting U-Boot on QEMU sabrelite, we see:
10
which are larger than 128MB without accidentally putting the
11
initrd or dtb in locations that clash with the kernel itself.
12
4
13
Fixes: https://bugs.launchpad.net/qemu/+bug/1823998
5
Net: Board Net Initialization Failed
6
No ethernet found.
7
8
U-Boot scans PHY at address 4/5/6/7 (see board_eth_init() in the
9
U-Boot source: board/boundary/nitrogen6x/nitrogen6x.c). On the real
10
board, the Ethernet PHY is at address 6. Adjust this by updating the
11
"fec-phy-num" property of the fsl_imx6 SoC object.
12
13
With this change, U-Boot sees the PHY but complains MAC address:
14
15
Net: using phy at 6
16
FEC [PRIME]
17
Error: FEC address not set.
18
19
This is due to U-Boot tries to read the MAC address from the fuse,
20
which QEMU does not have any valid content filled in. However this
21
does not prevent the Ethernet from working in QEMU. We just need to
22
set up the MAC address later in the U-Boot command shell, by:
23
24
=> setenv ethaddr 00:11:22:33:44:55
25
26
Signed-off-by: Bin Meng <bin.meng@windriver.com>
27
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
28
Message-id: 20210106063504.10841-4-bmeng.cn@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Tested-by: Mark Rutland <mark.rutland@arm.com>
18
Message-id: 20190516144733.32399-5-peter.maydell@linaro.org
19
---
30
---
20
hw/arm/boot.c | 17 +++++++++++++++--
31
hw/arm/sabrelite.c | 4 ++++
21
1 file changed, 15 insertions(+), 2 deletions(-)
32
1 file changed, 4 insertions(+)
22
33
23
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
34
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
24
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/boot.c
36
--- a/hw/arm/sabrelite.c
26
+++ b/hw/arm/boot.c
37
+++ b/hw/arm/sabrelite.c
27
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
38
@@ -XXX,XX +XXX,XX @@ static void sabrelite_init(MachineState *machine)
28
hwaddr *entry, AddressSpace *as)
39
29
{
40
s = FSL_IMX6(object_new(TYPE_FSL_IMX6));
30
hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
41
object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
31
+ uint64_t kernel_size = 0;
32
uint8_t *buffer;
33
int size;
34
35
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
36
* is only valid if the image_size is non-zero.
37
*/
38
memcpy(&hdrvals, buffer + ARM64_TEXT_OFFSET_OFFSET, sizeof(hdrvals));
39
- if (hdrvals[1] != 0) {
40
+
42
+
41
+ kernel_size = le64_to_cpu(hdrvals[1]);
43
+ /* Ethernet PHY address is 6 */
44
+ object_property_set_int(OBJECT(s), "fec-phy-num", 6, &error_fatal);
42
+
45
+
43
+ if (kernel_size != 0) {
46
qdev_realize(DEVICE(s), NULL, &error_fatal);
44
kernel_load_offset = le64_to_cpu(hdrvals[0]);
47
45
48
memory_region_add_subregion(get_system_memory(), FSL_IMX6_MMDC_ADDR,
46
/*
47
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
48
}
49
}
50
51
+ /*
52
+ * Kernels before v3.17 don't populate the image_size field, and
53
+ * raw images have no header. For those our best guess at the size
54
+ * is the size of the Image file itself.
55
+ */
56
+ if (kernel_size == 0) {
57
+ kernel_size = size;
58
+ }
59
+
60
*entry = mem_base + kernel_load_offset;
61
rom_add_blob_fixed_as(filename, buffer, size, *entry, as);
62
63
g_free(buffer);
64
65
- return size;
66
+ return kernel_size;
67
}
68
69
static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
70
--
49
--
71
2.20.1
50
2.20.1
72
51
73
52
diff view generated by jsdifflib
1
We calculate the locations in memory where we want to put the
1
From: Bin Meng <bin.meng@windriver.com>
2
initrd and the DTB based on the size of the kernel, since they
3
come after it. Add some explicit checks that these aren't off the
4
end of RAM entirely.
5
2
6
(At the moment the way we calculate the initrd_start means that
3
This adds the target guide for SABRE Lite board, and documents how
7
it can't ever be off the end of RAM, but that will change with
4
to boot a Linux kernel and U-Boot bootloader.
8
the next commit.)
9
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20210106063504.10841-5-bmeng.cn@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Tested-by: Mark Rutland <mark.rutland@arm.com>
13
Message-id: 20190516144733.32399-3-peter.maydell@linaro.org
14
---
10
---
15
hw/arm/boot.c | 23 +++++++++++++++++++++++
11
docs/system/arm/sabrelite.rst | 119 ++++++++++++++++++++++++++++++++++
16
1 file changed, 23 insertions(+)
12
docs/system/target-arm.rst | 1 +
13
2 files changed, 120 insertions(+)
14
create mode 100644 docs/system/arm/sabrelite.rst
17
15
18
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
16
diff --git a/docs/system/arm/sabrelite.rst b/docs/system/arm/sabrelite.rst
17
new file mode 100644
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
20
+++ b/docs/system/arm/sabrelite.rst
21
@@ -XXX,XX +XXX,XX @@
22
+Boundary Devices SABRE Lite (``sabrelite``)
23
+===========================================
24
+
25
+Boundary Devices SABRE Lite i.MX6 Development Board is a low-cost development
26
+platform featuring the powerful Freescale / NXP Semiconductor's i.MX 6 Quad
27
+Applications Processor.
28
+
29
+Supported devices
30
+-----------------
31
+
32
+The SABRE Lite machine supports the following devices:
33
+
34
+ * Up to 4 Cortex A9 cores
35
+ * Generic Interrupt Controller
36
+ * 1 Clock Controller Module
37
+ * 1 System Reset Controller
38
+ * 5 UARTs
39
+ * 2 EPIC timers
40
+ * 1 GPT timer
41
+ * 2 Watchdog timers
42
+ * 1 FEC Ethernet controller
43
+ * 3 I2C controllers
44
+ * 7 GPIO controllers
45
+ * 4 SDHC storage controllers
46
+ * 4 USB 2.0 host controllers
47
+ * 5 ECSPI controllers
48
+ * 1 SST 25VF016B flash
49
+
50
+Please note above list is a complete superset the QEMU SABRE Lite machine can
51
+support. For a normal use case, a device tree blob that represents a real world
52
+SABRE Lite board, only exposes a subset of devices to the guest software.
53
+
54
+Boot options
55
+------------
56
+
57
+The SABRE Lite machine can start using the standard -kernel functionality
58
+for loading a Linux kernel, U-Boot bootloader or ELF executable.
59
+
60
+Running Linux kernel
61
+--------------------
62
+
63
+Linux mainline v5.10 release is tested at the time of writing. To build a Linux
64
+mainline kernel that can be booted by the SABRE Lite machine, simply configure
65
+the kernel using the imx_v6_v7_defconfig configuration:
66
+
67
+.. code-block:: bash
68
+
69
+ $ export ARCH=arm
70
+ $ export CROSS_COMPILE=arm-linux-gnueabihf-
71
+ $ make imx_v6_v7_defconfig
72
+ $ make
73
+
74
+To boot the newly built Linux kernel in QEMU with the SABRE Lite machine, use:
75
+
76
+.. code-block:: bash
77
+
78
+ $ qemu-system-arm -M sabrelite -smp 4 -m 1G \
79
+ -display none -serial null -serial stdio \
80
+ -kernel arch/arm/boot/zImage \
81
+ -dtb arch/arm/boot/dts/imx6q-sabrelite.dtb \
82
+ -initrd /path/to/rootfs.ext4 \
83
+ -append "root=/dev/ram"
84
+
85
+Running U-Boot
86
+--------------
87
+
88
+U-Boot mainline v2020.10 release is tested at the time of writing. To build a
89
+U-Boot mainline bootloader that can be booted by the SABRE Lite machine, use
90
+the mx6qsabrelite_defconfig with similar commands as described above for Linux:
91
+
92
+.. code-block:: bash
93
+
94
+ $ export CROSS_COMPILE=arm-linux-gnueabihf-
95
+ $ make mx6qsabrelite_defconfig
96
+
97
+Note we need to adjust settings by:
98
+
99
+.. code-block:: bash
100
+
101
+ $ make menuconfig
102
+
103
+then manually select the following configuration in U-Boot:
104
+
105
+ Device Tree Control > Provider of DTB for DT Control > Embedded DTB
106
+
107
+To start U-Boot using the SABRE Lite machine, provide the u-boot binary to
108
+the -kernel argument, along with an SD card image with rootfs:
109
+
110
+.. code-block:: bash
111
+
112
+ $ qemu-system-arm -M sabrelite -smp 4 -m 1G \
113
+ -display none -serial null -serial stdio \
114
+ -kernel u-boot
115
+
116
+The following example shows booting Linux kernel from dhcp, and uses the
117
+rootfs on an SD card. This requires some additional command line parameters
118
+for QEMU:
119
+
120
+.. code-block:: none
121
+
122
+ -nic user,tftp=/path/to/kernel/zImage \
123
+ -drive file=sdcard.img,id=rootfs -device sd-card,drive=rootfs
124
+
125
+The directory for the built-in TFTP server should also contain the device tree
126
+blob of the SABRE Lite board. The sample SD card image was populated with the
127
+root file system with one single partition. You may adjust the kernel "root="
128
+boot parameter accordingly.
129
+
130
+After U-Boot boots, type the following commands in the U-Boot command shell to
131
+boot the Linux kernel:
132
+
133
+.. code-block:: none
134
+
135
+ => setenv ethaddr 00:11:22:33:44:55
136
+ => setenv bootfile zImage
137
+ => dhcp
138
+ => tftpboot 14000000 imx6q-sabrelite.dtb
139
+ => setenv bootargs root=/dev/mmcblk3p1
140
+ => bootz 12000000 - 14000000
141
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
19
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/boot.c
143
--- a/docs/system/target-arm.rst
21
+++ b/hw/arm/boot.c
144
+++ b/docs/system/target-arm.rst
22
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
145
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
23
error_report("could not load kernel '%s'", info->kernel_filename);
146
arm/versatile
24
exit(1);
147
arm/vexpress
25
}
148
arm/aspeed
26
+
149
+ arm/sabrelite
27
+ if (kernel_size > info->ram_size) {
150
arm/digic
28
+ error_report("kernel '%s' is too large to fit in RAM "
151
arm/musicpal
29
+ "(kernel size %d, RAM size %" PRId64 ")",
152
arm/gumstix
30
+ info->kernel_filename, kernel_size, info->ram_size);
31
+ exit(1);
32
+ }
33
+
34
info->entry = entry;
35
if (is_linux) {
36
uint32_t fixupcontext[FIXUP_MAX];
37
38
if (info->initrd_filename) {
39
+
40
+ if (info->initrd_start >= ram_end) {
41
+ error_report("not enough space after kernel to load initrd");
42
+ exit(1);
43
+ }
44
+
45
initrd_size = load_ramdisk_as(info->initrd_filename,
46
info->initrd_start,
47
ram_end - info->initrd_start, as);
48
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
49
info->initrd_filename);
50
exit(1);
51
}
52
+ if (info->initrd_start + initrd_size > info->ram_size) {
53
+ error_report("could not load initrd '%s': "
54
+ "too big to fit into RAM after the kernel",
55
+ info->initrd_filename);
56
+ }
57
} else {
58
initrd_size = 0;
59
}
60
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
61
/* Place the DTB after the initrd in memory with alignment. */
62
info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
63
align);
64
+ if (info->dtb_start >= ram_end) {
65
+ error_report("Not enough space for DTB after kernel/initrd");
66
+ exit(1);
67
+ }
68
fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
69
fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
70
} else {
71
--
153
--
72
2.20.1
154
2.20.1
73
155
74
156
diff view generated by jsdifflib