1
More arm patches (mostly the SDHCI ones from Philippe)
1
Small pile of bug fixes for rc1. I've included my patches to get
2
our docs building with Sphinx 3, just for convenience...
2
3
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit f521eeee3bd060b460c99e605472b7e03967db43:
6
The following changes since commit b149dea55cce97cb226683d06af61984a1c11e96:
7
7
8
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20180115' into staging (2018-01-15 13:17:47 +0000)
8
Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20201102' into staging (2020-11-02 10:57:48 +0000)
9
9
10
are available in the git repository at:
10
are available in the Git repository at:
11
11
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180116
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201102
13
13
14
for you to fetch changes up to 60765b6ceeb4998a0d4220b3a53f1f185061da77:
14
for you to fetch changes up to ffb4fbf90a2f63c9cb33e4bb9f854c79bf04ca4a:
15
15
16
sdhci: add a 'dma' property to the sysbus devices (2018-01-16 13:28:21 +0000)
16
tests/qtest/npcm7xx_rng-test: Disable randomness tests (2020-11-02 16:52:18 +0000)
17
17
18
----------------------------------------------------------------
18
----------------------------------------------------------------
19
target-arm queue:
19
target-arm queue:
20
* SDHCI: cleanups and minor bug fixes
20
* target/arm: Fix Neon emulation bugs on big-endian hosts
21
* target/arm: minor refactor preparatory to fp16 support
21
* target/arm: fix handling of HCR.FB
22
* omap_ssd, ssi-sd, pl181, milkymist-memcard: reset the SD
22
* target/arm: fix LORID_EL1 access check
23
card on controller reset (fixes migration failures)
23
* disas/capstone: Fix monitor disassembly of >32 bytes
24
* target/arm: Handle page table walk load failures correctly
24
* hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
25
* hw/arm/virt: Add virt-2.12 machine type
25
* hw/arm/boot: fix SVE for EL3 direct kernel boot
26
* get_phys_addr_pmsav7: Support AP=0b111 for v7M
26
* hw/display/omap_lcdc: Fix potential NULL pointer dereference
27
* hw/intc/armv7m: Support byte and halfword accesses to CFSR
27
* hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
28
* target/arm: Get correct MMU index for other-security-state
29
* configure: Test that gio libs from pkg-config work
30
* hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
31
* docs: Fix building with Sphinx 3
32
* tests/qtest/npcm7xx_rng-test: Disable randomness tests
28
33
29
----------------------------------------------------------------
34
----------------------------------------------------------------
30
Andrey Smirnov (1):
35
AlexChen (2):
31
sdhci: Implement write method of ACMD12ERRSTS register
36
hw/display/omap_lcdc: Fix potential NULL pointer dereference
37
hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
32
38
33
Peter Maydell (8):
39
Peter Maydell (9):
34
hw/intc/armv7m: Support byte and halfword accesses to CFSR
40
target/arm: Fix float16 pairwise Neon ops on big-endian hosts
35
get_phys_addr_pmsav7: Support AP=0b111 for v7M
41
target/arm: Fix VUDOT/VSDOT (scalar) on big-endian hosts
36
hw/arm/virt: Add virt-2.12 machine type
42
disas/capstone: Fix monitor disassembly of >32 bytes
37
target/arm: Handle page table walk load failures correctly
43
target/arm: Get correct MMU index for other-security-state
38
hw/sd/pl181: Reset SD card on controller reset
44
configure: Test that gio libs from pkg-config work
39
hw/sd/milkymist-memcard: Reset SD card on controller reset
45
hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
40
hw/sd/ssi-sd: Reset SD card on controller reset
46
scripts/kerneldoc: For Sphinx 3 use c:macro for macros with arguments
41
hw/sd/omap_mmc: Reset SD card on controller reset
47
qemu-option-trace.rst.inc: Don't use option:: markup
48
tests/qtest/npcm7xx_rng-test: Disable randomness tests
42
49
43
Philippe Mathieu-Daudé (13):
50
Philippe Mathieu-Daudé (1):
44
sdhci: clean up includes
51
hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
45
sdhci: remove dead code
46
sdhci: use DEFINE_SDHCI_COMMON_PROPERTIES() for common sysbus/pci properties
47
sdhci: refactor common sysbus/pci class_init() into sdhci_common_class_init()
48
sdhci: refactor common sysbus/pci realize() into sdhci_common_realize()
49
sdhci: refactor common sysbus/pci unrealize() into sdhci_common_unrealize()
50
sdhci: use qemu_log_mask(UNIMP) instead of fprintf()
51
sdhci: convert the DPRINT() calls into trace events
52
sdhci: move MASK_TRNMOD with other SDHC_TRN* defines in "sd-internal.h"
53
sdhci: rename the SDHC_CAPAB register
54
sdhci: fix CAPAB/MAXCURR registers, both are 64bit and read-only
55
sdhci: fix the PCI device, using the PCI address space for DMA
56
sdhci: add a 'dma' property to the sysbus devices
57
52
58
Richard Henderson (2):
53
Richard Henderson (11):
59
target/arm: Split out vfp_expand_imm
54
target/arm: Introduce neon_full_reg_offset
60
target/arm: Add fp16 support to vfp_expand_imm
55
target/arm: Move neon_element_offset to translate.c
56
target/arm: Use neon_element_offset in neon_load/store_reg
57
target/arm: Use neon_element_offset in vfp_reg_offset
58
target/arm: Add read/write_neon_element32
59
target/arm: Expand read/write_neon_element32 to all MemOp
60
target/arm: Rename neon_load_reg32 to vfp_load_reg32
61
target/arm: Add read/write_neon_element64
62
target/arm: Rename neon_load_reg64 to vfp_load_reg64
63
target/arm: Simplify do_long_3d and do_2scalar_long
64
target/arm: Improve do_prewiden_3d
61
65
62
hw/sd/sdhci-internal.h | 7 +-
66
Rémi Denis-Courmont (3):
63
include/hw/sd/sdhci.h | 19 +++-
67
target/arm: fix handling of HCR.FB
64
target/arm/internals.h | 10 ++
68
target/arm: fix LORID_EL1 access check
65
hw/arm/virt.c | 19 +++-
69
hw/arm/boot: fix SVE for EL3 direct kernel boot
66
hw/intc/armv7m_nvic.c | 38 ++++---
67
hw/sd/milkymist-memcard.c | 4 +
68
hw/sd/omap_mmc.c | 14 ++-
69
hw/sd/pl181.c | 4 +
70
hw/sd/sdhci.c | 266 +++++++++++++++++++++++++++------------------
71
hw/sd/ssi-sd.c | 25 ++++-
72
target/arm/helper.c | 53 ++++++++-
73
target/arm/op_helper.c | 7 +-
74
target/arm/translate-a64.c | 49 ++++++---
75
hw/sd/trace-events | 14 +++
76
14 files changed, 362 insertions(+), 167 deletions(-)
77
70
71
docs/qemu-option-trace.rst.inc | 6 +-
72
configure | 10 +-
73
include/hw/intc/arm_gicv3_common.h | 1 -
74
disas/capstone.c | 2 +-
75
hw/arm/boot.c | 3 +
76
hw/arm/smmuv3.c | 3 +-
77
hw/display/exynos4210_fimd.c | 4 +-
78
hw/display/omap_lcdc.c | 10 +-
79
hw/intc/arm_gicv3_cpuif.c | 5 +-
80
target/arm/helper.c | 24 +-
81
target/arm/m_helper.c | 3 +-
82
target/arm/translate.c | 153 +++++++++---
83
target/arm/vec_helper.c | 12 +-
84
tests/qtest/npcm7xx_rng-test.c | 14 +-
85
scripts/kernel-doc | 18 +-
86
target/arm/translate-neon.c.inc | 472 ++++++++++++++++++++-----------------
87
target/arm/translate-vfp.c.inc | 341 +++++++++++----------------
88
17 files changed, 588 insertions(+), 493 deletions(-)
89
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
This function makes it clear that we're talking about the whole
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
register, and not the 32-bit piece at index 0. This fixes a bug
5
Message-id: 20180115182436.2066-6-f4bug@amsat.org
5
when running on a big-endian host.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201030022618.785675-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
hw/sd/sdhci.c | 30 +++++++++++++++++++++---------
12
target/arm/translate.c | 8 ++++++
9
1 file changed, 21 insertions(+), 9 deletions(-)
13
target/arm/translate-neon.c.inc | 44 ++++++++++++++++-----------------
14
target/arm/translate-vfp.c.inc | 2 +-
15
3 files changed, 31 insertions(+), 23 deletions(-)
10
16
11
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/sdhci.c
19
--- a/target/arm/translate.c
14
+++ b/hw/sd/sdhci.c
20
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static void sdhci_uninitfn(SDHCIState *s)
21
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
16
s->fifo_buffer = NULL;
22
unallocated_encoding(s);
17
}
23
}
18
24
19
+static void sdhci_common_realize(SDHCIState *s, Error **errp)
25
+/*
26
+ * Return the offset of a "full" NEON Dreg.
27
+ */
28
+static long neon_full_reg_offset(unsigned reg)
20
+{
29
+{
21
+ s->buf_maxsz = sdhci_get_fifolen(s);
30
+ return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
22
+ s->fifo_buffer = g_malloc0(s->buf_maxsz);
23
+
24
+ memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
25
+ SDHC_REGISTERS_MAP_SIZE);
26
+}
31
+}
27
+
32
+
28
static bool sdhci_pending_insert_vmstate_needed(void *opaque)
33
static inline long vfp_reg_offset(bool dp, unsigned reg)
29
{
34
{
30
SDHCIState *s = opaque;
35
if (dp) {
31
@@ -XXX,XX +XXX,XX @@ static Property sdhci_pci_properties[] = {
36
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
32
static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.c.inc
39
+++ b/target/arm/translate-neon.c.inc
40
@@ -XXX,XX +XXX,XX @@ neon_element_offset(int reg, int element, MemOp size)
41
ofs ^= 8 - element_size;
42
}
43
#endif
44
- return neon_reg_offset(reg, 0) + ofs;
45
+ return neon_full_reg_offset(reg) + ofs;
46
}
47
48
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
50
* We cannot write 16 bytes at once because the
51
* destination is unaligned.
52
*/
53
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
54
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
55
8, 8, tmp);
56
- tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
57
- neon_reg_offset(vd, 0), 8, 8);
58
+ tcg_gen_gvec_mov(0, neon_full_reg_offset(vd + 1),
59
+ neon_full_reg_offset(vd), 8, 8);
60
} else {
61
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
62
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
63
vec_size, vec_size, tmp);
64
}
65
tcg_gen_addi_i32(addr, addr, 1 << size);
66
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
67
static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
33
{
68
{
34
SDHCIState *s = PCI_SDHCI(dev);
69
int vec_size = a->q ? 16 : 8;
35
+
70
- int rd_ofs = neon_reg_offset(a->vd, 0);
36
+ sdhci_initfn(s);
71
- int rn_ofs = neon_reg_offset(a->vn, 0);
37
+ sdhci_common_realize(s, errp);
72
- int rm_ofs = neon_reg_offset(a->vm, 0);
38
+ if (errp && *errp) {
73
+ int rd_ofs = neon_full_reg_offset(a->vd);
39
+ return;
74
+ int rn_ofs = neon_full_reg_offset(a->vn);
40
+ }
75
+ int rm_ofs = neon_full_reg_offset(a->vm);
41
+
76
42
dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */
77
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
43
dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
78
return false;
44
- sdhci_initfn(s);
79
@@ -XXX,XX +XXX,XX @@ static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
45
- s->buf_maxsz = sdhci_get_fifolen(s);
80
{
46
- s->fifo_buffer = g_malloc0(s->buf_maxsz);
81
/* Handle a 2-reg-shift insn which can be vectorized. */
47
s->irq = pci_allocate_irq(dev);
82
int vec_size = a->q ? 16 : 8;
48
- memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
83
- int rd_ofs = neon_reg_offset(a->vd, 0);
49
- SDHC_REGISTERS_MAP_SIZE);
84
- int rm_ofs = neon_reg_offset(a->vm, 0);
50
pci_register_bar(dev, 0, 0, &s->iomem);
85
+ int rd_ofs = neon_full_reg_offset(a->vd);
86
+ int rm_ofs = neon_full_reg_offset(a->vm);
87
88
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
89
return false;
90
@@ -XXX,XX +XXX,XX @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
91
{
92
/* FP operations in 2-reg-and-shift group */
93
int vec_size = a->q ? 16 : 8;
94
- int rd_ofs = neon_reg_offset(a->vd, 0);
95
- int rm_ofs = neon_reg_offset(a->vm, 0);
96
+ int rd_ofs = neon_full_reg_offset(a->vd);
97
+ int rm_ofs = neon_full_reg_offset(a->vm);
98
TCGv_ptr fpst;
99
100
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
101
@@ -XXX,XX +XXX,XX @@ static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
102
return true;
103
}
104
105
- reg_ofs = neon_reg_offset(a->vd, 0);
106
+ reg_ofs = neon_full_reg_offset(a->vd);
107
vec_size = a->q ? 16 : 8;
108
imm = asimd_imm_const(a->imm, a->cmode, a->op);
109
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMULL_P_3d(DisasContext *s, arg_3diff *a)
111
return true;
112
}
113
114
- tcg_gen_gvec_3_ool(neon_reg_offset(a->vd, 0),
115
- neon_reg_offset(a->vn, 0),
116
- neon_reg_offset(a->vm, 0),
117
+ tcg_gen_gvec_3_ool(neon_full_reg_offset(a->vd),
118
+ neon_full_reg_offset(a->vn),
119
+ neon_full_reg_offset(a->vm),
120
16, 16, 0, fn_gvec);
121
return true;
51
}
122
}
52
123
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
53
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
124
{
54
SDHCIState *s = SYSBUS_SDHCI(dev);
125
/* Two registers and a scalar, using gvec */
55
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
126
int vec_size = a->q ? 16 : 8;
56
127
- int rd_ofs = neon_reg_offset(a->vd, 0);
57
- s->buf_maxsz = sdhci_get_fifolen(s);
128
- int rn_ofs = neon_reg_offset(a->vn, 0);
58
- s->fifo_buffer = g_malloc0(s->buf_maxsz);
129
+ int rd_ofs = neon_full_reg_offset(a->vd);
59
+ sdhci_common_realize(s, errp);
130
+ int rn_ofs = neon_full_reg_offset(a->vn);
60
+ if (errp && *errp) {
131
int rm_ofs;
61
+ return;
132
int idx;
62
+ }
133
TCGv_ptr fpstatus;
63
+
134
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
64
sysbus_init_irq(sbd, &s->irq);
135
/* a->vm is M:Vm, which encodes both register and index */
65
- memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
136
idx = extract32(a->vm, a->size + 2, 2);
66
- SDHC_REGISTERS_MAP_SIZE);
137
a->vm = extract32(a->vm, 0, a->size + 2);
67
sysbus_init_mmio(sbd, &s->iomem);
138
- rm_ofs = neon_reg_offset(a->vm, 0);
68
}
139
+ rm_ofs = neon_full_reg_offset(a->vm);
140
141
fpstatus = fpstatus_ptr(a->size == 1 ? FPST_STD_F16 : FPST_STD);
142
tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpstatus,
143
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
144
return true;
145
}
146
147
- tcg_gen_gvec_dup_mem(a->size, neon_reg_offset(a->vd, 0),
148
+ tcg_gen_gvec_dup_mem(a->size, neon_full_reg_offset(a->vd),
149
neon_element_offset(a->vm, a->index, a->size),
150
a->q ? 16 : 8, a->q ? 16 : 8);
151
return true;
152
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
153
static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
154
{
155
int vec_size = a->q ? 16 : 8;
156
- int rd_ofs = neon_reg_offset(a->vd, 0);
157
- int rm_ofs = neon_reg_offset(a->vm, 0);
158
+ int rd_ofs = neon_full_reg_offset(a->vd);
159
+ int rm_ofs = neon_full_reg_offset(a->vm);
160
161
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
return false;
163
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/translate-vfp.c.inc
166
+++ b/target/arm/translate-vfp.c.inc
167
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
168
}
169
170
tmp = load_reg(s, a->rt);
171
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(a->vn, 0),
172
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(a->vn),
173
vec_size, vec_size, tmp);
174
tcg_temp_free_i32(tmp);
69
175
70
--
176
--
71
2.7.4
177
2.20.1
72
178
73
179
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
running qtests:
3
This will shortly have users outside of translate-neon.c.inc.
4
4
5
$ make check-qtest-arm
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
GTESTER check-qtest-arm
6
Message-id: 20201030022618.785675-3-richard.henderson@linaro.org
7
SDHC rd_4b @0x44 not implemented
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
SDHC wr_4b @0x40 <- 0x89abcdef not implemented
9
SDHC wr_4b @0x44 <- 0x01234567 not implemented
10
11
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
13
Message-id: 20180115182436.2066-12-f4bug@amsat.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
include/hw/sd/sdhci.h | 4 ++--
10
target/arm/translate.c | 20 ++++++++++++++++++++
17
hw/sd/sdhci.c | 23 +++++++++++++++++++----
11
target/arm/translate-neon.c.inc | 19 -------------------
18
2 files changed, 21 insertions(+), 6 deletions(-)
12
2 files changed, 20 insertions(+), 19 deletions(-)
19
13
20
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/sd/sdhci.h
16
--- a/target/arm/translate.c
23
+++ b/include/hw/sd/sdhci.h
17
+++ b/target/arm/translate.c
24
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
18
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
25
uint64_t admasysaddr; /* ADMA System Address Register */
19
return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
26
20
}
27
/* Read-only registers */
21
28
- uint32_t capareg; /* Capabilities Register */
22
+/*
29
- uint32_t maxcurr; /* Maximum Current Capabilities Register */
23
+ * Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
30
+ uint64_t capareg; /* Capabilities Register */
24
+ * where 0 is the least significant end of the register.
31
+ uint64_t maxcurr; /* Maximum Current Capabilities Register */
25
+ */
32
26
+static long neon_element_offset(int reg, int element, MemOp size)
33
uint8_t *fifo_buffer; /* SD host i/o FIFO buffer */
27
+{
34
uint32_t buf_maxsz;
28
+ int element_size = 1 << size;
35
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
29
+ int ofs = element * element_size;
30
+#ifdef HOST_WORDS_BIGENDIAN
31
+ /*
32
+ * Calculate the offset assuming fully little-endian,
33
+ * then XOR to account for the order of the 8-byte units.
34
+ */
35
+ if (element_size < 8) {
36
+ ofs ^= 8 - element_size;
37
+ }
38
+#endif
39
+ return neon_full_reg_offset(reg) + ofs;
40
+}
41
+
42
static inline long vfp_reg_offset(bool dp, unsigned reg)
43
{
44
if (dp) {
45
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
36
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/sd/sdhci.c
47
--- a/target/arm/translate-neon.c.inc
38
+++ b/hw/sd/sdhci.c
48
+++ b/target/arm/translate-neon.c.inc
39
@@ -XXX,XX +XXX,XX @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
49
@@ -XXX,XX +XXX,XX @@ static inline int neon_3same_fp_size(DisasContext *s, int x)
40
ret = s->acmd12errsts;
50
#include "decode-neon-ls.c.inc"
41
break;
51
#include "decode-neon-shared.c.inc"
42
case SDHC_CAPAB:
52
43
- ret = s->capareg;
53
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
44
+ ret = (uint32_t)s->capareg;
54
- * where 0 is the least significant end of the register.
45
+ break;
55
- */
46
+ case SDHC_CAPAB + 4:
56
-static inline long
47
+ ret = (uint32_t)(s->capareg >> 32);
57
-neon_element_offset(int reg, int element, MemOp size)
48
break;
58
-{
49
case SDHC_MAXCURR:
59
- int element_size = 1 << size;
50
- ret = s->maxcurr;
60
- int ofs = element * element_size;
51
+ ret = (uint32_t)s->maxcurr;
61
-#ifdef HOST_WORDS_BIGENDIAN
52
+ break;
62
- /* Calculate the offset assuming fully little-endian,
53
+ case SDHC_MAXCURR + 4:
63
- * then XOR to account for the order of the 8-byte units.
54
+ ret = (uint32_t)(s->maxcurr >> 32);
64
- */
55
break;
65
- if (element_size < 8) {
56
case SDHC_ADMAERR:
66
- ofs ^= 8 - element_size;
57
ret = s->admaerr;
67
- }
58
@@ -XXX,XX +XXX,XX @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
68
-#endif
59
}
69
- return neon_full_reg_offset(reg) + ofs;
60
sdhci_update_irq(s);
70
-}
61
break;
71
-
62
+
72
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
63
+ case SDHC_CAPAB:
64
+ case SDHC_CAPAB + 4:
65
+ case SDHC_MAXCURR:
66
+ case SDHC_MAXCURR + 4:
67
+ qemu_log_mask(LOG_GUEST_ERROR, "SDHC wr_%ub @0x%02" HWADDR_PRIx
68
+ " <- 0x%08x read-only\n", size, offset, value >> shift);
69
+ break;
70
+
71
default:
72
qemu_log_mask(LOG_UNIMP, "SDHC wr_%ub @0x%02" HWADDR_PRIx " <- 0x%08x "
73
"not implemented\n", size, offset, value >> shift);
74
@@ -XXX,XX +XXX,XX @@ static inline unsigned int sdhci_get_fifolen(SDHCIState *s)
75
#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \
76
/* Capabilities registers provide information on supported features
77
* of this specific host controller implementation */ \
78
- DEFINE_PROP_UINT32("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \
79
- DEFINE_PROP_UINT32("maxcurr", _state, maxcurr, 0)
80
+ DEFINE_PROP_UINT64("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \
81
+ DEFINE_PROP_UINT64("maxcurr", _state, maxcurr, 0)
82
83
static void sdhci_initfn(SDHCIState *s)
84
{
73
{
74
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
85
--
75
--
86
2.7.4
76
2.20.1
87
77
88
78
diff view generated by jsdifflib
1
Since omap_mmc is still using the legacy SD card API, the SD
1
From: Richard Henderson <richard.henderson@linaro.org>
2
card created by sd_init() is not plugged into any bus. This
3
means that the controller has to reset it manually.
4
2
5
Failing to do this mostly didn't affect the guest since the
3
These are the only users of neon_reg_offset, so remove that.
6
guest typically does a programmed SD card reset as part of
7
its SD controller driver initialization, but would mean that
8
migration fails because it's only in sd_reset() that we
9
set up the wpgrps_size field.
10
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-4-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 1515506513-31961-5-git-send-email-peter.maydell@linaro.org
15
---
9
---
16
hw/sd/omap_mmc.c | 14 ++++++++++----
10
target/arm/translate.c | 14 ++------------
17
1 file changed, 10 insertions(+), 4 deletions(-)
11
1 file changed, 2 insertions(+), 12 deletions(-)
18
12
19
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/sd/omap_mmc.c
15
--- a/target/arm/translate.c
22
+++ b/hw/sd/omap_mmc.c
16
+++ b/target/arm/translate.c
23
@@ -XXX,XX +XXX,XX @@ void omap_mmc_reset(struct omap_mmc_s *host)
17
@@ -XXX,XX +XXX,XX @@ static inline long vfp_reg_offset(bool dp, unsigned reg)
24
host->cdet_enable = 0;
18
}
25
qemu_set_irq(host->coverswitch, host->cdet_state);
26
host->clkdiv = 0;
27
+
28
+ /* Since we're still using the legacy SD API the card is not plugged
29
+ * into any bus, and we must reset it manually. When omap_mmc is
30
+ * QOMified this must move into the QOM reset function.
31
+ */
32
+ device_reset(DEVICE(host->card));
33
}
19
}
34
20
35
static uint64_t omap_mmc_read(void *opaque, hwaddr offset,
21
-/* Return the offset of a 32-bit piece of a NEON register.
36
@@ -XXX,XX +XXX,XX @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
22
- zero is the least significant end of the register. */
37
s->lines = 1;    /* TODO: needs to be settable per-board */
23
-static inline long
38
s->rev = 1;
24
-neon_reg_offset (int reg, int n)
39
25
-{
40
- omap_mmc_reset(s);
26
- int sreg;
27
- sreg = reg * 2 + n;
28
- return vfp_reg_offset(0, sreg);
29
-}
41
-
30
-
42
memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc", 0x800);
31
static TCGv_i32 neon_load_reg(int reg, int pass)
43
memory_region_add_subregion(sysmem, base, &s->iomem);
32
{
44
33
TCGv_i32 tmp = tcg_temp_new_i32();
45
@@ -XXX,XX +XXX,XX @@ struct omap_mmc_s *omap_mmc_init(hwaddr base,
34
- tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
46
exit(1);
35
+ tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
47
}
36
return tmp;
48
49
+ omap_mmc_reset(s);
50
+
51
return s;
52
}
37
}
53
38
54
@@ -XXX,XX +XXX,XX @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
39
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
55
s->lines = 4;
40
{
56
s->rev = 2;
41
- tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
57
42
+ tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
58
- omap_mmc_reset(s);
43
tcg_temp_free_i32(var);
59
-
60
memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc",
61
omap_l4_region_size(ta, 0));
62
omap_l4_attach(ta, 0, &s->iomem);
63
@@ -XXX,XX +XXX,XX @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
64
s->cdet = qemu_allocate_irq(omap_mmc_cover_cb, s, 0);
65
sd_set_cb(s->card, NULL, s->cdet);
66
67
+ omap_mmc_reset(s);
68
+
69
return s;
70
}
44
}
71
45
72
--
46
--
73
2.7.4
47
2.20.1
74
48
75
49
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now both inherited classes appear as DEVICE_CATEGORY_STORAGE.
3
This seems a bit more readable than using offsetof CPU_DoubleU.
4
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
6
Message-id: 20201030022618.785675-5-richard.henderson@linaro.org
7
Message-id: 20180115182436.2066-5-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
hw/sd/sdhci.c | 18 +++++++++++++-----
10
target/arm/translate.c | 13 ++++---------
11
1 file changed, 13 insertions(+), 5 deletions(-)
11
1 file changed, 4 insertions(+), 9 deletions(-)
12
12
13
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/sd/sdhci.c
15
--- a/target/arm/translate.c
16
+++ b/hw/sd/sdhci.c
16
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ const VMStateDescription sdhci_vmstate = {
17
@@ -XXX,XX +XXX,XX @@ static long neon_element_offset(int reg, int element, MemOp size)
18
},
18
return neon_full_reg_offset(reg) + ofs;
19
};
20
21
+static void sdhci_common_class_init(ObjectClass *klass, void *data)
22
+{
23
+ DeviceClass *dc = DEVICE_CLASS(klass);
24
+
25
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
26
+ dc->vmsd = &sdhci_vmstate;
27
+ dc->reset = sdhci_poweron_reset;
28
+}
29
+
30
/* --- qdev PCI --- */
31
32
static Property sdhci_pci_properties[] = {
33
@@ -XXX,XX +XXX,XX @@ static void sdhci_pci_class_init(ObjectClass *klass, void *data)
34
k->vendor_id = PCI_VENDOR_ID_REDHAT;
35
k->device_id = PCI_DEVICE_ID_REDHAT_SDHCI;
36
k->class_id = PCI_CLASS_SYSTEM_SDHCI;
37
- set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
38
- dc->vmsd = &sdhci_vmstate;
39
dc->props = sdhci_pci_properties;
40
- dc->reset = sdhci_poweron_reset;
41
+
42
+ sdhci_common_class_init(klass, data);
43
}
19
}
44
20
45
static const TypeInfo sdhci_pci_info = {
21
-static inline long vfp_reg_offset(bool dp, unsigned reg)
46
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
22
+/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
23
+static long vfp_reg_offset(bool dp, unsigned reg)
47
{
24
{
48
DeviceClass *dc = DEVICE_CLASS(klass);
25
if (dp) {
49
26
- return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
50
- dc->vmsd = &sdhci_vmstate;
27
+ return neon_element_offset(reg, 0, MO_64);
51
dc->props = sdhci_sysbus_properties;
28
} else {
52
dc->realize = sdhci_sysbus_realize;
29
- long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
53
- dc->reset = sdhci_poweron_reset;
30
- if (reg & 1) {
54
+
31
- ofs += offsetof(CPU_DoubleU, l.upper);
55
+ sdhci_common_class_init(klass, data);
32
- } else {
33
- ofs += offsetof(CPU_DoubleU, l.lower);
34
- }
35
- return ofs;
36
+ return neon_element_offset(reg >> 1, reg & 1, MO_32);
37
}
56
}
38
}
57
39
58
static const TypeInfo sdhci_sysbus_info = {
59
--
40
--
60
2.7.4
41
2.20.1
61
42
62
43
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Model these off the aa64 read/write_vec_element functions.
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
Use it within translate-neon.c.inc. The new functions do
5
Message-id: 20180115182436.2066-7-f4bug@amsat.org
5
not allocate or free temps, so this rearranges the calling
6
code a bit.
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20201030022618.785675-6-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
hw/sd/sdhci.c | 22 ++++++++++++++++++++++
13
target/arm/translate.c | 26 ++++
9
1 file changed, 22 insertions(+)
14
target/arm/translate-neon.c.inc | 256 ++++++++++++++++++++------------
15
2 files changed, 183 insertions(+), 99 deletions(-)
10
16
11
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/sdhci.c
19
--- a/target/arm/translate.c
14
+++ b/hw/sd/sdhci.c
20
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
16
#include "qemu/bitops.h"
22
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
17
#include "hw/sd/sdhci.h"
23
}
18
#include "sdhci-internal.h"
24
19
+#include "qapi/error.h"
25
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
20
#include "qemu/log.h"
21
22
/* host controller debug messages */
23
@@ -XXX,XX +XXX,XX @@ static void sdhci_common_realize(SDHCIState *s, Error **errp)
24
SDHC_REGISTERS_MAP_SIZE);
25
}
26
27
+static void sdhci_common_unrealize(SDHCIState *s, Error **errp)
28
+{
26
+{
29
+ /* This function is expected to be called only once for each class:
27
+ long off = neon_element_offset(reg, ele, size);
30
+ * - SysBus: via DeviceClass->unrealize(),
28
+
31
+ * - PCI: via PCIDeviceClass->exit().
29
+ switch (size) {
32
+ * However to avoid double-free and/or use-after-free we still nullify
30
+ case MO_32:
33
+ * this variable (better safe than sorry!). */
31
+ tcg_gen_ld_i32(dest, cpu_env, off);
34
+ g_free(s->fifo_buffer);
32
+ break;
35
+ s->fifo_buffer = NULL;
33
+ default:
34
+ g_assert_not_reached();
35
+ }
36
+}
36
+}
37
+
37
+
38
static bool sdhci_pending_insert_vmstate_needed(void *opaque)
38
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
39
+{
40
+ long off = neon_element_offset(reg, ele, size);
41
+
42
+ switch (size) {
43
+ case MO_32:
44
+ tcg_gen_st_i32(src, cpu_env, off);
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
+}
50
+
51
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
39
{
52
{
40
SDHCIState *s = opaque;
53
TCGv_ptr ret = tcg_temp_new_ptr();
41
@@ -XXX,XX +XXX,XX @@ static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
54
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
42
static void sdhci_pci_exit(PCIDevice *dev)
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/translate-neon.c.inc
57
+++ b/target/arm/translate-neon.c.inc
58
@@ -XXX,XX +XXX,XX @@ static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
59
* early. Since Q is 0 there are always just two passes, so instead
60
* of a complicated loop over each pass we just unroll.
61
*/
62
- tmp = neon_load_reg(a->vn, 0);
63
- tmp2 = neon_load_reg(a->vn, 1);
64
+ tmp = tcg_temp_new_i32();
65
+ tmp2 = tcg_temp_new_i32();
66
+ tmp3 = tcg_temp_new_i32();
67
+
68
+ read_neon_element32(tmp, a->vn, 0, MO_32);
69
+ read_neon_element32(tmp2, a->vn, 1, MO_32);
70
fn(tmp, tmp, tmp2);
71
- tcg_temp_free_i32(tmp2);
72
73
- tmp3 = neon_load_reg(a->vm, 0);
74
- tmp2 = neon_load_reg(a->vm, 1);
75
+ read_neon_element32(tmp3, a->vm, 0, MO_32);
76
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
77
fn(tmp3, tmp3, tmp2);
78
- tcg_temp_free_i32(tmp2);
79
80
- neon_store_reg(a->vd, 0, tmp);
81
- neon_store_reg(a->vd, 1, tmp3);
82
+ write_neon_element32(tmp, a->vd, 0, MO_32);
83
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
84
+
85
+ tcg_temp_free_i32(tmp);
86
+ tcg_temp_free_i32(tmp2);
87
+ tcg_temp_free_i32(tmp3);
88
return true;
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
92
* 2-reg-and-shift operations, size < 3 case, where the
93
* helper needs to be passed cpu_env.
94
*/
95
- TCGv_i32 constimm;
96
+ TCGv_i32 constimm, tmp;
97
int pass;
98
99
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
100
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
101
* by immediate using the variable shift operations.
102
*/
103
constimm = tcg_const_i32(dup_const(a->size, a->shift));
104
+ tmp = tcg_temp_new_i32();
105
106
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
107
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
108
+ read_neon_element32(tmp, a->vm, pass, MO_32);
109
fn(tmp, cpu_env, tmp, constimm);
110
- neon_store_reg(a->vd, pass, tmp);
111
+ write_neon_element32(tmp, a->vd, pass, MO_32);
112
}
113
+ tcg_temp_free_i32(tmp);
114
tcg_temp_free_i32(constimm);
115
return true;
116
}
117
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
118
constimm = tcg_const_i64(-a->shift);
119
rm1 = tcg_temp_new_i64();
120
rm2 = tcg_temp_new_i64();
121
+ rd = tcg_temp_new_i32();
122
123
/* Load both inputs first to avoid potential overwrite if rm == rd */
124
neon_load_reg64(rm1, a->vm);
125
neon_load_reg64(rm2, a->vm + 1);
126
127
shiftfn(rm1, rm1, constimm);
128
- rd = tcg_temp_new_i32();
129
narrowfn(rd, cpu_env, rm1);
130
- neon_store_reg(a->vd, 0, rd);
131
+ write_neon_element32(rd, a->vd, 0, MO_32);
132
133
shiftfn(rm2, rm2, constimm);
134
- rd = tcg_temp_new_i32();
135
narrowfn(rd, cpu_env, rm2);
136
- neon_store_reg(a->vd, 1, rd);
137
+ write_neon_element32(rd, a->vd, 1, MO_32);
138
139
+ tcg_temp_free_i32(rd);
140
tcg_temp_free_i64(rm1);
141
tcg_temp_free_i64(rm2);
142
tcg_temp_free_i64(constimm);
143
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
144
constimm = tcg_const_i32(imm);
145
146
/* Load all inputs first to avoid potential overwrite */
147
- rm1 = neon_load_reg(a->vm, 0);
148
- rm2 = neon_load_reg(a->vm, 1);
149
- rm3 = neon_load_reg(a->vm + 1, 0);
150
- rm4 = neon_load_reg(a->vm + 1, 1);
151
+ rm1 = tcg_temp_new_i32();
152
+ rm2 = tcg_temp_new_i32();
153
+ rm3 = tcg_temp_new_i32();
154
+ rm4 = tcg_temp_new_i32();
155
+ read_neon_element32(rm1, a->vm, 0, MO_32);
156
+ read_neon_element32(rm2, a->vm, 1, MO_32);
157
+ read_neon_element32(rm3, a->vm, 2, MO_32);
158
+ read_neon_element32(rm4, a->vm, 3, MO_32);
159
rtmp = tcg_temp_new_i64();
160
161
shiftfn(rm1, rm1, constimm);
162
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
163
tcg_temp_free_i32(rm2);
164
165
narrowfn(rm1, cpu_env, rtmp);
166
- neon_store_reg(a->vd, 0, rm1);
167
+ write_neon_element32(rm1, a->vd, 0, MO_32);
168
+ tcg_temp_free_i32(rm1);
169
170
shiftfn(rm3, rm3, constimm);
171
shiftfn(rm4, rm4, constimm);
172
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
173
174
narrowfn(rm3, cpu_env, rtmp);
175
tcg_temp_free_i64(rtmp);
176
- neon_store_reg(a->vd, 1, rm3);
177
+ write_neon_element32(rm3, a->vd, 1, MO_32);
178
+ tcg_temp_free_i32(rm3);
179
return true;
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
183
widen_mask = dup_const(a->size + 1, widen_mask);
184
}
185
186
- rm0 = neon_load_reg(a->vm, 0);
187
- rm1 = neon_load_reg(a->vm, 1);
188
+ rm0 = tcg_temp_new_i32();
189
+ rm1 = tcg_temp_new_i32();
190
+ read_neon_element32(rm0, a->vm, 0, MO_32);
191
+ read_neon_element32(rm1, a->vm, 1, MO_32);
192
tmp = tcg_temp_new_i64();
193
194
widenfn(tmp, rm0);
195
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
196
if (src1_wide) {
197
neon_load_reg64(rn0_64, a->vn);
198
} else {
199
- TCGv_i32 tmp = neon_load_reg(a->vn, 0);
200
+ TCGv_i32 tmp = tcg_temp_new_i32();
201
+ read_neon_element32(tmp, a->vn, 0, MO_32);
202
widenfn(rn0_64, tmp);
203
tcg_temp_free_i32(tmp);
204
}
205
- rm = neon_load_reg(a->vm, 0);
206
+ rm = tcg_temp_new_i32();
207
+ read_neon_element32(rm, a->vm, 0, MO_32);
208
209
widenfn(rm_64, rm);
210
tcg_temp_free_i32(rm);
211
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
212
if (src1_wide) {
213
neon_load_reg64(rn1_64, a->vn + 1);
214
} else {
215
- TCGv_i32 tmp = neon_load_reg(a->vn, 1);
216
+ TCGv_i32 tmp = tcg_temp_new_i32();
217
+ read_neon_element32(tmp, a->vn, 1, MO_32);
218
widenfn(rn1_64, tmp);
219
tcg_temp_free_i32(tmp);
220
}
221
- rm = neon_load_reg(a->vm, 1);
222
+ rm = tcg_temp_new_i32();
223
+ read_neon_element32(rm, a->vm, 1, MO_32);
224
225
neon_store_reg64(rn0_64, a->vd);
226
227
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
228
229
narrowfn(rd1, rn_64);
230
231
- neon_store_reg(a->vd, 0, rd0);
232
- neon_store_reg(a->vd, 1, rd1);
233
+ write_neon_element32(rd0, a->vd, 0, MO_32);
234
+ write_neon_element32(rd1, a->vd, 1, MO_32);
235
236
+ tcg_temp_free_i32(rd0);
237
+ tcg_temp_free_i32(rd1);
238
tcg_temp_free_i64(rn_64);
239
tcg_temp_free_i64(rm_64);
240
241
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
242
rd0 = tcg_temp_new_i64();
243
rd1 = tcg_temp_new_i64();
244
245
- rn = neon_load_reg(a->vn, 0);
246
- rm = neon_load_reg(a->vm, 0);
247
+ rn = tcg_temp_new_i32();
248
+ rm = tcg_temp_new_i32();
249
+ read_neon_element32(rn, a->vn, 0, MO_32);
250
+ read_neon_element32(rm, a->vm, 0, MO_32);
251
opfn(rd0, rn, rm);
252
- tcg_temp_free_i32(rn);
253
- tcg_temp_free_i32(rm);
254
255
- rn = neon_load_reg(a->vn, 1);
256
- rm = neon_load_reg(a->vm, 1);
257
+ read_neon_element32(rn, a->vn, 1, MO_32);
258
+ read_neon_element32(rm, a->vm, 1, MO_32);
259
opfn(rd1, rn, rm);
260
tcg_temp_free_i32(rn);
261
tcg_temp_free_i32(rm);
262
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
263
264
static inline TCGv_i32 neon_get_scalar(int size, int reg)
43
{
265
{
44
SDHCIState *s = PCI_SDHCI(dev);
266
- TCGv_i32 tmp;
45
+
267
- if (size == 1) {
46
+ sdhci_common_unrealize(s, &error_abort);
268
- tmp = neon_load_reg(reg & 7, reg >> 4);
47
sdhci_uninitfn(s);
269
+ TCGv_i32 tmp = tcg_temp_new_i32();
48
}
270
+ if (size == MO_16) {
49
271
+ read_neon_element32(tmp, reg & 7, reg >> 4, MO_32);
50
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
272
if (reg & 8) {
51
sysbus_init_mmio(sbd, &s->iomem);
273
gen_neon_dup_high16(tmp);
52
}
274
} else {
53
275
gen_neon_dup_low16(tmp);
54
+static void sdhci_sysbus_unrealize(DeviceState *dev, Error **errp)
276
}
55
+{
277
} else {
56
+ SDHCIState *s = SYSBUS_SDHCI(dev);
278
- tmp = neon_load_reg(reg & 15, reg >> 4);
57
+
279
+ read_neon_element32(tmp, reg & 15, reg >> 4, MO_32);
58
+ sdhci_common_unrealize(s, &error_abort);
280
}
59
+}
281
return tmp;
60
+
282
}
61
static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
283
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
284
* perform an accumulation operation of that result into the
285
* destination.
286
*/
287
- TCGv_i32 scalar;
288
+ TCGv_i32 scalar, tmp;
289
int pass;
290
291
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
292
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
293
}
294
295
scalar = neon_get_scalar(a->size, a->vm);
296
+ tmp = tcg_temp_new_i32();
297
298
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
299
- TCGv_i32 tmp = neon_load_reg(a->vn, pass);
300
+ read_neon_element32(tmp, a->vn, pass, MO_32);
301
opfn(tmp, tmp, scalar);
302
if (accfn) {
303
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
304
+ TCGv_i32 rd = tcg_temp_new_i32();
305
+ read_neon_element32(rd, a->vd, pass, MO_32);
306
accfn(tmp, rd, tmp);
307
tcg_temp_free_i32(rd);
308
}
309
- neon_store_reg(a->vd, pass, tmp);
310
+ write_neon_element32(tmp, a->vd, pass, MO_32);
311
}
312
+ tcg_temp_free_i32(tmp);
313
tcg_temp_free_i32(scalar);
314
return true;
315
}
316
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
317
* performs a kind of fused op-then-accumulate using a helper
318
* function that takes all of rd, rn and the scalar at once.
319
*/
320
- TCGv_i32 scalar;
321
+ TCGv_i32 scalar, rn, rd;
322
int pass;
323
324
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
325
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
326
}
327
328
scalar = neon_get_scalar(a->size, a->vm);
329
+ rn = tcg_temp_new_i32();
330
+ rd = tcg_temp_new_i32();
331
332
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
333
- TCGv_i32 rn = neon_load_reg(a->vn, pass);
334
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
335
+ read_neon_element32(rn, a->vn, pass, MO_32);
336
+ read_neon_element32(rd, a->vd, pass, MO_32);
337
opfn(rd, cpu_env, rn, scalar, rd);
338
- tcg_temp_free_i32(rn);
339
- neon_store_reg(a->vd, pass, rd);
340
+ write_neon_element32(rd, a->vd, pass, MO_32);
341
}
342
+ tcg_temp_free_i32(rn);
343
+ tcg_temp_free_i32(rd);
344
tcg_temp_free_i32(scalar);
345
346
return true;
347
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
348
scalar = neon_get_scalar(a->size, a->vm);
349
350
/* Load all inputs before writing any outputs, in case of overlap */
351
- rn = neon_load_reg(a->vn, 0);
352
+ rn = tcg_temp_new_i32();
353
+ read_neon_element32(rn, a->vn, 0, MO_32);
354
rn0_64 = tcg_temp_new_i64();
355
opfn(rn0_64, rn, scalar);
356
- tcg_temp_free_i32(rn);
357
358
- rn = neon_load_reg(a->vn, 1);
359
+ read_neon_element32(rn, a->vn, 1, MO_32);
360
rn1_64 = tcg_temp_new_i64();
361
opfn(rn1_64, rn, scalar);
362
tcg_temp_free_i32(rn);
363
@@ -XXX,XX +XXX,XX @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
364
return false;
365
}
366
n <<= 3;
367
+ tmp = tcg_temp_new_i32();
368
if (a->op) {
369
- tmp = neon_load_reg(a->vd, 0);
370
+ read_neon_element32(tmp, a->vd, 0, MO_32);
371
} else {
372
- tmp = tcg_temp_new_i32();
373
tcg_gen_movi_i32(tmp, 0);
374
}
375
- tmp2 = neon_load_reg(a->vm, 0);
376
+ tmp2 = tcg_temp_new_i32();
377
+ read_neon_element32(tmp2, a->vm, 0, MO_32);
378
ptr1 = vfp_reg_ptr(true, a->vn);
379
tmp4 = tcg_const_i32(n);
380
gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp4);
381
- tcg_temp_free_i32(tmp);
382
+
383
if (a->op) {
384
- tmp = neon_load_reg(a->vd, 1);
385
+ read_neon_element32(tmp, a->vd, 1, MO_32);
386
} else {
387
- tmp = tcg_temp_new_i32();
388
tcg_gen_movi_i32(tmp, 0);
389
}
390
- tmp3 = neon_load_reg(a->vm, 1);
391
+ tmp3 = tcg_temp_new_i32();
392
+ read_neon_element32(tmp3, a->vm, 1, MO_32);
393
gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp4);
394
+ tcg_temp_free_i32(tmp);
395
tcg_temp_free_i32(tmp4);
396
tcg_temp_free_ptr(ptr1);
397
- neon_store_reg(a->vd, 0, tmp2);
398
- neon_store_reg(a->vd, 1, tmp3);
399
- tcg_temp_free_i32(tmp);
400
+
401
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
402
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
403
+ tcg_temp_free_i32(tmp2);
404
+ tcg_temp_free_i32(tmp3);
405
return true;
406
}
407
408
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
409
static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
62
{
410
{
63
DeviceClass *dc = DEVICE_CLASS(klass);
411
int pass, half;
64
412
+ TCGv_i32 tmp[2];
65
dc->props = sdhci_sysbus_properties;
413
66
dc->realize = sdhci_sysbus_realize;
414
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
67
+ dc->unrealize = sdhci_sysbus_unrealize;
415
return false;
68
416
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
69
sdhci_common_class_init(klass, data);
417
return true;
418
}
419
420
- for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
421
- TCGv_i32 tmp[2];
422
+ tmp[0] = tcg_temp_new_i32();
423
+ tmp[1] = tcg_temp_new_i32();
424
425
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
426
for (half = 0; half < 2; half++) {
427
- tmp[half] = neon_load_reg(a->vm, pass * 2 + half);
428
+ read_neon_element32(tmp[half], a->vm, pass * 2 + half, MO_32);
429
switch (a->size) {
430
case 0:
431
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
432
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
433
g_assert_not_reached();
434
}
435
}
436
- neon_store_reg(a->vd, pass * 2, tmp[1]);
437
- neon_store_reg(a->vd, pass * 2 + 1, tmp[0]);
438
+ write_neon_element32(tmp[1], a->vd, pass * 2, MO_32);
439
+ write_neon_element32(tmp[0], a->vd, pass * 2 + 1, MO_32);
440
}
441
+
442
+ tcg_temp_free_i32(tmp[0]);
443
+ tcg_temp_free_i32(tmp[1]);
444
return true;
445
}
446
447
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
448
rm0_64 = tcg_temp_new_i64();
449
rm1_64 = tcg_temp_new_i64();
450
rd_64 = tcg_temp_new_i64();
451
- tmp = neon_load_reg(a->vm, pass * 2);
452
+
453
+ tmp = tcg_temp_new_i32();
454
+ read_neon_element32(tmp, a->vm, pass * 2, MO_32);
455
widenfn(rm0_64, tmp);
456
- tcg_temp_free_i32(tmp);
457
- tmp = neon_load_reg(a->vm, pass * 2 + 1);
458
+ read_neon_element32(tmp, a->vm, pass * 2 + 1, MO_32);
459
widenfn(rm1_64, tmp);
460
tcg_temp_free_i32(tmp);
461
+
462
opfn(rd_64, rm0_64, rm1_64);
463
tcg_temp_free_i64(rm0_64);
464
tcg_temp_free_i64(rm1_64);
465
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
466
narrowfn(rd0, cpu_env, rm);
467
neon_load_reg64(rm, a->vm + 1);
468
narrowfn(rd1, cpu_env, rm);
469
- neon_store_reg(a->vd, 0, rd0);
470
- neon_store_reg(a->vd, 1, rd1);
471
+ write_neon_element32(rd0, a->vd, 0, MO_32);
472
+ write_neon_element32(rd1, a->vd, 1, MO_32);
473
+ tcg_temp_free_i32(rd0);
474
+ tcg_temp_free_i32(rd1);
475
tcg_temp_free_i64(rm);
476
return true;
477
}
478
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
479
}
480
481
rd = tcg_temp_new_i64();
482
+ rm0 = tcg_temp_new_i32();
483
+ rm1 = tcg_temp_new_i32();
484
485
- rm0 = neon_load_reg(a->vm, 0);
486
- rm1 = neon_load_reg(a->vm, 1);
487
+ read_neon_element32(rm0, a->vm, 0, MO_32);
488
+ read_neon_element32(rm1, a->vm, 1, MO_32);
489
490
widenfn(rd, rm0);
491
tcg_gen_shli_i64(rd, rd, 8 << a->size);
492
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
493
494
fpst = fpstatus_ptr(FPST_STD);
495
ahp = get_ahp_flag();
496
- tmp = neon_load_reg(a->vm, 0);
497
+ tmp = tcg_temp_new_i32();
498
+ read_neon_element32(tmp, a->vm, 0, MO_32);
499
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
500
- tmp2 = neon_load_reg(a->vm, 1);
501
+ tmp2 = tcg_temp_new_i32();
502
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
503
gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
504
tcg_gen_shli_i32(tmp2, tmp2, 16);
505
tcg_gen_or_i32(tmp2, tmp2, tmp);
506
- tcg_temp_free_i32(tmp);
507
- tmp = neon_load_reg(a->vm, 2);
508
+ read_neon_element32(tmp, a->vm, 2, MO_32);
509
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
510
- tmp3 = neon_load_reg(a->vm, 3);
511
- neon_store_reg(a->vd, 0, tmp2);
512
+ tmp3 = tcg_temp_new_i32();
513
+ read_neon_element32(tmp3, a->vm, 3, MO_32);
514
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
515
+ tcg_temp_free_i32(tmp2);
516
gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
517
tcg_gen_shli_i32(tmp3, tmp3, 16);
518
tcg_gen_or_i32(tmp3, tmp3, tmp);
519
- neon_store_reg(a->vd, 1, tmp3);
520
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
521
+ tcg_temp_free_i32(tmp3);
522
tcg_temp_free_i32(tmp);
523
tcg_temp_free_i32(ahp);
524
tcg_temp_free_ptr(fpst);
525
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
526
fpst = fpstatus_ptr(FPST_STD);
527
ahp = get_ahp_flag();
528
tmp3 = tcg_temp_new_i32();
529
- tmp = neon_load_reg(a->vm, 0);
530
- tmp2 = neon_load_reg(a->vm, 1);
531
+ tmp2 = tcg_temp_new_i32();
532
+ tmp = tcg_temp_new_i32();
533
+ read_neon_element32(tmp, a->vm, 0, MO_32);
534
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
535
tcg_gen_ext16u_i32(tmp3, tmp);
536
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
537
- neon_store_reg(a->vd, 0, tmp3);
538
+ write_neon_element32(tmp3, a->vd, 0, MO_32);
539
tcg_gen_shri_i32(tmp, tmp, 16);
540
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
541
- neon_store_reg(a->vd, 1, tmp);
542
- tmp3 = tcg_temp_new_i32();
543
+ write_neon_element32(tmp, a->vd, 1, MO_32);
544
+ tcg_temp_free_i32(tmp);
545
tcg_gen_ext16u_i32(tmp3, tmp2);
546
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
547
- neon_store_reg(a->vd, 2, tmp3);
548
+ write_neon_element32(tmp3, a->vd, 2, MO_32);
549
+ tcg_temp_free_i32(tmp3);
550
tcg_gen_shri_i32(tmp2, tmp2, 16);
551
gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
552
- neon_store_reg(a->vd, 3, tmp2);
553
+ write_neon_element32(tmp2, a->vd, 3, MO_32);
554
+ tcg_temp_free_i32(tmp2);
555
tcg_temp_free_i32(ahp);
556
tcg_temp_free_ptr(fpst);
557
558
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
559
560
static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
561
{
562
+ TCGv_i32 tmp;
563
int pass;
564
565
/* Handle a 2-reg-misc operation by iterating 32 bits at a time */
566
@@ -XXX,XX +XXX,XX @@ static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
567
return true;
568
}
569
570
+ tmp = tcg_temp_new_i32();
571
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
572
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
573
+ read_neon_element32(tmp, a->vm, pass, MO_32);
574
fn(tmp, tmp);
575
- neon_store_reg(a->vd, pass, tmp);
576
+ write_neon_element32(tmp, a->vd, pass, MO_32);
577
}
578
+ tcg_temp_free_i32(tmp);
579
580
return true;
581
}
582
@@ -XXX,XX +XXX,XX @@ static bool trans_VTRN(DisasContext *s, arg_2misc *a)
583
return true;
584
}
585
586
- if (a->size == 2) {
587
+ tmp = tcg_temp_new_i32();
588
+ tmp2 = tcg_temp_new_i32();
589
+ if (a->size == MO_32) {
590
for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) {
591
- tmp = neon_load_reg(a->vm, pass);
592
- tmp2 = neon_load_reg(a->vd, pass + 1);
593
- neon_store_reg(a->vm, pass, tmp2);
594
- neon_store_reg(a->vd, pass + 1, tmp);
595
+ read_neon_element32(tmp, a->vm, pass, MO_32);
596
+ read_neon_element32(tmp2, a->vd, pass + 1, MO_32);
597
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
598
+ write_neon_element32(tmp, a->vd, pass + 1, MO_32);
599
}
600
} else {
601
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
602
- tmp = neon_load_reg(a->vm, pass);
603
- tmp2 = neon_load_reg(a->vd, pass);
604
- if (a->size == 0) {
605
+ read_neon_element32(tmp, a->vm, pass, MO_32);
606
+ read_neon_element32(tmp2, a->vd, pass, MO_32);
607
+ if (a->size == MO_8) {
608
gen_neon_trn_u8(tmp, tmp2);
609
} else {
610
gen_neon_trn_u16(tmp, tmp2);
611
}
612
- neon_store_reg(a->vm, pass, tmp2);
613
- neon_store_reg(a->vd, pass, tmp);
614
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
615
+ write_neon_element32(tmp, a->vd, pass, MO_32);
616
}
617
}
618
+ tcg_temp_free_i32(tmp);
619
+ tcg_temp_free_i32(tmp2);
620
return true;
70
}
621
}
71
--
622
--
72
2.7.4
623
2.20.1
73
624
74
625
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
We can then use this to improve VMOV (scalar to gp) and
4
VMOV (gp to scalar) so that we simply perform the memory
5
operation that we wanted, rather than inserting or
6
extracting from a 32-bit quantity.
7
8
These were the last uses of neon_load/store_reg, so remove them.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20201030022618.785675-7-richard.henderson@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/translate.c | 50 +++++++++++++-----------
16
target/arm/translate-vfp.c.inc | 71 +++++-----------------------------
17
2 files changed, 37 insertions(+), 84 deletions(-)
18
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate.c
22
+++ b/target/arm/translate.c
23
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
24
* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
25
* where 0 is the least significant end of the register.
26
*/
27
-static long neon_element_offset(int reg, int element, MemOp size)
28
+static long neon_element_offset(int reg, int element, MemOp memop)
29
{
30
- int element_size = 1 << size;
31
+ int element_size = 1 << (memop & MO_SIZE);
32
int ofs = element * element_size;
33
#ifdef HOST_WORDS_BIGENDIAN
34
/*
35
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
36
}
37
}
38
39
-static TCGv_i32 neon_load_reg(int reg, int pass)
40
-{
41
- TCGv_i32 tmp = tcg_temp_new_i32();
42
- tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
43
- return tmp;
44
-}
45
-
46
-static void neon_store_reg(int reg, int pass, TCGv_i32 var)
47
-{
48
- tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
49
- tcg_temp_free_i32(var);
50
-}
51
-
52
static inline void neon_load_reg64(TCGv_i64 var, int reg)
53
{
54
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
55
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
56
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
57
}
58
59
-static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
60
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
61
{
62
- long off = neon_element_offset(reg, ele, size);
63
+ long off = neon_element_offset(reg, ele, memop);
64
65
- switch (size) {
66
- case MO_32:
67
+ switch (memop) {
68
+ case MO_SB:
69
+ tcg_gen_ld8s_i32(dest, cpu_env, off);
70
+ break;
71
+ case MO_UB:
72
+ tcg_gen_ld8u_i32(dest, cpu_env, off);
73
+ break;
74
+ case MO_SW:
75
+ tcg_gen_ld16s_i32(dest, cpu_env, off);
76
+ break;
77
+ case MO_UW:
78
+ tcg_gen_ld16u_i32(dest, cpu_env, off);
79
+ break;
80
+ case MO_UL:
81
+ case MO_SL:
82
tcg_gen_ld_i32(dest, cpu_env, off);
83
break;
84
default:
85
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
86
}
87
}
88
89
-static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
90
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
91
{
92
- long off = neon_element_offset(reg, ele, size);
93
+ long off = neon_element_offset(reg, ele, memop);
94
95
- switch (size) {
96
+ switch (memop) {
97
+ case MO_8:
98
+ tcg_gen_st8_i32(src, cpu_env, off);
99
+ break;
100
+ case MO_16:
101
+ tcg_gen_st16_i32(src, cpu_env, off);
102
+ break;
103
case MO_32:
104
tcg_gen_st_i32(src, cpu_env, off);
105
break;
106
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-vfp.c.inc
109
+++ b/target/arm/translate-vfp.c.inc
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
111
{
112
/* VMOV scalar to general purpose register */
113
TCGv_i32 tmp;
114
- int pass;
115
- uint32_t offset;
116
117
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
118
- if (a->size == 2
119
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
120
+ if (a->size == MO_32
121
? !dc_isar_feature(aa32_fpsp_v2, s)
122
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
123
return false;
124
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
125
return false;
126
}
127
128
- offset = a->index << a->size;
129
- pass = extract32(offset, 2, 1);
130
- offset = extract32(offset, 0, 2) * 8;
131
-
132
if (!vfp_access_check(s)) {
133
return true;
134
}
135
136
- tmp = neon_load_reg(a->vn, pass);
137
- switch (a->size) {
138
- case 0:
139
- if (offset) {
140
- tcg_gen_shri_i32(tmp, tmp, offset);
141
- }
142
- if (a->u) {
143
- gen_uxtb(tmp);
144
- } else {
145
- gen_sxtb(tmp);
146
- }
147
- break;
148
- case 1:
149
- if (a->u) {
150
- if (offset) {
151
- tcg_gen_shri_i32(tmp, tmp, 16);
152
- } else {
153
- gen_uxth(tmp);
154
- }
155
- } else {
156
- if (offset) {
157
- tcg_gen_sari_i32(tmp, tmp, 16);
158
- } else {
159
- gen_sxth(tmp);
160
- }
161
- }
162
- break;
163
- case 2:
164
- break;
165
- }
166
+ tmp = tcg_temp_new_i32();
167
+ read_neon_element32(tmp, a->vn, a->index, a->size | (a->u ? 0 : MO_SIGN));
168
store_reg(s, a->rt, tmp);
169
170
return true;
171
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
172
static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
173
{
174
/* VMOV general purpose register to scalar */
175
- TCGv_i32 tmp, tmp2;
176
- int pass;
177
- uint32_t offset;
178
+ TCGv_i32 tmp;
179
180
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
181
- if (a->size == 2
182
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
183
+ if (a->size == MO_32
184
? !dc_isar_feature(aa32_fpsp_v2, s)
185
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
186
return false;
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
188
return false;
189
}
190
191
- offset = a->index << a->size;
192
- pass = extract32(offset, 2, 1);
193
- offset = extract32(offset, 0, 2) * 8;
194
-
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
199
tmp = load_reg(s, a->rt);
200
- switch (a->size) {
201
- case 0:
202
- tmp2 = neon_load_reg(a->vn, pass);
203
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
204
- tcg_temp_free_i32(tmp2);
205
- break;
206
- case 1:
207
- tmp2 = neon_load_reg(a->vn, pass);
208
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
209
- tcg_temp_free_i32(tmp2);
210
- break;
211
- case 2:
212
- break;
213
- }
214
- neon_store_reg(a->vn, pass, tmp);
215
+ write_neon_element32(tmp, a->vn, a->index, a->size);
216
+ tcg_temp_free_i32(tmp);
217
218
return true;
219
}
220
--
221
2.20.1
222
223
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The only uses of this function are for loading VFP
4
single-precision values, and nothing to do with NEON.
5
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-8-richard.henderson@linaro.org
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180110063337.21538-3-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/translate-a64.c | 5 +++++
11
target/arm/translate.c | 4 +-
9
1 file changed, 5 insertions(+)
12
target/arm/translate-vfp.c.inc | 184 ++++++++++++++++-----------------
13
2 files changed, 94 insertions(+), 94 deletions(-)
10
14
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate.c
14
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static uint64_t vfp_expand_imm(int size, uint8_t imm8)
19
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg64(TCGv_i64 var, int reg)
16
(extract32(imm8, 0, 6) << 3);
20
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
17
imm <<= 16;
21
}
18
break;
22
19
+ case MO_16:
23
-static inline void neon_load_reg32(TCGv_i32 var, int reg)
20
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
24
+static inline void vfp_load_reg32(TCGv_i32 var, int reg)
21
+ (extract32(imm8, 6, 1) ? 0x3000 : 0x4000) |
25
{
22
+ (extract32(imm8, 0, 6) << 6);
26
tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
23
+ break;
27
}
24
default:
28
29
-static inline void neon_store_reg32(TCGv_i32 var, int reg)
30
+static inline void vfp_store_reg32(TCGv_i32 var, int reg)
31
{
32
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
33
}
34
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-vfp.c.inc
37
+++ b/target/arm/translate-vfp.c.inc
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
39
frn = tcg_temp_new_i32();
40
frm = tcg_temp_new_i32();
41
dest = tcg_temp_new_i32();
42
- neon_load_reg32(frn, rn);
43
- neon_load_reg32(frm, rm);
44
+ vfp_load_reg32(frn, rn);
45
+ vfp_load_reg32(frm, rm);
46
switch (a->cc) {
47
case 0: /* eq: Z */
48
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
50
if (sz == 1) {
51
tcg_gen_andi_i32(dest, dest, 0xffff);
52
}
53
- neon_store_reg32(dest, rd);
54
+ vfp_store_reg32(dest, rd);
55
tcg_temp_free_i32(frn);
56
tcg_temp_free_i32(frm);
57
tcg_temp_free_i32(dest);
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
59
TCGv_i32 tcg_res;
60
tcg_op = tcg_temp_new_i32();
61
tcg_res = tcg_temp_new_i32();
62
- neon_load_reg32(tcg_op, rm);
63
+ vfp_load_reg32(tcg_op, rm);
64
if (sz == 1) {
65
gen_helper_rinth(tcg_res, tcg_op, fpst);
66
} else {
67
gen_helper_rints(tcg_res, tcg_op, fpst);
68
}
69
- neon_store_reg32(tcg_res, rd);
70
+ vfp_store_reg32(tcg_res, rd);
71
tcg_temp_free_i32(tcg_op);
72
tcg_temp_free_i32(tcg_res);
73
}
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
75
gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
76
}
77
tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
78
- neon_store_reg32(tcg_tmp, rd);
79
+ vfp_store_reg32(tcg_tmp, rd);
80
tcg_temp_free_i32(tcg_tmp);
81
tcg_temp_free_i64(tcg_res);
82
tcg_temp_free_i64(tcg_double);
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
84
TCGv_i32 tcg_single, tcg_res;
85
tcg_single = tcg_temp_new_i32();
86
tcg_res = tcg_temp_new_i32();
87
- neon_load_reg32(tcg_single, rm);
88
+ vfp_load_reg32(tcg_single, rm);
89
if (sz == 1) {
90
if (is_signed) {
91
gen_helper_vfp_toslh(tcg_res, tcg_single, tcg_shift, fpst);
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
93
gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
94
}
95
}
96
- neon_store_reg32(tcg_res, rd);
97
+ vfp_store_reg32(tcg_res, rd);
98
tcg_temp_free_i32(tcg_res);
99
tcg_temp_free_i32(tcg_single);
100
}
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a)
102
if (a->l) {
103
/* VFP to general purpose register */
104
tmp = tcg_temp_new_i32();
105
- neon_load_reg32(tmp, a->vn);
106
+ vfp_load_reg32(tmp, a->vn);
107
tcg_gen_andi_i32(tmp, tmp, 0xffff);
108
store_reg(s, a->rt, tmp);
109
} else {
110
/* general purpose register to VFP */
111
tmp = load_reg(s, a->rt);
112
tcg_gen_andi_i32(tmp, tmp, 0xffff);
113
- neon_store_reg32(tmp, a->vn);
114
+ vfp_store_reg32(tmp, a->vn);
115
tcg_temp_free_i32(tmp);
116
}
117
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
119
if (a->l) {
120
/* VFP to general purpose register */
121
tmp = tcg_temp_new_i32();
122
- neon_load_reg32(tmp, a->vn);
123
+ vfp_load_reg32(tmp, a->vn);
124
if (a->rt == 15) {
125
/* Set the 4 flag bits in the CPSR. */
126
gen_set_nzcv(tmp);
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
128
} else {
129
/* general purpose register to VFP */
130
tmp = load_reg(s, a->rt);
131
- neon_store_reg32(tmp, a->vn);
132
+ vfp_store_reg32(tmp, a->vn);
133
tcg_temp_free_i32(tmp);
134
}
135
136
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
137
if (a->op) {
138
/* fpreg to gpreg */
139
tmp = tcg_temp_new_i32();
140
- neon_load_reg32(tmp, a->vm);
141
+ vfp_load_reg32(tmp, a->vm);
142
store_reg(s, a->rt, tmp);
143
tmp = tcg_temp_new_i32();
144
- neon_load_reg32(tmp, a->vm + 1);
145
+ vfp_load_reg32(tmp, a->vm + 1);
146
store_reg(s, a->rt2, tmp);
147
} else {
148
/* gpreg to fpreg */
149
tmp = load_reg(s, a->rt);
150
- neon_store_reg32(tmp, a->vm);
151
+ vfp_store_reg32(tmp, a->vm);
152
tcg_temp_free_i32(tmp);
153
tmp = load_reg(s, a->rt2);
154
- neon_store_reg32(tmp, a->vm + 1);
155
+ vfp_store_reg32(tmp, a->vm + 1);
156
tcg_temp_free_i32(tmp);
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
160
if (a->op) {
161
/* fpreg to gpreg */
162
tmp = tcg_temp_new_i32();
163
- neon_load_reg32(tmp, a->vm * 2);
164
+ vfp_load_reg32(tmp, a->vm * 2);
165
store_reg(s, a->rt, tmp);
166
tmp = tcg_temp_new_i32();
167
- neon_load_reg32(tmp, a->vm * 2 + 1);
168
+ vfp_load_reg32(tmp, a->vm * 2 + 1);
169
store_reg(s, a->rt2, tmp);
170
} else {
171
/* gpreg to fpreg */
172
tmp = load_reg(s, a->rt);
173
- neon_store_reg32(tmp, a->vm * 2);
174
+ vfp_store_reg32(tmp, a->vm * 2);
175
tcg_temp_free_i32(tmp);
176
tmp = load_reg(s, a->rt2);
177
- neon_store_reg32(tmp, a->vm * 2 + 1);
178
+ vfp_store_reg32(tmp, a->vm * 2 + 1);
179
tcg_temp_free_i32(tmp);
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
183
tmp = tcg_temp_new_i32();
184
if (a->l) {
185
gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
186
- neon_store_reg32(tmp, a->vd);
187
+ vfp_store_reg32(tmp, a->vd);
188
} else {
189
- neon_load_reg32(tmp, a->vd);
190
+ vfp_load_reg32(tmp, a->vd);
191
gen_aa32_st16(s, tmp, addr, get_mem_index(s));
192
}
193
tcg_temp_free_i32(tmp);
194
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
195
tmp = tcg_temp_new_i32();
196
if (a->l) {
197
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
198
- neon_store_reg32(tmp, a->vd);
199
+ vfp_store_reg32(tmp, a->vd);
200
} else {
201
- neon_load_reg32(tmp, a->vd);
202
+ vfp_load_reg32(tmp, a->vd);
203
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
204
}
205
tcg_temp_free_i32(tmp);
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
207
if (a->l) {
208
/* load */
209
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
210
- neon_store_reg32(tmp, a->vd + i);
211
+ vfp_store_reg32(tmp, a->vd + i);
212
} else {
213
/* store */
214
- neon_load_reg32(tmp, a->vd + i);
215
+ vfp_load_reg32(tmp, a->vd + i);
216
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
217
}
218
tcg_gen_addi_i32(addr, addr, offset);
219
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
220
fd = tcg_temp_new_i32();
221
fpst = fpstatus_ptr(FPST_FPCR);
222
223
- neon_load_reg32(f0, vn);
224
- neon_load_reg32(f1, vm);
225
+ vfp_load_reg32(f0, vn);
226
+ vfp_load_reg32(f1, vm);
227
228
for (;;) {
229
if (reads_vd) {
230
- neon_load_reg32(fd, vd);
231
+ vfp_load_reg32(fd, vd);
232
}
233
fn(fd, f0, f1, fpst);
234
- neon_store_reg32(fd, vd);
235
+ vfp_store_reg32(fd, vd);
236
237
if (veclen == 0) {
238
break;
239
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
240
veclen--;
241
vd = vfp_advance_sreg(vd, delta_d);
242
vn = vfp_advance_sreg(vn, delta_d);
243
- neon_load_reg32(f0, vn);
244
+ vfp_load_reg32(f0, vn);
245
if (delta_m) {
246
vm = vfp_advance_sreg(vm, delta_m);
247
- neon_load_reg32(f1, vm);
248
+ vfp_load_reg32(f1, vm);
249
}
250
}
251
252
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn,
253
fd = tcg_temp_new_i32();
254
fpst = fpstatus_ptr(FPST_FPCR_F16);
255
256
- neon_load_reg32(f0, vn);
257
- neon_load_reg32(f1, vm);
258
+ vfp_load_reg32(f0, vn);
259
+ vfp_load_reg32(f1, vm);
260
261
if (reads_vd) {
262
- neon_load_reg32(fd, vd);
263
+ vfp_load_reg32(fd, vd);
264
}
265
fn(fd, f0, f1, fpst);
266
- neon_store_reg32(fd, vd);
267
+ vfp_store_reg32(fd, vd);
268
269
tcg_temp_free_i32(f0);
270
tcg_temp_free_i32(f1);
271
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
272
f0 = tcg_temp_new_i32();
273
fd = tcg_temp_new_i32();
274
275
- neon_load_reg32(f0, vm);
276
+ vfp_load_reg32(f0, vm);
277
278
for (;;) {
279
fn(fd, f0);
280
- neon_store_reg32(fd, vd);
281
+ vfp_store_reg32(fd, vd);
282
283
if (veclen == 0) {
284
break;
285
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
286
/* single source one-many */
287
while (veclen--) {
288
vd = vfp_advance_sreg(vd, delta_d);
289
- neon_store_reg32(fd, vd);
290
+ vfp_store_reg32(fd, vd);
291
}
292
break;
293
}
294
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
295
veclen--;
296
vd = vfp_advance_sreg(vd, delta_d);
297
vm = vfp_advance_sreg(vm, delta_m);
298
- neon_load_reg32(f0, vm);
299
+ vfp_load_reg32(f0, vm);
300
}
301
302
tcg_temp_free_i32(f0);
303
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_hp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
304
}
305
306
f0 = tcg_temp_new_i32();
307
- neon_load_reg32(f0, vm);
308
+ vfp_load_reg32(f0, vm);
309
fn(f0, f0);
310
- neon_store_reg32(f0, vd);
311
+ vfp_store_reg32(f0, vd);
312
tcg_temp_free_i32(f0);
313
314
return true;
315
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_hp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
316
vm = tcg_temp_new_i32();
317
vd = tcg_temp_new_i32();
318
319
- neon_load_reg32(vn, a->vn);
320
- neon_load_reg32(vm, a->vm);
321
+ vfp_load_reg32(vn, a->vn);
322
+ vfp_load_reg32(vm, a->vm);
323
if (neg_n) {
324
/* VFNMS, VFMS */
325
gen_helper_vfp_negh(vn, vn);
326
}
327
- neon_load_reg32(vd, a->vd);
328
+ vfp_load_reg32(vd, a->vd);
329
if (neg_d) {
330
/* VFNMA, VFNMS */
331
gen_helper_vfp_negh(vd, vd);
332
}
333
fpst = fpstatus_ptr(FPST_FPCR_F16);
334
gen_helper_vfp_muladdh(vd, vn, vm, vd, fpst);
335
- neon_store_reg32(vd, a->vd);
336
+ vfp_store_reg32(vd, a->vd);
337
338
tcg_temp_free_ptr(fpst);
339
tcg_temp_free_i32(vn);
340
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
341
vm = tcg_temp_new_i32();
342
vd = tcg_temp_new_i32();
343
344
- neon_load_reg32(vn, a->vn);
345
- neon_load_reg32(vm, a->vm);
346
+ vfp_load_reg32(vn, a->vn);
347
+ vfp_load_reg32(vm, a->vm);
348
if (neg_n) {
349
/* VFNMS, VFMS */
350
gen_helper_vfp_negs(vn, vn);
351
}
352
- neon_load_reg32(vd, a->vd);
353
+ vfp_load_reg32(vd, a->vd);
354
if (neg_d) {
355
/* VFNMA, VFNMS */
356
gen_helper_vfp_negs(vd, vd);
357
}
358
fpst = fpstatus_ptr(FPST_FPCR);
359
gen_helper_vfp_muladds(vd, vn, vm, vd, fpst);
360
- neon_store_reg32(vd, a->vd);
361
+ vfp_store_reg32(vd, a->vd);
362
363
tcg_temp_free_ptr(fpst);
364
tcg_temp_free_i32(vn);
365
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_hp(DisasContext *s, arg_VMOV_imm_sp *a)
366
}
367
368
fd = tcg_const_i32(vfp_expand_imm(MO_16, a->imm));
369
- neon_store_reg32(fd, a->vd);
370
+ vfp_store_reg32(fd, a->vd);
371
tcg_temp_free_i32(fd);
372
return true;
373
}
374
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
375
fd = tcg_const_i32(vfp_expand_imm(MO_32, a->imm));
376
377
for (;;) {
378
- neon_store_reg32(fd, vd);
379
+ vfp_store_reg32(fd, vd);
380
381
if (veclen == 0) {
382
break;
383
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
384
vd = tcg_temp_new_i32();
385
vm = tcg_temp_new_i32();
386
387
- neon_load_reg32(vd, a->vd);
388
+ vfp_load_reg32(vd, a->vd);
389
if (a->z) {
390
tcg_gen_movi_i32(vm, 0);
391
} else {
392
- neon_load_reg32(vm, a->vm);
393
+ vfp_load_reg32(vm, a->vm);
394
}
395
396
if (a->e) {
397
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
398
vd = tcg_temp_new_i32();
399
vm = tcg_temp_new_i32();
400
401
- neon_load_reg32(vd, a->vd);
402
+ vfp_load_reg32(vd, a->vd);
403
if (a->z) {
404
tcg_gen_movi_i32(vm, 0);
405
} else {
406
- neon_load_reg32(vm, a->vm);
407
+ vfp_load_reg32(vm, a->vm);
408
}
409
410
if (a->e) {
411
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f32_f16(DisasContext *s, arg_VCVT_f32_f16 *a)
412
/* The T bit tells us if we want the low or high 16 bits of Vm */
413
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
414
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp_mode);
415
- neon_store_reg32(tmp, a->vd);
416
+ vfp_store_reg32(tmp, a->vd);
417
tcg_temp_free_i32(ahp_mode);
418
tcg_temp_free_ptr(fpst);
419
tcg_temp_free_i32(tmp);
420
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a)
421
ahp_mode = get_ahp_flag();
422
tmp = tcg_temp_new_i32();
423
424
- neon_load_reg32(tmp, a->vm);
425
+ vfp_load_reg32(tmp, a->vm);
426
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp_mode);
427
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
428
tcg_temp_free_i32(ahp_mode);
429
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_hp(DisasContext *s, arg_VRINTR_sp *a)
430
}
431
432
tmp = tcg_temp_new_i32();
433
- neon_load_reg32(tmp, a->vm);
434
+ vfp_load_reg32(tmp, a->vm);
435
fpst = fpstatus_ptr(FPST_FPCR_F16);
436
gen_helper_rinth(tmp, tmp, fpst);
437
- neon_store_reg32(tmp, a->vd);
438
+ vfp_store_reg32(tmp, a->vd);
439
tcg_temp_free_ptr(fpst);
440
tcg_temp_free_i32(tmp);
441
return true;
442
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
443
}
444
445
tmp = tcg_temp_new_i32();
446
- neon_load_reg32(tmp, a->vm);
447
+ vfp_load_reg32(tmp, a->vm);
448
fpst = fpstatus_ptr(FPST_FPCR);
449
gen_helper_rints(tmp, tmp, fpst);
450
- neon_store_reg32(tmp, a->vd);
451
+ vfp_store_reg32(tmp, a->vd);
452
tcg_temp_free_ptr(fpst);
453
tcg_temp_free_i32(tmp);
454
return true;
455
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_hp(DisasContext *s, arg_VRINTZ_sp *a)
456
}
457
458
tmp = tcg_temp_new_i32();
459
- neon_load_reg32(tmp, a->vm);
460
+ vfp_load_reg32(tmp, a->vm);
461
fpst = fpstatus_ptr(FPST_FPCR_F16);
462
tcg_rmode = tcg_const_i32(float_round_to_zero);
463
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
464
gen_helper_rinth(tmp, tmp, fpst);
465
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
466
- neon_store_reg32(tmp, a->vd);
467
+ vfp_store_reg32(tmp, a->vd);
468
tcg_temp_free_ptr(fpst);
469
tcg_temp_free_i32(tcg_rmode);
470
tcg_temp_free_i32(tmp);
471
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
472
}
473
474
tmp = tcg_temp_new_i32();
475
- neon_load_reg32(tmp, a->vm);
476
+ vfp_load_reg32(tmp, a->vm);
477
fpst = fpstatus_ptr(FPST_FPCR);
478
tcg_rmode = tcg_const_i32(float_round_to_zero);
479
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
480
gen_helper_rints(tmp, tmp, fpst);
481
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
482
- neon_store_reg32(tmp, a->vd);
483
+ vfp_store_reg32(tmp, a->vd);
484
tcg_temp_free_ptr(fpst);
485
tcg_temp_free_i32(tcg_rmode);
486
tcg_temp_free_i32(tmp);
487
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_hp(DisasContext *s, arg_VRINTX_sp *a)
488
}
489
490
tmp = tcg_temp_new_i32();
491
- neon_load_reg32(tmp, a->vm);
492
+ vfp_load_reg32(tmp, a->vm);
493
fpst = fpstatus_ptr(FPST_FPCR_F16);
494
gen_helper_rinth_exact(tmp, tmp, fpst);
495
- neon_store_reg32(tmp, a->vd);
496
+ vfp_store_reg32(tmp, a->vd);
497
tcg_temp_free_ptr(fpst);
498
tcg_temp_free_i32(tmp);
499
return true;
500
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_sp(DisasContext *s, arg_VRINTX_sp *a)
501
}
502
503
tmp = tcg_temp_new_i32();
504
- neon_load_reg32(tmp, a->vm);
505
+ vfp_load_reg32(tmp, a->vm);
506
fpst = fpstatus_ptr(FPST_FPCR);
507
gen_helper_rints_exact(tmp, tmp, fpst);
508
- neon_store_reg32(tmp, a->vd);
509
+ vfp_store_reg32(tmp, a->vd);
510
tcg_temp_free_ptr(fpst);
511
tcg_temp_free_i32(tmp);
512
return true;
513
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
514
515
vm = tcg_temp_new_i32();
516
vd = tcg_temp_new_i64();
517
- neon_load_reg32(vm, a->vm);
518
+ vfp_load_reg32(vm, a->vm);
519
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
520
neon_store_reg64(vd, a->vd);
521
tcg_temp_free_i32(vm);
522
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
523
vm = tcg_temp_new_i64();
524
neon_load_reg64(vm, a->vm);
525
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
526
- neon_store_reg32(vd, a->vd);
527
+ vfp_store_reg32(vd, a->vd);
528
tcg_temp_free_i32(vd);
529
tcg_temp_free_i64(vm);
530
return true;
531
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
532
}
533
534
vm = tcg_temp_new_i32();
535
- neon_load_reg32(vm, a->vm);
536
+ vfp_load_reg32(vm, a->vm);
537
fpst = fpstatus_ptr(FPST_FPCR_F16);
538
if (a->s) {
539
/* i32 -> f16 */
540
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
541
/* u32 -> f16 */
542
gen_helper_vfp_uitoh(vm, vm, fpst);
543
}
544
- neon_store_reg32(vm, a->vd);
545
+ vfp_store_reg32(vm, a->vd);
546
tcg_temp_free_i32(vm);
547
tcg_temp_free_ptr(fpst);
548
return true;
549
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
550
}
551
552
vm = tcg_temp_new_i32();
553
- neon_load_reg32(vm, a->vm);
554
+ vfp_load_reg32(vm, a->vm);
555
fpst = fpstatus_ptr(FPST_FPCR);
556
if (a->s) {
557
/* i32 -> f32 */
558
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
559
/* u32 -> f32 */
560
gen_helper_vfp_uitos(vm, vm, fpst);
561
}
562
- neon_store_reg32(vm, a->vd);
563
+ vfp_store_reg32(vm, a->vd);
564
tcg_temp_free_i32(vm);
565
tcg_temp_free_ptr(fpst);
566
return true;
567
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
568
569
vm = tcg_temp_new_i32();
570
vd = tcg_temp_new_i64();
571
- neon_load_reg32(vm, a->vm);
572
+ vfp_load_reg32(vm, a->vm);
573
fpst = fpstatus_ptr(FPST_FPCR);
574
if (a->s) {
575
/* i32 -> f64 */
576
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
577
vd = tcg_temp_new_i32();
578
neon_load_reg64(vm, a->vm);
579
gen_helper_vjcvt(vd, vm, cpu_env);
580
- neon_store_reg32(vd, a->vd);
581
+ vfp_store_reg32(vd, a->vd);
582
tcg_temp_free_i64(vm);
583
tcg_temp_free_i32(vd);
584
return true;
585
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
586
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
587
588
vd = tcg_temp_new_i32();
589
- neon_load_reg32(vd, a->vd);
590
+ vfp_load_reg32(vd, a->vd);
591
592
fpst = fpstatus_ptr(FPST_FPCR_F16);
593
shift = tcg_const_i32(frac_bits);
594
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
25
g_assert_not_reached();
595
g_assert_not_reached();
26
}
596
}
597
598
- neon_store_reg32(vd, a->vd);
599
+ vfp_store_reg32(vd, a->vd);
600
tcg_temp_free_i32(vd);
601
tcg_temp_free_i32(shift);
602
tcg_temp_free_ptr(fpst);
603
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
604
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
605
606
vd = tcg_temp_new_i32();
607
- neon_load_reg32(vd, a->vd);
608
+ vfp_load_reg32(vd, a->vd);
609
610
fpst = fpstatus_ptr(FPST_FPCR);
611
shift = tcg_const_i32(frac_bits);
612
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
613
g_assert_not_reached();
614
}
615
616
- neon_store_reg32(vd, a->vd);
617
+ vfp_store_reg32(vd, a->vd);
618
tcg_temp_free_i32(vd);
619
tcg_temp_free_i32(shift);
620
tcg_temp_free_ptr(fpst);
621
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
622
623
fpst = fpstatus_ptr(FPST_FPCR_F16);
624
vm = tcg_temp_new_i32();
625
- neon_load_reg32(vm, a->vm);
626
+ vfp_load_reg32(vm, a->vm);
627
628
if (a->s) {
629
if (a->rz) {
630
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
631
gen_helper_vfp_touih(vm, vm, fpst);
632
}
633
}
634
- neon_store_reg32(vm, a->vd);
635
+ vfp_store_reg32(vm, a->vd);
636
tcg_temp_free_i32(vm);
637
tcg_temp_free_ptr(fpst);
638
return true;
639
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
640
641
fpst = fpstatus_ptr(FPST_FPCR);
642
vm = tcg_temp_new_i32();
643
- neon_load_reg32(vm, a->vm);
644
+ vfp_load_reg32(vm, a->vm);
645
646
if (a->s) {
647
if (a->rz) {
648
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
649
gen_helper_vfp_touis(vm, vm, fpst);
650
}
651
}
652
- neon_store_reg32(vm, a->vd);
653
+ vfp_store_reg32(vm, a->vd);
654
tcg_temp_free_i32(vm);
655
tcg_temp_free_ptr(fpst);
656
return true;
657
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
658
gen_helper_vfp_touid(vd, vm, fpst);
659
}
660
}
661
- neon_store_reg32(vd, a->vd);
662
+ vfp_store_reg32(vd, a->vd);
663
tcg_temp_free_i32(vd);
664
tcg_temp_free_i64(vm);
665
tcg_temp_free_ptr(fpst);
666
@@ -XXX,XX +XXX,XX @@ static bool trans_VINS(DisasContext *s, arg_VINS *a)
667
/* Insert low half of Vm into high half of Vd */
668
rm = tcg_temp_new_i32();
669
rd = tcg_temp_new_i32();
670
- neon_load_reg32(rm, a->vm);
671
- neon_load_reg32(rd, a->vd);
672
+ vfp_load_reg32(rm, a->vm);
673
+ vfp_load_reg32(rd, a->vd);
674
tcg_gen_deposit_i32(rd, rd, rm, 16, 16);
675
- neon_store_reg32(rd, a->vd);
676
+ vfp_store_reg32(rd, a->vd);
677
tcg_temp_free_i32(rm);
678
tcg_temp_free_i32(rd);
679
return true;
680
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOVX(DisasContext *s, arg_VINS *a)
681
682
/* Set Vd to high half of Vm */
683
rm = tcg_temp_new_i32();
684
- neon_load_reg32(rm, a->vm);
685
+ vfp_load_reg32(rm, a->vm);
686
tcg_gen_shri_i32(rm, rm, 16);
687
- neon_store_reg32(rm, a->vd);
688
+ vfp_store_reg32(rm, a->vd);
689
tcg_temp_free_i32(rm);
690
return true;
691
}
27
--
692
--
28
2.7.4
693
2.20.1
29
694
30
695
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Replace all uses of neon_load/store_reg64 within translate-neon.c.inc.
4
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-9-richard.henderson@linaro.org
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180110063337.21538-2-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/translate-a64.c | 44 ++++++++++++++++++++++++++++----------------
10
target/arm/translate.c | 26 +++++++++
9
1 file changed, 28 insertions(+), 16 deletions(-)
11
target/arm/translate-neon.c.inc | 94 ++++++++++++++++-----------------
10
12
2 files changed, 73 insertions(+), 47 deletions(-)
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
16
--- a/target/arm/translate.c
14
+++ b/target/arm/translate-a64.c
17
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
18
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
16
}
19
}
17
}
20
}
18
21
19
+/* The imm8 encodes the sign bit, enough bits to represent an exponent in
22
+static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
20
+ * the range 01....1xx to 10....0xx, and the most significant 4 bits of
21
+ * the mantissa; see VFPExpandImm() in the v8 ARM ARM.
22
+ */
23
+static uint64_t vfp_expand_imm(int size, uint8_t imm8)
24
+{
23
+{
25
+ uint64_t imm;
24
+ long off = neon_element_offset(reg, ele, memop);
26
+
25
+
27
+ switch (size) {
26
+ switch (memop) {
28
+ case MO_64:
27
+ case MO_Q:
29
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
28
+ tcg_gen_ld_i64(dest, cpu_env, off);
30
+ (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
31
+ extract32(imm8, 0, 6);
32
+ imm <<= 48;
33
+ break;
34
+ case MO_32:
35
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
36
+ (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
37
+ (extract32(imm8, 0, 6) << 3);
38
+ imm <<= 16;
39
+ break;
29
+ break;
40
+ default:
30
+ default:
41
+ g_assert_not_reached();
31
+ g_assert_not_reached();
42
+ }
32
+ }
43
+ return imm;
44
+}
33
+}
45
+
34
+
46
/* Floating point immediate
35
static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
47
* 31 30 29 28 24 23 22 21 20 13 12 10 9 5 4 0
36
{
48
* +---+---+---+-----------+------+---+------------+-------+------+------+
37
long off = neon_element_offset(reg, ele, memop);
49
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
38
@@ -XXX,XX +XXX,XX @@ static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
50
return;
39
}
51
}
40
}
52
41
53
- /* The imm8 encodes the sign bit, enough bits to represent
42
+static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
54
- * an exponent in the range 01....1xx to 10....0xx,
43
+{
55
- * and the most significant 4 bits of the mantissa; see
44
+ long off = neon_element_offset(reg, ele, memop);
56
- * VFPExpandImm() in the v8 ARM ARM.
45
+
57
- */
46
+ switch (memop) {
58
- if (is_double) {
47
+ case MO_64:
59
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
48
+ tcg_gen_st_i64(src, cpu_env, off);
60
- (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
49
+ break;
61
- extract32(imm8, 0, 6);
50
+ default:
62
- imm <<= 48;
51
+ g_assert_not_reached();
63
- } else {
52
+ }
64
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
53
+}
65
- (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
54
+
66
- (extract32(imm8, 0, 6) << 3);
55
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
67
- imm <<= 16;
56
{
68
- }
57
TCGv_ptr ret = tcg_temp_new_ptr();
69
+ imm = vfp_expand_imm(MO_32 + is_double, imm8);
58
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
70
59
index XXXXXXX..XXXXXXX 100644
71
tcg_res = tcg_const_i64(imm);
60
--- a/target/arm/translate-neon.c.inc
72
write_fp_dreg(s, rd, tcg_res);
61
+++ b/target/arm/translate-neon.c.inc
62
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_64(DisasContext *s, arg_2reg_shift *a,
63
for (pass = 0; pass < a->q + 1; pass++) {
64
TCGv_i64 tmp = tcg_temp_new_i64();
65
66
- neon_load_reg64(tmp, a->vm + pass);
67
+ read_neon_element64(tmp, a->vm, pass, MO_64);
68
fn(tmp, cpu_env, tmp, constimm);
69
- neon_store_reg64(tmp, a->vd + pass);
70
+ write_neon_element64(tmp, a->vd, pass, MO_64);
71
tcg_temp_free_i64(tmp);
72
}
73
tcg_temp_free_i64(constimm);
74
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
75
rd = tcg_temp_new_i32();
76
77
/* Load both inputs first to avoid potential overwrite if rm == rd */
78
- neon_load_reg64(rm1, a->vm);
79
- neon_load_reg64(rm2, a->vm + 1);
80
+ read_neon_element64(rm1, a->vm, 0, MO_64);
81
+ read_neon_element64(rm2, a->vm, 1, MO_64);
82
83
shiftfn(rm1, rm1, constimm);
84
narrowfn(rd, cpu_env, rm1);
85
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
86
tcg_gen_shli_i64(tmp, tmp, a->shift);
87
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
88
}
89
- neon_store_reg64(tmp, a->vd);
90
+ write_neon_element64(tmp, a->vd, 0, MO_64);
91
92
widenfn(tmp, rm1);
93
tcg_temp_free_i32(rm1);
94
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
95
tcg_gen_shli_i64(tmp, tmp, a->shift);
96
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
97
}
98
- neon_store_reg64(tmp, a->vd + 1);
99
+ write_neon_element64(tmp, a->vd, 1, MO_64);
100
tcg_temp_free_i64(tmp);
101
return true;
102
}
103
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
104
rm_64 = tcg_temp_new_i64();
105
106
if (src1_wide) {
107
- neon_load_reg64(rn0_64, a->vn);
108
+ read_neon_element64(rn0_64, a->vn, 0, MO_64);
109
} else {
110
TCGv_i32 tmp = tcg_temp_new_i32();
111
read_neon_element32(tmp, a->vn, 0, MO_32);
112
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
113
* avoid incorrect results if a narrow input overlaps with the result.
114
*/
115
if (src1_wide) {
116
- neon_load_reg64(rn1_64, a->vn + 1);
117
+ read_neon_element64(rn1_64, a->vn, 1, MO_64);
118
} else {
119
TCGv_i32 tmp = tcg_temp_new_i32();
120
read_neon_element32(tmp, a->vn, 1, MO_32);
121
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
122
rm = tcg_temp_new_i32();
123
read_neon_element32(rm, a->vm, 1, MO_32);
124
125
- neon_store_reg64(rn0_64, a->vd);
126
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
127
128
widenfn(rm_64, rm);
129
tcg_temp_free_i32(rm);
130
opfn(rn1_64, rn1_64, rm_64);
131
- neon_store_reg64(rn1_64, a->vd + 1);
132
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
133
134
tcg_temp_free_i64(rn0_64);
135
tcg_temp_free_i64(rn1_64);
136
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
137
rd0 = tcg_temp_new_i32();
138
rd1 = tcg_temp_new_i32();
139
140
- neon_load_reg64(rn_64, a->vn);
141
- neon_load_reg64(rm_64, a->vm);
142
+ read_neon_element64(rn_64, a->vn, 0, MO_64);
143
+ read_neon_element64(rm_64, a->vm, 0, MO_64);
144
145
opfn(rn_64, rn_64, rm_64);
146
147
narrowfn(rd0, rn_64);
148
149
- neon_load_reg64(rn_64, a->vn + 1);
150
- neon_load_reg64(rm_64, a->vm + 1);
151
+ read_neon_element64(rn_64, a->vn, 1, MO_64);
152
+ read_neon_element64(rm_64, a->vm, 1, MO_64);
153
154
opfn(rn_64, rn_64, rm_64);
155
156
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
157
/* Don't store results until after all loads: they might overlap */
158
if (accfn) {
159
tmp = tcg_temp_new_i64();
160
- neon_load_reg64(tmp, a->vd);
161
+ read_neon_element64(tmp, a->vd, 0, MO_64);
162
accfn(tmp, tmp, rd0);
163
- neon_store_reg64(tmp, a->vd);
164
- neon_load_reg64(tmp, a->vd + 1);
165
+ write_neon_element64(tmp, a->vd, 0, MO_64);
166
+ read_neon_element64(tmp, a->vd, 1, MO_64);
167
accfn(tmp, tmp, rd1);
168
- neon_store_reg64(tmp, a->vd + 1);
169
+ write_neon_element64(tmp, a->vd, 1, MO_64);
170
tcg_temp_free_i64(tmp);
171
} else {
172
- neon_store_reg64(rd0, a->vd);
173
- neon_store_reg64(rd1, a->vd + 1);
174
+ write_neon_element64(rd0, a->vd, 0, MO_64);
175
+ write_neon_element64(rd1, a->vd, 1, MO_64);
176
}
177
178
tcg_temp_free_i64(rd0);
179
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
180
181
if (accfn) {
182
TCGv_i64 t64 = tcg_temp_new_i64();
183
- neon_load_reg64(t64, a->vd);
184
+ read_neon_element64(t64, a->vd, 0, MO_64);
185
accfn(t64, t64, rn0_64);
186
- neon_store_reg64(t64, a->vd);
187
- neon_load_reg64(t64, a->vd + 1);
188
+ write_neon_element64(t64, a->vd, 0, MO_64);
189
+ read_neon_element64(t64, a->vd, 1, MO_64);
190
accfn(t64, t64, rn1_64);
191
- neon_store_reg64(t64, a->vd + 1);
192
+ write_neon_element64(t64, a->vd, 1, MO_64);
193
tcg_temp_free_i64(t64);
194
} else {
195
- neon_store_reg64(rn0_64, a->vd);
196
- neon_store_reg64(rn1_64, a->vd + 1);
197
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
198
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
199
}
200
tcg_temp_free_i64(rn0_64);
201
tcg_temp_free_i64(rn1_64);
202
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
203
right = tcg_temp_new_i64();
204
dest = tcg_temp_new_i64();
205
206
- neon_load_reg64(right, a->vn);
207
- neon_load_reg64(left, a->vm);
208
+ read_neon_element64(right, a->vn, 0, MO_64);
209
+ read_neon_element64(left, a->vm, 0, MO_64);
210
tcg_gen_extract2_i64(dest, right, left, a->imm * 8);
211
- neon_store_reg64(dest, a->vd);
212
+ write_neon_element64(dest, a->vd, 0, MO_64);
213
214
tcg_temp_free_i64(left);
215
tcg_temp_free_i64(right);
216
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
217
destright = tcg_temp_new_i64();
218
219
if (a->imm < 8) {
220
- neon_load_reg64(right, a->vn);
221
- neon_load_reg64(middle, a->vn + 1);
222
+ read_neon_element64(right, a->vn, 0, MO_64);
223
+ read_neon_element64(middle, a->vn, 1, MO_64);
224
tcg_gen_extract2_i64(destright, right, middle, a->imm * 8);
225
- neon_load_reg64(left, a->vm);
226
+ read_neon_element64(left, a->vm, 0, MO_64);
227
tcg_gen_extract2_i64(destleft, middle, left, a->imm * 8);
228
} else {
229
- neon_load_reg64(right, a->vn + 1);
230
- neon_load_reg64(middle, a->vm);
231
+ read_neon_element64(right, a->vn, 1, MO_64);
232
+ read_neon_element64(middle, a->vm, 0, MO_64);
233
tcg_gen_extract2_i64(destright, right, middle, (a->imm - 8) * 8);
234
- neon_load_reg64(left, a->vm + 1);
235
+ read_neon_element64(left, a->vm, 1, MO_64);
236
tcg_gen_extract2_i64(destleft, middle, left, (a->imm - 8) * 8);
237
}
238
239
- neon_store_reg64(destright, a->vd);
240
- neon_store_reg64(destleft, a->vd + 1);
241
+ write_neon_element64(destright, a->vd, 0, MO_64);
242
+ write_neon_element64(destleft, a->vd, 1, MO_64);
243
244
tcg_temp_free_i64(destright);
245
tcg_temp_free_i64(destleft);
246
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
247
248
if (accfn) {
249
TCGv_i64 tmp64 = tcg_temp_new_i64();
250
- neon_load_reg64(tmp64, a->vd + pass);
251
+ read_neon_element64(tmp64, a->vd, pass, MO_64);
252
accfn(rd_64, tmp64, rd_64);
253
tcg_temp_free_i64(tmp64);
254
}
255
- neon_store_reg64(rd_64, a->vd + pass);
256
+ write_neon_element64(rd_64, a->vd, pass, MO_64);
257
tcg_temp_free_i64(rd_64);
258
}
259
return true;
260
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
261
rd0 = tcg_temp_new_i32();
262
rd1 = tcg_temp_new_i32();
263
264
- neon_load_reg64(rm, a->vm);
265
+ read_neon_element64(rm, a->vm, 0, MO_64);
266
narrowfn(rd0, cpu_env, rm);
267
- neon_load_reg64(rm, a->vm + 1);
268
+ read_neon_element64(rm, a->vm, 1, MO_64);
269
narrowfn(rd1, cpu_env, rm);
270
write_neon_element32(rd0, a->vd, 0, MO_32);
271
write_neon_element32(rd1, a->vd, 1, MO_32);
272
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
273
274
widenfn(rd, rm0);
275
tcg_gen_shli_i64(rd, rd, 8 << a->size);
276
- neon_store_reg64(rd, a->vd);
277
+ write_neon_element64(rd, a->vd, 0, MO_64);
278
widenfn(rd, rm1);
279
tcg_gen_shli_i64(rd, rd, 8 << a->size);
280
- neon_store_reg64(rd, a->vd + 1);
281
+ write_neon_element64(rd, a->vd, 1, MO_64);
282
283
tcg_temp_free_i64(rd);
284
tcg_temp_free_i32(rm0);
285
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
286
rm = tcg_temp_new_i64();
287
rd = tcg_temp_new_i64();
288
for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
289
- neon_load_reg64(rm, a->vm + pass);
290
- neon_load_reg64(rd, a->vd + pass);
291
- neon_store_reg64(rm, a->vd + pass);
292
- neon_store_reg64(rd, a->vm + pass);
293
+ read_neon_element64(rm, a->vm, pass, MO_64);
294
+ read_neon_element64(rd, a->vd, pass, MO_64);
295
+ write_neon_element64(rm, a->vd, pass, MO_64);
296
+ write_neon_element64(rd, a->vm, pass, MO_64);
297
}
298
tcg_temp_free_i64(rm);
299
tcg_temp_free_i64(rd);
73
--
300
--
74
2.7.4
301
2.20.1
75
302
76
303
diff view generated by jsdifflib
1
Since ssi-sd is still using the legacy SD card API, the SD
1
From: Richard Henderson <richard.henderson@linaro.org>
2
card created by sd_init() is not plugged into any bus. This
2
3
means that the controller has to reset it manually.
3
The only uses of this function are for loading VFP
4
4
double-precision values, and nothing to do with NEON.
5
Failing to do this mostly didn't affect the guest since the
5
6
guest typically does a programmed SD card reset as part of
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
its SD controller driver initialization, but meant that
7
Message-id: 20201030022618.785675-10-richard.henderson@linaro.org
8
migration failed because it's only in sd_reset() that we
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
set up the wpgrps_size field.
10
11
In the case of sd-ssi, we have to implement an entire
12
reset function since there wasn't one previously, and
13
that requires a QOM cast macro that got omitted when this
14
device was QOMified.
15
16
Cc: qemu-stable@nongnu.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Message-id: 1515506513-31961-4-git-send-email-peter.maydell@linaro.org
21
---
10
---
22
hw/sd/ssi-sd.c | 25 +++++++++++++++++++++++--
11
target/arm/translate.c | 8 ++--
23
1 file changed, 23 insertions(+), 2 deletions(-)
12
target/arm/translate-vfp.c.inc | 84 +++++++++++++++++-----------------
24
13
2 files changed, 46 insertions(+), 46 deletions(-)
25
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
14
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/sd/ssi-sd.c
17
--- a/target/arm/translate.c
28
+++ b/hw/sd/ssi-sd.c
18
+++ b/target/arm/translate.c
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
19
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
30
SDState *sd;
31
} ssi_sd_state;
32
33
+#define TYPE_SSI_SD "ssi-sd"
34
+#define SSI_SD(obj) OBJECT_CHECK(ssi_sd_state, (obj), TYPE_SSI_SD)
35
+
36
/* State word bits. */
37
#define SSI_SDR_LOCKED 0x0001
38
#define SSI_SDR_WP_ERASE 0x0002
39
@@ -XXX,XX +XXX,XX @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
40
ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
41
DriveInfo *dinfo;
42
43
- s->mode = SSI_SD_CMD;
44
/* FIXME use a qdev drive property instead of drive_get_next() */
45
dinfo = drive_get_next(IF_SD);
46
s->sd = sd_init(dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, true);
47
@@ -XXX,XX +XXX,XX @@ static void ssi_sd_realize(SSISlave *d, Error **errp)
48
}
20
}
49
}
21
}
50
22
51
+static void ssi_sd_reset(DeviceState *dev)
23
-static inline void neon_load_reg64(TCGv_i64 var, int reg)
52
+{
24
+static inline void vfp_load_reg64(TCGv_i64 var, int reg)
53
+ ssi_sd_state *s = SSI_SD(dev);
54
+
55
+ s->mode = SSI_SD_CMD;
56
+ s->cmd = 0;
57
+ memset(s->cmdarg, 0, sizeof(s->cmdarg));
58
+ memset(s->response, 0, sizeof(s->response));
59
+ s->arglen = 0;
60
+ s->response_pos = 0;
61
+ s->stopping = 0;
62
+
63
+ /* Since we're still using the legacy SD API the card is not plugged
64
+ * into any bus, and we must reset it manually.
65
+ */
66
+ device_reset(DEVICE(s->sd));
67
+}
68
+
69
static void ssi_sd_class_init(ObjectClass *klass, void *data)
70
{
25
{
71
DeviceClass *dc = DEVICE_CLASS(klass);
26
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
72
@@ -XXX,XX +XXX,XX @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
27
+ tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
73
k->transfer = ssi_sd_transfer;
74
k->cs_polarity = SSI_CS_LOW;
75
dc->vmsd = &vmstate_ssi_sd;
76
+ dc->reset = ssi_sd_reset;
77
}
28
}
78
29
79
static const TypeInfo ssi_sd_info = {
30
-static inline void neon_store_reg64(TCGv_i64 var, int reg)
80
- .name = "ssi-sd",
31
+static inline void vfp_store_reg64(TCGv_i64 var, int reg)
81
+ .name = TYPE_SSI_SD,
32
{
82
.parent = TYPE_SSI_SLAVE,
33
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
83
.instance_size = sizeof(ssi_sd_state),
34
+ tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
84
.class_init = ssi_sd_class_init,
35
}
36
37
static inline void vfp_load_reg32(TCGv_i32 var, int reg)
38
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate-vfp.c.inc
41
+++ b/target/arm/translate-vfp.c.inc
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
43
tcg_gen_ext_i32_i64(nf, cpu_NF);
44
tcg_gen_ext_i32_i64(vf, cpu_VF);
45
46
- neon_load_reg64(frn, rn);
47
- neon_load_reg64(frm, rm);
48
+ vfp_load_reg64(frn, rn);
49
+ vfp_load_reg64(frm, rm);
50
switch (a->cc) {
51
case 0: /* eq: Z */
52
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
53
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
54
tcg_temp_free_i64(tmp);
55
break;
56
}
57
- neon_store_reg64(dest, rd);
58
+ vfp_store_reg64(dest, rd);
59
tcg_temp_free_i64(frn);
60
tcg_temp_free_i64(frm);
61
tcg_temp_free_i64(dest);
62
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
63
TCGv_i64 tcg_res;
64
tcg_op = tcg_temp_new_i64();
65
tcg_res = tcg_temp_new_i64();
66
- neon_load_reg64(tcg_op, rm);
67
+ vfp_load_reg64(tcg_op, rm);
68
gen_helper_rintd(tcg_res, tcg_op, fpst);
69
- neon_store_reg64(tcg_res, rd);
70
+ vfp_store_reg64(tcg_res, rd);
71
tcg_temp_free_i64(tcg_op);
72
tcg_temp_free_i64(tcg_res);
73
} else {
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
75
tcg_double = tcg_temp_new_i64();
76
tcg_res = tcg_temp_new_i64();
77
tcg_tmp = tcg_temp_new_i32();
78
- neon_load_reg64(tcg_double, rm);
79
+ vfp_load_reg64(tcg_double, rm);
80
if (is_signed) {
81
gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
82
} else {
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
84
tmp = tcg_temp_new_i64();
85
if (a->l) {
86
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
87
- neon_store_reg64(tmp, a->vd);
88
+ vfp_store_reg64(tmp, a->vd);
89
} else {
90
- neon_load_reg64(tmp, a->vd);
91
+ vfp_load_reg64(tmp, a->vd);
92
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
93
}
94
tcg_temp_free_i64(tmp);
95
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
96
if (a->l) {
97
/* load */
98
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
99
- neon_store_reg64(tmp, a->vd + i);
100
+ vfp_store_reg64(tmp, a->vd + i);
101
} else {
102
/* store */
103
- neon_load_reg64(tmp, a->vd + i);
104
+ vfp_load_reg64(tmp, a->vd + i);
105
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
106
}
107
tcg_gen_addi_i32(addr, addr, offset);
108
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
109
fd = tcg_temp_new_i64();
110
fpst = fpstatus_ptr(FPST_FPCR);
111
112
- neon_load_reg64(f0, vn);
113
- neon_load_reg64(f1, vm);
114
+ vfp_load_reg64(f0, vn);
115
+ vfp_load_reg64(f1, vm);
116
117
for (;;) {
118
if (reads_vd) {
119
- neon_load_reg64(fd, vd);
120
+ vfp_load_reg64(fd, vd);
121
}
122
fn(fd, f0, f1, fpst);
123
- neon_store_reg64(fd, vd);
124
+ vfp_store_reg64(fd, vd);
125
126
if (veclen == 0) {
127
break;
128
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
129
veclen--;
130
vd = vfp_advance_dreg(vd, delta_d);
131
vn = vfp_advance_dreg(vn, delta_d);
132
- neon_load_reg64(f0, vn);
133
+ vfp_load_reg64(f0, vn);
134
if (delta_m) {
135
vm = vfp_advance_dreg(vm, delta_m);
136
- neon_load_reg64(f1, vm);
137
+ vfp_load_reg64(f1, vm);
138
}
139
}
140
141
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
142
f0 = tcg_temp_new_i64();
143
fd = tcg_temp_new_i64();
144
145
- neon_load_reg64(f0, vm);
146
+ vfp_load_reg64(f0, vm);
147
148
for (;;) {
149
fn(fd, f0);
150
- neon_store_reg64(fd, vd);
151
+ vfp_store_reg64(fd, vd);
152
153
if (veclen == 0) {
154
break;
155
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
156
/* single source one-many */
157
while (veclen--) {
158
vd = vfp_advance_dreg(vd, delta_d);
159
- neon_store_reg64(fd, vd);
160
+ vfp_store_reg64(fd, vd);
161
}
162
break;
163
}
164
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
165
veclen--;
166
vd = vfp_advance_dreg(vd, delta_d);
167
vd = vfp_advance_dreg(vm, delta_m);
168
- neon_load_reg64(f0, vm);
169
+ vfp_load_reg64(f0, vm);
170
}
171
172
tcg_temp_free_i64(f0);
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
174
vm = tcg_temp_new_i64();
175
vd = tcg_temp_new_i64();
176
177
- neon_load_reg64(vn, a->vn);
178
- neon_load_reg64(vm, a->vm);
179
+ vfp_load_reg64(vn, a->vn);
180
+ vfp_load_reg64(vm, a->vm);
181
if (neg_n) {
182
/* VFNMS, VFMS */
183
gen_helper_vfp_negd(vn, vn);
184
}
185
- neon_load_reg64(vd, a->vd);
186
+ vfp_load_reg64(vd, a->vd);
187
if (neg_d) {
188
/* VFNMA, VFNMS */
189
gen_helper_vfp_negd(vd, vd);
190
}
191
fpst = fpstatus_ptr(FPST_FPCR);
192
gen_helper_vfp_muladdd(vd, vn, vm, vd, fpst);
193
- neon_store_reg64(vd, a->vd);
194
+ vfp_store_reg64(vd, a->vd);
195
196
tcg_temp_free_ptr(fpst);
197
tcg_temp_free_i64(vn);
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
199
fd = tcg_const_i64(vfp_expand_imm(MO_64, a->imm));
200
201
for (;;) {
202
- neon_store_reg64(fd, vd);
203
+ vfp_store_reg64(fd, vd);
204
205
if (veclen == 0) {
206
break;
207
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
208
vd = tcg_temp_new_i64();
209
vm = tcg_temp_new_i64();
210
211
- neon_load_reg64(vd, a->vd);
212
+ vfp_load_reg64(vd, a->vd);
213
if (a->z) {
214
tcg_gen_movi_i64(vm, 0);
215
} else {
216
- neon_load_reg64(vm, a->vm);
217
+ vfp_load_reg64(vm, a->vm);
218
}
219
220
if (a->e) {
221
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
222
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
223
vd = tcg_temp_new_i64();
224
gen_helper_vfp_fcvt_f16_to_f64(vd, tmp, fpst, ahp_mode);
225
- neon_store_reg64(vd, a->vd);
226
+ vfp_store_reg64(vd, a->vd);
227
tcg_temp_free_i32(ahp_mode);
228
tcg_temp_free_ptr(fpst);
229
tcg_temp_free_i32(tmp);
230
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
231
tmp = tcg_temp_new_i32();
232
vm = tcg_temp_new_i64();
233
234
- neon_load_reg64(vm, a->vm);
235
+ vfp_load_reg64(vm, a->vm);
236
gen_helper_vfp_fcvt_f64_to_f16(tmp, vm, fpst, ahp_mode);
237
tcg_temp_free_i64(vm);
238
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
239
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
240
}
241
242
tmp = tcg_temp_new_i64();
243
- neon_load_reg64(tmp, a->vm);
244
+ vfp_load_reg64(tmp, a->vm);
245
fpst = fpstatus_ptr(FPST_FPCR);
246
gen_helper_rintd(tmp, tmp, fpst);
247
- neon_store_reg64(tmp, a->vd);
248
+ vfp_store_reg64(tmp, a->vd);
249
tcg_temp_free_ptr(fpst);
250
tcg_temp_free_i64(tmp);
251
return true;
252
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
253
}
254
255
tmp = tcg_temp_new_i64();
256
- neon_load_reg64(tmp, a->vm);
257
+ vfp_load_reg64(tmp, a->vm);
258
fpst = fpstatus_ptr(FPST_FPCR);
259
tcg_rmode = tcg_const_i32(float_round_to_zero);
260
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
261
gen_helper_rintd(tmp, tmp, fpst);
262
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
263
- neon_store_reg64(tmp, a->vd);
264
+ vfp_store_reg64(tmp, a->vd);
265
tcg_temp_free_ptr(fpst);
266
tcg_temp_free_i64(tmp);
267
tcg_temp_free_i32(tcg_rmode);
268
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
269
}
270
271
tmp = tcg_temp_new_i64();
272
- neon_load_reg64(tmp, a->vm);
273
+ vfp_load_reg64(tmp, a->vm);
274
fpst = fpstatus_ptr(FPST_FPCR);
275
gen_helper_rintd_exact(tmp, tmp, fpst);
276
- neon_store_reg64(tmp, a->vd);
277
+ vfp_store_reg64(tmp, a->vd);
278
tcg_temp_free_ptr(fpst);
279
tcg_temp_free_i64(tmp);
280
return true;
281
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
282
vd = tcg_temp_new_i64();
283
vfp_load_reg32(vm, a->vm);
284
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
285
- neon_store_reg64(vd, a->vd);
286
+ vfp_store_reg64(vd, a->vd);
287
tcg_temp_free_i32(vm);
288
tcg_temp_free_i64(vd);
289
return true;
290
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
291
292
vd = tcg_temp_new_i32();
293
vm = tcg_temp_new_i64();
294
- neon_load_reg64(vm, a->vm);
295
+ vfp_load_reg64(vm, a->vm);
296
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
297
vfp_store_reg32(vd, a->vd);
298
tcg_temp_free_i32(vd);
299
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
300
/* u32 -> f64 */
301
gen_helper_vfp_uitod(vd, vm, fpst);
302
}
303
- neon_store_reg64(vd, a->vd);
304
+ vfp_store_reg64(vd, a->vd);
305
tcg_temp_free_i32(vm);
306
tcg_temp_free_i64(vd);
307
tcg_temp_free_ptr(fpst);
308
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
309
310
vm = tcg_temp_new_i64();
311
vd = tcg_temp_new_i32();
312
- neon_load_reg64(vm, a->vm);
313
+ vfp_load_reg64(vm, a->vm);
314
gen_helper_vjcvt(vd, vm, cpu_env);
315
vfp_store_reg32(vd, a->vd);
316
tcg_temp_free_i64(vm);
317
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
318
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
319
320
vd = tcg_temp_new_i64();
321
- neon_load_reg64(vd, a->vd);
322
+ vfp_load_reg64(vd, a->vd);
323
324
fpst = fpstatus_ptr(FPST_FPCR);
325
shift = tcg_const_i32(frac_bits);
326
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
327
g_assert_not_reached();
328
}
329
330
- neon_store_reg64(vd, a->vd);
331
+ vfp_store_reg64(vd, a->vd);
332
tcg_temp_free_i64(vd);
333
tcg_temp_free_i32(shift);
334
tcg_temp_free_ptr(fpst);
335
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
336
fpst = fpstatus_ptr(FPST_FPCR);
337
vm = tcg_temp_new_i64();
338
vd = tcg_temp_new_i32();
339
- neon_load_reg64(vm, a->vm);
340
+ vfp_load_reg64(vm, a->vm);
341
342
if (a->s) {
343
if (a->rz) {
85
--
344
--
86
2.7.4
345
2.20.1
87
346
88
347
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
In both cases, we can sink the write-back and perform
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
the accumulate into the normal destination temps.
5
Message-id: 20180115182436.2066-11-f4bug@amsat.org
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-11-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
hw/sd/sdhci-internal.h | 2 +-
11
target/arm/translate-neon.c.inc | 23 +++++++++--------------
9
hw/sd/sdhci.c | 2 +-
12
1 file changed, 9 insertions(+), 14 deletions(-)
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
13
12
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
14
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sdhci-internal.h
16
--- a/target/arm/translate-neon.c.inc
15
+++ b/hw/sd/sdhci-internal.h
17
+++ b/target/arm/translate-neon.c.inc
16
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
17
#define SDHC_ACMD12ERRSTS 0x3C
19
if (accfn) {
18
20
tmp = tcg_temp_new_i64();
19
/* HWInit Capabilities Register 0x05E80080 */
21
read_neon_element64(tmp, a->vd, 0, MO_64);
20
-#define SDHC_CAPAREG 0x40
22
- accfn(tmp, tmp, rd0);
21
+#define SDHC_CAPAB 0x40
23
- write_neon_element64(tmp, a->vd, 0, MO_64);
22
#define SDHC_CAN_DO_DMA 0x00400000
24
+ accfn(rd0, tmp, rd0);
23
#define SDHC_CAN_DO_ADMA2 0x00080000
25
read_neon_element64(tmp, a->vd, 1, MO_64);
24
#define SDHC_CAN_DO_ADMA1 0x00100000
26
- accfn(tmp, tmp, rd1);
25
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
27
- write_neon_element64(tmp, a->vd, 1, MO_64);
26
index XXXXXXX..XXXXXXX 100644
28
+ accfn(rd1, tmp, rd1);
27
--- a/hw/sd/sdhci.c
29
tcg_temp_free_i64(tmp);
28
+++ b/hw/sd/sdhci.c
30
- } else {
29
@@ -XXX,XX +XXX,XX @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
31
- write_neon_element64(rd0, a->vd, 0, MO_64);
30
case SDHC_ACMD12ERRSTS:
32
- write_neon_element64(rd1, a->vd, 1, MO_64);
31
ret = s->acmd12errsts;
33
}
32
break;
34
33
- case SDHC_CAPAREG:
35
+ write_neon_element64(rd0, a->vd, 0, MO_64);
34
+ case SDHC_CAPAB:
36
+ write_neon_element64(rd1, a->vd, 1, MO_64);
35
ret = s->capareg;
37
tcg_temp_free_i64(rd0);
36
break;
38
tcg_temp_free_i64(rd1);
37
case SDHC_MAXCURR:
39
40
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
41
if (accfn) {
42
TCGv_i64 t64 = tcg_temp_new_i64();
43
read_neon_element64(t64, a->vd, 0, MO_64);
44
- accfn(t64, t64, rn0_64);
45
- write_neon_element64(t64, a->vd, 0, MO_64);
46
+ accfn(rn0_64, t64, rn0_64);
47
read_neon_element64(t64, a->vd, 1, MO_64);
48
- accfn(t64, t64, rn1_64);
49
- write_neon_element64(t64, a->vd, 1, MO_64);
50
+ accfn(rn1_64, t64, rn1_64);
51
tcg_temp_free_i64(t64);
52
- } else {
53
- write_neon_element64(rn0_64, a->vd, 0, MO_64);
54
- write_neon_element64(rn1_64, a->vd, 1, MO_64);
55
}
56
+
57
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
58
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
59
tcg_temp_free_i64(rn0_64);
60
tcg_temp_free_i64(rn1_64);
61
return true;
38
--
62
--
39
2.7.4
63
2.20.1
40
64
41
65
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
zero-initialize ADMADescr 'dscr' in sdhci_do_adma() to avoid:
3
We can use proper widening loads to extend 32-bit inputs,
4
and skip the "widenfn" step.
4
5
5
hw/sd/sdhci.c: In function ‘sdhci_do_adma’:
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
hw/sd/sdhci.c:714:29: error: ‘dscr.addr’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
7
Message-id: 20201030022618.785675-12-richard.henderson@linaro.org
7
trace_sdhci_adma("link", s->admasysaddr);
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
^
9
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
12
Message-id: 20180115182436.2066-9-f4bug@amsat.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
10
---
15
hw/sd/sdhci.c | 89 ++++++++++++++++++------------------------------------
11
target/arm/translate.c | 6 +++
16
hw/sd/trace-events | 14 +++++++++
12
target/arm/translate-neon.c.inc | 66 ++++++++++++++++++---------------
17
2 files changed, 44 insertions(+), 59 deletions(-)
13
2 files changed, 43 insertions(+), 29 deletions(-)
18
14
19
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/sd/sdhci.c
17
--- a/target/arm/translate.c
22
+++ b/hw/sd/sdhci.c
18
+++ b/target/arm/translate.c
23
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
24
#include "sdhci-internal.h"
20
long off = neon_element_offset(reg, ele, memop);
25
#include "qapi/error.h"
21
26
#include "qemu/log.h"
22
switch (memop) {
27
-
23
+ case MO_SL:
28
-/* host controller debug messages */
24
+ tcg_gen_ld32s_i64(dest, cpu_env, off);
29
-#ifndef SDHC_DEBUG
25
+ break;
30
-#define SDHC_DEBUG 0
26
+ case MO_UL:
31
-#endif
27
+ tcg_gen_ld32u_i64(dest, cpu_env, off);
32
-
28
+ break;
33
-#define DPRINT_L1(fmt, args...) \
29
case MO_Q:
34
- do { \
30
tcg_gen_ld_i64(dest, cpu_env, off);
35
- if (SDHC_DEBUG) { \
31
break;
36
- fprintf(stderr, "QEMU SDHC: " fmt, ## args); \
32
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
37
- } \
33
index XXXXXXX..XXXXXXX 100644
38
- } while (0)
34
--- a/target/arm/translate-neon.c.inc
39
-#define DPRINT_L2(fmt, args...) \
35
+++ b/target/arm/translate-neon.c.inc
40
- do { \
36
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1reg_imm *a)
41
- if (SDHC_DEBUG > 1) { \
37
static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
42
- fprintf(stderr, "QEMU SDHC: " fmt, ## args); \
38
NeonGenWidenFn *widenfn,
43
- } \
39
NeonGenTwo64OpFn *opfn,
44
- } while (0)
40
- bool src1_wide)
45
-#define ERRPRINT(fmt, args...) \
41
+ int src1_mop, int src2_mop)
46
- do { \
47
- if (SDHC_DEBUG) { \
48
- fprintf(stderr, "QEMU SDHC ERROR: " fmt, ## args); \
49
- } \
50
- } while (0)
51
+#include "trace.h"
52
53
#define TYPE_SDHCI_BUS "sdhci-bus"
54
#define SDHCI_BUS(obj) OBJECT_CHECK(SDBus, (obj), TYPE_SDHCI_BUS)
55
@@ -XXX,XX +XXX,XX @@ static void sdhci_raise_insertion_irq(void *opaque)
56
static void sdhci_set_inserted(DeviceState *dev, bool level)
57
{
42
{
58
SDHCIState *s = (SDHCIState *)dev;
43
/* 3-regs different lengths, prewidening case (VADDL/VSUBL/VAADW/VSUBW) */
59
- DPRINT_L1("Card state changed: %s!\n", level ? "insert" : "eject");
44
TCGv_i64 rn0_64, rn1_64, rm_64;
60
45
- TCGv_i32 rm;
61
+ trace_sdhci_set_inserted(level ? "insert" : "eject");
46
62
if ((s->norintsts & SDHC_NIS_REMOVE) && level) {
47
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
63
/* Give target some time to notice card ejection */
48
return false;
64
timer_mod(s->insert_timer,
49
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
65
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
66
s->acmd12errsts = 0;
67
request.cmd = s->cmdreg >> 8;
68
request.arg = s->argument;
69
- DPRINT_L1("sending CMD%u ARG[0x%08x]\n", request.cmd, request.arg);
70
+
71
+ trace_sdhci_send_command(request.cmd, request.arg);
72
rlen = sdbus_do_command(&s->sdbus, &request, response);
73
74
if (s->cmdreg & SDHC_CMD_RESPONSE) {
75
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
76
s->rspreg[0] = (response[0] << 24) | (response[1] << 16) |
77
(response[2] << 8) | response[3];
78
s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
79
- DPRINT_L1("Response: RSPREG[31..0]=0x%08x\n", s->rspreg[0]);
80
+ trace_sdhci_response4(s->rspreg[0]);
81
} else if (rlen == 16) {
82
s->rspreg[0] = (response[11] << 24) | (response[12] << 16) |
83
(response[13] << 8) | response[14];
84
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
85
(response[5] << 8) | response[6];
86
s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |
87
response[2];
88
- DPRINT_L1("Response received:\n RSPREG[127..96]=0x%08x, RSPREG[95.."
89
- "64]=0x%08x,\n RSPREG[63..32]=0x%08x, RSPREG[31..0]=0x%08x\n",
90
- s->rspreg[3], s->rspreg[2], s->rspreg[1], s->rspreg[0]);
91
+ trace_sdhci_response16(s->rspreg[3], s->rspreg[2],
92
+ s->rspreg[1], s->rspreg[0]);
93
} else {
94
- ERRPRINT("Timeout waiting for command response\n");
95
+ trace_sdhci_error("timeout waiting for command response");
96
if (s->errintstsen & SDHC_EISEN_CMDTIMEOUT) {
97
s->errintsts |= SDHC_EIS_CMDTIMEOUT;
98
s->norintsts |= SDHC_NIS_ERR;
99
@@ -XXX,XX +XXX,XX @@ static void sdhci_end_transfer(SDHCIState *s)
100
101
request.cmd = 0x0C;
102
request.arg = 0;
103
- DPRINT_L1("Automatically issue CMD%d %08x\n", request.cmd, request.arg);
104
+ trace_sdhci_end_transfer(request.cmd, request.arg);
105
sdbus_do_command(&s->sdbus, &request, response);
106
/* Auto CMD12 response goes to the upper Response register */
107
s->rspreg[3] = (response[0] << 24) | (response[1] << 16) |
108
@@ -XXX,XX +XXX,XX @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
109
110
/* first check that a valid data exists in host controller input buffer */
111
if ((s->prnsts & SDHC_DATA_AVAILABLE) == 0) {
112
- ERRPRINT("Trying to read from empty buffer\n");
113
+ trace_sdhci_error("read from empty buffer");
114
return 0;
115
}
116
117
@@ -XXX,XX +XXX,XX @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
118
s->data_count++;
119
/* check if we've read all valid data (blksize bytes) from buffer */
120
if ((s->data_count) >= (s->blksize & 0x0fff)) {
121
- DPRINT_L2("All %u bytes of data have been read from input buffer\n",
122
- s->data_count);
123
+ trace_sdhci_read_dataport(s->data_count);
124
s->prnsts &= ~SDHC_DATA_AVAILABLE; /* no more data in a buffer */
125
s->data_count = 0; /* next buff read must start at position [0] */
126
127
@@ -XXX,XX +XXX,XX @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
128
129
/* Check that there is free space left in a buffer */
130
if (!(s->prnsts & SDHC_SPACE_AVAILABLE)) {
131
- ERRPRINT("Can't write to data buffer: buffer full\n");
132
+ trace_sdhci_error("Can't write to data buffer: buffer full");
133
return;
134
}
135
136
@@ -XXX,XX +XXX,XX @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
137
s->data_count++;
138
value >>= 8;
139
if (s->data_count >= (s->blksize & 0x0fff)) {
140
- DPRINT_L2("write buffer filled with %u bytes of data\n",
141
- s->data_count);
142
+ trace_sdhci_write_dataport(s->data_count);
143
s->data_count = 0;
144
s->prnsts &= ~SDHC_SPACE_AVAILABLE;
145
if (s->prnsts & SDHC_DOING_WRITE) {
146
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
147
{
148
unsigned int n, begin, length;
149
const uint16_t block_size = s->blksize & 0x0fff;
150
- ADMADescr dscr;
151
+ ADMADescr dscr = {};
152
int i;
153
154
for (i = 0; i < SDHC_ADMA_DESCS_PER_DELAY; ++i) {
155
s->admaerr &= ~SDHC_ADMAERR_LENGTH_MISMATCH;
156
157
get_adma_description(s, &dscr);
158
- DPRINT_L2("ADMA loop: addr=" TARGET_FMT_plx ", len=%d, attr=%x\n",
159
- dscr.addr, dscr.length, dscr.attr);
160
+ trace_sdhci_adma_loop(dscr.addr, dscr.length, dscr.attr);
161
162
if ((dscr.attr & SDHC_ADMA_ATTR_VALID) == 0) {
163
/* Indicate that error occurred in ST_FDS state */
164
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
165
break;
166
case SDHC_ADMA_ATTR_ACT_LINK: /* link to next descriptor table */
167
s->admasysaddr = dscr.addr;
168
- DPRINT_L1("ADMA link: admasysaddr=0x%" PRIx64 "\n",
169
- s->admasysaddr);
170
+ trace_sdhci_adma("link", s->admasysaddr);
171
break;
172
default:
173
s->admasysaddr += dscr.incr;
174
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
175
}
176
177
if (dscr.attr & SDHC_ADMA_ATTR_INT) {
178
- DPRINT_L1("ADMA interrupt: admasysaddr=0x%" PRIx64 "\n",
179
- s->admasysaddr);
180
+ trace_sdhci_adma("interrupt", s->admasysaddr);
181
if (s->norintstsen & SDHC_NISEN_DMA) {
182
s->norintsts |= SDHC_NIS_DMA;
183
}
184
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
185
/* ADMA transfer terminates if blkcnt == 0 or by END attribute */
186
if (((s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
187
(s->blkcnt == 0)) || (dscr.attr & SDHC_ADMA_ATTR_END)) {
188
- DPRINT_L2("ADMA transfer completed\n");
189
+ trace_sdhci_adma_transfer_completed();
190
if (length || ((dscr.attr & SDHC_ADMA_ATTR_END) &&
191
(s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
192
s->blkcnt != 0)) {
193
- ERRPRINT("SD/MMC host ADMA length mismatch\n");
194
+ trace_sdhci_error("SD/MMC host ADMA length mismatch");
195
s->admaerr |= SDHC_ADMAERR_LENGTH_MISMATCH |
196
SDHC_ADMAERR_STATE_ST_TFR;
197
if (s->errintstsen & SDHC_EISEN_ADMAERR) {
198
- ERRPRINT("Set ADMA error flag\n");
199
+ trace_sdhci_error("Set ADMA error flag");
200
s->errintsts |= SDHC_EIS_ADMAERR;
201
s->norintsts |= SDHC_NIS_ERR;
202
}
203
@@ -XXX,XX +XXX,XX @@ static void sdhci_data_transfer(void *opaque)
204
break;
205
case SDHC_CTRL_ADMA1_32:
206
if (!(s->capareg & SDHC_CAN_DO_ADMA1)) {
207
- ERRPRINT("ADMA1 not supported\n");
208
+ trace_sdhci_error("ADMA1 not supported");
209
break;
210
}
211
212
@@ -XXX,XX +XXX,XX @@ static void sdhci_data_transfer(void *opaque)
213
break;
214
case SDHC_CTRL_ADMA2_32:
215
if (!(s->capareg & SDHC_CAN_DO_ADMA2)) {
216
- ERRPRINT("ADMA2 not supported\n");
217
+ trace_sdhci_error("ADMA2 not supported");
218
break;
219
}
220
221
@@ -XXX,XX +XXX,XX @@ static void sdhci_data_transfer(void *opaque)
222
case SDHC_CTRL_ADMA2_64:
223
if (!(s->capareg & SDHC_CAN_DO_ADMA2) ||
224
!(s->capareg & SDHC_64_BIT_BUS_SUPPORT)) {
225
- ERRPRINT("64 bit ADMA not supported\n");
226
+ trace_sdhci_error("64 bit ADMA not supported");
227
break;
228
}
229
230
sdhci_do_adma(s);
231
break;
232
default:
233
- ERRPRINT("Unsupported DMA type\n");
234
+ trace_sdhci_error("Unsupported DMA type");
235
break;
236
}
237
} else {
238
@@ -XXX,XX +XXX,XX @@ static inline bool
239
sdhci_buff_access_is_sequential(SDHCIState *s, unsigned byte_num)
240
{
241
if ((s->data_count & 0x3) != byte_num) {
242
- ERRPRINT("Non-sequential access to Buffer Data Port register"
243
- "is prohibited\n");
244
+ trace_sdhci_error("Non-sequential access to Buffer Data Port register"
245
+ "is prohibited\n");
246
return false;
50
return false;
247
}
51
}
52
53
- if (!widenfn || !opfn) {
54
+ if (!opfn) {
55
/* size == 3 case, which is an entirely different insn group */
56
return false;
57
}
58
59
- if ((a->vd & 1) || (src1_wide && (a->vn & 1))) {
60
+ if ((a->vd & 1) || (src1_mop == MO_Q && (a->vn & 1))) {
61
return false;
62
}
63
64
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
65
rn1_64 = tcg_temp_new_i64();
66
rm_64 = tcg_temp_new_i64();
67
68
- if (src1_wide) {
69
- read_neon_element64(rn0_64, a->vn, 0, MO_64);
70
+ if (src1_mop >= 0) {
71
+ read_neon_element64(rn0_64, a->vn, 0, src1_mop);
72
} else {
73
TCGv_i32 tmp = tcg_temp_new_i32();
74
read_neon_element32(tmp, a->vn, 0, MO_32);
75
widenfn(rn0_64, tmp);
76
tcg_temp_free_i32(tmp);
77
}
78
- rm = tcg_temp_new_i32();
79
- read_neon_element32(rm, a->vm, 0, MO_32);
80
+ if (src2_mop >= 0) {
81
+ read_neon_element64(rm_64, a->vm, 0, src2_mop);
82
+ } else {
83
+ TCGv_i32 tmp = tcg_temp_new_i32();
84
+ read_neon_element32(tmp, a->vm, 0, MO_32);
85
+ widenfn(rm_64, tmp);
86
+ tcg_temp_free_i32(tmp);
87
+ }
88
89
- widenfn(rm_64, rm);
90
- tcg_temp_free_i32(rm);
91
opfn(rn0_64, rn0_64, rm_64);
92
93
/*
94
* Load second pass inputs before storing the first pass result, to
95
* avoid incorrect results if a narrow input overlaps with the result.
96
*/
97
- if (src1_wide) {
98
- read_neon_element64(rn1_64, a->vn, 1, MO_64);
99
+ if (src1_mop >= 0) {
100
+ read_neon_element64(rn1_64, a->vn, 1, src1_mop);
101
} else {
102
TCGv_i32 tmp = tcg_temp_new_i32();
103
read_neon_element32(tmp, a->vn, 1, MO_32);
104
widenfn(rn1_64, tmp);
105
tcg_temp_free_i32(tmp);
106
}
107
- rm = tcg_temp_new_i32();
108
- read_neon_element32(rm, a->vm, 1, MO_32);
109
+ if (src2_mop >= 0) {
110
+ read_neon_element64(rm_64, a->vm, 1, src2_mop);
111
+ } else {
112
+ TCGv_i32 tmp = tcg_temp_new_i32();
113
+ read_neon_element32(tmp, a->vm, 1, MO_32);
114
+ widenfn(rm_64, tmp);
115
+ tcg_temp_free_i32(tmp);
116
+ }
117
118
write_neon_element64(rn0_64, a->vd, 0, MO_64);
119
120
- widenfn(rm_64, rm);
121
- tcg_temp_free_i32(rm);
122
opfn(rn1_64, rn1_64, rm_64);
123
write_neon_element64(rn1_64, a->vd, 1, MO_64);
124
125
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
248
return true;
126
return true;
249
@@ -XXX,XX +XXX,XX @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
250
case SDHC_BDATA:
251
if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {
252
ret = sdhci_read_dataport(s, size);
253
- DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, (int)offset,
254
- ret, ret);
255
+ trace_sdhci_access("rd", size << 3, offset, "->", ret, ret);
256
return ret;
257
}
258
break;
259
@@ -XXX,XX +XXX,XX @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
260
261
ret >>= (offset & 0x3) * 8;
262
ret &= (1ULL << (size * 8)) - 1;
263
- DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, (int)offset, ret, ret);
264
+ trace_sdhci_access("rd", size << 3, offset, "->", ret, ret);
265
return ret;
266
}
127
}
267
128
268
@@ -XXX,XX +XXX,XX @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
129
-#define DO_PREWIDEN(INSN, S, EXT, OP, SRC1WIDE) \
269
"not implemented\n", size, offset, value >> shift);
130
+#define DO_PREWIDEN(INSN, S, OP, SRC1WIDE, SIGN) \
270
break;
131
static bool trans_##INSN##_3d(DisasContext *s, arg_3diff *a) \
132
{ \
133
static NeonGenWidenFn * const widenfn[] = { \
134
gen_helper_neon_widen_##S##8, \
135
gen_helper_neon_widen_##S##16, \
136
- tcg_gen_##EXT##_i32_i64, \
137
- NULL, \
138
+ NULL, NULL, \
139
}; \
140
static NeonGenTwo64OpFn * const addfn[] = { \
141
gen_helper_neon_##OP##l_u16, \
142
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
143
tcg_gen_##OP##_i64, \
144
NULL, \
145
}; \
146
- return do_prewiden_3d(s, a, widenfn[a->size], \
147
- addfn[a->size], SRC1WIDE); \
148
+ int narrow_mop = a->size == MO_32 ? MO_32 | SIGN : -1; \
149
+ return do_prewiden_3d(s, a, widenfn[a->size], addfn[a->size], \
150
+ SRC1WIDE ? MO_Q : narrow_mop, \
151
+ narrow_mop); \
271
}
152
}
272
- DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",
153
273
- size, (int)offset, value >> shift, value >> shift);
154
-DO_PREWIDEN(VADDL_S, s, ext, add, false)
274
+ trace_sdhci_access("wr", size << 3, offset, "<-",
155
-DO_PREWIDEN(VADDL_U, u, extu, add, false)
275
+ value >> shift, value >> shift);
156
-DO_PREWIDEN(VSUBL_S, s, ext, sub, false)
276
}
157
-DO_PREWIDEN(VSUBL_U, u, extu, sub, false)
277
158
-DO_PREWIDEN(VADDW_S, s, ext, add, true)
278
static const MemoryRegionOps sdhci_mmio_ops = {
159
-DO_PREWIDEN(VADDW_U, u, extu, add, true)
279
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
160
-DO_PREWIDEN(VSUBW_S, s, ext, sub, true)
280
index XXXXXXX..XXXXXXX 100644
161
-DO_PREWIDEN(VSUBW_U, u, extu, sub, true)
281
--- a/hw/sd/trace-events
162
+DO_PREWIDEN(VADDL_S, s, add, false, MO_SIGN)
282
+++ b/hw/sd/trace-events
163
+DO_PREWIDEN(VADDL_U, u, add, false, 0)
283
@@ -XXX,XX +XXX,XX @@
164
+DO_PREWIDEN(VSUBL_S, s, sub, false, MO_SIGN)
284
# See docs/devel/tracing.txt for syntax documentation.
165
+DO_PREWIDEN(VSUBL_U, u, sub, false, 0)
285
166
+DO_PREWIDEN(VADDW_S, s, add, true, MO_SIGN)
286
+# hw/sd/sdhci.c
167
+DO_PREWIDEN(VADDW_U, u, add, true, 0)
287
+sdhci_set_inserted(const char *level) "card state changed: %s"
168
+DO_PREWIDEN(VSUBW_S, s, sub, true, MO_SIGN)
288
+sdhci_send_command(uint8_t cmd, uint32_t arg) "CMD%02u ARG[0x%08x]"
169
+DO_PREWIDEN(VSUBW_U, u, sub, true, 0)
289
+sdhci_error(const char *msg) "%s"
170
290
+sdhci_response4(uint32_t r0) "RSPREG[31..0]=0x%08x"
171
static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
291
+sdhci_response16(uint32_t r3, uint32_t r2, uint32_t r1, uint32_t r0) "RSPREG[127..96]=0x%08x, RSPREG[95..64]=0x%08x, RSPREG[63..32]=0x%08x, RSPREG[31..0]=0x%08x"
172
NeonGenTwo64OpFn *opfn, NeonGenNarrowFn *narrowfn)
292
+sdhci_end_transfer(uint8_t cmd, uint32_t arg) "Automatically issue CMD%02u 0x%08x"
293
+sdhci_adma(const char *desc, uint32_t sysad) "%s: admasysaddr=0x%" PRIx32
294
+sdhci_adma_loop(uint64_t addr, uint16_t length, uint8_t attr) "addr=0x%08" PRIx64 ", len=%d, attr=0x%x"
295
+sdhci_adma_transfer_completed(void) ""
296
+sdhci_access(const char *access, unsigned int size, uint64_t offset, const char *dir, uint64_t val, uint64_t val2) "%s%u: addr[0x%04" PRIx64 "] %s 0x%08" PRIx64 " (%" PRIu64 ")"
297
+sdhci_read_dataport(uint16_t data_count) "all %u bytes of data have been read from input buffer"
298
+sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of data"
299
+
300
# hw/sd/milkymist-memcard.c
301
milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
302
milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
303
--
173
--
304
2.7.4
174
2.20.1
305
175
306
176
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
In the neon_padd/pmax/pmin helpers for float16, a cut-and-paste error
2
meant we were using the H4() address swizzler macro rather than the
3
H2() which is required for 2-byte data. This had no effect on
4
little-endian hosts but meant we put the result data into the
5
destination Dreg in the wrong order on big-endian hosts.
2
6
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
5
Message-id: 20180115182436.2066-8-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20201028191712.4910-2-peter.maydell@linaro.org
7
---
11
---
8
hw/sd/sdhci.c | 7 ++++---
12
target/arm/vec_helper.c | 8 ++++----
9
1 file changed, 4 insertions(+), 3 deletions(-)
13
1 file changed, 4 insertions(+), 4 deletions(-)
10
14
11
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/sdhci.c
17
--- a/target/arm/vec_helper.c
14
+++ b/hw/sd/sdhci.c
18
+++ b/target/arm/vec_helper.c
15
@@ -XXX,XX +XXX,XX @@ static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
19
@@ -XXX,XX +XXX,XX @@ DO_ABA(gvec_uaba_d, uint64_t)
16
ret = (SD_HOST_SPECv2_VERS << 16) | sdhci_slotint(s);
20
r2 = float16_##OP(m[H2(0)], m[H2(1)], fpst); \
17
break;
21
r3 = float16_##OP(m[H2(2)], m[H2(3)], fpst); \
18
default:
22
\
19
- ERRPRINT("bad %ub read: addr[0x%04x]\n", size, (int)offset);
23
- d[H4(0)] = r0; \
20
+ qemu_log_mask(LOG_UNIMP, "SDHC rd_%ub @0x%02" HWADDR_PRIx " "
24
- d[H4(1)] = r1; \
21
+ "not implemented\n", size, offset);
25
- d[H4(2)] = r2; \
22
break;
26
- d[H4(3)] = r3; \
27
+ d[H2(0)] = r0; \
28
+ d[H2(1)] = r1; \
29
+ d[H2(2)] = r2; \
30
+ d[H2(3)] = r3; \
23
}
31
}
24
32
25
@@ -XXX,XX +XXX,XX @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
33
DO_NEON_PAIRWISE(neon_padd, add)
26
sdhci_update_irq(s);
27
break;
28
default:
29
- ERRPRINT("bad %ub write offset: addr[0x%04x] <- %u(0x%x)\n",
30
- size, (int)offset, value >> shift, value >> shift);
31
+ qemu_log_mask(LOG_UNIMP, "SDHC wr_%ub @0x%02" HWADDR_PRIx " <- 0x%08x "
32
+ "not implemented\n", size, offset, value >> shift);
33
break;
34
}
35
DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",
36
--
34
--
37
2.7.4
35
2.20.1
38
36
39
37
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The helper functions for performing the udot/sdot operations against
2
a scalar were not using an address-swizzling macro when converting
3
the index of the scalar element into a pointer into the vm array.
4
This had no effect on little-endian hosts but meant we generated
5
incorrect results on big-endian hosts.
2
6
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
For these insns, the index is indexing over group of 4 8-bit values,
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
8
so 32 bits per indexed entity, and H4() is therefore what we want.
5
Message-id: 20180115182436.2066-10-f4bug@amsat.org
9
(For Neon the only possible input indexes are 0 and 1.)
10
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20201028191712.4910-3-peter.maydell@linaro.org
7
---
15
---
8
hw/sd/sdhci-internal.h | 1 +
16
target/arm/vec_helper.c | 4 ++--
9
hw/sd/sdhci.c | 3 +--
17
1 file changed, 2 insertions(+), 2 deletions(-)
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
18
12
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
19
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
13
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sdhci-internal.h
21
--- a/target/arm/vec_helper.c
15
+++ b/hw/sd/sdhci-internal.h
22
+++ b/target/arm/vec_helper.c
16
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
17
#define SDHC_TRNS_ACMD12 0x0004
24
intptr_t index = simd_data(desc);
18
#define SDHC_TRNS_READ 0x0010
25
uint32_t *d = vd;
19
#define SDHC_TRNS_MULTI 0x0020
26
int8_t *n = vn;
20
+#define SDHC_TRNMOD_MASK 0x0037
27
- int8_t *m_indexed = (int8_t *)vm + index * 4;
21
28
+ int8_t *m_indexed = (int8_t *)vm + H4(index) * 4;
22
/* R/W Command Register 0x0 */
29
23
#define SDHC_CMDREG 0x0E
30
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
24
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
31
* Otherwise opr_sz is a multiple of 16.
25
index XXXXXXX..XXXXXXX 100644
32
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
26
--- a/hw/sd/sdhci.c
33
intptr_t index = simd_data(desc);
27
+++ b/hw/sd/sdhci.c
34
uint32_t *d = vd;
28
@@ -XXX,XX +XXX,XX @@
35
uint8_t *n = vn;
29
(SDHC_CAPAB_BASECLKFREQ << 8) | (SDHC_CAPAB_TOUNIT << 7) | \
36
- uint8_t *m_indexed = (uint8_t *)vm + index * 4;
30
(SDHC_CAPAB_TOCLKFREQ))
37
+ uint8_t *m_indexed = (uint8_t *)vm + H4(index) * 4;
31
38
32
-#define MASK_TRNMOD 0x0037
39
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
33
#define MASKED_WRITE(reg, mask, val) (reg = (reg & (mask)) | (val))
40
* Otherwise opr_sz is a multiple of 16.
34
35
static uint8_t sdhci_slotint(SDHCIState *s)
36
@@ -XXX,XX +XXX,XX @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
37
if (!(s->capareg & SDHC_CAN_DO_DMA)) {
38
value &= ~SDHC_TRNS_DMA;
39
}
40
- MASKED_WRITE(s->trnmod, mask, value & MASK_TRNMOD);
41
+ MASKED_WRITE(s->trnmod, mask, value & SDHC_TRNMOD_MASK);
42
MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);
43
44
/* Writing to the upper byte of CMDREG triggers SD command generation */
45
--
41
--
46
2.7.4
42
2.20.1
47
43
48
44
diff view generated by jsdifflib
1
Instead of ignoring the response from address_space_ld*()
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
2
(indicating an attempt to read a page table descriptor from
3
an invalid physical address), use it to report the failure
4
correctly.
5
2
6
Since this is another couple of locations where we need to
3
HCR should be applied when NS is set, not when it is cleared.
7
decide the value of the ARMMMUFaultInfo ea bit based on a
8
MemTxResult, we factor out that operation into a helper
9
function.
10
4
5
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
8
---
13
target/arm/internals.h | 10 ++++++++++
9
target/arm/helper.c | 5 ++---
14
target/arm/helper.c | 39 ++++++++++++++++++++++++++++++++++-----
10
1 file changed, 2 insertions(+), 3 deletions(-)
15
target/arm/op_helper.c | 7 +------
16
3 files changed, 45 insertions(+), 11 deletions(-)
17
11
18
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/internals.h
21
+++ b/target/arm/internals.h
22
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
23
return fsc;
24
}
25
26
+static inline bool arm_extabort_type(MemTxResult result)
27
+{
28
+ /* The EA bit in syndromes and fault status registers is an
29
+ * IMPDEF classification of external aborts. ARM implementations
30
+ * usually use this to indicate AXI bus Decode error (0) or
31
+ * Slave error (1); in QEMU we follow that.
32
+ */
33
+ return result != MEMTX_DECODE_ERROR;
34
+}
35
+
36
/* Do a page table walk and add page to TLB if possible */
37
bool arm_tlb_fill(CPUState *cpu, vaddr address,
38
MMUAccessType access_type, int mmu_idx,
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
14
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
15
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
16
@@ -XXX,XX +XXX,XX @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
44
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
17
45
&txattrs, &s2prot, &s2size, fi, NULL);
18
/*
46
if (ret) {
19
* Non-IS variants of TLB operations are upgraded to
47
+ assert(fi->type != ARMFault_None);
20
- * IS versions if we are at NS EL1 and HCR_EL2.FB is set to
48
fi->s2addr = addr;
21
+ * IS versions if we are at EL1 and HCR_EL2.FB is effectively set to
49
fi->stage2 = true;
22
* force broadcast of these operations.
50
fi->s1ptw = true;
23
*/
51
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
24
static bool tlb_force_broadcast(CPUARMState *env)
52
ARMCPU *cpu = ARM_CPU(cs);
25
{
53
CPUARMState *env = &cpu->env;
26
- return (env->cp15.hcr_el2 & HCR_FB) &&
54
MemTxAttrs attrs = {};
27
- arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
55
+ MemTxResult result = MEMTX_OK;
28
+ return arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_FB);
56
AddressSpace *as;
57
+ uint32_t data;
58
59
attrs.secure = is_secure;
60
as = arm_addressspace(cs, attrs);
61
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
62
return 0;
63
}
64
if (regime_translation_big_endian(env, mmu_idx)) {
65
- return address_space_ldl_be(as, addr, attrs, NULL);
66
+ data = address_space_ldl_be(as, addr, attrs, &result);
67
} else {
68
- return address_space_ldl_le(as, addr, attrs, NULL);
69
+ data = address_space_ldl_le(as, addr, attrs, &result);
70
}
71
+ if (result == MEMTX_OK) {
72
+ return data;
73
+ }
74
+ fi->type = ARMFault_SyncExternalOnWalk;
75
+ fi->ea = arm_extabort_type(result);
76
+ return 0;
77
}
29
}
78
30
79
static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
31
static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
80
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
81
ARMCPU *cpu = ARM_CPU(cs);
82
CPUARMState *env = &cpu->env;
83
MemTxAttrs attrs = {};
84
+ MemTxResult result = MEMTX_OK;
85
AddressSpace *as;
86
+ uint32_t data;
87
88
attrs.secure = is_secure;
89
as = arm_addressspace(cs, attrs);
90
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
91
return 0;
92
}
93
if (regime_translation_big_endian(env, mmu_idx)) {
94
- return address_space_ldq_be(as, addr, attrs, NULL);
95
+ data = address_space_ldq_be(as, addr, attrs, &result);
96
} else {
97
- return address_space_ldq_le(as, addr, attrs, NULL);
98
+ data = address_space_ldq_le(as, addr, attrs, &result);
99
+ }
100
+ if (result == MEMTX_OK) {
101
+ return data;
102
}
103
+ fi->type = ARMFault_SyncExternalOnWalk;
104
+ fi->ea = arm_extabort_type(result);
105
+ return 0;
106
}
107
108
static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
109
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
110
}
111
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
112
mmu_idx, fi);
113
+ if (fi->type != ARMFault_None) {
114
+ goto do_fault;
115
+ }
116
type = (desc & 3);
117
domain = (desc >> 5) & 0x0f;
118
if (regime_el(env, mmu_idx) == 1) {
119
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
120
}
121
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
122
mmu_idx, fi);
123
+ if (fi->type != ARMFault_None) {
124
+ goto do_fault;
125
+ }
126
switch (desc & 3) {
127
case 0: /* Page translation fault. */
128
fi->type = ARMFault_Translation;
129
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
130
}
131
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
132
mmu_idx, fi);
133
+ if (fi->type != ARMFault_None) {
134
+ goto do_fault;
135
+ }
136
type = (desc & 3);
137
if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) {
138
/* Section translation fault, or attempt to use the encoding
139
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
140
table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
141
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
142
mmu_idx, fi);
143
+ if (fi->type != ARMFault_None) {
144
+ goto do_fault;
145
+ }
146
ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
147
switch (desc & 3) {
148
case 0: /* Page translation fault. */
149
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
150
descaddr &= ~7ULL;
151
nstable = extract32(tableattrs, 4, 1);
152
descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fi);
153
- if (fi->s1ptw) {
154
+ if (fi->type != ARMFault_None) {
155
goto do_fault;
156
}
157
158
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/op_helper.c
161
+++ b/target/arm/op_helper.c
162
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
163
/* now we have a real cpu fault */
164
cpu_restore_state(cs, retaddr);
165
166
- /* The EA bit in syndromes and fault status registers is an
167
- * IMPDEF classification of external aborts. ARM implementations
168
- * usually use this to indicate AXI bus Decode error (0) or
169
- * Slave error (1); in QEMU we follow that.
170
- */
171
- fi.ea = (response != MEMTX_DECODE_ERROR);
172
+ fi.ea = arm_extabort_type(response);
173
fi.type = ARMFault_SyncExternal;
174
deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
175
}
176
--
32
--
177
2.7.4
33
2.20.1
178
34
179
35
diff view generated by jsdifflib
1
For PMSAv7, the v7A/R Arm ARM defines that setting AP to 0b111
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
2
is an UNPREDICTABLE reserved combination. However, for v7M
3
this value is documented as having the same behaviour as 0b110:
4
read-only for both privileged and unprivileged. Accept this
5
value on an M profile core rather than treating it as a guest
6
error and a no-access page.
7
2
8
Reported-by: Andy Gross <andy.gross@linaro.org>
3
Secure mode is not exempted from checking SCR_EL3.TLOR, and in the
4
future HCR_EL2.TLOR when S-EL2 is enabled.
5
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 1512742402-31669-1-git-send-email-peter.maydell@linaro.org
12
---
9
---
13
target/arm/helper.c | 14 ++++++++++++++
10
target/arm/helper.c | 19 +++++--------------
14
1 file changed, 14 insertions(+)
11
1 file changed, 5 insertions(+), 14 deletions(-)
15
12
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
17
@@ -XXX,XX +XXX,XX @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
21
case 6:
18
#endif
22
*prot |= PAGE_READ | PAGE_EXEC;
19
23
break;
20
/* Shared logic between LORID and the rest of the LOR* registers.
24
+ case 7:
21
- * Secure state has already been delt with.
25
+ /* for v7M, same as 6; for R profile a reserved value */
22
+ * Secure state exclusion has already been dealt with.
26
+ if (arm_feature(env, ARM_FEATURE_M)) {
23
*/
27
+ *prot |= PAGE_READ | PAGE_EXEC;
24
-static CPAccessResult access_lor_ns(CPUARMState *env)
28
+ break;
25
+static CPAccessResult access_lor_ns(CPUARMState *env,
29
+ }
26
+ const ARMCPRegInfo *ri, bool isread)
30
+ /* fall through */
27
{
31
default:
28
int el = arm_current_el(env);
32
qemu_log_mask(LOG_GUEST_ERROR,
29
33
"DRACR[%d]: Bad value for AP bits: 0x%"
30
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_ns(CPUARMState *env)
34
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
31
return CP_ACCESS_OK;
35
case 6:
32
}
36
*prot |= PAGE_READ | PAGE_EXEC;
33
37
break;
34
-static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
38
+ case 7:
35
- bool isread)
39
+ /* for v7M, same as 6; for R profile a reserved value */
36
-{
40
+ if (arm_feature(env, ARM_FEATURE_M)) {
37
- if (arm_is_secure_below_el3(env)) {
41
+ *prot |= PAGE_READ | PAGE_EXEC;
38
- /* Access ok in secure mode. */
42
+ break;
39
- return CP_ACCESS_OK;
43
+ }
40
- }
44
+ /* fall through */
41
- return access_lor_ns(env);
45
default:
42
-}
46
qemu_log_mask(LOG_GUEST_ERROR,
43
-
47
"DRACR[%d]: Bad value for AP bits: 0x%"
44
static CPAccessResult access_lor_other(CPUARMState *env,
45
const ARMCPRegInfo *ri, bool isread)
46
{
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_other(CPUARMState *env,
48
/* Access denied in secure mode. */
49
return CP_ACCESS_TRAP;
50
}
51
- return access_lor_ns(env);
52
+ return access_lor_ns(env, ri, isread);
53
}
54
55
/*
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
57
.type = ARM_CP_CONST, .resetvalue = 0 },
58
{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
59
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
60
- .access = PL1_R, .accessfn = access_lorid,
61
+ .access = PL1_R, .accessfn = access_lor_ns,
62
.type = ARM_CP_CONST, .resetvalue = 0 },
63
REGINFO_SENTINEL
64
};
48
--
65
--
49
2.7.4
66
2.20.1
50
67
51
68
diff view generated by jsdifflib
1
Since milkymist-memcard is still using the legacy SD card API,
1
If we're using the capstone disassembler, disassembly of a run of
2
the SD card created by sd_init() is not plugged into any bus.
2
instructions more than 32 bytes long disassembles the wrong data for
3
This means that the controller has to reset it manually.
3
instructions beyond the 32 byte mark:
4
4
5
Failing to do this mostly didn't affect the guest since the
5
(qemu) xp /16x 0x100
6
guest typically does a programmed SD card reset as part of
6
0000000000000100: 0x00000005 0x54410001 0x00000001 0x00001000
7
its SD controller driver initialization, but meant that
7
0000000000000110: 0x00000000 0x00000004 0x54410002 0x3c000000
8
migration failed because it's only in sd_reset() that we
8
0000000000000120: 0x00000000 0x00000004 0x54410009 0x74736574
9
set up the wpgrps_size field.
9
0000000000000130: 0x00000000 0x00000000 0x00000000 0x00000000
10
(qemu) xp /16i 0x100
11
0x00000100: 00000005 andeq r0, r0, r5
12
0x00000104: 54410001 strbpl r0, [r1], #-1
13
0x00000108: 00000001 andeq r0, r0, r1
14
0x0000010c: 00001000 andeq r1, r0, r0
15
0x00000110: 00000000 andeq r0, r0, r0
16
0x00000114: 00000004 andeq r0, r0, r4
17
0x00000118: 54410002 strbpl r0, [r1], #-2
18
0x0000011c: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
19
0x00000120: 54410001 strbpl r0, [r1], #-1
20
0x00000124: 00000001 andeq r0, r0, r1
21
0x00000128: 00001000 andeq r1, r0, r0
22
0x0000012c: 00000000 andeq r0, r0, r0
23
0x00000130: 00000004 andeq r0, r0, r4
24
0x00000134: 54410002 strbpl r0, [r1], #-2
25
0x00000138: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
26
0x0000013c: 00000000 andeq r0, r0, r0
27
28
Here the disassembly of 0x120..0x13f is using the data that is in
29
0x104..0x123.
30
31
This is caused by passing the wrong value to the read_memory_func().
32
The intention is that at this point in the loop the 'cap_buf' buffer
33
already contains 'csize' bytes of data for the instruction at guest
34
addr 'pc', and we want to read in an extra 'tsize' bytes. Those
35
extra bytes are therefore at 'pc + csize', not 'pc'. On the first
36
time through the loop 'csize' happens to be zero, so the initial read
37
of 32 bytes into cap_buf is correct and as long as the disassembly
38
never needs to read more data we return the correct information.
39
40
Use the correct guest address in the call to read_memory_func().
10
41
11
Cc: qemu-stable@nongnu.org
42
Cc: qemu-stable@nongnu.org
43
Fixes: https://bugs.launchpad.net/qemu/+bug/1900779
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
45
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Message-id: 20201022132445.25039-1-peter.maydell@linaro.org
15
Message-id: 1515506513-31961-3-git-send-email-peter.maydell@linaro.org
16
---
47
---
17
hw/sd/milkymist-memcard.c | 4 ++++
48
disas/capstone.c | 2 +-
18
1 file changed, 4 insertions(+)
49
1 file changed, 1 insertion(+), 1 deletion(-)
19
50
20
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
51
diff --git a/disas/capstone.c b/disas/capstone.c
21
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/sd/milkymist-memcard.c
53
--- a/disas/capstone.c
23
+++ b/hw/sd/milkymist-memcard.c
54
+++ b/disas/capstone.c
24
@@ -XXX,XX +XXX,XX @@ static void milkymist_memcard_reset(DeviceState *d)
55
@@ -XXX,XX +XXX,XX @@ bool cap_disas_monitor(disassemble_info *info, uint64_t pc, int count)
25
for (i = 0; i < R_MAX; i++) {
56
26
s->regs[i] = 0;
57
/* Make certain that we can make progress. */
27
}
58
assert(tsize != 0);
28
+ /* Since we're still using the legacy SD API the card is not plugged
59
- info->read_memory_func(pc, cap_buf + csize, tsize, info);
29
+ * into any bus, and we must reset it manually.
60
+ info->read_memory_func(pc + csize, cap_buf + csize, tsize, info);
30
+ */
61
csize += tsize;
31
+ device_reset(DEVICE(s->card));
62
32
}
63
if (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) {
33
34
static int milkymist_memcard_init(SysBusDevice *dev)
35
--
64
--
36
2.7.4
65
2.20.1
37
66
38
67
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Add common/sysbus/pci/sdbus comments to have clearer code blocks separation.
3
Use the BIT_ULL() macro to ensure we use 64-bit arithmetic.
4
This fixes the following Coverity issue (OVERFLOW_BEFORE_WIDEN):
4
5
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
CID 1432363 (#1 of 1): Unintentional integer overflow:
6
Message-id: 20180115182436.2066-4-f4bug@amsat.org
7
8
overflow_before_widen:
9
Potentially overflowing expression 1 << scale with type int
10
(32 bits, signed) is evaluated using 32-bit arithmetic, and
11
then used in a context that expects an expression of type
12
hwaddr (64 bits, unsigned).
13
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Acked-by: Eric Auger <eric.auger@redhat.com>
16
Message-id: 20201030144617.1535064-1-philmd@redhat.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
---
19
---
10
include/hw/sd/sdhci.h | 4 +++-
20
hw/arm/smmuv3.c | 3 ++-
11
hw/sd/sdhci.c | 25 +++++++++++++++++--------
21
1 file changed, 2 insertions(+), 1 deletion(-)
12
2 files changed, 20 insertions(+), 9 deletions(-)
13
22
14
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
23
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/sd/sdhci.h
25
--- a/hw/arm/smmuv3.c
17
+++ b/include/hw/sd/sdhci.h
26
+++ b/hw/arm/smmuv3.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
19
uint32_t buf_maxsz;
20
uint16_t data_count; /* current element in FIFO buffer */
21
uint8_t stopped_state;/* Current SDHC state */
22
- bool pending_insert_quirk;/* Quirk for Raspberry Pi card insert int */
23
bool pending_insert_state;
24
/* Buffer Data Port Register - virtual access point to R and W buffers */
25
/* Software Reset Register - always reads as 0 */
26
/* Force Event Auto CMD12 Error Interrupt Reg - write only */
27
/* Force Event Error Interrupt Register- write only */
28
/* RO Host Controller Version Register always reads as 0x2401 */
29
+
30
+ /* Configurable properties */
31
+ bool pending_insert_quirk; /* Quirk for Raspberry Pi card insert int */
32
} SDHCIState;
33
34
#define TYPE_PCI_SDHCI "sdhci-pci"
35
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/sd/sdhci.c
38
+++ b/hw/sd/sdhci.c
39
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@
40
*/
28
*/
41
29
42
#include "qemu/osdep.h"
30
#include "qemu/osdep.h"
43
+#include "qapi/error.h"
31
+#include "qemu/bitops.h"
44
#include "hw/hw.h"
32
#include "hw/irq.h"
45
#include "sysemu/block-backend.h"
33
#include "hw/sysbus.h"
46
#include "sysemu/blockdev.h"
34
#include "migration/vmstate.h"
47
@@ -XXX,XX +XXX,XX @@ static inline unsigned int sdhci_get_fifolen(SDHCIState *s)
35
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
36
scale = CMD_SCALE(cmd);
37
num = CMD_NUM(cmd);
38
ttl = CMD_TTL(cmd);
39
- num_pages = (num + 1) * (1 << (scale));
40
+ num_pages = (num + 1) * BIT_ULL(scale);
48
}
41
}
49
}
42
50
43
if (type == SMMU_CMD_TLBI_NH_VA) {
51
+/* --- qdev common --- */
52
+
53
+#define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \
54
+ /* Capabilities registers provide information on supported features
55
+ * of this specific host controller implementation */ \
56
+ DEFINE_PROP_UINT32("capareg", _state, capareg, SDHC_CAPAB_REG_DEFAULT), \
57
+ DEFINE_PROP_UINT32("maxcurr", _state, maxcurr, 0)
58
+
59
static void sdhci_initfn(SDHCIState *s)
60
{
61
qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
62
@@ -XXX,XX +XXX,XX @@ const VMStateDescription sdhci_vmstate = {
63
},
64
};
65
66
-/* Capabilities registers provide information on supported features of this
67
- * specific host controller implementation */
68
+/* --- qdev PCI --- */
69
+
70
static Property sdhci_pci_properties[] = {
71
- DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
72
- SDHC_CAPAB_REG_DEFAULT),
73
- DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
74
+ DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState),
75
DEFINE_PROP_END_OF_LIST(),
76
};
77
78
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sdhci_pci_info = {
79
},
80
};
81
82
+/* --- qdev SysBus --- */
83
+
84
static Property sdhci_sysbus_properties[] = {
85
- DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
86
- SDHC_CAPAB_REG_DEFAULT),
87
- DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
88
+ DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState),
89
DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk,
90
false),
91
DEFINE_PROP_END_OF_LIST(),
92
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sdhci_sysbus_info = {
93
.class_init = sdhci_sysbus_class_init,
94
};
95
96
+/* --- qdev bus master --- */
97
+
98
static void sdhci_bus_class_init(ObjectClass *klass, void *data)
99
{
100
SDBusClass *sbc = SD_BUS_CLASS(klass);
101
--
44
--
102
2.7.4
45
2.20.1
103
46
104
47
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
2
2
3
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
3
When booting a CPU with EL3 using the -kernel flag, set up CPTR_EL3 so
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
that SVE will not trap to EL3.
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
7
Message-id: 20180115182436.2066-13-f4bug@amsat.org
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201030151541.11976-1-remi@remlab.net
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
hw/sd/sdhci.c | 3 +++
11
hw/arm/boot.c | 3 +++
11
1 file changed, 3 insertions(+)
12
1 file changed, 3 insertions(+)
12
13
13
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
14
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/sd/sdhci.c
16
--- a/hw/arm/boot.c
16
+++ b/hw/sd/sdhci.c
17
+++ b/hw/arm/boot.c
17
@@ -XXX,XX +XXX,XX @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
18
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
18
}
19
if (cpu_isar_feature(aa64_mte, cpu)) {
19
sdhci_update_irq(s);
20
env->cp15.scr_el3 |= SCR_ATA;
20
break;
21
}
21
+ case SDHC_ACMD12ERRSTS:
22
+ if (cpu_isar_feature(aa64_sve, cpu)) {
22
+ MASKED_WRITE(s->acmd12errsts, mask, value);
23
+ env->cp15.cptr_el[3] |= CPTR_EZ;
23
+ break;
24
+ }
24
25
/* AArch64 kernels never boot in secure mode */
25
case SDHC_CAPAB:
26
assert(!info->secure_boot);
26
case SDHC_CAPAB + 4:
27
/* This hook is only supported for AArch32 currently:
27
--
28
--
28
2.7.4
29
2.20.1
29
30
30
31
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: AlexChen <alex.chen@huawei.com>
2
2
3
Add a 'dma' property allowing machine creation to provide the address-space
3
In omap_lcd_interrupts(), the pointer omap_lcd is dereferinced before
4
SDHCI DMA operates on.
4
being check if it is valid, which may lead to NULL pointer dereference.
5
So move the assignment to surface after checking that the omap_lcd is valid
6
and move surface_bits_per_pixel(surface) to after the surface assignment.
5
7
6
[based on a patch from Alistair Francis <alistair.francis@xilinx.com>
8
Reported-by: Euler Robot <euler.robot@huawei.com>
7
from qemu/xilinx tag xilinx-v2016.1]
9
Signed-off-by: AlexChen <alex.chen@huawei.com>
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 5F9CDB8A.9000001@huawei.com
9
Message-id: 20180115182436.2066-15-f4bug@amsat.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
include/hw/sd/sdhci.h | 1 +
14
hw/display/omap_lcdc.c | 10 +++++++---
13
hw/sd/sdhci.c | 18 +++++++++++++++++-
15
1 file changed, 7 insertions(+), 3 deletions(-)
14
2 files changed, 18 insertions(+), 1 deletion(-)
15
16
16
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
17
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/sd/sdhci.h
19
--- a/hw/display/omap_lcdc.c
19
+++ b/include/hw/sd/sdhci.h
20
+++ b/hw/display/omap_lcdc.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
21
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
21
SDBus sdbus;
22
static void omap_update_display(void *opaque)
22
MemoryRegion iomem;
23
AddressSpace *dma_as;
24
+ MemoryRegion *dma_mr;
25
26
QEMUTimer *insert_timer; /* timer for 'changing' sd card. */
27
QEMUTimer *transfer_timer;
28
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/sd/sdhci.c
31
+++ b/hw/sd/sdhci.c
32
@@ -XXX,XX +XXX,XX @@ static Property sdhci_sysbus_properties[] = {
33
DEFINE_SDHCI_COMMON_PROPERTIES(SDHCIState),
34
DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk,
35
false),
36
+ DEFINE_PROP_LINK("dma", SDHCIState,
37
+ dma_mr, TYPE_MEMORY_REGION, MemoryRegion *),
38
DEFINE_PROP_END_OF_LIST(),
39
};
40
41
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_init(Object *obj)
42
static void sdhci_sysbus_finalize(Object *obj)
43
{
23
{
44
SDHCIState *s = SYSBUS_SDHCI(obj);
24
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
45
+
25
- DisplaySurface *surface = qemu_console_surface(omap_lcd->con);
46
+ if (s->dma_mr) {
26
+ DisplaySurface *surface;
47
+ object_unparent(OBJECT(s->dma_mr));
27
draw_line_func draw_line;
28
int size, height, first, last;
29
int width, linesize, step, bpp, frame_offset;
30
hwaddr frame_base;
31
32
- if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable ||
33
- !surface_bits_per_pixel(surface)) {
34
+ if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable) {
35
+ return;
48
+ }
36
+ }
49
+
37
+
50
sdhci_uninitfn(s);
38
+ surface = qemu_console_surface(omap_lcd->con);
51
}
39
+ if (!surface_bits_per_pixel(surface)) {
52
53
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
54
return;
40
return;
55
}
41
}
56
42
57
- s->dma_as = &address_space_memory;
58
+ if (s->dma_mr) {
59
+ address_space_init(s->dma_as, s->dma_mr, "sdhci-dma");
60
+ } else {
61
+ /* use system_memory() if property "dma" not set */
62
+ s->dma_as = &address_space_memory;
63
+ }
64
65
sysbus_init_irq(sbd, &s->irq);
66
sysbus_init_mmio(sbd, &s->iomem);
67
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_unrealize(DeviceState *dev, Error **errp)
68
SDHCIState *s = SYSBUS_SDHCI(dev);
69
70
sdhci_common_unrealize(s, &error_abort);
71
+
72
+ if (s->dma_mr) {
73
+ address_space_destroy(s->dma_as);
74
+ }
75
}
76
77
static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
78
--
43
--
79
2.7.4
44
2.20.1
80
45
81
46
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: AlexChen <alex.chen@huawei.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
In exynos4210_fimd_update(), the pointer s is dereferinced before
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
being check if it is valid, which may lead to NULL pointer dereference.
5
Message-id: 20180115182436.2066-2-f4bug@amsat.org
5
So move the assignment to global_width after checking that the s is valid.
6
7
Reported-by: Euler Robot <euler.robot@huawei.com>
8
Signed-off-by: Alex Chen <alex.chen@huawei.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 5F9F8D88.9030102@huawei.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
hw/sd/sdhci-internal.h | 4 ----
13
hw/display/exynos4210_fimd.c | 4 +++-
9
include/hw/sd/sdhci.h | 7 ++++++-
14
1 file changed, 3 insertions(+), 1 deletion(-)
10
hw/sd/sdhci.c | 1 +
11
3 files changed, 7 insertions(+), 5 deletions(-)
12
15
13
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
16
diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/sd/sdhci-internal.h
18
--- a/hw/display/exynos4210_fimd.c
16
+++ b/hw/sd/sdhci-internal.h
19
+++ b/hw/display/exynos4210_fimd.c
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void exynos4210_fimd_update(void *opaque)
18
#ifndef SDHCI_INTERNAL_H
21
bool blend = false;
19
#define SDHCI_INTERNAL_H
22
uint8_t *host_fb_addr;
20
23
bool is_dirty = false;
21
-#include "hw/sd/sdhci.h"
24
- const int global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
22
-
25
+ int global_width;
23
/* R/W SDMA System Address register 0x0 */
26
24
#define SDHC_SYSAD 0x00
27
if (!s || !s->console || !s->enabled ||
25
28
surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) {
26
@@ -XXX,XX +XXX,XX @@ enum {
29
return;
27
sdhc_gap_write = 2 /* SDHC stopped at block gap during write operation */
30
}
28
};
29
30
-extern const VMStateDescription sdhci_vmstate;
31
-
32
#endif
33
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/sd/sdhci.h
36
+++ b/include/hw/sd/sdhci.h
37
@@ -XXX,XX +XXX,XX @@
38
#define SDHCI_H
39
40
#include "qemu-common.h"
41
-#include "hw/block/block.h"
42
#include "hw/pci/pci.h"
43
#include "hw/sysbus.h"
44
#include "hw/sd/sd.h"
45
46
/* SD/MMC host controller state */
47
typedef struct SDHCIState {
48
+ /*< private >*/
49
union {
50
PCIDevice pcidev;
51
SysBusDevice busdev;
52
};
53
+
31
+
54
+ /*< public >*/
32
+ global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
55
SDBus sdbus;
33
exynos4210_update_resolution(s);
56
MemoryRegion iomem;
34
surface = qemu_console_surface(s->console);
57
58
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
59
qemu_irq ro_cb;
60
qemu_irq irq;
61
62
+ /* Registers cleared on reset */
63
uint32_t sdmasysad; /* SDMA System Address register */
64
uint16_t blksize; /* Host DMA Buff Boundary and Transfer BlkSize Reg */
65
uint16_t blkcnt; /* Blocks count for current transfer */
66
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
67
uint16_t acmd12errsts; /* Auto CMD12 error status register */
68
uint64_t admasysaddr; /* ADMA System Address Register */
69
70
+ /* Read-only registers */
71
uint32_t capareg; /* Capabilities Register */
72
uint32_t maxcurr; /* Maximum Current Capabilities Register */
73
+
74
uint8_t *fifo_buffer; /* SD host i/o FIFO buffer */
75
uint32_t buf_maxsz;
76
uint16_t data_count; /* current element in FIFO buffer */
77
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/sd/sdhci.c
80
+++ b/hw/sd/sdhci.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "sysemu/dma.h"
83
#include "qemu/timer.h"
84
#include "qemu/bitops.h"
85
+#include "hw/sd/sdhci.h"
86
#include "sdhci-internal.h"
87
#include "qemu/log.h"
88
35
89
--
36
--
90
2.7.4
37
2.20.1
91
38
92
39
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
In arm_v7m_mmu_idx_for_secstate() we get the 'priv' level to pass to
2
armv7m_mmu_idx_for_secstate_and_priv() by calling arm_current_el().
3
This is incorrect when the security state being queried is not the
4
current one, because arm_current_el() uses the current security state
5
to determine which of the banked CONTROL.nPRIV bits to look at.
6
The effect was that if (for instance) Secure state was in privileged
7
mode but Non-Secure was not then we would return the wrong MMU index.
2
8
3
While SysBus devices can use the get_system_memory() address space,
9
The only places where we are using this function in a way that could
4
PCI devices should use the bus master address space for DMA.
10
trigger this bug are for the stack loads during a v8M function-return
11
and for the instruction fetch of a v8M SG insn.
5
12
6
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
13
Fix the bug by expanding out the M-profile version of the
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
arm_current_el() logic inline so it can use the passed in secstate
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
rather than env->v7m.secure.
9
Message-id: 20180115182436.2066-14-f4bug@amsat.org
16
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20201022164408.13214-1-peter.maydell@linaro.org
11
---
20
---
12
include/hw/sd/sdhci.h | 1 +
21
target/arm/m_helper.c | 3 ++-
13
hw/sd/sdhci.c | 29 +++++++++++++++--------------
22
1 file changed, 2 insertions(+), 1 deletion(-)
14
2 files changed, 16 insertions(+), 14 deletions(-)
15
23
16
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
24
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
17
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/sd/sdhci.h
26
--- a/target/arm/m_helper.c
19
+++ b/include/hw/sd/sdhci.h
27
+++ b/target/arm/m_helper.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
28
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
21
/*< public >*/
29
/* Return the MMU index for a v7M CPU in the specified security state */
22
SDBus sdbus;
30
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
23
MemoryRegion iomem;
31
{
24
+ AddressSpace *dma_as;
32
- bool priv = arm_current_el(env) != 0;
25
33
+ bool priv = arm_v7m_is_handler_mode(env) ||
26
QEMUTimer *insert_timer; /* timer for 'changing' sd card. */
34
+ !(env->v7m.control[secstate] & 1);
27
QEMUTimer *transfer_timer;
35
28
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
36
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/sd/sdhci.c
31
+++ b/hw/sd/sdhci.c
32
@@ -XXX,XX +XXX,XX @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
33
s->blkcnt--;
34
}
35
}
36
- dma_memory_write(&address_space_memory, s->sdmasysad,
37
+ dma_memory_write(s->dma_as, s->sdmasysad,
38
&s->fifo_buffer[begin], s->data_count - begin);
39
s->sdmasysad += s->data_count - begin;
40
if (s->data_count == block_size) {
41
@@ -XXX,XX +XXX,XX @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
42
s->data_count = block_size;
43
boundary_count -= block_size - begin;
44
}
45
- dma_memory_read(&address_space_memory, s->sdmasysad,
46
+ dma_memory_read(s->dma_as, s->sdmasysad,
47
&s->fifo_buffer[begin], s->data_count - begin);
48
s->sdmasysad += s->data_count - begin;
49
if (s->data_count == block_size) {
50
@@ -XXX,XX +XXX,XX @@ static void sdhci_sdma_transfer_single_block(SDHCIState *s)
51
for (n = 0; n < datacnt; n++) {
52
s->fifo_buffer[n] = sdbus_read_data(&s->sdbus);
53
}
54
- dma_memory_write(&address_space_memory, s->sdmasysad, s->fifo_buffer,
55
- datacnt);
56
+ dma_memory_write(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt);
57
} else {
58
- dma_memory_read(&address_space_memory, s->sdmasysad, s->fifo_buffer,
59
- datacnt);
60
+ dma_memory_read(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt);
61
for (n = 0; n < datacnt; n++) {
62
sdbus_write_data(&s->sdbus, s->fifo_buffer[n]);
63
}
64
@@ -XXX,XX +XXX,XX @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
65
hwaddr entry_addr = (hwaddr)s->admasysaddr;
66
switch (SDHC_DMA_TYPE(s->hostctl)) {
67
case SDHC_CTRL_ADMA2_32:
68
- dma_memory_read(&address_space_memory, entry_addr, (uint8_t *)&adma2,
69
+ dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma2,
70
sizeof(adma2));
71
adma2 = le64_to_cpu(adma2);
72
/* The spec does not specify endianness of descriptor table.
73
@@ -XXX,XX +XXX,XX @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
74
dscr->incr = 8;
75
break;
76
case SDHC_CTRL_ADMA1_32:
77
- dma_memory_read(&address_space_memory, entry_addr, (uint8_t *)&adma1,
78
+ dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma1,
79
sizeof(adma1));
80
adma1 = le32_to_cpu(adma1);
81
dscr->addr = (hwaddr)(adma1 & 0xFFFFF000);
82
@@ -XXX,XX +XXX,XX @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
83
}
84
break;
85
case SDHC_CTRL_ADMA2_64:
86
- dma_memory_read(&address_space_memory, entry_addr,
87
+ dma_memory_read(s->dma_as, entry_addr,
88
(uint8_t *)(&dscr->attr), 1);
89
- dma_memory_read(&address_space_memory, entry_addr + 2,
90
+ dma_memory_read(s->dma_as, entry_addr + 2,
91
(uint8_t *)(&dscr->length), 2);
92
dscr->length = le16_to_cpu(dscr->length);
93
- dma_memory_read(&address_space_memory, entry_addr + 4,
94
+ dma_memory_read(s->dma_as, entry_addr + 4,
95
(uint8_t *)(&dscr->addr), 8);
96
dscr->attr = le64_to_cpu(dscr->attr);
97
dscr->attr &= 0xfffffff8;
98
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
99
s->data_count = block_size;
100
length -= block_size - begin;
101
}
102
- dma_memory_write(&address_space_memory, dscr.addr,
103
+ dma_memory_write(s->dma_as, dscr.addr,
104
&s->fifo_buffer[begin],
105
s->data_count - begin);
106
dscr.addr += s->data_count - begin;
107
@@ -XXX,XX +XXX,XX @@ static void sdhci_do_adma(SDHCIState *s)
108
s->data_count = block_size;
109
length -= block_size - begin;
110
}
111
- dma_memory_read(&address_space_memory, dscr.addr,
112
+ dma_memory_read(s->dma_as, dscr.addr,
113
&s->fifo_buffer[begin],
114
s->data_count - begin);
115
dscr.addr += s->data_count - begin;
116
@@ -XXX,XX +XXX,XX @@ static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
117
dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */
118
dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
119
s->irq = pci_allocate_irq(dev);
120
- pci_register_bar(dev, 0, 0, &s->iomem);
121
+ s->dma_as = pci_get_address_space(dev);
122
+ pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->iomem);
123
}
124
125
static void sdhci_pci_exit(PCIDevice *dev)
126
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
127
return;
128
}
129
130
+ s->dma_as = &address_space_memory;
131
+
132
sysbus_init_irq(sbd, &s->irq);
133
sysbus_init_mmio(sbd, &s->iomem);
134
}
37
}
135
--
38
--
136
2.7.4
39
2.20.1
137
40
138
41
diff view generated by jsdifflib
New patch
1
On some hosts (eg Ubuntu Bionic) pkg-config returns a set of
2
libraries for gio-2.0 which don't actually work when compiling
3
statically. (Specifically, the returned library string includes
4
-lmount, but not -lblkid which -lmount depends upon, so linking
5
fails due to missing symbols.)
1
6
7
Check that the libraries work, and don't enable gio if they don't,
8
in the same way we do for gnutls.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20200928160402.7961-1-peter.maydell@linaro.org
14
---
15
configure | 10 +++++++++-
16
1 file changed, 9 insertions(+), 1 deletion(-)
17
18
diff --git a/configure b/configure
19
index XXXXXXX..XXXXXXX 100755
20
--- a/configure
21
+++ b/configure
22
@@ -XXX,XX +XXX,XX @@ if test "$static" = yes && test "$mingw32" = yes; then
23
fi
24
25
if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
26
- gio=yes
27
gio_cflags=$($pkg_config --cflags gio-2.0)
28
gio_libs=$($pkg_config --libs gio-2.0)
29
gdbus_codegen=$($pkg_config --variable=gdbus_codegen gio-2.0)
30
if [ ! -x "$gdbus_codegen" ]; then
31
gdbus_codegen=
32
fi
33
+ # Check that the libraries actually work -- Ubuntu 18.04 ships
34
+ # with pkg-config --static --libs data for gio-2.0 that is missing
35
+ # -lblkid and will give a link error.
36
+ write_c_skeleton
37
+ if compile_prog "" "gio_libs" ; then
38
+ gio=yes
39
+ else
40
+ gio=no
41
+ fi
42
else
43
gio=no
44
fi
45
--
46
2.20.1
47
48
diff view generated by jsdifflib
1
Since pl181 is still using the legacy SD card API, the SD
1
In gicv3_init_cpuif() we copy the ARMCPU gicv3_maintenance_interrupt
2
card created by sd_init() is not plugged into any bus. This
2
into the GICv3CPUState struct's maintenance_irq field. This will
3
means that the controller has to reset it manually.
3
only work if the board happens to have already wired up the CPU
4
maintenance IRQ before the GIC was realized. Unfortunately this is
5
not the case for the 'virt' board, and so the value that gets copied
6
is NULL (since a qemu_irq is really a pointer to an IRQState struct
7
under the hood). The effect is that the CPU interface code never
8
actually raises the maintenance interrupt line.
4
9
5
Failing to do this mostly didn't affect the guest since the
10
Instead, since the GICv3CPUState has a pointer to the CPUState, make
6
guest typically does a programmed SD card reset as part of
11
the dereference at the point where we want to raise the interrupt, to
7
its SD controller driver initialization, but meant that
12
avoid an implicit requirement on board code to wire things up in a
8
migration failed because it's only in sd_reset() that we
13
particular order.
9
set up the wpgrps_size field.
10
14
11
Cc: qemu-stable@nongnu.org
15
Reported-by: Jose Martins <josemartins90@gmail.com>
12
Fixes: https://bugs.launchpad.net/qemu/+bug/1739378
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20201009153904.28529-1-peter.maydell@linaro.org
15
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
16
Message-id: 1515506513-31961-2-git-send-email-peter.maydell@linaro.org
17
---
19
---
18
hw/sd/pl181.c | 4 ++++
20
include/hw/intc/arm_gicv3_common.h | 1 -
19
1 file changed, 4 insertions(+)
21
hw/intc/arm_gicv3_cpuif.c | 5 ++---
22
2 files changed, 2 insertions(+), 4 deletions(-)
20
23
21
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
24
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
22
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/sd/pl181.c
26
--- a/include/hw/intc/arm_gicv3_common.h
24
+++ b/hw/sd/pl181.c
27
+++ b/include/hw/intc/arm_gicv3_common.h
25
@@ -XXX,XX +XXX,XX @@ static void pl181_reset(DeviceState *d)
28
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
26
29
qemu_irq parent_fiq;
27
/* We can assume our GPIO outputs have been wired up now */
30
qemu_irq parent_virq;
28
sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]);
31
qemu_irq parent_vfiq;
29
+ /* Since we're still using the legacy SD API the card is not plugged
32
- qemu_irq maintenance_irq;
30
+ * into any bus, and we must reset it manually.
33
31
+ */
34
/* Redistributor */
32
+ device_reset(DEVICE(s->card));
35
uint32_t level; /* Current IRQ level */
36
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/arm_gicv3_cpuif.c
39
+++ b/hw/intc/arm_gicv3_cpuif.c
40
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
41
int irqlevel = 0;
42
int fiqlevel = 0;
43
int maintlevel = 0;
44
+ ARMCPU *cpu = ARM_CPU(cs->cpu);
45
46
idx = hppvi_index(cs);
47
trace_gicv3_cpuif_virt_update(gicv3_redist_affid(cs), idx);
48
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
49
50
qemu_set_irq(cs->parent_vfiq, fiqlevel);
51
qemu_set_irq(cs->parent_virq, irqlevel);
52
- qemu_set_irq(cs->maintenance_irq, maintlevel);
53
+ qemu_set_irq(cpu->gicv3_maintenance_interrupt, maintlevel);
33
}
54
}
34
55
35
static void pl181_init(Object *obj)
56
static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
57
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
58
&& cpu->gic_num_lrs) {
59
int j;
60
61
- cs->maintenance_irq = cpu->gicv3_maintenance_interrupt;
62
-
63
cs->num_list_regs = cpu->gic_num_lrs;
64
cs->vpribits = cpu->gic_vpribits;
65
cs->vprebits = cpu->gic_vprebits;
36
--
66
--
37
2.7.4
67
2.20.1
38
68
39
69
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The kerneldoc script currently emits Sphinx markup for a macro with
2
arguments that uses the c:function directive. This is correct for
3
Sphinx versions earlier than Sphinx 3, where c:macro doesn't allow
4
documentation of macros with arguments and c:function is not picky
5
about the syntax of what it is passed. However, in Sphinx 3 the
6
c:macro directive was enhanced to support macros with arguments,
7
and c:function was made more picky about what syntax it accepted.
2
8
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
When kerneldoc is told that it needs to produce output for Sphinx
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
10
3 or later, make it emit c:function only for functions and c:macro
5
Message-id: 20180115182436.2066-3-f4bug@amsat.org
11
for macros with arguments. We assume that anything with a return
12
type is a function and anything without is a macro.
13
14
This fixes the Sphinx error:
15
16
/home/petmay01/linaro/qemu-from-laptop/qemu/docs/../include/qom/object.h:155:Error in declarator
17
If declarator-id with parameters (e.g., 'void f(int arg)'):
18
Invalid C declaration: Expected identifier in nested name. [error at 25]
19
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
20
-------------------------^
21
If parenthesis in noptr-declarator (e.g., 'void (*f(int arg))(double)'):
22
Error in declarator or parameters
23
Invalid C declaration: Expecting "(" in parameters. [error at 39]
24
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
25
---------------------------------------^
26
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
29
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
30
Message-id: 20201030174700.7204-2-peter.maydell@linaro.org
7
---
31
---
8
include/hw/sd/sdhci.h | 2 --
32
scripts/kernel-doc | 18 +++++++++++++++++-
9
hw/sd/sdhci.c | 2 --
33
1 file changed, 17 insertions(+), 1 deletion(-)
10
2 files changed, 4 deletions(-)
11
34
12
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
35
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
13
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100755
14
--- a/include/hw/sd/sdhci.h
37
--- a/scripts/kernel-doc
15
+++ b/include/hw/sd/sdhci.h
38
+++ b/scripts/kernel-doc
16
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
39
@@ -XXX,XX +XXX,XX @@ sub output_function_rst(%) {
17
40
    output_highlight_rst($args{'purpose'});
18
QEMUTimer *insert_timer; /* timer for 'changing' sd card. */
41
    $start = "\n\n**Syntax**\n\n ``";
19
QEMUTimer *transfer_timer;
42
} else {
20
- qemu_irq eject_cb;
43
-    print ".. c:function:: ";
21
- qemu_irq ro_cb;
44
+ if ((split(/\./, $sphinx_version))[0] >= 3) {
22
qemu_irq irq;
45
+ # Sphinx 3 and later distinguish macros and functions and
23
46
+ # complain if you use c:function with something that's not
24
/* Registers cleared on reset */
47
+ # syntactically valid as a function declaration.
25
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
48
+ # We assume that anything with a return type is a function
26
index XXXXXXX..XXXXXXX 100644
49
+ # and anything without is a macro.
27
--- a/hw/sd/sdhci.c
50
+ if ($args{'functiontype'} ne "") {
28
+++ b/hw/sd/sdhci.c
51
+ print ".. c:function:: ";
29
@@ -XXX,XX +XXX,XX @@ static void sdhci_uninitfn(SDHCIState *s)
52
+ } else {
30
timer_free(s->insert_timer);
53
+ print ".. c:macro:: ";
31
timer_del(s->transfer_timer);
54
+ }
32
timer_free(s->transfer_timer);
55
+ } else {
33
- qemu_free_irq(s->eject_cb);
56
+ # Older Sphinx don't support documenting macros that take
34
- qemu_free_irq(s->ro_cb);
57
+ # arguments with c:macro, and don't complain about the use
35
58
+ # of c:function for this.
36
g_free(s->fifo_buffer);
59
+ print ".. c:function:: ";
37
s->fifo_buffer = NULL;
60
+ }
61
}
62
if ($args{'functiontype'} ne "") {
63
    $start .= $args{'functiontype'} . " " . $args{'function'} . " (";
38
--
64
--
39
2.7.4
65
2.20.1
40
66
41
67
diff view generated by jsdifflib
1
Add virt-2.12 machine type.
1
Sphinx 3.2 is pickier than earlier versions about the option:: markup,
2
and complains about our usage in qemu-option-trace.rst:
3
4
../../docs/qemu-option-trace.rst.inc:4:Malformed option description
5
'[enable=]PATTERN', should look like "opt", "-opt args", "--opt args",
6
"/opt args" or "+opt args"
7
8
In this file, we're really trying to document the different parts of
9
the top-level --trace option, which qemu-nbd.rst and qemu-img.rst
10
have already introduced with an option:: markup. So it's not right
11
to use option:: here anyway. Switch to a different markup
12
(definition lists) which gives about the same formatted output.
13
14
(Unlike option::, this markup doesn't produce index entries; but
15
at the moment we don't do anything much with indexes anyway, and
16
in any case I think it doesn't make much sense to have individual
17
index entries for the sub-parts of the --trace option.)
2
18
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
21
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Message-id: 20201030174700.7204-3-peter.maydell@linaro.org
4
---
23
---
5
hw/arm/virt.c | 19 +++++++++++++++++--
24
docs/qemu-option-trace.rst.inc | 6 +++---
6
1 file changed, 17 insertions(+), 2 deletions(-)
25
1 file changed, 3 insertions(+), 3 deletions(-)
7
26
8
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
27
diff --git a/docs/qemu-option-trace.rst.inc b/docs/qemu-option-trace.rst.inc
9
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
10
--- a/hw/arm/virt.c
29
--- a/docs/qemu-option-trace.rst.inc
11
+++ b/hw/arm/virt.c
30
+++ b/docs/qemu-option-trace.rst.inc
12
@@ -XXX,XX +XXX,XX @@ static void machvirt_machine_init(void)
31
@@ -XXX,XX +XXX,XX @@
13
}
32
14
type_init(machvirt_machine_init);
33
Specify tracing options.
15
34
16
-static void virt_2_11_instance_init(Object *obj)
35
-.. option:: [enable=]PATTERN
17
+static void virt_2_12_instance_init(Object *obj)
36
+``[enable=]PATTERN``
18
{
37
19
VirtMachineState *vms = VIRT_MACHINE(obj);
38
Immediately enable events matching *PATTERN*
20
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
39
(either event name or a globbing pattern). This option is only
21
@@ -XXX,XX +XXX,XX @@ static void virt_2_11_instance_init(Object *obj)
40
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
22
vms->irqmap = a15irqmap;
41
23
}
42
Use :option:`-trace help` to print a list of names of trace points.
24
43
25
+static void virt_machine_2_12_options(MachineClass *mc)
44
-.. option:: events=FILE
26
+{
45
+``events=FILE``
27
+}
46
28
+DEFINE_VIRT_MACHINE_AS_LATEST(2, 12)
47
Immediately enable events listed in *FILE*.
29
+
48
The file must contain one event name (as listed in the ``trace-events-all``
30
+#define VIRT_COMPAT_2_11 \
49
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
31
+ HW_COMPAT_2_11
50
available if QEMU has been compiled with the ``simple``, ``log`` or
32
+
51
``ftrace`` tracing backend.
33
+static void virt_2_11_instance_init(Object *obj)
52
34
+{
53
-.. option:: file=FILE
35
+ virt_2_12_instance_init(obj);
54
+``file=FILE``
36
+}
55
37
+
56
Log output traces to *FILE*.
38
static void virt_machine_2_11_options(MachineClass *mc)
57
This option is only available if QEMU has been compiled with
39
{
40
+ virt_machine_2_12_options(mc);
41
+ SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_11);
42
}
43
-DEFINE_VIRT_MACHINE_AS_LATEST(2, 11)
44
+DEFINE_VIRT_MACHINE(2, 11)
45
46
#define VIRT_COMPAT_2_10 \
47
HW_COMPAT_2_10
48
--
58
--
49
2.7.4
59
2.20.1
50
60
51
61
diff view generated by jsdifflib
1
The Configurable Fault Status Register for ARMv7M and v8M is
1
The randomness tests in the NPCM7xx RNG test fail intermittently
2
supposed to be byte and halfword accessible, but we were only
2
but fairly frequently. On my machine running the test in a loop:
3
implementing word accesses. Add support for the other access
3
while QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/npcm7xx_rng-test; do true; done
4
sizes, which are used by the Zephyr RTOS.
4
5
will fail in less than a minute with an error like:
6
ERROR:../../tests/qtest/npcm7xx_rng-test.c:256:test_first_byte_runs:
7
assertion failed (calc_runs_p(buf.l, sizeof(buf) * BITS_PER_BYTE) > 0.01): (0.00286205989 > 0.01)
8
9
(Failures have been observed on all 4 of the randomness tests,
10
not just first_byte_runs.)
11
12
It's not clear why these tests are failing like this, but intermittent
13
failures make CI and merge testing awkward, so disable running them
14
unless a developer specifically sets QEMU_TEST_FLAKY_RNG_TESTS when
15
running the test suite, until we work out the cause.
5
16
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reported-by: Andy Gross <andy.gross@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Message-id: 20201102152454.8287-1-peter.maydell@linaro.org
9
Message-id: 1512742372-31517-1-git-send-email-peter.maydell@linaro.org
20
Reviewed-by: Havard Skinnemoen <hskinnemoen@google.com>
10
---
21
---
11
hw/intc/armv7m_nvic.c | 38 ++++++++++++++++++++++----------------
22
tests/qtest/npcm7xx_rng-test.c | 14 ++++++++++----
12
1 file changed, 22 insertions(+), 16 deletions(-)
23
1 file changed, 10 insertions(+), 4 deletions(-)
13
24
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
25
diff --git a/tests/qtest/npcm7xx_rng-test.c b/tests/qtest/npcm7xx_rng-test.c
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/armv7m_nvic.c
27
--- a/tests/qtest/npcm7xx_rng-test.c
17
+++ b/hw/intc/armv7m_nvic.c
28
+++ b/tests/qtest/npcm7xx_rng-test.c
18
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
29
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
19
val |= (1 << 8);
30
20
}
31
qtest_add_func("npcm7xx_rng/enable_disable", test_enable_disable);
21
return val;
32
qtest_add_func("npcm7xx_rng/rosel", test_rosel);
22
- case 0xd28: /* Configurable Fault Status. */
33
- qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
23
- /* The BFSR bits [15:8] are shared between security states
34
- qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
24
- * and we store them in the NS copy
35
- qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
25
- */
36
- qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
26
- val = cpu->env.v7m.cfsr[attrs.secure];
37
+ /*
27
- val |= cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
38
+ * These tests fail intermittently; only run them on explicit
28
- return val;
39
+ * request until we figure out why.
29
case 0xd2c: /* Hard Fault Status. */
40
+ */
30
return cpu->env.v7m.hfsr;
41
+ if (getenv("QEMU_TEST_FLAKY_RNG_TESTS")) {
31
case 0xd30: /* Debug Fault Status. */
42
+ qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
32
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
43
+ qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
33
s->vectors[ARMV7M_EXCP_DEBUG].active = (value & (1 << 8)) != 0;
44
+ qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
34
nvic_irq_update(s);
45
+ qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
35
break;
46
+ }
36
- case 0xd28: /* Configurable Fault Status. */
47
37
- cpu->env.v7m.cfsr[attrs.secure] &= ~value; /* W1C */
48
qtest_start("-machine npcm750-evb");
38
- if (attrs.secure) {
49
ret = g_test_run();
39
- /* The BFSR bits [15:8] are shared between security states
40
- * and we store them in the NS copy.
41
- */
42
- cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
43
- }
44
- break;
45
case 0xd2c: /* Hard Fault Status. */
46
cpu->env.v7m.hfsr &= ~value; /* W1C */
47
break;
48
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
49
val = deposit32(val, i * 8, 8, get_prio(s, hdlidx, sbank));
50
}
51
break;
52
+ case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
53
+ /* The BFSR bits [15:8] are shared between security states
54
+ * and we store them in the NS copy
55
+ */
56
+ val = s->cpu->env.v7m.cfsr[attrs.secure];
57
+ val |= s->cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK;
58
+ val = extract32(val, (offset - 0xd28) * 8, size * 8);
59
+ break;
60
case 0xfe0 ... 0xfff: /* ID. */
61
if (offset & 3) {
62
val = 0;
63
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
64
}
65
nvic_irq_update(s);
66
return MEMTX_OK;
67
+ case 0xd28 ... 0xd2b: /* Configurable Fault Status (CFSR) */
68
+ /* All bits are W1C, so construct 32 bit value with 0s in
69
+ * the parts not written by the access size
70
+ */
71
+ value <<= ((offset - 0xd28) * 8);
72
+
73
+ s->cpu->env.v7m.cfsr[attrs.secure] &= ~value;
74
+ if (attrs.secure) {
75
+ /* The BFSR bits [15:8] are shared between security states
76
+ * and we store them in the NS copy.
77
+ */
78
+ s->cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK);
79
+ }
80
+ return MEMTX_OK;
81
}
82
if (size == 4) {
83
nvic_writel(s, offset, value, attrs);
84
--
50
--
85
2.7.4
51
2.20.1
86
52
87
53
diff view generated by jsdifflib