1
The following changes since commit 0d3e41d5efd638a0c5682f6813b26448c3c51624:
1
Mostly just bug fixes. The important one here is
2
hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register
3
which fixes a buffer overrun that's a security issue if you're running
4
KVM on Arm with kernel-irqchip=off (which hopefully nobody is doing in
5
a security context, because kernel-irqchip=on is the default and the
6
sensible choice for performance).
2
7
3
Merge remote-tracking branch 'remotes/vivier2/tags/trivial-branch-pull-request' into staging (2019-02-14 17:42:25 +0000)
8
-- PMM
9
10
The following changes since commit cf7ca7d5b9faca13f1f8e3ea92cfb2f741eb0c0e:
11
12
Merge remote-tracking branch 'remotes/stefanha-gitlab/tags/tracing-pull-request' into staging (2021-02-01 16:28:00 +0000)
4
13
5
are available in the Git repository at:
14
are available in the Git repository at:
6
15
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190214
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210202-1
8
17
9
for you to fetch changes up to 497bc12b1b374ecd62903bf062229bd93f8924af:
18
for you to fetch changes up to 14657850c9cc10948551fbb884c30eb5a3a7370a:
10
19
11
gdbstub: Send a reply to the vKill packet. (2019-02-14 18:45:49 +0000)
20
hw/arm: Display CPU type in machine description (2021-02-02 17:53:44 +0000)
12
21
13
----------------------------------------------------------------
22
----------------------------------------------------------------
14
target-arm queue:
23
target-arm queue:
15
* gdbstub: Send a reply to the vKill packet
24
* hw/intc/arm_gic: Allow to use QTest without crashing
16
* Improve codegen for neon min/max and saturating arithmetic
25
* hw/char/exynos4210_uart: Fix buffer size reporting with FIFO disabled
17
* Fix a bug in clearing FPSCR exception status bits
26
* hw/char/exynos4210_uart: Fix missing call to report ready for input
18
* hw/arm/armsse: Fix miswiring of expansion IRQs
27
* hw/arm/smmuv3: Fix addr_mask for range-based invalidation
19
* hw/intc/armv7m_nvic: Allow byte accesses to SHPR1
28
* hw/ssi/imx_spi: Fix various minor bugs
20
* MAINTAINERS: Remove Peter Crosthwaite from various entries
29
* hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register
21
* arm: Allow system registers for KVM guests to be changed by QEMU code
30
* hw/arm: Add missing Kconfig dependencies
22
* linux-user: support HWCAP_CPUID which exposes ID registers to user code
31
* hw/arm: Display CPU type in machine description
23
* Fix bug in 128-bit cmpxchg for BE Arm guests
24
* Implement (no-op) HACR_EL2
25
* Fix CRn to be 14 for PMEVTYPER/PMEVCNTR
26
32
27
----------------------------------------------------------------
33
----------------------------------------------------------------
28
Aaron Lindsay OS (1):
34
Bin Meng (5):
29
target/arm: Fix CRn to be 14 for PMEVTYPER/PMEVCNTR
35
hw/ssi: imx_spi: Use a macro for number of chip selects supported
36
hw/ssi: imx_spi: Remove imx_spi_update_irq() in imx_spi_reset()
37
hw/ssi: imx_spi: Round up the burst length to be multiple of 8
38
hw/ssi: imx_spi: Correct the burst length > 32 bit transfer logic
39
hw/ssi: imx_spi: Correct tx and rx fifo endianness
30
40
31
Alex Bennée (5):
41
Iris Johnson (2):
32
target/arm: relax permission checks for HWCAP_CPUID registers
42
hw/char/exynos4210_uart: Fix buffer size reporting with FIFO disabled
33
target/arm: expose CPUID registers to userspace
43
hw/char/exynos4210_uart: Fix missing call to report ready for input
34
target/arm: expose MPIDR_EL1 to userspace
35
target/arm: expose remaining CPUID registers as RAZ
36
linux-user/elfload: enable HWCAP_CPUID for AArch64
37
44
38
Catherine Ho (1):
45
Philippe Mathieu-Daudé (12):
39
target/arm: Fix int128_make128 lo, hi order in paired_cmpxchg64_be
46
hw/intc/arm_gic: Allow to use QTest without crashing
47
hw/ssi: imx_spi: Remove pointless variable initialization
48
hw/ssi: imx_spi: Rework imx_spi_reset() to keep CONREG register value
49
hw/ssi: imx_spi: Rework imx_spi_read() to handle block disabled
50
hw/ssi: imx_spi: Rework imx_spi_write() to handle block disabled
51
hw/intc/arm_gic: Fix interrupt ID in GICD_SGIR register
52
hw/arm/stm32f405_soc: Add missing dependency on OR_IRQ
53
hw/arm/exynos4210: Add missing dependency on OR_IRQ
54
hw/arm/xlnx-versal: Versal SoC requires ZDMA
55
hw/arm/xlnx-versal: Versal SoC requires ZynqMP peripherals
56
hw/net/can: ZynqMP CAN device requires PTIMER
57
hw/arm: Display CPU type in machine description
40
58
41
Peter Maydell (5):
59
Xuzhou Cheng (1):
42
target/arm: Implement HACR_EL2
60
hw/ssi: imx_spi: Disable chip selects when controller is disabled
43
arm: Allow system registers for KVM guests to be changed by QEMU code
44
MAINTAINERS: Remove Peter Crosthwaite from various entries
45
hw/intc/armv7m_nvic: Allow byte accesses to SHPR1
46
hw/arm/armsse: Fix miswiring of expansion IRQs
47
61
48
Richard Henderson (14):
62
Zenghui Yu (1):
49
target/arm: Force result size into dp after operation
63
hw/arm/smmuv3: Fix addr_mask for range-based invalidation
50
target/arm: Restructure disas_fp_int_conv
51
target/arm: Rely on optimization within tcg_gen_gvec_or
52
target/arm: Use vector minmax expanders for aarch64
53
target/arm: Use vector minmax expanders for aarch32
54
target/arm: Use tcg integer min/max primitives for neon
55
target/arm: Remove neon min/max helpers
56
target/arm: Fix vfp_gdb_get/set_reg vs FPSCR
57
target/arm: Fix arm_cpu_dump_state vs FPSCR
58
target/arm: Split out flags setting from vfp compares
59
target/arm: Fix set of bits kept in xregs[ARM_VFP_FPSCR]
60
target/arm: Split out FPSCR.QC to a vector field
61
target/arm: Use vector operations for saturation
62
target/arm: Add missing clear_tail calls
63
64
64
Sandra Loosemore (1):
65
include/hw/ssi/imx_spi.h | 5 +-
65
gdbstub: Send a reply to the vKill packet.
66
hw/arm/digic_boards.c | 2 +-
67
hw/arm/microbit.c | 2 +-
68
hw/arm/netduino2.c | 2 +-
69
hw/arm/netduinoplus2.c | 2 +-
70
hw/arm/orangepi.c | 2 +-
71
hw/arm/smmuv3.c | 4 +-
72
hw/arm/stellaris.c | 4 +-
73
hw/char/exynos4210_uart.c | 7 ++-
74
hw/intc/arm_gic.c | 5 +-
75
hw/ssi/imx_spi.c | 153 +++++++++++++++++++++++++++++-----------------
76
hw/Kconfig | 1 +
77
hw/arm/Kconfig | 5 ++
78
hw/dma/Kconfig | 3 +
79
hw/dma/meson.build | 2 +-
80
15 files changed, 130 insertions(+), 69 deletions(-)
66
81
67
target/arm/cpu.h | 50 ++++++++-
68
target/arm/helper.h | 45 +++++---
69
target/arm/translate.h | 4 +
70
gdbstub.c | 1 +
71
hw/arm/armsse.c | 2 +-
72
hw/intc/armv7m_nvic.c | 4 +-
73
linux-user/elfload.c | 1 +
74
target/arm/helper-a64.c | 4 +-
75
target/arm/helper.c | 228 ++++++++++++++++++++++++++++++++--------
76
target/arm/kvm32.c | 20 +---
77
target/arm/kvm64.c | 2 +
78
target/arm/machine.c | 2 +-
79
target/arm/neon_helper.c | 14 +--
80
target/arm/translate-a64.c | 171 +++++++++++++++---------------
81
target/arm/translate-sve.c | 6 +-
82
target/arm/translate.c | 251 ++++++++++++++++++++++++++++++++++-----------
83
target/arm/vec_helper.c | 134 +++++++++++++++++++++++-
84
MAINTAINERS | 4 -
85
18 files changed, 687 insertions(+), 256 deletions(-)
86
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
2
1
3
This bug was introduced in:
4
commit 5ecdd3e47cadae83a62dc92b472f1fe163b56f59
5
target/arm: Finish implementation of PM[X]EVCNTR and PM[X]EVTYPER
6
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190205135129.19338-1-aaron@os.amperecomputing.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/helper.c | 8 ++++----
14
1 file changed, 4 insertions(+), 4 deletions(-)
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
21
char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
22
char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
23
ARMCPRegInfo pmev_regs[] = {
24
- { .name = pmevcntr_name, .cp = 15, .crn = 15,
25
+ { .name = pmevcntr_name, .cp = 15, .crn = 14,
26
.crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
27
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
28
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
29
.accessfn = pmreg_access },
30
{ .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
31
- .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 8 | (3 & (i >> 3)),
32
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
33
.opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
34
.type = ARM_CP_IO,
35
.readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
36
.raw_readfn = pmevcntr_rawread,
37
.raw_writefn = pmevcntr_rawwrite },
38
- { .name = pmevtyper_name, .cp = 15, .crn = 15,
39
+ { .name = pmevtyper_name, .cp = 15, .crn = 14,
40
.crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
41
.access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
42
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
43
.accessfn = pmreg_access },
44
{ .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
45
- .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 12 | (3 & (i >> 3)),
46
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
47
.opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
48
.type = ARM_CP_IO,
49
.readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
50
--
51
2.20.1
52
53
diff view generated by jsdifflib
Deleted patch
1
HACR_EL2 is a register with IMPDEF behaviour, which allows
2
implementation specific trapping to EL2. Implement it as RAZ/WI,
3
since QEMU's implementation has no extra traps. This also
4
matches what h/w implementations like Cortex-A53 and A57 do.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190205181218.8995-1-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 6 ++++++
11
1 file changed, 6 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
18
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
19
.access = PL2_RW,
20
.type = ARM_CP_CONST, .resetvalue = 0 },
21
+ { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
22
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
23
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
24
{ .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
25
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
26
.access = PL2_RW,
27
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
28
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
29
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
30
.writefn = hcr_writelow },
31
+ { .name = "HACR_EL2", .state = ARM_CP_STATE_BOTH,
32
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 7,
33
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
34
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
35
.type = ARM_CP_ALIAS,
36
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
37
--
38
2.20.1
39
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
The components of this register is stored in several
3
Alexander reported an issue in gic_get_current_cpu() using the
4
different locations.
4
fuzzer. Yet another "deref current_cpu with QTest" bug, reproducible
5
doing:
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
$ echo readb 0xf03ff000 | qemu-system-arm -M npcm750-evb,accel=qtest -qtest stdio
7
Message-id: 20190209033847.9014-7-richard.henderson@linaro.org
8
[I 1611849440.651452] OPENED
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
[R +0.242498] readb 0xf03ff000
10
hw/intc/arm_gic.c:63:29: runtime error: member access within null pointer of type 'CPUState' (aka 'struct CPUState')
11
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior hw/intc/arm_gic.c:63:29 in
12
AddressSanitizer:DEADLYSIGNAL
13
=================================================================
14
==3719691==ERROR: AddressSanitizer: SEGV on unknown address 0x0000000082a0 (pc 0x5618790ac882 bp 0x7ffca946f4f0 sp 0x7ffca946f4a0 T0)
15
==3719691==The signal is caused by a READ memory access.
16
#0 0x5618790ac882 in gic_get_current_cpu hw/intc/arm_gic.c:63:29
17
#1 0x5618790a8901 in gic_dist_readb hw/intc/arm_gic.c:955:11
18
#2 0x5618790a7489 in gic_dist_read hw/intc/arm_gic.c:1158:17
19
#3 0x56187adc573b in memory_region_read_with_attrs_accessor softmmu/memory.c:464:9
20
#4 0x56187ad7903a in access_with_adjusted_size softmmu/memory.c:552:18
21
#5 0x56187ad766d6 in memory_region_dispatch_read1 softmmu/memory.c:1426:16
22
#6 0x56187ad758a8 in memory_region_dispatch_read softmmu/memory.c:1449:9
23
#7 0x56187b09e84c in flatview_read_continue softmmu/physmem.c:2822:23
24
#8 0x56187b0a0115 in flatview_read softmmu/physmem.c:2862:12
25
#9 0x56187b09fc9e in address_space_read_full softmmu/physmem.c:2875:18
26
#10 0x56187aa88633 in address_space_read include/exec/memory.h:2489:18
27
#11 0x56187aa88633 in qtest_process_command softmmu/qtest.c:558:13
28
#12 0x56187aa81881 in qtest_process_inbuf softmmu/qtest.c:797:9
29
#13 0x56187aa80e02 in qtest_read softmmu/qtest.c:809:5
30
31
current_cpu is NULL because QTest accelerator does not use CPU.
32
33
Fix by skipping the check and returning the first CPU index when
34
QTest accelerator is used, similarly to commit c781a2cc423
35
("hw/i386/vmport: Allow QTest use without crashing").
36
37
Reported-by: Alexander Bulekov <alxndr@bu.edu>
38
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
39
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
40
Reviewed-by: Alexander Bulekov <alxndr@bu.edu>
41
Message-id: 20210128161417.3726358-1-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
43
---
11
target/arm/helper.c | 4 ++--
44
hw/intc/arm_gic.c | 3 ++-
12
1 file changed, 2 insertions(+), 2 deletions(-)
45
1 file changed, 2 insertions(+), 1 deletion(-)
13
46
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
47
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
15
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
49
--- a/hw/intc/arm_gic.c
17
+++ b/target/arm/helper.c
50
+++ b/hw/intc/arm_gic.c
18
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
51
@@ -XXX,XX +XXX,XX @@
19
}
52
#include "qemu/module.h"
20
switch (reg - nregs) {
53
#include "trace.h"
21
case 0: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSID]); return 4;
54
#include "sysemu/kvm.h"
22
- case 1: stl_p(buf, env->vfp.xregs[ARM_VFP_FPSCR]); return 4;
55
+#include "sysemu/qtest.h"
23
+ case 1: stl_p(buf, vfp_get_fpscr(env)); return 4;
56
24
case 2: stl_p(buf, env->vfp.xregs[ARM_VFP_FPEXC]); return 4;
57
/* #define DEBUG_GIC */
25
}
58
26
return 0;
59
@@ -XXX,XX +XXX,XX @@ static const uint8_t gic_id_gicv2[] = {
27
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
60
28
}
61
static inline int gic_get_current_cpu(GICState *s)
29
switch (reg - nregs) {
62
{
30
case 0: env->vfp.xregs[ARM_VFP_FPSID] = ldl_p(buf); return 4;
63
- if (s->num_cpu > 1) {
31
- case 1: env->vfp.xregs[ARM_VFP_FPSCR] = ldl_p(buf); return 4;
64
+ if (!qtest_enabled() && s->num_cpu > 1) {
32
+ case 1: vfp_set_fpscr(env, ldl_p(buf)); return 4;
65
return current_cpu->cpu_index;
33
case 2: env->vfp.xregs[ARM_VFP_FPEXC] = ldl_p(buf) & (1 << 30); return 4;
34
}
66
}
35
return 0;
67
return 0;
36
--
68
--
37
2.20.1
69
2.20.1
38
70
39
71
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Iris Johnson <iris@modwiz.com>
2
2
3
Fortunately, the functions affected are so far only called from SVE,
3
Currently the Exynos 4210 UART code always reports available FIFO space
4
so there is no tail to be cleared. But as we convert more of AdvSIMD
4
when the backend checks for buffer space. When the FIFO is disabled this
5
to gvec, this will matter.
5
is behavior causes the backend chardev code to replace the data before the
6
guest can read it.
6
7
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
This patch changes adds the logic to report the capacity properly when the
8
Message-id: 20190209033847.9014-13-richard.henderson@linaro.org
9
FIFO is not being used.
10
11
Buglink: https://bugs.launchpad.net/qemu/+bug/1913344
12
Signed-off-by: Iris Johnson <iris@modwiz.com>
13
Message-id: 20210128033655.1029577-1-iris@modwiz.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
16
---
12
target/arm/vec_helper.c | 2 ++
17
hw/char/exynos4210_uart.c | 6 +++++-
13
1 file changed, 2 insertions(+)
18
1 file changed, 5 insertions(+), 1 deletion(-)
14
19
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
20
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/vec_helper.c
22
--- a/hw/char/exynos4210_uart.c
18
+++ b/target/arm/vec_helper.c
23
+++ b/hw/char/exynos4210_uart.c
19
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *stat, uint32_t desc) \
24
@@ -XXX,XX +XXX,XX @@ static int exynos4210_uart_can_receive(void *opaque)
20
for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
25
{
21
d[i] = FUNC(n[i], stat); \
26
Exynos4210UartState *s = (Exynos4210UartState *)opaque;
22
} \
27
23
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
28
- return fifo_empty_elements_number(&s->rx);
29
+ if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
30
+ return fifo_empty_elements_number(&s->rx);
31
+ } else {
32
+ return !(s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY);
33
+ }
24
}
34
}
25
35
26
DO_2OP(gvec_frecpe_h, helper_recpe_f16, float16)
36
static void exynos4210_uart_receive(void *opaque, const uint8_t *buf, int size)
27
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
28
for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
29
d[i] = FUNC(n[i], m[i], stat); \
30
} \
31
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
32
}
33
34
DO_3OP(gvec_fadd_h, float16_add, float16)
35
--
37
--
36
2.20.1
38
2.20.1
37
39
38
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Iris Johnson <iris@modwiz.com>
2
2
3
Change the representation of this field such that it is easy
3
When the frontend device has no space for a read the fd is removed
4
to set from vector code.
4
from polling to allow time for the guest to read and clear the buffer.
5
Without the call to qemu_chr_fe_accept_input(), the poll will not be
6
broken out of when the guest has cleared the buffer causing significant
7
IO delays that get worse with smaller buffers.
5
8
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Buglink: https://bugs.launchpad.net/qemu/+bug/1913341
7
Message-id: 20190209033847.9014-11-richard.henderson@linaro.org
10
Signed-off-by: Iris Johnson <iris@modwiz.com>
11
Message-id: 20210130184016.1787097-1-iris@modwiz.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/cpu.h | 5 ++++-
15
hw/char/exynos4210_uart.c | 1 +
12
target/arm/helper.c | 19 +++++++++++++++----
16
1 file changed, 1 insertion(+)
13
target/arm/neon_helper.c | 2 +-
14
target/arm/vec_helper.c | 2 +-
15
4 files changed, 21 insertions(+), 7 deletions(-)
16
17
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
--- a/hw/char/exynos4210_uart.c
20
+++ b/target/arm/cpu.h
21
+++ b/hw/char/exynos4210_uart.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
22
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_uart_read(void *opaque, hwaddr offset,
22
ARMPredicateReg preg_tmp;
23
s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY;
23
#endif
24
res = s->reg[I_(URXH)];
24
25
}
25
- uint32_t xregs[16];
26
+ qemu_chr_fe_accept_input(&s->chr);
26
/* We store these fpcsr fields separately for convenience. */
27
exynos4210_uart_update_dmabusy(s);
27
+ uint32_t qc[4] QEMU_ALIGNED(16);
28
trace_exynos_uart_read(s->channel, offset,
28
int vec_len;
29
exynos4210_uart_regname(offset), res);
29
int vec_stride;
30
31
+ uint32_t xregs[16];
32
+
33
/* Scratch space for aa32 neon expansion. */
34
uint32_t scratch[8];
35
36
@@ -XXX,XX +XXX,XX @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
37
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
38
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
39
#define FPCR_DN (1 << 25) /* Default NaN enable bit */
40
+#define FPCR_QC (1 << 27) /* Cumulative saturation bit */
41
42
static inline uint32_t vfp_get_fpsr(CPUARMState *env)
43
{
44
diff --git a/target/arm/helper.c b/target/arm/helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/helper.c
47
+++ b/target/arm/helper.c
48
@@ -XXX,XX +XXX,XX @@ static inline int vfp_exceptbits_from_host(int host_bits)
49
50
uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
51
{
52
- int i;
53
- uint32_t fpscr;
54
+ uint32_t i, fpscr;
55
56
fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
57
| (env->vfp.vec_len << 16)
58
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
59
/* FZ16 does not generate an input denormal exception. */
60
i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
61
& ~float_flag_input_denormal);
62
-
63
fpscr |= vfp_exceptbits_from_host(i);
64
+
65
+ i = env->vfp.qc[0] | env->vfp.qc[1] | env->vfp.qc[2] | env->vfp.qc[3];
66
+ fpscr |= i ? FPCR_QC : 0;
67
+
68
return fpscr;
69
}
70
71
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
72
* (which are stored in fp_status), and the other RES0 bits
73
* in between, then we clear all of the low 16 bits.
74
*/
75
- env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xffc80000;
76
+ env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c80000;
77
env->vfp.vec_len = (val >> 16) & 7;
78
env->vfp.vec_stride = (val >> 20) & 3;
79
80
+ /*
81
+ * The bit we set within fpscr_q is arbitrary; the register as a
82
+ * whole being zero/non-zero is what counts.
83
+ */
84
+ env->vfp.qc[0] = val & FPCR_QC;
85
+ env->vfp.qc[1] = 0;
86
+ env->vfp.qc[2] = 0;
87
+ env->vfp.qc[3] = 0;
88
+
89
changed ^= val;
90
if (changed & (3 << 22)) {
91
i = (val >> 22) & 3;
92
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/target/arm/neon_helper.c
95
+++ b/target/arm/neon_helper.c
96
@@ -XXX,XX +XXX,XX @@
97
#define SIGNBIT (uint32_t)0x80000000
98
#define SIGNBIT64 ((uint64_t)1 << 63)
99
100
-#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q
101
+#define SET_QC() env->vfp.qc[0] = 1
102
103
#define NEON_TYPE1(name, type) \
104
typedef struct \
105
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/vec_helper.c
108
+++ b/target/arm/vec_helper.c
109
@@ -XXX,XX +XXX,XX @@
110
#define H4(x) (x)
111
#endif
112
113
-#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q
114
+#define SET_QC() env->vfp.qc[0] = 1
115
116
static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
117
{
118
--
30
--
119
2.20.1
31
2.20.1
120
32
121
33
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Zenghui Yu <yuzenghui@huawei.com>
2
2
3
For same-sign saturation, we have tcg vector operations. We can
3
When handling guest range-based IOTLB invalidation, we should decode the TG
4
compute the QC bit by comparing the saturated value against the
4
field into the corresponding translation granule size so that we can pass
5
unsaturated value.
5
the correct invalidation range to backend. Set @granule to (tg * 2 + 10) to
6
properly emulate the architecture.
6
7
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Fixes: d52915616c05 ("hw/arm/smmuv3: Get prepared for range invalidation")
8
Message-id: 20190209033847.9014-12-richard.henderson@linaro.org
9
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Acked-by: Eric Auger <eric.auger@redhat.com>
11
Message-id: 20210130043220.1345-1-yuzenghui@huawei.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
target/arm/helper.h | 33 +++++++
14
hw/arm/smmuv3.c | 4 +++-
13
target/arm/translate.h | 4 +
15
1 file changed, 3 insertions(+), 1 deletion(-)
14
target/arm/translate-a64.c | 36 ++++----
15
target/arm/translate.c | 172 +++++++++++++++++++++++++++++++------
16
target/arm/vec_helper.c | 130 ++++++++++++++++++++++++++++
17
5 files changed, 331 insertions(+), 44 deletions(-)
18
16
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
17
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
19
--- a/hw/arm/smmuv3.c
22
+++ b/target/arm/helper.h
20
+++ b/hw/arm/smmuv3.c
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(gvec_fmla_idx_s, TCG_CALL_NO_RWG,
21
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
24
DEF_HELPER_FLAGS_6(gvec_fmla_idx_d, TCG_CALL_NO_RWG,
22
{
25
void, ptr, ptr, ptr, ptr, ptr, i32)
23
SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
26
24
IOMMUTLBEvent event;
27
+DEF_HELPER_FLAGS_5(gvec_uqadd_b, TCG_CALL_NO_RWG,
25
- uint8_t granule = tg;
28
+ void, ptr, ptr, ptr, ptr, i32)
26
+ uint8_t granule;
29
+DEF_HELPER_FLAGS_5(gvec_uqadd_h, TCG_CALL_NO_RWG,
27
30
+ void, ptr, ptr, ptr, ptr, i32)
28
if (!tg) {
31
+DEF_HELPER_FLAGS_5(gvec_uqadd_s, TCG_CALL_NO_RWG,
29
SMMUEventInfo event = {.inval_ste_allowed = true};
32
+ void, ptr, ptr, ptr, ptr, i32)
30
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
33
+DEF_HELPER_FLAGS_5(gvec_uqadd_d, TCG_CALL_NO_RWG,
31
return;
34
+ void, ptr, ptr, ptr, ptr, i32)
32
}
35
+DEF_HELPER_FLAGS_5(gvec_sqadd_b, TCG_CALL_NO_RWG,
33
granule = tt->granule_sz;
36
+ void, ptr, ptr, ptr, ptr, i32)
34
+ } else {
37
+DEF_HELPER_FLAGS_5(gvec_sqadd_h, TCG_CALL_NO_RWG,
35
+ granule = tg * 2 + 10;
38
+ void, ptr, ptr, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_5(gvec_sqadd_s, TCG_CALL_NO_RWG,
40
+ void, ptr, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_5(gvec_sqadd_d, TCG_CALL_NO_RWG,
42
+ void, ptr, ptr, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_5(gvec_uqsub_b, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_5(gvec_uqsub_h, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_5(gvec_uqsub_s, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, ptr, i32)
49
+DEF_HELPER_FLAGS_5(gvec_uqsub_d, TCG_CALL_NO_RWG,
50
+ void, ptr, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_5(gvec_sqsub_b, TCG_CALL_NO_RWG,
52
+ void, ptr, ptr, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_5(gvec_sqsub_h, TCG_CALL_NO_RWG,
54
+ void, ptr, ptr, ptr, ptr, i32)
55
+DEF_HELPER_FLAGS_5(gvec_sqsub_s, TCG_CALL_NO_RWG,
56
+ void, ptr, ptr, ptr, ptr, i32)
57
+DEF_HELPER_FLAGS_5(gvec_sqsub_d, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, ptr, i32)
59
+
60
#ifdef TARGET_AARCH64
61
#include "helper-a64.h"
62
#include "helper-sve.h"
63
diff --git a/target/arm/translate.h b/target/arm/translate.h
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.h
66
+++ b/target/arm/translate.h
67
@@ -XXX,XX +XXX,XX @@ extern const GVecGen2i ssra_op[4];
68
extern const GVecGen2i usra_op[4];
69
extern const GVecGen2i sri_op[4];
70
extern const GVecGen2i sli_op[4];
71
+extern const GVecGen4 uqadd_op[4];
72
+extern const GVecGen4 sqadd_op[4];
73
+extern const GVecGen4 uqsub_op[4];
74
+extern const GVecGen4 sqsub_op[4];
75
void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
76
77
/*
78
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/translate-a64.c
81
+++ b/target/arm/translate-a64.c
82
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
83
}
36
}
84
37
85
switch (opcode) {
38
event.type = IOMMU_NOTIFIER_UNMAP;
86
+ case 0x01: /* SQADD, UQADD */
87
+ tcg_gen_gvec_4(vec_full_reg_offset(s, rd),
88
+ offsetof(CPUARMState, vfp.qc),
89
+ vec_full_reg_offset(s, rn),
90
+ vec_full_reg_offset(s, rm),
91
+ is_q ? 16 : 8, vec_full_reg_size(s),
92
+ (u ? uqadd_op : sqadd_op) + size);
93
+ return;
94
+ case 0x05: /* SQSUB, UQSUB */
95
+ tcg_gen_gvec_4(vec_full_reg_offset(s, rd),
96
+ offsetof(CPUARMState, vfp.qc),
97
+ vec_full_reg_offset(s, rn),
98
+ vec_full_reg_offset(s, rm),
99
+ is_q ? 16 : 8, vec_full_reg_size(s),
100
+ (u ? uqsub_op : sqsub_op) + size);
101
+ return;
102
case 0x0c: /* SMAX, UMAX */
103
if (u) {
104
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
105
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
106
genfn = fns[size][u];
107
break;
108
}
109
- case 0x1: /* SQADD, UQADD */
110
- {
111
- static NeonGenTwoOpEnvFn * const fns[3][2] = {
112
- { gen_helper_neon_qadd_s8, gen_helper_neon_qadd_u8 },
113
- { gen_helper_neon_qadd_s16, gen_helper_neon_qadd_u16 },
114
- { gen_helper_neon_qadd_s32, gen_helper_neon_qadd_u32 },
115
- };
116
- genenvfn = fns[size][u];
117
- break;
118
- }
119
case 0x2: /* SRHADD, URHADD */
120
{
121
static NeonGenTwoOpFn * const fns[3][2] = {
122
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
123
genfn = fns[size][u];
124
break;
125
}
126
- case 0x5: /* SQSUB, UQSUB */
127
- {
128
- static NeonGenTwoOpEnvFn * const fns[3][2] = {
129
- { gen_helper_neon_qsub_s8, gen_helper_neon_qsub_u8 },
130
- { gen_helper_neon_qsub_s16, gen_helper_neon_qsub_u16 },
131
- { gen_helper_neon_qsub_s32, gen_helper_neon_qsub_u32 },
132
- };
133
- genenvfn = fns[size][u];
134
- break;
135
- }
136
case 0x8: /* SSHL, USHL */
137
{
138
static NeonGenTwoOpFn * const fns[3][2] = {
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
142
+++ b/target/arm/translate.c
143
@@ -XXX,XX +XXX,XX @@ const GVecGen3 cmtst_op[4] = {
144
.vece = MO_64 },
145
};
146
147
+static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
148
+ TCGv_vec a, TCGv_vec b)
149
+{
150
+ TCGv_vec x = tcg_temp_new_vec_matching(t);
151
+ tcg_gen_add_vec(vece, x, a, b);
152
+ tcg_gen_usadd_vec(vece, t, a, b);
153
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
154
+ tcg_gen_or_vec(vece, sat, sat, x);
155
+ tcg_temp_free_vec(x);
156
+}
157
+
158
+const GVecGen4 uqadd_op[4] = {
159
+ { .fniv = gen_uqadd_vec,
160
+ .fno = gen_helper_gvec_uqadd_b,
161
+ .opc = INDEX_op_usadd_vec,
162
+ .write_aofs = true,
163
+ .vece = MO_8 },
164
+ { .fniv = gen_uqadd_vec,
165
+ .fno = gen_helper_gvec_uqadd_h,
166
+ .opc = INDEX_op_usadd_vec,
167
+ .write_aofs = true,
168
+ .vece = MO_16 },
169
+ { .fniv = gen_uqadd_vec,
170
+ .fno = gen_helper_gvec_uqadd_s,
171
+ .opc = INDEX_op_usadd_vec,
172
+ .write_aofs = true,
173
+ .vece = MO_32 },
174
+ { .fniv = gen_uqadd_vec,
175
+ .fno = gen_helper_gvec_uqadd_d,
176
+ .opc = INDEX_op_usadd_vec,
177
+ .write_aofs = true,
178
+ .vece = MO_64 },
179
+};
180
+
181
+static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
182
+ TCGv_vec a, TCGv_vec b)
183
+{
184
+ TCGv_vec x = tcg_temp_new_vec_matching(t);
185
+ tcg_gen_add_vec(vece, x, a, b);
186
+ tcg_gen_ssadd_vec(vece, t, a, b);
187
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
188
+ tcg_gen_or_vec(vece, sat, sat, x);
189
+ tcg_temp_free_vec(x);
190
+}
191
+
192
+const GVecGen4 sqadd_op[4] = {
193
+ { .fniv = gen_sqadd_vec,
194
+ .fno = gen_helper_gvec_sqadd_b,
195
+ .opc = INDEX_op_ssadd_vec,
196
+ .write_aofs = true,
197
+ .vece = MO_8 },
198
+ { .fniv = gen_sqadd_vec,
199
+ .fno = gen_helper_gvec_sqadd_h,
200
+ .opc = INDEX_op_ssadd_vec,
201
+ .write_aofs = true,
202
+ .vece = MO_16 },
203
+ { .fniv = gen_sqadd_vec,
204
+ .fno = gen_helper_gvec_sqadd_s,
205
+ .opc = INDEX_op_ssadd_vec,
206
+ .write_aofs = true,
207
+ .vece = MO_32 },
208
+ { .fniv = gen_sqadd_vec,
209
+ .fno = gen_helper_gvec_sqadd_d,
210
+ .opc = INDEX_op_ssadd_vec,
211
+ .write_aofs = true,
212
+ .vece = MO_64 },
213
+};
214
+
215
+static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
216
+ TCGv_vec a, TCGv_vec b)
217
+{
218
+ TCGv_vec x = tcg_temp_new_vec_matching(t);
219
+ tcg_gen_sub_vec(vece, x, a, b);
220
+ tcg_gen_ussub_vec(vece, t, a, b);
221
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
222
+ tcg_gen_or_vec(vece, sat, sat, x);
223
+ tcg_temp_free_vec(x);
224
+}
225
+
226
+const GVecGen4 uqsub_op[4] = {
227
+ { .fniv = gen_uqsub_vec,
228
+ .fno = gen_helper_gvec_uqsub_b,
229
+ .opc = INDEX_op_ussub_vec,
230
+ .write_aofs = true,
231
+ .vece = MO_8 },
232
+ { .fniv = gen_uqsub_vec,
233
+ .fno = gen_helper_gvec_uqsub_h,
234
+ .opc = INDEX_op_ussub_vec,
235
+ .write_aofs = true,
236
+ .vece = MO_16 },
237
+ { .fniv = gen_uqsub_vec,
238
+ .fno = gen_helper_gvec_uqsub_s,
239
+ .opc = INDEX_op_ussub_vec,
240
+ .write_aofs = true,
241
+ .vece = MO_32 },
242
+ { .fniv = gen_uqsub_vec,
243
+ .fno = gen_helper_gvec_uqsub_d,
244
+ .opc = INDEX_op_ussub_vec,
245
+ .write_aofs = true,
246
+ .vece = MO_64 },
247
+};
248
+
249
+static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
250
+ TCGv_vec a, TCGv_vec b)
251
+{
252
+ TCGv_vec x = tcg_temp_new_vec_matching(t);
253
+ tcg_gen_sub_vec(vece, x, a, b);
254
+ tcg_gen_sssub_vec(vece, t, a, b);
255
+ tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
256
+ tcg_gen_or_vec(vece, sat, sat, x);
257
+ tcg_temp_free_vec(x);
258
+}
259
+
260
+const GVecGen4 sqsub_op[4] = {
261
+ { .fniv = gen_sqsub_vec,
262
+ .fno = gen_helper_gvec_sqsub_b,
263
+ .opc = INDEX_op_sssub_vec,
264
+ .write_aofs = true,
265
+ .vece = MO_8 },
266
+ { .fniv = gen_sqsub_vec,
267
+ .fno = gen_helper_gvec_sqsub_h,
268
+ .opc = INDEX_op_sssub_vec,
269
+ .write_aofs = true,
270
+ .vece = MO_16 },
271
+ { .fniv = gen_sqsub_vec,
272
+ .fno = gen_helper_gvec_sqsub_s,
273
+ .opc = INDEX_op_sssub_vec,
274
+ .write_aofs = true,
275
+ .vece = MO_32 },
276
+ { .fniv = gen_sqsub_vec,
277
+ .fno = gen_helper_gvec_sqsub_d,
278
+ .opc = INDEX_op_sssub_vec,
279
+ .write_aofs = true,
280
+ .vece = MO_64 },
281
+};
282
+
283
/* Translate a NEON data processing instruction. Return nonzero if the
284
instruction is invalid.
285
We process data in a mixture of 32-bit and 64-bit chunks.
286
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
287
}
288
return 0;
289
290
+ case NEON_3R_VQADD:
291
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
292
+ rn_ofs, rm_ofs, vec_size, vec_size,
293
+ (u ? uqadd_op : sqadd_op) + size);
294
+ break;
295
+
296
+ case NEON_3R_VQSUB:
297
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
298
+ rn_ofs, rm_ofs, vec_size, vec_size,
299
+ (u ? uqsub_op : sqsub_op) + size);
300
+ break;
301
+
302
case NEON_3R_VMUL: /* VMUL */
303
if (u) {
304
/* Polynomial case allows only P8 and is handled below. */
305
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
306
neon_load_reg64(cpu_V0, rn + pass);
307
neon_load_reg64(cpu_V1, rm + pass);
308
switch (op) {
309
- case NEON_3R_VQADD:
310
- if (u) {
311
- gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
312
- cpu_V0, cpu_V1);
313
- } else {
314
- gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
315
- cpu_V0, cpu_V1);
316
- }
317
- break;
318
- case NEON_3R_VQSUB:
319
- if (u) {
320
- gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
321
- cpu_V0, cpu_V1);
322
- } else {
323
- gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
324
- cpu_V0, cpu_V1);
325
- }
326
- break;
327
case NEON_3R_VSHL:
328
if (u) {
329
gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
330
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
331
case NEON_3R_VHADD:
332
GEN_NEON_INTEGER_OP(hadd);
333
break;
334
- case NEON_3R_VQADD:
335
- GEN_NEON_INTEGER_OP_ENV(qadd);
336
- break;
337
case NEON_3R_VRHADD:
338
GEN_NEON_INTEGER_OP(rhadd);
339
break;
340
case NEON_3R_VHSUB:
341
GEN_NEON_INTEGER_OP(hsub);
342
break;
343
- case NEON_3R_VQSUB:
344
- GEN_NEON_INTEGER_OP_ENV(qsub);
345
- break;
346
case NEON_3R_VSHL:
347
GEN_NEON_INTEGER_OP(shl);
348
break;
349
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
350
index XXXXXXX..XXXXXXX 100644
351
--- a/target/arm/vec_helper.c
352
+++ b/target/arm/vec_helper.c
353
@@ -XXX,XX +XXX,XX @@ DO_FMLA_IDX(gvec_fmla_idx_s, float32, H4)
354
DO_FMLA_IDX(gvec_fmla_idx_d, float64, )
355
356
#undef DO_FMLA_IDX
357
+
358
+#define DO_SAT(NAME, WTYPE, TYPEN, TYPEM, OP, MIN, MAX) \
359
+void HELPER(NAME)(void *vd, void *vq, void *vn, void *vm, uint32_t desc) \
360
+{ \
361
+ intptr_t i, oprsz = simd_oprsz(desc); \
362
+ TYPEN *d = vd, *n = vn; TYPEM *m = vm; \
363
+ bool q = false; \
364
+ for (i = 0; i < oprsz / sizeof(TYPEN); i++) { \
365
+ WTYPE dd = (WTYPE)n[i] OP m[i]; \
366
+ if (dd < MIN) { \
367
+ dd = MIN; \
368
+ q = true; \
369
+ } else if (dd > MAX) { \
370
+ dd = MAX; \
371
+ q = true; \
372
+ } \
373
+ d[i] = dd; \
374
+ } \
375
+ if (q) { \
376
+ uint32_t *qc = vq; \
377
+ qc[0] = 1; \
378
+ } \
379
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
380
+}
381
+
382
+DO_SAT(gvec_uqadd_b, int, uint8_t, uint8_t, +, 0, UINT8_MAX)
383
+DO_SAT(gvec_uqadd_h, int, uint16_t, uint16_t, +, 0, UINT16_MAX)
384
+DO_SAT(gvec_uqadd_s, int64_t, uint32_t, uint32_t, +, 0, UINT32_MAX)
385
+
386
+DO_SAT(gvec_sqadd_b, int, int8_t, int8_t, +, INT8_MIN, INT8_MAX)
387
+DO_SAT(gvec_sqadd_h, int, int16_t, int16_t, +, INT16_MIN, INT16_MAX)
388
+DO_SAT(gvec_sqadd_s, int64_t, int32_t, int32_t, +, INT32_MIN, INT32_MAX)
389
+
390
+DO_SAT(gvec_uqsub_b, int, uint8_t, uint8_t, -, 0, UINT8_MAX)
391
+DO_SAT(gvec_uqsub_h, int, uint16_t, uint16_t, -, 0, UINT16_MAX)
392
+DO_SAT(gvec_uqsub_s, int64_t, uint32_t, uint32_t, -, 0, UINT32_MAX)
393
+
394
+DO_SAT(gvec_sqsub_b, int, int8_t, int8_t, -, INT8_MIN, INT8_MAX)
395
+DO_SAT(gvec_sqsub_h, int, int16_t, int16_t, -, INT16_MIN, INT16_MAX)
396
+DO_SAT(gvec_sqsub_s, int64_t, int32_t, int32_t, -, INT32_MIN, INT32_MAX)
397
+
398
+#undef DO_SAT
399
+
400
+void HELPER(gvec_uqadd_d)(void *vd, void *vq, void *vn,
401
+ void *vm, uint32_t desc)
402
+{
403
+ intptr_t i, oprsz = simd_oprsz(desc);
404
+ uint64_t *d = vd, *n = vn, *m = vm;
405
+ bool q = false;
406
+
407
+ for (i = 0; i < oprsz / 8; i++) {
408
+ uint64_t nn = n[i], mm = m[i], dd = nn + mm;
409
+ if (dd < nn) {
410
+ dd = UINT64_MAX;
411
+ q = true;
412
+ }
413
+ d[i] = dd;
414
+ }
415
+ if (q) {
416
+ uint32_t *qc = vq;
417
+ qc[0] = 1;
418
+ }
419
+ clear_tail(d, oprsz, simd_maxsz(desc));
420
+}
421
+
422
+void HELPER(gvec_uqsub_d)(void *vd, void *vq, void *vn,
423
+ void *vm, uint32_t desc)
424
+{
425
+ intptr_t i, oprsz = simd_oprsz(desc);
426
+ uint64_t *d = vd, *n = vn, *m = vm;
427
+ bool q = false;
428
+
429
+ for (i = 0; i < oprsz / 8; i++) {
430
+ uint64_t nn = n[i], mm = m[i], dd = nn - mm;
431
+ if (nn < mm) {
432
+ dd = 0;
433
+ q = true;
434
+ }
435
+ d[i] = dd;
436
+ }
437
+ if (q) {
438
+ uint32_t *qc = vq;
439
+ qc[0] = 1;
440
+ }
441
+ clear_tail(d, oprsz, simd_maxsz(desc));
442
+}
443
+
444
+void HELPER(gvec_sqadd_d)(void *vd, void *vq, void *vn,
445
+ void *vm, uint32_t desc)
446
+{
447
+ intptr_t i, oprsz = simd_oprsz(desc);
448
+ int64_t *d = vd, *n = vn, *m = vm;
449
+ bool q = false;
450
+
451
+ for (i = 0; i < oprsz / 8; i++) {
452
+ int64_t nn = n[i], mm = m[i], dd = nn + mm;
453
+ if (((dd ^ nn) & ~(nn ^ mm)) & INT64_MIN) {
454
+ dd = (nn >> 63) ^ ~INT64_MIN;
455
+ q = true;
456
+ }
457
+ d[i] = dd;
458
+ }
459
+ if (q) {
460
+ uint32_t *qc = vq;
461
+ qc[0] = 1;
462
+ }
463
+ clear_tail(d, oprsz, simd_maxsz(desc));
464
+}
465
+
466
+void HELPER(gvec_sqsub_d)(void *vd, void *vq, void *vn,
467
+ void *vm, uint32_t desc)
468
+{
469
+ intptr_t i, oprsz = simd_oprsz(desc);
470
+ int64_t *d = vd, *n = vn, *m = vm;
471
+ bool q = false;
472
+
473
+ for (i = 0; i < oprsz / 8; i++) {
474
+ int64_t nn = n[i], mm = m[i], dd = nn - mm;
475
+ if (((dd ^ nn) & (nn ^ mm)) & INT64_MIN) {
476
+ dd = (nn >> 63) ^ ~INT64_MIN;
477
+ q = true;
478
+ }
479
+ d[i] = dd;
480
+ }
481
+ if (q) {
482
+ uint32_t *qc = vq;
483
+ qc[0] = 1;
484
+ }
485
+ clear_tail(d, oprsz, simd_maxsz(desc));
486
+}
487
--
39
--
488
2.20.1
40
2.20.1
489
41
490
42
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Given that we mask bits properly on set, there is no reason
3
Avoid using a magic number (4) everywhere for the number of chip
4
to mask them again on get. We failed to clear the exception
4
selects supported.
5
status bits, 0x9f, which means that the wrong value would be
6
returned on get. Except in the (probably normal) case in which
7
the set clears all of the bits.
8
5
9
Simplify the code in set to also clear the RES0 bits.
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20190209033847.9014-10-richard.henderson@linaro.org
9
Reviewed-by: Juan Quintela <quintela@redhat.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20210129132323.30946-2-bmeng.cn@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
12
---
16
target/arm/helper.c | 15 ++++++++-------
13
include/hw/ssi/imx_spi.h | 5 ++++-
17
1 file changed, 8 insertions(+), 7 deletions(-)
14
hw/ssi/imx_spi.c | 4 ++--
15
2 files changed, 6 insertions(+), 3 deletions(-)
18
16
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/include/hw/ssi/imx_spi.h b/include/hw/ssi/imx_spi.h
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
19
--- a/include/hw/ssi/imx_spi.h
22
+++ b/target/arm/helper.c
20
+++ b/include/hw/ssi/imx_spi.h
23
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
21
@@ -XXX,XX +XXX,XX @@
24
int i;
22
25
uint32_t fpscr;
23
#define EXTRACT(value, name) extract32(value, name##_SHIFT, name##_LENGTH)
26
24
27
- fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
25
+/* number of chip selects supported */
28
+ fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
26
+#define ECSPI_NUM_CS 4
29
| (env->vfp.vec_len << 16)
27
+
30
| (env->vfp.vec_stride << 20);
28
#define TYPE_IMX_SPI "imx.spi"
31
29
OBJECT_DECLARE_SIMPLE_TYPE(IMXSPIState, IMX_SPI)
32
@@ -XXX,XX +XXX,XX @@ static inline int vfp_exceptbits_to_host(int target_bits)
30
33
void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
31
@@ -XXX,XX +XXX,XX @@ struct IMXSPIState {
34
{
32
35
int i;
33
qemu_irq irq;
36
- uint32_t changed;
34
37
+ uint32_t changed = env->vfp.xregs[ARM_VFP_FPSCR];
35
- qemu_irq cs_lines[4];
38
36
+ qemu_irq cs_lines[ECSPI_NUM_CS];
39
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
37
40
if (!cpu_isar_feature(aa64_fp16, arm_env_get_cpu(env))) {
38
SSIBus *bus;
41
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
39
42
40
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
43
/*
41
index XXXXXXX..XXXXXXX 100644
44
* We don't implement trapped exception handling, so the
42
--- a/hw/ssi/imx_spi.c
45
- * trap enable bits are all RAZ/WI (not RES0!)
43
+++ b/hw/ssi/imx_spi.c
46
+ * trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
44
@@ -XXX,XX +XXX,XX @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
47
+ *
45
48
+ * If we exclude the exception flags, IOC|DZC|OFC|UFC|IXC|IDC
46
/* We are in master mode */
49
+ * (which are stored in fp_status), and the other RES0 bits
47
50
+ * in between, then we clear all of the low 16 bits.
48
- for (i = 0; i < 4; i++) {
51
*/
49
+ for (i = 0; i < ECSPI_NUM_CS; i++) {
52
- val &= ~(FPCR_IDE | FPCR_IXE | FPCR_UFE | FPCR_OFE | FPCR_DZE | FPCR_IOE);
50
qemu_set_irq(s->cs_lines[i],
53
-
51
i == imx_spi_selected_channel(s) ? 0 : 1);
54
- changed = env->vfp.xregs[ARM_VFP_FPSCR];
52
}
55
- env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
53
@@ -XXX,XX +XXX,XX @@ static void imx_spi_realize(DeviceState *dev, Error **errp)
56
+ env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xffc80000;
54
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
57
env->vfp.vec_len = (val >> 16) & 7;
55
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
58
env->vfp.vec_stride = (val >> 20) & 3;
56
57
- for (i = 0; i < 4; ++i) {
58
+ for (i = 0; i < ECSPI_NUM_CS; ++i) {
59
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cs_lines[i]);
60
}
59
61
60
--
62
--
61
2.20.1
63
2.20.1
62
64
63
65
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
As this is a single register we could expose it with a simple ifdef
3
Usually the approach is that the device on the other end of the line
4
but we use the existing modify_arm_cp_regs mechanism for consistency.
4
is going to reset its state anyway, so there's no need to actively
5
signal an irq line change during the reset hook.
5
6
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Move imx_spi_update_irq() out of imx_spi_reset(), to a new function
7
Message-id: 20190205190224.2198-4-alex.bennee@linaro.org
8
imx_spi_soft_reset() that is called when the controller is disabled.
9
10
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20210129132323.30946-3-bmeng.cn@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/helper.c | 21 ++++++++++++++-------
15
hw/ssi/imx_spi.c | 14 ++++++++++----
12
1 file changed, 14 insertions(+), 7 deletions(-)
16
1 file changed, 10 insertions(+), 4 deletions(-)
13
17
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
20
--- a/hw/ssi/imx_spi.c
17
+++ b/target/arm/helper.c
21
+++ b/hw/ssi/imx_spi.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t mpidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
22
@@ -XXX,XX +XXX,XX @@ static void imx_spi_reset(DeviceState *dev)
19
return mpidr_read_val(env);
23
imx_spi_rxfifo_reset(s);
24
imx_spi_txfifo_reset(s);
25
26
- imx_spi_update_irq(s);
27
-
28
s->burst_length = 0;
20
}
29
}
21
30
22
-static const ARMCPRegInfo mpidr_cp_reginfo[] = {
31
+static void imx_spi_soft_reset(IMXSPIState *s)
23
- { .name = "MPIDR", .state = ARM_CP_STATE_BOTH,
32
+{
24
- .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
33
+ imx_spi_reset(DEVICE(s));
25
- .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
34
+
26
- REGINFO_SENTINEL
35
+ imx_spi_update_irq(s);
27
-};
36
+}
28
-
37
+
29
static const ARMCPRegInfo lpae_cp_reginfo[] = {
38
static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size)
30
/* NOP AMAIR0/1 */
39
{
31
{ .name = "AMAIR0", .state = ARM_CP_STATE_BOTH,
40
uint32_t value = 0;
32
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
41
@@ -XXX,XX +XXX,XX @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
33
}
42
s->regs[ECSPI_CONREG] = value;
34
43
35
if (arm_feature(env, ARM_FEATURE_MPIDR)) {
44
if (!imx_spi_is_enabled(s)) {
36
+ ARMCPRegInfo mpidr_cp_reginfo[] = {
45
- /* device is disabled, so this is a reset */
37
+ { .name = "MPIDR_EL1", .state = ARM_CP_STATE_BOTH,
46
- imx_spi_reset(DEVICE(s));
38
+ .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 5,
47
+ /* device is disabled, so this is a soft reset */
39
+ .access = PL1_R, .readfn = mpidr_read, .type = ARM_CP_NO_RAW },
48
+ imx_spi_soft_reset(s);
40
+ REGINFO_SENTINEL
49
+
41
+ };
50
return;
42
+#ifdef CONFIG_USER_ONLY
51
}
43
+ ARMCPRegUserSpaceInfo mpidr_user_cp_reginfo[] = {
44
+ { .name = "MPIDR_EL1",
45
+ .fixed_bits = 0x0000000080000000 },
46
+ REGUSERINFO_SENTINEL
47
+ };
48
+ modify_arm_cp_regs(mpidr_cp_reginfo, mpidr_user_cp_reginfo);
49
+#endif
50
define_arm_cp_regs(cpu, mpidr_cp_reginfo);
51
}
52
52
53
--
53
--
54
2.20.1
54
2.20.1
55
55
56
56
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
'burst_length' is cleared in imx_spi_reset(), which is called
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
after imx_spi_realize(). Remove the initialization to simplify.
5
Message-id: 20190209033847.9014-3-richard.henderson@linaro.org
5
6
Reviewed-by: Juan Quintela <quintela@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Bin Meng <bin.meng@windriver.com>
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Message-id: 20210129132323.30946-4-bmeng.cn@gmail.com
11
Message-Id: <20210115153049.3353008-3-f4bug@amsat.org>
12
Reviewed-by: Bin Meng <bin.meng@windriver.com>
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
15
---
8
target/arm/translate-a64.c | 35 ++++++++++++++---------------------
16
hw/ssi/imx_spi.c | 2 --
9
1 file changed, 14 insertions(+), 21 deletions(-)
17
1 file changed, 2 deletions(-)
10
18
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
19
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
12
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
21
--- a/hw/ssi/imx_spi.c
14
+++ b/target/arm/translate-a64.c
22
+++ b/hw/ssi/imx_spi.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
23
@@ -XXX,XX +XXX,XX @@ static void imx_spi_realize(DeviceState *dev, Error **errp)
24
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cs_lines[i]);
16
}
25
}
17
26
18
switch (opcode) {
27
- s->burst_length = 0;
19
+ case 0x0c: /* SMAX, UMAX */
20
+ if (u) {
21
+ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
22
+ } else {
23
+ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smax, size);
24
+ }
25
+ return;
26
+ case 0x0d: /* SMIN, UMIN */
27
+ if (u) {
28
+ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umin, size);
29
+ } else {
30
+ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smin, size);
31
+ }
32
+ return;
33
case 0x10: /* ADD, SUB */
34
if (u) {
35
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size);
36
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
37
genenvfn = fns[size][u];
38
break;
39
}
40
- case 0xc: /* SMAX, UMAX */
41
- {
42
- static NeonGenTwoOpFn * const fns[3][2] = {
43
- { gen_helper_neon_max_s8, gen_helper_neon_max_u8 },
44
- { gen_helper_neon_max_s16, gen_helper_neon_max_u16 },
45
- { tcg_gen_smax_i32, tcg_gen_umax_i32 },
46
- };
47
- genfn = fns[size][u];
48
- break;
49
- }
50
-
28
-
51
- case 0xd: /* SMIN, UMIN */
29
fifo32_create(&s->tx_fifo, ECSPI_FIFO_SIZE);
52
- {
30
fifo32_create(&s->rx_fifo, ECSPI_FIFO_SIZE);
53
- static NeonGenTwoOpFn * const fns[3][2] = {
31
}
54
- { gen_helper_neon_min_s8, gen_helper_neon_min_u8 },
55
- { gen_helper_neon_min_s16, gen_helper_neon_min_u16 },
56
- { tcg_gen_smin_i32, tcg_gen_umin_i32 },
57
- };
58
- genfn = fns[size][u];
59
- break;
60
- }
61
case 0xe: /* SABD, UABD */
62
case 0xf: /* SABA, UABA */
63
{
64
--
32
--
65
2.20.1
33
2.20.1
66
34
67
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Minimize the code within a macro by splitting out a helper function.
3
When the block is disabled, all registers are reset with the
4
Use deposit32 instead of manual bit manipulation.
4
exception of the ECSPI_CONREG. It is initialized to zero
5
when the instance is created.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Ref: i.MX 6DQ Applications Processor Reference Manual (IMX6DQRM),
7
Message-id: 20190209033847.9014-9-richard.henderson@linaro.org
8
chapter 21.7.3: Control Register (ECSPIx_CONREG)
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Bin Meng <bin.meng@windriver.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20210129132323.30946-5-bmeng.cn@gmail.com
14
[bmeng: add a 'common_reset' function that does most of reset operation]
15
Signed-off-by: Bin Meng <bin.meng@windriver.com>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
17
---
11
target/arm/helper.c | 45 +++++++++++++++++++++++++++------------------
18
hw/ssi/imx_spi.c | 32 ++++++++++++++++++++++++--------
12
1 file changed, 27 insertions(+), 18 deletions(-)
19
1 file changed, 24 insertions(+), 8 deletions(-)
13
20
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
23
--- a/hw/ssi/imx_spi.c
17
+++ b/target/arm/helper.c
24
+++ b/hw/ssi/imx_spi.c
18
@@ -XXX,XX +XXX,XX @@ float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env)
25
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
19
return float64_sqrt(a, &env->vfp.fp_status);
26
fifo32_num_used(&s->tx_fifo), fifo32_num_used(&s->rx_fifo));
20
}
27
}
21
28
22
+static void softfloat_to_vfp_compare(CPUARMState *env, int cmp)
29
-static void imx_spi_reset(DeviceState *dev)
30
+static void imx_spi_common_reset(IMXSPIState *s)
31
{
32
- IMXSPIState *s = IMX_SPI(dev);
33
+ int i;
34
35
- DPRINTF("\n");
36
-
37
- memset(s->regs, 0, sizeof(s->regs));
38
-
39
- s->regs[ECSPI_STATREG] = 0x00000003;
40
+ for (i = 0; i < ARRAY_SIZE(s->regs); i++) {
41
+ switch (i) {
42
+ case ECSPI_CONREG:
43
+ /* CONREG is not updated on soft reset */
44
+ break;
45
+ case ECSPI_STATREG:
46
+ s->regs[i] = 0x00000003;
47
+ break;
48
+ default:
49
+ s->regs[i] = 0;
50
+ break;
51
+ }
52
+ }
53
54
imx_spi_rxfifo_reset(s);
55
imx_spi_txfifo_reset(s);
56
@@ -XXX,XX +XXX,XX @@ static void imx_spi_reset(DeviceState *dev)
57
58
static void imx_spi_soft_reset(IMXSPIState *s)
59
{
60
- imx_spi_reset(DEVICE(s));
61
+ imx_spi_common_reset(s);
62
63
imx_spi_update_irq(s);
64
}
65
66
+static void imx_spi_reset(DeviceState *dev)
23
+{
67
+{
24
+ uint32_t flags;
68
+ IMXSPIState *s = IMX_SPI(dev);
25
+ switch (cmp) {
69
+
26
+ case float_relation_equal:
70
+ imx_spi_common_reset(s);
27
+ flags = 0x6;
71
+ s->regs[ECSPI_CONREG] = 0;
28
+ break;
29
+ case float_relation_less:
30
+ flags = 0x8;
31
+ break;
32
+ case float_relation_greater:
33
+ flags = 0x2;
34
+ break;
35
+ case float_relation_unordered:
36
+ flags = 0x3;
37
+ break;
38
+ default:
39
+ g_assert_not_reached();
40
+ }
41
+ env->vfp.xregs[ARM_VFP_FPSCR] =
42
+ deposit32(env->vfp.xregs[ARM_VFP_FPSCR], 28, 4, flags);
43
+}
72
+}
44
+
73
+
45
/* XXX: check quiet/signaling case */
74
static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size)
46
#define DO_VFP_cmp(p, type) \
75
{
47
void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
76
uint32_t value = 0;
48
{ \
49
- uint32_t flags; \
50
- switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
51
- case 0: flags = 0x6; break; \
52
- case -1: flags = 0x8; break; \
53
- case 1: flags = 0x2; break; \
54
- default: case 2: flags = 0x3; break; \
55
- } \
56
- env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
57
- | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
58
+ softfloat_to_vfp_compare(env, \
59
+ type ## _compare_quiet(a, b, &env->vfp.fp_status)); \
60
} \
61
void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
62
{ \
63
- uint32_t flags; \
64
- switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
65
- case 0: flags = 0x6; break; \
66
- case -1: flags = 0x8; break; \
67
- case 1: flags = 0x2; break; \
68
- default: case 2: flags = 0x3; break; \
69
- } \
70
- env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
71
- | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
72
+ softfloat_to_vfp_compare(env, \
73
+ type ## _compare(a, b, &env->vfp.fp_status)); \
74
}
75
DO_VFP_cmp(s, float32)
76
DO_VFP_cmp(d, float64)
77
--
77
--
78
2.20.1
78
2.20.1
79
79
80
80
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
For opcodes 0-5, move some if conditions into the structure
3
When the block is disabled, it stay it is 'internal reset logic'
4
of a switch statement. For opcodes 6 & 7, decode everything
4
(internal clocks are gated off). Reading any register returns
5
at once with a second switch.
5
its reset value. Only update this value if the device is enabled.
6
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Ref: i.MX 6DQ Applications Processor Reference Manual (IMX6DQRM),
8
Message-id: 20190206052857.5077-3-richard.henderson@linaro.org
8
chapter 21.7.3: Control Register (ECSPIx_CONREG)
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
10
Reviewed-by: Juan Quintela <quintela@redhat.com>
11
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Bin Meng <bin.meng@windriver.com>
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
14
Message-id: 20210129132323.30946-6-bmeng.cn@gmail.com
15
Message-Id: <20210115153049.3353008-5-f4bug@amsat.org>
16
Reviewed-by: Bin Meng <bin.meng@windriver.com>
17
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
target/arm/translate-a64.c | 94 ++++++++++++++++++++------------------
20
hw/ssi/imx_spi.c | 60 +++++++++++++++++++++++-------------------------
13
1 file changed, 49 insertions(+), 45 deletions(-)
21
1 file changed, 29 insertions(+), 31 deletions(-)
14
22
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
23
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
25
--- a/hw/ssi/imx_spi.c
18
+++ b/target/arm/translate-a64.c
26
+++ b/hw/ssi/imx_spi.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
27
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size)
20
int type = extract32(insn, 22, 2);
28
return 0;
21
bool sbit = extract32(insn, 29, 1);
22
bool sf = extract32(insn, 31, 1);
23
+ bool itof = false;
24
25
if (sbit) {
26
- unallocated_encoding(s);
27
- return;
28
+ goto do_unallocated;
29
}
29
}
30
30
31
- if (opcode > 5) {
31
- switch (index) {
32
- /* FMOV */
32
- case ECSPI_RXDATA:
33
- bool itof = opcode & 1;
33
- if (!imx_spi_is_enabled(s)) {
34
- value = 0;
35
- } else if (fifo32_is_empty(&s->rx_fifo)) {
36
- /* value is undefined */
37
- value = 0xdeadbeef;
38
- } else {
39
- /* read from the RX FIFO */
40
- value = fifo32_pop(&s->rx_fifo);
41
+ value = s->regs[index];
42
+
43
+ if (imx_spi_is_enabled(s)) {
44
+ switch (index) {
45
+ case ECSPI_RXDATA:
46
+ if (fifo32_is_empty(&s->rx_fifo)) {
47
+ /* value is undefined */
48
+ value = 0xdeadbeef;
49
+ } else {
50
+ /* read from the RX FIFO */
51
+ value = fifo32_pop(&s->rx_fifo);
52
+ }
53
+ break;
54
+ case ECSPI_TXDATA:
55
+ qemu_log_mask(LOG_GUEST_ERROR,
56
+ "[%s]%s: Trying to read from TX FIFO\n",
57
+ TYPE_IMX_SPI, __func__);
58
+
59
+ /* Reading from TXDATA gives 0 */
60
+ break;
61
+ case ECSPI_MSGDATA:
62
+ qemu_log_mask(LOG_GUEST_ERROR,
63
+ "[%s]%s: Trying to read from MSG FIFO\n",
64
+ TYPE_IMX_SPI, __func__);
65
+ /* Reading from MSGDATA gives 0 */
66
+ break;
67
+ default:
68
+ break;
69
}
70
71
- break;
72
- case ECSPI_TXDATA:
73
- qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read from TX FIFO\n",
74
- TYPE_IMX_SPI, __func__);
34
-
75
-
35
- if (rmode >= 2) {
76
- /* Reading from TXDATA gives 0 */
36
- unallocated_encoding(s);
37
- return;
38
- }
39
-
77
-
40
- switch (sf << 3 | type << 1 | rmode) {
78
- break;
41
- case 0x0: /* 32 bit */
79
- case ECSPI_MSGDATA:
42
- case 0xa: /* 64 bit */
80
- qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read from MSG FIFO\n",
43
- case 0xd: /* 64 bit to top half of quad */
81
- TYPE_IMX_SPI, __func__);
44
- break;
45
- case 0x6: /* 16-bit float, 32-bit int */
46
- case 0xe: /* 16-bit float, 64-bit int */
47
- if (dc_isar_feature(aa64_fp16, s)) {
48
- break;
49
- }
50
- /* fallthru */
51
- default:
52
- /* all other sf/type/rmode combinations are invalid */
53
- unallocated_encoding(s);
54
- return;
55
- }
56
-
82
-
57
- if (!fp_access_check(s)) {
83
- /* Reading from MSGDATA gives 0 */
58
- return;
59
- }
60
- handle_fmov(s, rd, rn, type, itof);
61
- } else {
62
- /* actual FP conversions */
63
- bool itof = extract32(opcode, 1, 1);
64
-
84
-
65
- if (rmode != 0 && opcode > 1) {
85
- break;
66
- unallocated_encoding(s);
86
- default:
67
- return;
87
- value = s->regs[index];
68
+ switch (opcode) {
88
- break;
69
+ case 2: /* SCVTF */
89
+ imx_spi_update_irq(s);
70
+ case 3: /* UCVTF */
90
}
71
+ itof = true;
72
+ /* fallthru */
73
+ case 4: /* FCVTAS */
74
+ case 5: /* FCVTAU */
75
+ if (rmode != 0) {
76
+ goto do_unallocated;
77
}
78
+ /* fallthru */
79
+ case 0: /* FCVT[NPMZ]S */
80
+ case 1: /* FCVT[NPMZ]U */
81
switch (type) {
82
case 0: /* float32 */
83
case 1: /* float64 */
84
break;
85
case 3: /* float16 */
86
- if (dc_isar_feature(aa64_fp16, s)) {
87
- break;
88
+ if (!dc_isar_feature(aa64_fp16, s)) {
89
+ goto do_unallocated;
90
}
91
- /* fallthru */
92
+ break;
93
default:
94
- unallocated_encoding(s);
95
- return;
96
+ goto do_unallocated;
97
}
98
-
91
-
99
if (!fp_access_check(s)) {
92
DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx_spi_reg_name(index), value);
100
return;
93
101
}
94
- imx_spi_update_irq(s);
102
handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type);
95
-
103
+ break;
96
return (uint64_t)value;
104
+
105
+ default:
106
+ switch (sf << 7 | type << 5 | rmode << 3 | opcode) {
107
+ case 0b01100110: /* FMOV half <-> 32-bit int */
108
+ case 0b01100111:
109
+ case 0b11100110: /* FMOV half <-> 64-bit int */
110
+ case 0b11100111:
111
+ if (!dc_isar_feature(aa64_fp16, s)) {
112
+ goto do_unallocated;
113
+ }
114
+ /* fallthru */
115
+ case 0b00000110: /* FMOV 32-bit */
116
+ case 0b00000111:
117
+ case 0b10100110: /* FMOV 64-bit */
118
+ case 0b10100111:
119
+ case 0b11001110: /* FMOV top half of 128-bit */
120
+ case 0b11001111:
121
+ if (!fp_access_check(s)) {
122
+ return;
123
+ }
124
+ itof = opcode & 1;
125
+ handle_fmov(s, rd, rn, type, itof);
126
+ break;
127
+
128
+ default:
129
+ do_unallocated:
130
+ unallocated_encoding(s);
131
+ return;
132
+ }
133
+ break;
134
}
135
}
97
}
136
98
137
--
99
--
138
2.20.1
100
2.20.1
139
101
140
102
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
A number of CPUID registers are exposed to userspace by modern Linux
3
When the block is disabled, only the ECSPI_CONREG register can
4
kernels thanks to the "ARM64 CPU Feature Registers" ABI. For QEMU's
4
be modified. Setting the EN bit enabled the device, clearing it
5
user-mode emulation we don't need to emulate the kernels trap but just
5
"disables the block and resets the internal logic with the
6
return the value the trap would have done. To avoid too much #ifdef
6
exception of the ECSPI_CONREG" register.
7
hackery we process ARMCPRegInfo with a new helper (modify_arm_cp_regs)
8
before defining the registers. The modify routine is driven by a
9
simple data structure which describes which bits are exported and
10
which are fixed.
11
7
12
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Ignore all other registers write except ECSPI_CONREG when the
13
Message-id: 20190205190224.2198-3-alex.bennee@linaro.org
9
block is disabled.
10
11
Ref: i.MX 6DQ Applications Processor Reference Manual (IMX6DQRM),
12
chapter 21.7.3: Control Register (ECSPIx_CONREG)
13
14
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Bin Meng <bin.meng@windriver.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20210129132323.30946-7-bmeng.cn@gmail.com
18
Message-Id: <20210115153049.3353008-6-f4bug@amsat.org>
19
Signed-off-by: Bin Meng <bin.meng@windriver.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
22
---
17
target/arm/cpu.h | 21 ++++++++++++++++
23
hw/ssi/imx_spi.c | 13 +++++++++----
18
target/arm/helper.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
24
1 file changed, 9 insertions(+), 4 deletions(-)
19
2 files changed, 80 insertions(+)
20
25
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
22
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
28
--- a/hw/ssi/imx_spi.c
24
+++ b/target/arm/cpu.h
29
+++ b/hw/ssi/imx_spi.c
25
@@ -XXX,XX +XXX,XX @@ static inline void define_one_arm_cp_reg(ARMCPU *cpu, const ARMCPRegInfo *regs)
30
@@ -XXX,XX +XXX,XX @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
26
}
31
DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_spi_reg_name(index),
27
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp);
32
(uint32_t)value);
28
33
29
+/*
34
+ if (!imx_spi_is_enabled(s)) {
30
+ * Definition of an ARM co-processor register as viewed from
35
+ /* Block is disabled */
31
+ * userspace. This is used for presenting sanitised versions of
36
+ if (index != ECSPI_CONREG) {
32
+ * registers to userspace when emulating the Linux AArch64 CPU
37
+ /* Ignore access */
33
+ * ID/feature ABI (advertised as HWCAP_CPUID).
38
+ return;
34
+ */
35
+typedef struct ARMCPRegUserSpaceInfo {
36
+ /* Name of register */
37
+ const char *name;
38
+
39
+ /* Only some bits are exported to user space */
40
+ uint64_t exported_bits;
41
+
42
+ /* Fixed bits are applied after the mask */
43
+ uint64_t fixed_bits;
44
+} ARMCPRegUserSpaceInfo;
45
+
46
+#define REGUSERINFO_SENTINEL { .name = NULL }
47
+
48
+void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods);
49
+
50
/* CPWriteFn that can be used to implement writes-ignored behaviour */
51
void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
52
uint64_t value);
53
diff --git a/target/arm/helper.c b/target/arm/helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/helper.c
56
+++ b/target/arm/helper.c
57
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
58
.resetvalue = cpu->pmceid1 },
59
REGINFO_SENTINEL
60
};
61
+#ifdef CONFIG_USER_ONLY
62
+ ARMCPRegUserSpaceInfo v8_user_idregs[] = {
63
+ { .name = "ID_AA64PFR0_EL1",
64
+ .exported_bits = 0x000f000f00ff0000,
65
+ .fixed_bits = 0x0000000000000011 },
66
+ { .name = "ID_AA64PFR1_EL1",
67
+ .exported_bits = 0x00000000000000f0 },
68
+ { .name = "ID_AA64ZFR0_EL1" },
69
+ { .name = "ID_AA64MMFR0_EL1",
70
+ .fixed_bits = 0x00000000ff000000 },
71
+ { .name = "ID_AA64MMFR1_EL1" },
72
+ { .name = "ID_AA64DFR0_EL1",
73
+ .fixed_bits = 0x0000000000000006 },
74
+ { .name = "ID_AA64DFR1_EL1" },
75
+ { .name = "ID_AA64AFR0_EL1" },
76
+ { .name = "ID_AA64AFR1_EL1" },
77
+ { .name = "ID_AA64ISAR0_EL1",
78
+ .exported_bits = 0x00fffffff0fffff0 },
79
+ { .name = "ID_AA64ISAR1_EL1",
80
+ .exported_bits = 0x000000f0ffffffff },
81
+ REGUSERINFO_SENTINEL
82
+ };
83
+ modify_arm_cp_regs(v8_idregs, v8_user_idregs);
84
+#endif
85
/* RVBAR_EL1 is only implemented if EL1 is the highest EL */
86
if (!arm_feature(env, ARM_FEATURE_EL3) &&
87
!arm_feature(env, ARM_FEATURE_EL2)) {
88
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
89
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
90
.type = ARM_CP_NOP | ARM_CP_OVERRIDE
91
};
92
+#ifdef CONFIG_USER_ONLY
93
+ ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
94
+ { .name = "MIDR_EL1",
95
+ .exported_bits = 0x00000000ffffffff },
96
+ { .name = "REVIDR_EL1" },
97
+ REGUSERINFO_SENTINEL
98
+ };
99
+ modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
100
+#endif
101
if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
102
arm_feature(env, ARM_FEATURE_STRONGARM)) {
103
ARMCPRegInfo *r;
104
@@ -XXX,XX +XXX,XX @@ void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
105
}
106
}
107
108
+/*
109
+ * Modify ARMCPRegInfo for access from userspace.
110
+ *
111
+ * This is a data driven modification directed by
112
+ * ARMCPRegUserSpaceInfo. All registers become ARM_CP_CONST as
113
+ * user-space cannot alter any values and dynamic values pertaining to
114
+ * execution state are hidden from user space view anyway.
115
+ */
116
+void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
117
+{
118
+ const ARMCPRegUserSpaceInfo *m;
119
+ ARMCPRegInfo *r;
120
+
121
+ for (m = mods; m->name; m++) {
122
+ for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
123
+ if (strcmp(r->name, m->name) == 0) {
124
+ r->type = ARM_CP_CONST;
125
+ r->access = PL0U_R;
126
+ r->resetvalue &= m->exported_bits;
127
+ r->resetvalue |= m->fixed_bits;
128
+ break;
129
+ }
130
+ }
39
+ }
131
+ }
40
+ }
132
+}
133
+
41
+
134
const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
42
change_mask = s->regs[index] ^ value;
135
{
43
136
return g_hash_table_lookup(cpregs, &encoded_cp);
44
switch (index) {
45
@@ -XXX,XX +XXX,XX @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
46
TYPE_IMX_SPI, __func__);
47
break;
48
case ECSPI_TXDATA:
49
- if (!imx_spi_is_enabled(s)) {
50
- /* Ignore writes if device is disabled */
51
- break;
52
- } else if (fifo32_is_full(&s->tx_fifo)) {
53
+ if (fifo32_is_full(&s->tx_fifo)) {
54
/* Ignore writes if queue is full */
55
break;
56
}
137
--
57
--
138
2.20.1
58
2.20.1
139
59
140
60
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Xuzhou Cheng <xuzhou.cheng@windriver.com>
2
2
3
Since we're now handling a == b generically, we no longer need
3
When a write to ECSPI_CONREG register to disable the SPI controller,
4
to do it by hand within target/arm/.
4
imx_spi_soft_reset() is called to reset the controller, but chip
5
select lines should have been disabled, otherwise the state machine
6
of any devices (e.g.: SPI flashes) connected to the SPI master is
7
stuck to its last state and responds incorrectly to any follow-up
8
commands.
5
9
6
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
10
Fixes: c906a3a01582 ("i.MX: Add the Freescale SPI Controller")
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
8
Message-id: 20190209033847.9014-2-richard.henderson@linaro.org
12
Signed-off-by: Bin Meng <bin.meng@windriver.com>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20210129132323.30946-8-bmeng.cn@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
target/arm/translate-a64.c | 6 +-----
17
hw/ssi/imx_spi.c | 6 ++++++
12
target/arm/translate-sve.c | 6 +-----
18
1 file changed, 6 insertions(+)
13
target/arm/translate.c | 12 +++---------
14
3 files changed, 5 insertions(+), 19 deletions(-)
15
19
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
20
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
22
--- a/hw/ssi/imx_spi.c
19
+++ b/target/arm/translate-a64.c
23
+++ b/hw/ssi/imx_spi.c
20
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_logic(DisasContext *s, uint32_t insn)
24
@@ -XXX,XX +XXX,XX @@ static void imx_spi_common_reset(IMXSPIState *s)
21
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_andc, 0);
25
22
return;
26
static void imx_spi_soft_reset(IMXSPIState *s)
23
case 2: /* ORR */
24
- if (rn == rm) { /* MOV */
25
- gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_mov, 0);
26
- } else {
27
- gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_or, 0);
28
- }
29
+ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_or, 0);
30
return;
31
case 3: /* ORN */
32
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_orc, 0);
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-sve.c
36
+++ b/target/arm/translate-sve.c
37
@@ -XXX,XX +XXX,XX @@ static bool trans_AND_zzz(DisasContext *s, arg_rrr_esz *a)
38
39
static bool trans_ORR_zzz(DisasContext *s, arg_rrr_esz *a)
40
{
27
{
41
- if (a->rn == a->rm) { /* MOV */
28
+ int i;
42
- return do_mov_z(s, a->rd, a->rn);
29
+
43
- } else {
30
imx_spi_common_reset(s);
44
- return do_vector3_z(s, tcg_gen_gvec_or, 0, a->rd, a->rn, a->rm);
31
45
- }
32
imx_spi_update_irq(s);
46
+ return do_vector3_z(s, tcg_gen_gvec_or, 0, a->rd, a->rn, a->rm);
33
+
34
+ for (i = 0; i < ECSPI_NUM_CS; i++) {
35
+ qemu_set_irq(s->cs_lines[i], 1);
36
+ }
47
}
37
}
48
38
49
static bool trans_EOR_zzz(DisasContext *s, arg_rrr_esz *a)
39
static void imx_spi_reset(DeviceState *dev)
50
diff --git a/target/arm/translate.c b/target/arm/translate.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate.c
53
+++ b/target/arm/translate.c
54
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
55
tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
56
vec_size, vec_size);
57
break;
58
- case 2:
59
- if (rn == rm) {
60
- /* VMOV */
61
- tcg_gen_gvec_mov(0, rd_ofs, rn_ofs, vec_size, vec_size);
62
- } else {
63
- /* VORR */
64
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
65
- vec_size, vec_size);
66
- }
67
+ case 2: /* VORR */
68
+ tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
69
+ vec_size, vec_size);
70
break;
71
case 3: /* VORN */
72
tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
73
--
40
--
74
2.20.1
41
2.20.1
75
42
76
43
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The 32-bit PMIN/PMAX has been decomposed to scalars,
3
Current implementation of the imx spi controller expects the burst
4
and so can be trivially expanded inline.
4
length to be multiple of 8, which is the most common use case.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
In case the burst length is not what we expect, log it to give user
7
Message-id: 20190209033847.9014-5-richard.henderson@linaro.org
7
a chance to notice it, and round it up to be multiple of 8.
8
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Message-id: 20210129132323.30946-9-bmeng.cn@gmail.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/translate.c | 8 ++++----
14
hw/ssi/imx_spi.c | 17 ++++++++++++++++-
12
1 file changed, 4 insertions(+), 4 deletions(-)
15
1 file changed, 16 insertions(+), 1 deletion(-)
13
16
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
19
--- a/hw/ssi/imx_spi.c
17
+++ b/target/arm/translate.c
20
+++ b/hw/ssi/imx_spi.c
18
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
21
@@ -XXX,XX +XXX,XX @@ static uint8_t imx_spi_selected_channel(IMXSPIState *s)
22
23
static uint32_t imx_spi_burst_length(IMXSPIState *s)
24
{
25
- return EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1;
26
+ uint32_t burst;
27
+
28
+ burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1;
29
+ if (burst % 8) {
30
+ burst = ROUND_UP(burst, 8);
31
+ }
32
+
33
+ return burst;
19
}
34
}
20
35
21
/* 32-bit pairwise ops end up the same as the elementwise versions. */
36
static bool imx_spi_is_enabled(IMXSPIState *s)
22
-#define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
37
@@ -XXX,XX +XXX,XX @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
23
-#define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
38
IMXSPIState *s = opaque;
24
-#define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
39
uint32_t index = offset >> 2;
25
-#define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
40
uint32_t change_mask;
26
+#define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
41
+ uint32_t burst;
27
+#define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
42
28
+#define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
43
if (index >= ECSPI_MAX) {
29
+#define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
44
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
30
45
@@ -XXX,XX +XXX,XX @@ static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
31
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
46
case ECSPI_CONREG:
32
switch ((size << 1) | u) { \
47
s->regs[ECSPI_CONREG] = value;
48
49
+ burst = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1;
50
+ if (burst % 8) {
51
+ qemu_log_mask(LOG_UNIMP,
52
+ "[%s]%s: burst length %d not supported: rounding up to next multiple of 8\n",
53
+ TYPE_IMX_SPI, __func__, burst);
54
+ }
55
+
56
if (!imx_spi_is_enabled(s)) {
57
/* device is disabled, so this is a soft reset */
58
imx_spi_soft_reset(s);
33
--
59
--
34
2.20.1
60
2.20.1
35
61
36
62
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
For the ECSPIx_CONREG register BURST_LENGTH field, the manual says:
4
Message-id: 20190209033847.9014-8-richard.henderson@linaro.org
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
0x020 A SPI burst contains the 1 LSB in first word and all 32 bits in second word.
6
0x021 A SPI burst contains the 2 LSB in first word and all 32 bits in second word.
7
8
Current logic uses either s->burst_length or 32, whichever smaller,
9
to determine how many bits it should read from the tx fifo each time.
10
For example, for a 48 bit burst length, current logic transfers the
11
first 32 bit from the first word in the tx fifo, followed by a 16
12
bit from the second word in the tx fifo, which is wrong. The correct
13
logic should be: transfer the first 16 bit from the first word in
14
the tx fifo, followed by a 32 bit from the second word in the tx fifo.
15
16
With this change, SPI flash can be successfully probed by U-Boot on
17
imx6 sabrelite board.
18
19
=> sf probe
20
SF: Detected sst25vf016b with page size 256 Bytes, erase size 4 KiB, total 2 MiB
21
22
Fixes: c906a3a01582 ("i.MX: Add the Freescale SPI Controller")
23
Signed-off-by: Bin Meng <bin.meng@windriver.com>
24
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Message-id: 20210129132323.30946-10-bmeng.cn@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
27
---
8
target/arm/translate.c | 2 +-
28
hw/ssi/imx_spi.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
29
1 file changed, 1 insertion(+), 1 deletion(-)
10
30
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
31
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
12
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
33
--- a/hw/ssi/imx_spi.c
14
+++ b/target/arm/translate.c
34
+++ b/hw/ssi/imx_spi.c
15
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
35
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
16
i * 2 + 1, (uint32_t)(v >> 32),
36
17
i, v);
37
DPRINTF("data tx:0x%08x\n", tx);
18
}
38
19
- cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
39
- tx_burst = MIN(s->burst_length, 32);
20
+ cpu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
40
+ tx_burst = (s->burst_length % 32) ? : 32;
21
}
41
22
}
42
rx = 0;
23
43
24
--
44
--
25
2.20.1
45
2.20.1
26
46
27
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The endianness of data exchange between tx and rx fifo is incorrect.
4
Earlier bytes are supposed to show up on MSB and later bytes on LSB,
5
ie: in big endian. The manual does not explicitly say this, but the
6
U-Boot and Linux driver codes have a swap on the data transferred
7
to tx fifo and from rx fifo.
8
9
With this change, U-Boot read from / write to SPI flash tests pass.
10
11
=> sf test 1ff000 1000
12
SPI flash test:
13
0 erase: 0 ticks, 4096000 KiB/s 32768.000 Mbps
14
1 check: 3 ticks, 1333 KiB/s 10.664 Mbps
15
2 write: 235 ticks, 17 KiB/s 0.136 Mbps
16
3 read: 2 ticks, 2000 KiB/s 16.000 Mbps
17
Test passed
18
0 erase: 0 ticks, 4096000 KiB/s 32768.000 Mbps
19
1 check: 3 ticks, 1333 KiB/s 10.664 Mbps
20
2 write: 235 ticks, 17 KiB/s 0.136 Mbps
21
3 read: 2 ticks, 2000 KiB/s 16.000 Mbps
22
23
Fixes: c906a3a01582 ("i.MX: Add the Freescale SPI Controller")
24
Signed-off-by: Bin Meng <bin.meng@windriver.com>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20210129132323.30946-11-bmeng.cn@gmail.com
5
Message-id: 20190209033847.9014-4-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
28
---
8
target/arm/translate.c | 25 +++++++++++++++++++------
29
hw/ssi/imx_spi.c | 7 ++-----
9
1 file changed, 19 insertions(+), 6 deletions(-)
30
1 file changed, 2 insertions(+), 5 deletions(-)
10
31
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
32
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
12
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
34
--- a/hw/ssi/imx_spi.c
14
+++ b/target/arm/translate.c
35
+++ b/hw/ssi/imx_spi.c
15
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
36
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
16
tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
37
17
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
38
while (!fifo32_is_empty(&s->tx_fifo)) {
18
return 0;
39
int tx_burst = 0;
19
+
40
- int index = 0;
20
+ case NEON_3R_VMAX:
41
21
+ if (u) {
42
if (s->burst_length <= 0) {
22
+ tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
43
s->burst_length = imx_spi_burst_length(s);
23
+ vec_size, vec_size);
44
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
24
+ } else {
45
rx = 0;
25
+ tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
46
26
+ vec_size, vec_size);
47
while (tx_burst > 0) {
27
+ }
48
- uint8_t byte = tx & 0xff;
28
+ return 0;
49
+ uint8_t byte = tx >> (tx_burst - 8);
29
+ case NEON_3R_VMIN:
50
30
+ if (u) {
51
DPRINTF("writing 0x%02x\n", (uint32_t)byte);
31
+ tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
52
32
+ vec_size, vec_size);
53
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
33
+ } else {
54
34
+ tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
55
DPRINTF("0x%02x read\n", (uint32_t)byte);
35
+ vec_size, vec_size);
56
36
+ }
57
- tx = tx >> 8;
37
+ return 0;
58
- rx |= (byte << (index * 8));
59
+ rx = (rx << 8) | byte;
60
61
/* Remove 8 bits from the actual burst */
62
tx_burst -= 8;
63
s->burst_length -= 8;
64
- index++;
38
}
65
}
39
66
40
if (size == 3) {
67
DPRINTF("data rx:0x%08x\n", rx);
41
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
42
case NEON_3R_VQRSHL:
43
GEN_NEON_INTEGER_OP_ENV(qrshl);
44
break;
45
- case NEON_3R_VMAX:
46
- GEN_NEON_INTEGER_OP(max);
47
- break;
48
- case NEON_3R_VMIN:
49
- GEN_NEON_INTEGER_OP(min);
50
- break;
51
case NEON_3R_VABD:
52
GEN_NEON_INTEGER_OP(abd);
53
break;
54
--
68
--
55
2.20.1
69
2.20.1
56
70
57
71
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
These are now unused.
3
Per the ARM Generic Interrupt Controller Architecture specification
4
(document "ARM IHI 0048B.b (ID072613)"), the SGIINTID field is 4 bit,
5
not 10:
4
6
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
- 4.3 Distributor register descriptions
6
Message-id: 20190209033847.9014-6-richard.henderson@linaro.org
8
- 4.3.15 Software Generated Interrupt Register, GICD_SG
9
10
- Table 4-21 GICD_SGIR bit assignments
11
12
The Interrupt ID of the SGI to forward to the specified CPU
13
interfaces. The value of this field is the Interrupt ID, in
14
the range 0-15, for example a value of 0b0011 specifies
15
Interrupt ID 3.
16
17
Correct the irq mask to fix an undefined behavior (which eventually
18
lead to a heap-buffer-overflow, see [Buglink]):
19
20
$ echo 'writel 0x8000f00 0xff4affb0' | qemu-system-aarch64 -M virt,accel=qtest -qtest stdio
21
[I 1612088147.116987] OPENED
22
[R +0.278293] writel 0x8000f00 0xff4affb0
23
../hw/intc/arm_gic.c:1498:13: runtime error: index 944 out of bounds for type 'uint8_t [16][8]'
24
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../hw/intc/arm_gic.c:1498:13
25
26
This fixes a security issue when running with KVM on Arm with
27
kernel-irqchip=off. (The default is kernel-irqchip=on, which is
28
unaffected, and which is also the correct choice for performance.)
29
30
Cc: qemu-stable@nongnu.org
31
Fixes: 9ee6e8bb853 ("ARMv7 support.")
32
Buglink: https://bugs.launchpad.net/qemu/+bug/1913916
33
Buglink: https://bugs.launchpad.net/qemu/+bug/1913917
34
Reported-by: Alexander Bulekov <alxndr@bu.edu>
35
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
36
Message-id: 20210131103401.217160-1-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
37
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
38
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
39
---
10
target/arm/helper.h | 12 ------------
40
hw/intc/arm_gic.c | 2 +-
11
target/arm/neon_helper.c | 12 ------------
41
1 file changed, 1 insertion(+), 1 deletion(-)
12
2 files changed, 24 deletions(-)
13
42
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
43
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
15
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
45
--- a/hw/intc/arm_gic.c
17
+++ b/target/arm/helper.h
46
+++ b/hw/intc/arm_gic.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_cge_s16, i32, i32, i32)
47
@@ -XXX,XX +XXX,XX @@ static void gic_dist_writel(void *opaque, hwaddr offset,
19
DEF_HELPER_2(neon_cge_u32, i32, i32, i32)
48
int target_cpu;
20
DEF_HELPER_2(neon_cge_s32, i32, i32, i32)
49
21
50
cpu = gic_get_current_cpu(s);
22
-DEF_HELPER_2(neon_min_u8, i32, i32, i32)
51
- irq = value & 0x3ff;
23
-DEF_HELPER_2(neon_min_s8, i32, i32, i32)
52
+ irq = value & 0xf;
24
-DEF_HELPER_2(neon_min_u16, i32, i32, i32)
53
switch ((value >> 24) & 3) {
25
-DEF_HELPER_2(neon_min_s16, i32, i32, i32)
54
case 0:
26
-DEF_HELPER_2(neon_min_u32, i32, i32, i32)
55
mask = (value >> 16) & ALL_CPU_MASK;
27
-DEF_HELPER_2(neon_min_s32, i32, i32, i32)
28
-DEF_HELPER_2(neon_max_u8, i32, i32, i32)
29
-DEF_HELPER_2(neon_max_s8, i32, i32, i32)
30
-DEF_HELPER_2(neon_max_u16, i32, i32, i32)
31
-DEF_HELPER_2(neon_max_s16, i32, i32, i32)
32
-DEF_HELPER_2(neon_max_u32, i32, i32, i32)
33
-DEF_HELPER_2(neon_max_s32, i32, i32, i32)
34
DEF_HELPER_2(neon_pmin_u8, i32, i32, i32)
35
DEF_HELPER_2(neon_pmin_s8, i32, i32, i32)
36
DEF_HELPER_2(neon_pmin_u16, i32, i32, i32)
37
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/neon_helper.c
40
+++ b/target/arm/neon_helper.c
41
@@ -XXX,XX +XXX,XX @@ NEON_VOP(cge_u32, neon_u32, 1)
42
#undef NEON_FN
43
44
#define NEON_FN(dest, src1, src2) dest = (src1 < src2) ? src1 : src2
45
-NEON_VOP(min_s8, neon_s8, 4)
46
-NEON_VOP(min_u8, neon_u8, 4)
47
-NEON_VOP(min_s16, neon_s16, 2)
48
-NEON_VOP(min_u16, neon_u16, 2)
49
-NEON_VOP(min_s32, neon_s32, 1)
50
-NEON_VOP(min_u32, neon_u32, 1)
51
NEON_POP(pmin_s8, neon_s8, 4)
52
NEON_POP(pmin_u8, neon_u8, 4)
53
NEON_POP(pmin_s16, neon_s16, 2)
54
@@ -XXX,XX +XXX,XX @@ NEON_POP(pmin_u16, neon_u16, 2)
55
#undef NEON_FN
56
57
#define NEON_FN(dest, src1, src2) dest = (src1 > src2) ? src1 : src2
58
-NEON_VOP(max_s8, neon_s8, 4)
59
-NEON_VOP(max_u8, neon_u8, 4)
60
-NEON_VOP(max_s16, neon_s16, 2)
61
-NEON_VOP(max_u16, neon_u16, 2)
62
-NEON_VOP(max_s32, neon_s32, 1)
63
-NEON_VOP(max_u32, neon_u32, 1)
64
NEON_POP(pmax_s8, neon_s8, 4)
65
NEON_POP(pmax_u8, neon_u8, 4)
66
NEON_POP(pmax_s16, neon_s16, 2)
67
--
56
--
68
2.20.1
57
2.20.1
69
58
70
59
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
There are a whole bunch more registers in the CPUID space which are
3
The STM32F405 SoC uses an OR gate on its ADC IRQs.
4
currently not used but are exposed as RAZ. To avoid too much
5
duplication we expand ARMCPRegUserSpaceInfo to understand glob
6
patterns so we only need one entry to tweak whole ranges of registers.
7
4
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
5
Fixes: 529fc5fd3e1 ("hw/arm: Add the STM32F4xx SoC")
9
Message-id: 20190205190224.2198-5-alex.bennee@linaro.org
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210131184449.382425-2-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/cpu.h | 3 +++
11
hw/arm/Kconfig | 1 +
14
target/arm/helper.c | 26 +++++++++++++++++++++++---
12
1 file changed, 1 insertion(+)
15
2 files changed, 26 insertions(+), 3 deletions(-)
16
13
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
16
--- a/hw/arm/Kconfig
20
+++ b/target/arm/cpu.h
17
+++ b/hw/arm/Kconfig
21
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCPRegUserSpaceInfo {
18
@@ -XXX,XX +XXX,XX @@ config STM32F205_SOC
22
/* Name of register */
19
config STM32F405_SOC
23
const char *name;
20
bool
24
21
select ARM_V7M
25
+ /* Is the name actually a glob pattern */
22
+ select OR_IRQ
26
+ bool is_glob;
23
select STM32F4XX_SYSCFG
27
+
24
select STM32F4XX_EXTI
28
/* Only some bits are exported to user space */
29
uint64_t exported_bits;
30
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
34
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
36
.fixed_bits = 0x0000000000000011 },
37
{ .name = "ID_AA64PFR1_EL1",
38
.exported_bits = 0x00000000000000f0 },
39
+ { .name = "ID_AA64PFR*_EL1_RESERVED",
40
+ .is_glob = true },
41
{ .name = "ID_AA64ZFR0_EL1" },
42
{ .name = "ID_AA64MMFR0_EL1",
43
.fixed_bits = 0x00000000ff000000 },
44
{ .name = "ID_AA64MMFR1_EL1" },
45
+ { .name = "ID_AA64MMFR*_EL1_RESERVED",
46
+ .is_glob = true },
47
{ .name = "ID_AA64DFR0_EL1",
48
.fixed_bits = 0x0000000000000006 },
49
{ .name = "ID_AA64DFR1_EL1" },
50
- { .name = "ID_AA64AFR0_EL1" },
51
- { .name = "ID_AA64AFR1_EL1" },
52
+ { .name = "ID_AA64DFR*_EL1_RESERVED",
53
+ .is_glob = true },
54
+ { .name = "ID_AA64AFR*",
55
+ .is_glob = true },
56
{ .name = "ID_AA64ISAR0_EL1",
57
.exported_bits = 0x00fffffff0fffff0 },
58
{ .name = "ID_AA64ISAR1_EL1",
59
.exported_bits = 0x000000f0ffffffff },
60
+ { .name = "ID_AA64ISAR*_EL1_RESERVED",
61
+ .is_glob = true },
62
REGUSERINFO_SENTINEL
63
};
64
modify_arm_cp_regs(v8_idregs, v8_user_idregs);
65
@@ -XXX,XX +XXX,XX @@ void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
66
ARMCPRegInfo *r;
67
68
for (m = mods; m->name; m++) {
69
+ GPatternSpec *pat = NULL;
70
+ if (m->is_glob) {
71
+ pat = g_pattern_spec_new(m->name);
72
+ }
73
for (r = regs; r->type != ARM_CP_SENTINEL; r++) {
74
- if (strcmp(r->name, m->name) == 0) {
75
+ if (pat && g_pattern_match_string(pat, r->name)) {
76
+ r->type = ARM_CP_CONST;
77
+ r->access = PL0U_R;
78
+ r->resetvalue = 0;
79
+ /* continue */
80
+ } else if (strcmp(r->name, m->name) == 0) {
81
r->type = ARM_CP_CONST;
82
r->access = PL0U_R;
83
r->resetvalue &= m->exported_bits;
84
@@ -XXX,XX +XXX,XX @@ void modify_arm_cp_regs(ARMCPRegInfo *regs, const ARMCPRegUserSpaceInfo *mods)
85
break;
86
}
87
}
88
+ if (pat) {
89
+ g_pattern_spec_free(pat);
90
+ }
91
}
92
}
93
25
94
--
26
--
95
2.20.1
27
2.20.1
96
28
97
29
diff view generated by jsdifflib
1
From: Sandra Loosemore <sandra@codesourcery.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Per the GDB remote protocol documentation
3
The Exynos4210 SoC uses an OR gate on the PL330 IRQ lines.
4
4
5
https://sourceware.org/gdb/current/onlinedocs/gdb/Packets.html#index-vKill-packet
5
Fixes: dab15fbe2ab ("hw/arm/exynos4210: Fix DMA initialization")
6
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
the debug stub is expected to send a reply to the 'vKill' packet. At
7
Message-id: 20210131184449.382425-3-f4bug@amsat.org
8
least some versions of GDB crash if the gdb stub simply exits without
9
sending a reply. This patch fixes QEMU's gdb stub to conform to the
10
expected behavior.
11
12
Note that QEMU's existing handling of the legacy 'k' packet is
13
correct: in that case GDB does not expect a reply, and QEMU does not
14
send one.
15
16
Signed-off-by: Sandra Loosemore <sandra@codesourcery.com>
17
Message-id: 1550008033-26540-1-git-send-email-sandra@codesourcery.com
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
gdbstub.c | 1 +
11
hw/arm/Kconfig | 1 +
22
1 file changed, 1 insertion(+)
12
1 file changed, 1 insertion(+)
23
13
24
diff --git a/gdbstub.c b/gdbstub.c
14
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/gdbstub.c
16
--- a/hw/arm/Kconfig
27
+++ b/gdbstub.c
17
+++ b/hw/arm/Kconfig
28
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
18
@@ -XXX,XX +XXX,XX @@ config EXYNOS4
29
break;
19
select PTIMER
30
} else if (strncmp(p, "Kill;", 5) == 0) {
20
select SDHCI
31
/* Kill the target */
21
select USB_EHCI_SYSBUS
32
+ put_packet(s, "OK");
22
+ select OR_IRQ
33
error_report("QEMU: Terminated via GDBstub");
23
34
exit(0);
24
config HIGHBANK
35
} else {
25
bool
36
--
26
--
37
2.20.1
27
2.20.1
38
28
39
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Rather than a complex set of cases testing for writeback,
3
The Versal SoC instantiates the TYPE_XLNX_ZDMA object in
4
adjust DP after performing the operation.
4
versal_create_admas(). Introduce the XLNX_ZDMA configuration
5
and select it to fix:
5
6
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
$ qemu-system-aarch64 -M xlnx-versal-virt ...
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
qemu-system-aarch64: missing object type 'xlnx.zdma'
8
Message-id: 20190206052857.5077-2-richard.henderson@linaro.org
9
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-id: 20210131184449.382425-4-f4bug@amsat.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/translate.c | 32 ++++++++++++++++----------------
15
hw/arm/Kconfig | 2 ++
12
1 file changed, 16 insertions(+), 16 deletions(-)
16
hw/dma/Kconfig | 3 +++
17
hw/dma/meson.build | 2 +-
18
3 files changed, 6 insertions(+), 1 deletion(-)
13
19
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
22
--- a/hw/arm/Kconfig
17
+++ b/target/arm/translate.c
23
+++ b/hw/arm/Kconfig
18
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
24
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP_ARM
19
tcg_gen_or_i32(tmp, tmp, tmp2);
25
select XILINX_AXI
20
tcg_temp_free_i32(tmp2);
26
select XILINX_SPIPS
21
gen_vfp_msr(tmp);
27
select XLNX_ZYNQMP
22
+ dp = 0; /* always a single precision result */
28
+ select XLNX_ZDMA
23
break;
29
24
}
30
config XLNX_VERSAL
25
case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
31
bool
26
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
32
@@ -XXX,XX +XXX,XX @@ config XLNX_VERSAL
27
tcg_gen_or_i32(tmp, tmp, tmp2);
33
select CADENCE
28
tcg_temp_free_i32(tmp2);
34
select VIRTIO_MMIO
29
gen_vfp_msr(tmp);
35
select UNIMP
30
+ dp = 0; /* always a single precision result */
36
+ select XLNX_ZDMA
31
break;
37
32
}
38
config NPCM7XX
33
case 8: /* cmp */
39
bool
34
gen_vfp_cmp(dp);
40
diff --git a/hw/dma/Kconfig b/hw/dma/Kconfig
35
+ dp = -1; /* no write back */
41
index XXXXXXX..XXXXXXX 100644
36
break;
42
--- a/hw/dma/Kconfig
37
case 9: /* cmpe */
43
+++ b/hw/dma/Kconfig
38
gen_vfp_cmpe(dp);
44
@@ -XXX,XX +XXX,XX @@ config ZYNQ_DEVCFG
39
+ dp = -1; /* no write back */
45
bool
40
break;
46
select REGISTER
41
case 10: /* cmpz */
47
42
gen_vfp_cmp(dp);
48
+config XLNX_ZDMA
43
+ dp = -1; /* no write back */
49
+ bool
44
break;
50
+
45
case 11: /* cmpez */
51
config STP2000
46
gen_vfp_F1_ld0(dp);
52
bool
47
gen_vfp_cmpe(dp);
53
48
+ dp = -1; /* no write back */
54
diff --git a/hw/dma/meson.build b/hw/dma/meson.build
49
break;
55
index XXXXXXX..XXXXXXX 100644
50
case 12: /* vrintr */
56
--- a/hw/dma/meson.build
51
{
57
+++ b/hw/dma/meson.build
52
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
58
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ZYNQ_DEVCFG', if_true: files('xlnx-zynq-devcfg.c'))
53
break;
59
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_dma.c'))
54
}
60
softmmu_ss.add(when: 'CONFIG_STP2000', if_true: files('sparc32_dma.c'))
55
case 15: /* single<->double conversion */
61
softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx_dpdma.c'))
56
- if (dp)
62
-softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zdma.c'))
57
+ if (dp) {
63
+softmmu_ss.add(when: 'CONFIG_XLNX_ZDMA', if_true: files('xlnx-zdma.c'))
58
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
64
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_dma.c', 'soc_dma.c'))
59
- else
65
softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_dma.c'))
60
+ } else {
66
softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c'))
61
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
62
+ }
63
+ dp = !dp; /* result size is opposite */
64
break;
65
case 16: /* fuito */
66
gen_vfp_uito(dp, 0);
67
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
68
break;
69
case 24: /* ftoui */
70
gen_vfp_toui(dp, 0);
71
+ dp = 0; /* always an integer result */
72
break;
73
case 25: /* ftouiz */
74
gen_vfp_touiz(dp, 0);
75
+ dp = 0; /* always an integer result */
76
break;
77
case 26: /* ftosi */
78
gen_vfp_tosi(dp, 0);
79
+ dp = 0; /* always an integer result */
80
break;
81
case 27: /* ftosiz */
82
gen_vfp_tosiz(dp, 0);
83
+ dp = 0; /* always an integer result */
84
break;
85
case 28: /* ftosh */
86
if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
87
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
88
return 1;
89
}
90
91
- /* Write back the result. */
92
- if (op == 15 && (rn >= 8 && rn <= 11)) {
93
- /* Comparison, do nothing. */
94
- } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
95
- (rn & 0x1e) == 0x6)) {
96
- /* VCVT double to int: always integer result.
97
- * VCVT double to half precision is always a single
98
- * precision result.
99
- */
100
- gen_mov_vreg_F0(0, rd);
101
- } else if (op == 15 && rn == 15) {
102
- /* conversion */
103
- gen_mov_vreg_F0(!dp, rd);
104
- } else {
105
+ /* Write back the result, if any. */
106
+ if (dp >= 0) {
107
gen_mov_vreg_F0(dp, rd);
108
}
109
110
--
67
--
111
2.20.1
68
2.20.1
112
69
113
70
diff view generated by jsdifflib
1
From: Catherine Ho <catherine.hecx@gmail.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
The lo,hi order is different from the comments. And in commit
3
The Versal SoC instantiates the TYPE_XLNX_ZYNQMP_RTC object in
4
1ec182c33379 ("target/arm: Convert to HAVE_CMPXCHG128"), it changes
4
versal_create_rtc()(). Select CONFIG_XLNX_ZYNQMP to fix:
5
the original code logic. So just restore the old code logic before this
6
commit:
7
do_paired_cmpxchg64_be():
8
cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
9
newv = int128_make128(new_hi, new_lo);
10
5
11
This fixes a bug that would only be visible for big-endian
6
$ make check-qtest-aarch64
12
AArch64 guest code.
7
...
8
Running test qtest-aarch64/qom-test
9
qemu-system-aarch64: missing object type 'xlnx-zynmp.rtc'
10
Broken pipe
13
11
14
Fixes: 1ec182c33379 ("target/arm: Convert to HAVE_CMPXCHG128")
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Catherine Ho <catherine.hecx@gmail.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210131184449.382425-5-f4bug@amsat.org
17
Message-id: 1548985244-24523-1-git-send-email-catherine.hecx@gmail.com
18
[PMM: added note that bug only affects BE guests]
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
16
---
21
target/arm/helper-a64.c | 4 ++--
17
hw/arm/Kconfig | 1 +
22
1 file changed, 2 insertions(+), 2 deletions(-)
18
1 file changed, 1 insertion(+)
23
19
24
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
20
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper-a64.c
22
--- a/hw/arm/Kconfig
27
+++ b/target/arm/helper-a64.c
23
+++ b/hw/arm/Kconfig
28
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be)(CPUARMState *env, uint64_t addr,
24
@@ -XXX,XX +XXX,XX @@ config XLNX_VERSAL
29
* High and low need to be switched here because this is not actually a
25
select VIRTIO_MMIO
30
* 128bit store but two doublewords stored consecutively
26
select UNIMP
31
*/
27
select XLNX_ZDMA
32
- Int128 cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
28
+ select XLNX_ZYNQMP
33
- Int128 newv = int128_make128(new_lo, new_hi);
29
34
+ Int128 cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
30
config NPCM7XX
35
+ Int128 newv = int128_make128(new_hi, new_lo);
31
bool
36
Int128 oldv;
37
uintptr_t ra = GETPC();
38
uint64_t o0, o1;
39
--
32
--
40
2.20.1
33
2.20.1
41
34
42
35
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Userspace programs should (in theory) query the ELF HWCAP before
3
Add a dependency XLNX_ZYNQMP -> PTIMER to fix:
4
probing these registers. Now we have implemented them all make it
5
public.
6
4
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
5
/usr/bin/ld:
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
libcommon.fa.p/hw_net_can_xlnx-zynqmp-can.c.o: in function `xlnx_zynqmp_can_realize':
9
Message-id: 20190205190224.2198-6-alex.bennee@linaro.org
7
hw/net/can/xlnx-zynqmp-can.c:1082: undefined reference to `ptimer_init'
8
hw/net/can/xlnx-zynqmp-can.c:1085: undefined reference to `ptimer_transaction_begin'
9
hw/net/can/xlnx-zynqmp-can.c:1087: undefined reference to `ptimer_set_freq'
10
hw/net/can/xlnx-zynqmp-can.c:1088: undefined reference to `ptimer_set_limit'
11
hw/net/can/xlnx-zynqmp-can.c:1089: undefined reference to `ptimer_run'
12
hw/net/can/xlnx-zynqmp-can.c:1090: undefined reference to `ptimer_transaction_commit'
13
libcommon.fa.p/hw_net_can_xlnx-zynqmp-can.c.o:(.data.rel+0x2c8): undefined reference to `vmstate_ptimer'
14
15
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-id: 20210131184449.382425-6-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
linux-user/elfload.c | 1 +
20
hw/Kconfig | 1 +
13
1 file changed, 1 insertion(+)
21
1 file changed, 1 insertion(+)
14
22
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
23
diff --git a/hw/Kconfig b/hw/Kconfig
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
25
--- a/hw/Kconfig
18
+++ b/linux-user/elfload.c
26
+++ b/hw/Kconfig
19
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
27
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP
20
28
bool
21
hwcaps |= ARM_HWCAP_A64_FP;
29
select REGISTER
22
hwcaps |= ARM_HWCAP_A64_ASIMD;
30
select CAN_BUS
23
+ hwcaps |= ARM_HWCAP_A64_CPUID;
31
+ select PTIMER
24
25
/* probe for the extra features */
26
#define GET_FEATURE_ID(feat, hwcap) \
27
--
32
--
28
2.20.1
33
2.20.1
29
34
30
35
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Although technically not visible to userspace the kernel does make
3
Most of ARM machines display their CPU when QEMU list the available
4
them visible via a trap and emulate ABI. We provide a new permission
4
machines (-M help). Some machines do not. Fix to unify the help
5
mask (PL0U_R) which maps to PL0_R for CONFIG_USER builds and adjust
5
output.
6
the minimum permission check accordingly.
7
6
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20190205190224.2198-2-alex.bennee@linaro.org
8
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20210131184449.382425-7-f4bug@amsat.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
target/arm/cpu.h | 12 ++++++++++++
14
hw/arm/digic_boards.c | 2 +-
14
target/arm/helper.c | 6 +++++-
15
hw/arm/microbit.c | 2 +-
15
2 files changed, 17 insertions(+), 1 deletion(-)
16
hw/arm/netduino2.c | 2 +-
17
hw/arm/netduinoplus2.c | 2 +-
18
hw/arm/orangepi.c | 2 +-
19
hw/arm/stellaris.c | 4 ++--
20
6 files changed, 7 insertions(+), 7 deletions(-)
16
21
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
18
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
24
--- a/hw/arm/digic_boards.c
20
+++ b/target/arm/cpu.h
25
+++ b/hw/arm/digic_boards.c
21
@@ -XXX,XX +XXX,XX @@ static inline bool cptype_valid(int cptype)
26
@@ -XXX,XX +XXX,XX @@ static void canon_a1100_init(MachineState *machine)
22
#define PL0_R (0x02 | PL1_R)
27
23
#define PL0_W (0x01 | PL1_W)
28
static void canon_a1100_machine_init(MachineClass *mc)
24
29
{
25
+/*
30
- mc->desc = "Canon PowerShot A1100 IS";
26
+ * For user-mode some registers are accessible to EL0 via a kernel
31
+ mc->desc = "Canon PowerShot A1100 IS (ARM946)";
27
+ * trap-and-emulate ABI. In this case we define the read permissions
32
mc->init = &canon_a1100_init;
28
+ * as actually being PL0_R. However some bits of any given register
33
mc->ignore_memory_transaction_failures = true;
29
+ * may still be masked.
34
mc->default_ram_size = 64 * MiB;
30
+ */
35
diff --git a/hw/arm/microbit.c b/hw/arm/microbit.c
31
+#ifdef CONFIG_USER_ONLY
32
+#define PL0U_R PL0_R
33
+#else
34
+#define PL0U_R PL1_R
35
+#endif
36
+
37
#define PL3_RW (PL3_R | PL3_W)
38
#define PL2_RW (PL2_R | PL2_W)
39
#define PL1_RW (PL1_R | PL1_W)
40
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.c
37
--- a/hw/arm/microbit.c
43
+++ b/target/arm/helper.c
38
+++ b/hw/arm/microbit.c
44
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
39
@@ -XXX,XX +XXX,XX @@ static void microbit_machine_class_init(ObjectClass *oc, void *data)
45
if (r->state != ARM_CP_STATE_AA32) {
40
{
46
int mask = 0;
41
MachineClass *mc = MACHINE_CLASS(oc);
47
switch (r->opc1) {
42
48
- case 0: case 1: case 2:
43
- mc->desc = "BBC micro:bit";
49
+ case 0:
44
+ mc->desc = "BBC micro:bit (Cortex-M0)";
50
+ /* min_EL EL1, but some accessible to EL0 via kernel ABI */
45
mc->init = microbit_init;
51
+ mask = PL0U_R | PL1_RW;
46
mc->max_cpus = 1;
52
+ break;
47
}
53
+ case 1: case 2:
48
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
54
/* min_EL EL1 */
49
index XXXXXXX..XXXXXXX 100644
55
mask = PL1_RW;
50
--- a/hw/arm/netduino2.c
56
break;
51
+++ b/hw/arm/netduino2.c
52
@@ -XXX,XX +XXX,XX @@ static void netduino2_init(MachineState *machine)
53
54
static void netduino2_machine_init(MachineClass *mc)
55
{
56
- mc->desc = "Netduino 2 Machine";
57
+ mc->desc = "Netduino 2 Machine (Cortex-M3)";
58
mc->init = netduino2_init;
59
mc->ignore_memory_transaction_failures = true;
60
}
61
diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/netduinoplus2.c
64
+++ b/hw/arm/netduinoplus2.c
65
@@ -XXX,XX +XXX,XX @@ static void netduinoplus2_init(MachineState *machine)
66
67
static void netduinoplus2_machine_init(MachineClass *mc)
68
{
69
- mc->desc = "Netduino Plus 2 Machine";
70
+ mc->desc = "Netduino Plus 2 Machine (Cortex-M4)";
71
mc->init = netduinoplus2_init;
72
}
73
74
diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/arm/orangepi.c
77
+++ b/hw/arm/orangepi.c
78
@@ -XXX,XX +XXX,XX @@ static void orangepi_init(MachineState *machine)
79
80
static void orangepi_machine_init(MachineClass *mc)
81
{
82
- mc->desc = "Orange Pi PC";
83
+ mc->desc = "Orange Pi PC (Cortex-A7)";
84
mc->init = orangepi_init;
85
mc->block_default_type = IF_SD;
86
mc->units_per_default_bus = 1;
87
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/arm/stellaris.c
90
+++ b/hw/arm/stellaris.c
91
@@ -XXX,XX +XXX,XX @@ static void lm3s811evb_class_init(ObjectClass *oc, void *data)
92
{
93
MachineClass *mc = MACHINE_CLASS(oc);
94
95
- mc->desc = "Stellaris LM3S811EVB";
96
+ mc->desc = "Stellaris LM3S811EVB (Cortex-M3)";
97
mc->init = lm3s811evb_init;
98
mc->ignore_memory_transaction_failures = true;
99
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
100
@@ -XXX,XX +XXX,XX @@ static void lm3s6965evb_class_init(ObjectClass *oc, void *data)
101
{
102
MachineClass *mc = MACHINE_CLASS(oc);
103
104
- mc->desc = "Stellaris LM3S6965EVB";
105
+ mc->desc = "Stellaris LM3S6965EVB (Cortex-M3)";
106
mc->init = lm3s6965evb_init;
107
mc->ignore_memory_transaction_failures = true;
108
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
57
--
109
--
58
2.20.1
110
2.20.1
59
111
60
112
diff view generated by jsdifflib
Deleted patch
1
At the moment the Arm implementations of kvm_arch_{get,put}_registers()
2
don't support having QEMU change the values of system registers
3
(aka coprocessor registers for AArch32). This is because although
4
kvm_arch_get_registers() calls write_list_to_cpustate() to
5
update the CPU state struct fields (so QEMU code can read the
6
values in the usual way), kvm_arch_put_registers() does not
7
call write_cpustate_to_list(), meaning that any changes to
8
the CPU state struct fields will not be passed back to KVM.
9
1
10
The rationale for this design is documented in a comment in the
11
AArch32 kvm_arch_put_registers() -- writing the values in the
12
cpregs list into the CPU state struct is "lossy" because the
13
write of a register might not succeed, and so if we blindly
14
copy the CPU state values back again we will incorrectly
15
change register values for the guest. The assumption was that
16
no QEMU code would need to write to the registers.
17
18
However, when we implemented debug support for KVM guests, we
19
broke that assumption: the code to handle "set the guest up
20
to take a breakpoint exception" does so by updating various
21
guest registers including ESR_EL1.
22
23
Support this by making kvm_arch_put_registers() synchronize
24
CPU state back into the list. We sync only those registers
25
where the initial write succeeds, which should be sufficient.
26
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
29
Tested-by: Alex Bennée <alex.bennee@linaro.org>
30
Tested-by: Dongjiu Geng <gengdongjiu@huawei.com>
31
---
32
target/arm/cpu.h | 9 ++++++++-
33
target/arm/helper.c | 27 +++++++++++++++++++++++++--
34
target/arm/kvm32.c | 20 ++------------------
35
target/arm/kvm64.c | 2 ++
36
target/arm/machine.c | 2 +-
37
5 files changed, 38 insertions(+), 22 deletions(-)
38
39
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/cpu.h
42
+++ b/target/arm/cpu.h
43
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu);
44
/**
45
* write_cpustate_to_list:
46
* @cpu: ARMCPU
47
+ * @kvm_sync: true if this is for syncing back to KVM
48
*
49
* For each register listed in the ARMCPU cpreg_indexes list, write
50
* its value from the ARMCPUState structure into the cpreg_values list.
51
* This is used to copy info from TCG's working data structures into
52
* KVM or for outbound migration.
53
*
54
+ * @kvm_sync is true if we are doing this in order to sync the
55
+ * register state back to KVM. In this case we will only update
56
+ * values in the list if the previous list->cpustate sync actually
57
+ * successfully wrote the CPU state. Otherwise we will keep the value
58
+ * that is in the list.
59
+ *
60
* Returns: true if all register values were read correctly,
61
* false if some register was unknown or could not be read.
62
* Note that we do not stop early on failure -- we will attempt
63
* reading all registers in the list.
64
*/
65
-bool write_cpustate_to_list(ARMCPU *cpu);
66
+bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
67
68
#define ARM_CPUID_TI915T 0x54029152
69
#define ARM_CPUID_TI925T 0x54029252
70
diff --git a/target/arm/helper.c b/target/arm/helper.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/helper.c
73
+++ b/target/arm/helper.c
74
@@ -XXX,XX +XXX,XX @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
75
return true;
76
}
77
78
-bool write_cpustate_to_list(ARMCPU *cpu)
79
+bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
80
{
81
/* Write the coprocessor state from cpu->env to the (index,value) list. */
82
int i;
83
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu)
84
for (i = 0; i < cpu->cpreg_array_len; i++) {
85
uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
86
const ARMCPRegInfo *ri;
87
+ uint64_t newval;
88
89
ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
90
if (!ri) {
91
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu)
92
if (ri->type & ARM_CP_NO_RAW) {
93
continue;
94
}
95
- cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri);
96
+
97
+ newval = read_raw_cp_reg(&cpu->env, ri);
98
+ if (kvm_sync) {
99
+ /*
100
+ * Only sync if the previous list->cpustate sync succeeded.
101
+ * Rather than tracking the success/failure state for every
102
+ * item in the list, we just recheck "does the raw write we must
103
+ * have made in write_list_to_cpustate() read back OK" here.
104
+ */
105
+ uint64_t oldval = cpu->cpreg_values[i];
106
+
107
+ if (oldval == newval) {
108
+ continue;
109
+ }
110
+
111
+ write_raw_cp_reg(&cpu->env, ri, oldval);
112
+ if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
113
+ continue;
114
+ }
115
+
116
+ write_raw_cp_reg(&cpu->env, ri, newval);
117
+ }
118
+ cpu->cpreg_values[i] = newval;
119
}
120
return ok;
121
}
122
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/target/arm/kvm32.c
125
+++ b/target/arm/kvm32.c
126
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
127
return ret;
128
}
129
130
- /* Note that we do not call write_cpustate_to_list()
131
- * here, so we are only writing the tuple list back to
132
- * KVM. This is safe because nothing can change the
133
- * CPUARMState cp15 fields (in particular gdb accesses cannot)
134
- * and so there are no changes to sync. In fact syncing would
135
- * be wrong at this point: for a constant register where TCG and
136
- * KVM disagree about its value, the preceding write_list_to_cpustate()
137
- * would not have had any effect on the CPUARMState value (since the
138
- * register is read-only), and a write_cpustate_to_list() here would
139
- * then try to write the TCG value back into KVM -- this would either
140
- * fail or incorrectly change the value the guest sees.
141
- *
142
- * If we ever want to allow the user to modify cp15 registers via
143
- * the gdb stub, we would need to be more clever here (for instance
144
- * tracking the set of registers kvm_arch_get_registers() successfully
145
- * managed to update the CPUARMState with, and only allowing those
146
- * to be written back up into the kernel).
147
- */
148
+ write_cpustate_to_list(cpu, true);
149
+
150
if (!write_list_to_kvmstate(cpu, level)) {
151
return EINVAL;
152
}
153
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/target/arm/kvm64.c
156
+++ b/target/arm/kvm64.c
157
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
158
return ret;
159
}
160
161
+ write_cpustate_to_list(cpu, true);
162
+
163
if (!write_list_to_kvmstate(cpu, level)) {
164
return EINVAL;
165
}
166
diff --git a/target/arm/machine.c b/target/arm/machine.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/target/arm/machine.c
169
+++ b/target/arm/machine.c
170
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
171
abort();
172
}
173
} else {
174
- if (!write_cpustate_to_list(cpu)) {
175
+ if (!write_cpustate_to_list(cpu, false)) {
176
/* This should never fail. */
177
abort();
178
}
179
--
180
2.20.1
181
182
diff view generated by jsdifflib
Deleted patch
1
Peter Crosthwaite hasn't had the bandwidth to do code review or
2
other QEMU work for some time now -- remove his email address
3
from MAINTAINERS file entries so we don't bombard him with
4
patch emails.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190207181422.4907-1-peter.maydell@linaro.org
8
---
9
MAINTAINERS | 4 ----
10
1 file changed, 4 deletions(-)
11
12
diff --git a/MAINTAINERS b/MAINTAINERS
13
index XXXXXXX..XXXXXXX 100644
14
--- a/MAINTAINERS
15
+++ b/MAINTAINERS
16
@@ -XXX,XX +XXX,XX @@ Guest CPU cores (TCG):
17
----------------------
18
Overall
19
L: qemu-devel@nongnu.org
20
-M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
21
M: Richard Henderson <rth@twiddle.net>
22
R: Paolo Bonzini <pbonzini@redhat.com>
23
S: Maintained
24
@@ -XXX,XX +XXX,XX @@ F: tests/virtio-scsi-test.c
25
T: git https://github.com/bonzini/qemu.git scsi-next
26
27
SSI
28
-M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
29
M: Alistair Francis <alistair@alistair23.me>
30
S: Maintained
31
F: hw/ssi/*
32
@@ -XXX,XX +XXX,XX @@ F: tests/m25p80-test.c
33
34
Xilinx SPI
35
M: Alistair Francis <alistair@alistair23.me>
36
-M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
37
S: Maintained
38
F: hw/ssi/xilinx_*
39
40
@@ -XXX,XX +XXX,XX @@ F: qom/cpu.c
41
F: include/qom/cpu.h
42
43
Device Tree
44
-M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
45
M: Alexander Graf <agraf@suse.de>
46
S: Maintained
47
F: device_tree.c
48
--
49
2.20.1
50
51
diff view generated by jsdifflib
Deleted patch
1
The code for handling the NVIC SHPR1 register intends to permit
2
byte and halfword accesses (as the architecture requires). However
3
the 'case' line for it only lists the base address of the
4
register, so attempts to access bytes other than the first one
5
end up in the "bad write" default logic. This bug was added
6
accidentally when we split out the SHPR1 logic from SHPR2 and
7
SHPR3 to support v6M.
8
1
9
Fixes: 7c9140afd594 ("nvic: Handle ARMv6-M SCS reserved registers")
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
---
13
The Zephyr RTOS happens to access SHPR1 byte at a time,
14
which is how I spotted this.
15
---
16
hw/intc/armv7m_nvic.c | 4 ++--
17
1 file changed, 2 insertions(+), 2 deletions(-)
18
19
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/intc/armv7m_nvic.c
22
+++ b/hw/intc/armv7m_nvic.c
23
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
24
}
25
}
26
break;
27
- case 0xd18: /* System Handler Priority (SHPR1) */
28
+ case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
29
if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
30
val = 0;
31
break;
32
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
33
}
34
nvic_irq_update(s);
35
return MEMTX_OK;
36
- case 0xd18: /* System Handler Priority (SHPR1) */
37
+ case 0xd18 ... 0xd1b: /* System Handler Priority (SHPR1) */
38
if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_MAIN)) {
39
return MEMTX_OK;
40
}
41
--
42
2.20.1
43
44
diff view generated by jsdifflib
Deleted patch
1
In commit 91c1e9fcbd7548db368 where we added dual-CPU support to
2
the ARMSSE, we set up the wiring of the expansion IRQs via nested
3
loops: the outer loop on 'i' loops for each CPU, and the inner loop
4
on 'j' loops for each interrupt. Fix a typo which meant we were
5
wiring every expansion IRQ line to external IRQ 0 on CPU 0 and
6
to external IRQ 1 on CPU 1.
7
1
8
Fixes: 91c1e9fcbd7548db368 ("hw/arm/armsse: Support dual-CPU configuration")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
---
12
hw/arm/armsse.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/armsse.c
18
+++ b/hw/arm/armsse.c
19
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
20
/* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
21
s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
22
for (j = 0; j < s->exp_numirq; j++) {
23
- s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, i + 32);
24
+ s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + 32);
25
}
26
if (i == 0) {
27
gpioname = g_strdup("EXP_IRQ");
28
--
29
2.20.1
30
31
diff view generated by jsdifflib