1
ARM queue, various patches accumulated over the Christmas break.
1
Arm queue built up to a point where it seems worth sending:
2
various bug fixes, plus RTH's refactoring in preparation for SVE.
2
3
4
thanks
3
-- PMM
5
-- PMM
6
7
8
The following changes since commit 0f79bfe38a2cf0f43c7ea4959da7f8ebd7858f3d:
4
9
5
The following changes since commit 612061b277915fadd80631eb7a6926f48a110c44:
10
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-2.12-pull-request' into staging (2018-01-25 09:53:53 +0000)
6
7
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-01-10' into staging (2018-01-11 11:52:40 +0000)
8
11
9
are available in the git repository at:
12
are available in the git repository at:
10
13
11
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180111
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180125
12
15
13
for you to fetch changes up to 0cf09852015e47a5fbb974ff7ac320366afd21ee:
16
for you to fetch changes up to 24da047af0e99a83fcc0d50b86c0f2627f7418b3:
14
17
15
hw/intc/arm_gic: reserved register addresses are RAZ/WI (2018-01-11 13:25:40 +0000)
18
pl110: Implement vertical compare/next base interrupts (2018-01-25 11:45:30 +0000)
16
19
17
----------------------------------------------------------------
20
----------------------------------------------------------------
18
target-arm queue:
21
target-arm queue:
19
* add aarch64_be linux-user target
22
* target/arm: Fix address truncation in 64-bit pagetable walks
20
* Virt: ACPI: fix qemu assert due to re-assigned table data address
23
* i.MX: Fix FEC/ENET receive functions
21
* imx_fec: various bug fixes and cleanups
24
* target/arm: preparatory refactoring for SVE emulation
22
* hw/timer/pxa2xx_timer: replace hw_error() -> qemu_log_mask()
25
* hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
23
* hw/sd/pxa2xx_mmci: add read/write() trace events
26
* hw/intc/arm_gic: Fix C_RPR value on idle priority
24
* linux-user/arm/nwfpe: Check coprocessor number for FPA emulation
27
* hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
25
* target/arm: Make disas_thumb2_insn() generate its own UNDEF exceptions
28
* hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
26
* hw/intc/arm_gicv3: Make reserved register addresses RAZ/WI
29
* hw/arm/virt: Check that the CPU realize method succeeded
27
* hw/intc/arm_gic: reserved register addresses are RAZ/WI
30
* sdhci: fix a NULL pointer dereference due to uninitialized AddressSpace object
31
* xilinx_spips: Correct usage of an uninitialized local variable
32
* pl110: Implement vertical compare/next base interrupts
28
33
29
----------------------------------------------------------------
34
----------------------------------------------------------------
30
Andrey Smirnov (11):
35
Ard Biesheuvel (1):
31
imx_fec: Do not link to netdev
36
target/arm: Fix 32-bit address truncation
32
imx_fec: Refactor imx_eth_enable_rx()
33
imx_fec: Change queue flushing heuristics
34
imx_fec: Move Tx frame buffer away from the stack
35
imx_fec: Use ENET_FTRL to determine truncation length
36
imx_fec: Use MIN instead of explicit ternary operator
37
imx_fec: Emulate SHIFT16 in ENETx_RACC
38
imx_fec: Add support for multiple Tx DMA rings
39
imx_fec: Use correct length for packet size
40
imx_fec: Fix a typo in imx_enet_receive()
41
imx_fec: Reserve full FSL_IMX25_FEC_SIZE page for the register file
42
37
43
Michael Weiser (8):
38
Francisco Iglesias (1):
44
linux-user: Add support for big-endian aarch64
39
xilinx_spips: Correct usage of an uninitialized local variable
45
linux-user: Add separate aarch64_be uname
46
linux-user: Fix endianess of aarch64 signal trampoline
47
configure: Add aarch64_be-linux-user target
48
linux-user: Add aarch64_be magic numbers to qemu-binfmt-conf.sh
49
linux-user: Separate binfmt arm CPU families
50
linux-user: Activate armeb handler registration
51
target/arm: Fix stlxp for aarch64_be
52
40
53
Peter Maydell (4):
41
Jean-Christophe Dubois (1):
54
linux-user/arm/nwfpe: Check coprocessor number for FPA emulation
42
i.MX: Fix FEC/ENET receive funtions
55
target/arm: Make disas_thumb2_insn() generate its own UNDEF exceptions
56
hw/intc/arm_gicv3: Make reserved register addresses RAZ/WI
57
hw/intc/arm_gic: reserved register addresses are RAZ/WI
58
43
59
Philippe Mathieu-Daudé (2):
44
Linus Walleij (1):
60
hw/timer/pxa2xx_timer: replace hw_error() -> qemu_log_mask()
45
pl110: Implement vertical compare/next base interrupts
61
hw/sd/pxa2xx_mmci: add read/write() trace events
62
46
63
Zhaoshenglong (1):
47
Luc MICHEL (4):
64
Virt: ACPI: fix qemu assert due to re-assigned table data address
48
hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
49
hw/intc/arm_gic: Fix C_RPR value on idle priority
50
hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
51
hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
65
52
66
configure | 5 +-
53
Peter Maydell (1):
67
include/hw/arm/fsl-imx25.h | 1 -
54
hw/arm/virt: Check that the CPU realize method succeeded
68
include/hw/net/imx_fec.h | 27 +++-
69
linux-user/aarch64/target_syscall.h | 4 +
70
hw/arm/fsl-imx6.c | 1 +
71
hw/arm/virt-acpi-build.c | 18 ++-
72
hw/intc/arm_gic.c | 5 +-
73
hw/intc/arm_gicv3_dist.c | 13 ++
74
hw/intc/arm_gicv3_its_common.c | 8 +-
75
hw/intc/arm_gicv3_redist.c | 13 ++
76
hw/net/imx_fec.c | 210 +++++++++++++++++++++++-------
77
hw/sd/pxa2xx_mmci.c | 78 +++++++----
78
hw/timer/pxa2xx_timer.c | 17 ++-
79
linux-user/arm/nwfpe/fpa11.c | 9 ++
80
linux-user/main.c | 6 +
81
linux-user/signal.c | 10 +-
82
target/arm/helper-a64.c | 7 +-
83
target/arm/translate.c | 23 ++--
84
default-configs/aarch64_be-linux-user.mak | 1 +
85
hw/sd/trace-events | 4 +
86
scripts/qemu-binfmt-conf.sh | 15 ++-
87
21 files changed, 356 insertions(+), 119 deletions(-)
88
create mode 100644 default-configs/aarch64_be-linux-user.mak
89
55
56
Philippe Mathieu-Daudé (1):
57
sdhci: fix a NULL pointer dereference due to uninitialized AddresSpace object
58
59
Richard Henderson (11):
60
target/arm: Mark disas_set_insn_syndrome inline
61
target/arm: Use pointers in crypto helpers
62
target/arm: Use pointers in neon zip/uzp helpers
63
target/arm: Use pointers in neon tbl helper
64
target/arm: Change the type of vfp.regs
65
target/arm: Add aa{32, 64}_vfp_{dreg, qreg} helpers
66
vmstate: Add VMSTATE_UINT64_SUB_ARRAY
67
target/arm: Add ARM_FEATURE_SVE
68
target/arm: Move cpu_get_tb_cpu_state out of line
69
target/arm: Hoist store to flags output in cpu_get_tb_cpu_state
70
target/arm: Simplify fp_exception_el for user-only
71
72
include/hw/sd/sdhci.h | 1 +
73
include/migration/vmstate.h | 9 ++-
74
target/arm/cpu.h | 157 ++++++++-----------------------------
75
target/arm/helper.h | 46 +++++------
76
target/arm/translate.h | 2 +-
77
hw/arm/virt.c | 2 +-
78
hw/display/pl110.c | 30 +++++++-
79
hw/intc/arm_gic.c | 25 +++++-
80
hw/net/imx_fec.c | 8 +-
81
hw/sd/sdhci.c | 1 +
82
hw/ssi/xilinx_spips.c | 18 ++++-
83
linux-user/signal.c | 22 +++---
84
target/arm/arch_dump.c | 8 +-
85
target/arm/crypto_helper.c | 184 +++++++++++++++++---------------------------
86
target/arm/helper-a64.c | 5 +-
87
target/arm/helper.c | 164 +++++++++++++++++++++++++++++++++++----
88
target/arm/kvm32.c | 4 +-
89
target/arm/kvm64.c | 31 +++-----
90
target/arm/machine.c | 2 +-
91
target/arm/neon_helper.c | 162 ++++++++++++++++++++------------------
92
target/arm/op_helper.c | 17 ++--
93
target/arm/translate-a64.c | 100 ++++++++++++------------
94
target/arm/translate.c | 134 +++++++++++++++++---------------
95
23 files changed, 607 insertions(+), 525 deletions(-)
96
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
Enable big-endian mode for data accesses on aarch64 for big-endian linux
4
user mode. Activate it for all exception levels as documented by ARM:
5
Set the SCTLR EE bit for ELs 1 through 3. Additionally set bit E0E in
6
EL1 to enable it in EL0 as well.
7
8
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20171220212308.12614-2-michael.weiser@gmx.de
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
linux-user/main.c | 6 ++++++
14
1 file changed, 6 insertions(+)
15
16
diff --git a/linux-user/main.c b/linux-user/main.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/linux-user/main.c
19
+++ b/linux-user/main.c
20
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
21
}
22
env->pc = regs->pc;
23
env->xregs[31] = regs->sp;
24
+#ifdef TARGET_WORDS_BIGENDIAN
25
+ env->cp15.sctlr_el[1] |= SCTLR_E0E;
26
+ for (i = 1; i < 4; ++i) {
27
+ env->cp15.sctlr_el[i] |= SCTLR_EE;
28
+ }
29
+#endif
30
}
31
#elif defined(TARGET_ARM)
32
{
33
--
34
2.7.4
35
36
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2
2
3
Cc: Peter Maydell <peter.maydell@linaro.org>
3
Commit ("3b39d734141a target/arm: Handle page table walk load failures
4
Cc: Jason Wang <jasowang@redhat.com>
4
correctly") modified both versions of the page table walking code (i.e.,
5
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
arm_ldl_ptw and arm_ldq_ptw) to record the result of the translation in
6
Cc: qemu-devel@nongnu.org
6
a temporary 'data' variable so that it can be inspected before being
7
Cc: qemu-arm@nongnu.org
7
returned. However, arm_ldq_ptw() returns an uint64_t, and using a
8
Cc: yurovsky@gmail.com
8
temporary uint32_t variable truncates the upper bits, corrupting the
9
result. This causes problems when using more than 4 GB of memory in
10
a TCG guest. So use a uint64_t instead.
11
12
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
13
Message-id: 20180119194648.25501-1-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
16
---
13
hw/net/imx_fec.c | 2 +-
17
target/arm/helper.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
18
1 file changed, 1 insertion(+), 1 deletion(-)
15
19
16
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/imx_fec.c
22
--- a/target/arm/helper.c
19
+++ b/hw/net/imx_fec.c
23
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
24
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
21
size += 2;
25
MemTxAttrs attrs = {};
22
}
26
MemTxResult result = MEMTX_OK;
23
27
AddressSpace *as;
24
- /* Huge frames are truncted. */
28
- uint32_t data;
25
+ /* Huge frames are truncated. */
29
+ uint64_t data;
26
if (size > s->regs[ENET_FTRL]) {
30
27
size = s->regs[ENET_FTRL];
31
attrs.secure = is_secure;
28
flags |= ENET_BD_TR | ENET_BD_LG;
32
as = arm_addressspace(cs, attrs);
29
--
33
--
30
2.7.4
34
2.7.4
31
35
32
36
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
Refactor imx_eth_enable_rx() to have more meaningfull variable name
3
The actual imx_eth_enable_rx() function is buggy.
4
than 'tmp' and to reduce number of logical negations done.
5
4
6
Cc: Peter Maydell <peter.maydell@linaro.org>
5
It updates s->regs[ENET_RDAR] after calling qemu_flush_queued_packets().
7
Cc: Jason Wang <jasowang@redhat.com>
6
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
qemu_flush_queued_packets() is going to call imx_XXX_receive() which itself
9
Cc: qemu-devel@nongnu.org
8
is going to call imx_eth_enable_rx().
10
Cc: qemu-arm@nongnu.org
9
11
Cc: yurovsky@gmail.com
10
By updating s->regs[ENET_RDAR] after calling qemu_flush_queued_packets()
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
we end up updating the register with an outdated value which might
12
lead to disabling the receive function in the i.MX FEC/ENET device.
13
14
This patch change the place where the register update is done so that the
15
register value stays up to date and the receive function can keep
16
running.
17
18
Reported-by: Fyleo <fyleo45@gmail.com>
19
Tested-by: Fyleo <fyleo45@gmail.com>
20
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
21
Message-id: 20180113113445.2705-1-jcd@tribudubois.net
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
23
Reviewed-by: Andrey Smirnov <andrew.smirnov@gmail.com>
24
Tested-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
26
---
17
hw/net/imx_fec.c | 8 ++++----
27
hw/net/imx_fec.c | 8 ++------
18
1 file changed, 4 insertions(+), 4 deletions(-)
28
1 file changed, 2 insertions(+), 6 deletions(-)
19
29
20
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
30
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
21
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/net/imx_fec.c
32
--- a/hw/net/imx_fec.c
23
+++ b/hw/net/imx_fec.c
33
+++ b/hw/net/imx_fec.c
24
@@ -XXX,XX +XXX,XX @@ static void imx_eth_do_tx(IMXFECState *s)
34
@@ -XXX,XX +XXX,XX @@ static void imx_eth_do_tx(IMXFECState *s, uint32_t index)
25
static void imx_eth_enable_rx(IMXFECState *s)
35
static void imx_eth_enable_rx(IMXFECState *s, bool flush)
26
{
36
{
27
IMXFECBufDesc bd;
37
IMXFECBufDesc bd;
28
- bool tmp;
38
- bool rx_ring_full;
29
+ bool rx_ring_full;
30
39
31
imx_fec_read_bd(&bd, s->rx_descriptor);
40
imx_fec_read_bd(&bd, s->rx_descriptor);
32
41
33
- tmp = ((bd.flags & ENET_BD_E) != 0);
42
- rx_ring_full = !(bd.flags & ENET_BD_E);
34
+ rx_ring_full = !(bd.flags & ENET_BD_E);
43
+ s->regs[ENET_RDAR] = (bd.flags & ENET_BD_E) ? ENET_RDAR_RDAR : 0;
35
44
36
- if (!tmp) {
45
- if (rx_ring_full) {
37
+ if (rx_ring_full) {
46
+ if (!s->regs[ENET_RDAR]) {
38
FEC_PRINTF("RX buffer full\n");
47
FEC_PRINTF("RX buffer full\n");
39
} else if (!s->regs[ENET_RDAR]) {
48
} else if (flush) {
40
qemu_flush_queued_packets(qemu_get_queue(s->nic));
49
qemu_flush_queued_packets(qemu_get_queue(s->nic));
41
}
50
}
42
51
-
43
- s->regs[ENET_RDAR] = tmp ? ENET_RDAR_RDAR : 0;
52
- s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
44
+ s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
45
}
53
}
46
54
47
static void imx_eth_reset(DeviceState *d)
55
static void imx_eth_reset(DeviceState *d)
56
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
57
case ENET_RDAR:
58
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
59
if (!s->regs[index]) {
60
- s->regs[index] = ENET_RDAR_RDAR;
61
imx_eth_enable_rx(s, true);
62
}
63
} else {
48
--
64
--
49
2.7.4
65
2.7.4
50
66
51
67
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use 'frame_size' instead of 'len' when calling qemu_send_packet(),
3
If it isn't used when translate.h is included,
4
failing to do so results in malformed packets send in case when that
4
we'll get a compiler Werror.
5
packed is fragmented into multiple DMA transactions.
6
5
7
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Cc: Jason Wang <jasowang@redhat.com>
9
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20180119045438.28582-2-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
12
---
17
hw/net/imx_fec.c | 2 +-
13
target/arm/translate.h | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
19
15
20
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
16
diff --git a/target/arm/translate.h b/target/arm/translate.h
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/net/imx_fec.c
18
--- a/target/arm/translate.h
23
+++ b/hw/net/imx_fec.c
19
+++ b/target/arm/translate.h
24
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
20
@@ -XXX,XX +XXX,XX @@ static inline int default_exception_el(DisasContext *s)
25
}
21
? 3 : MAX(1, s->current_el);
26
/* Last buffer in frame. */
22
}
27
23
28
- qemu_send_packet(qemu_get_queue(s->nic), s->frame, len);
24
-static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
29
+ qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
25
+static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
30
ptr = s->frame;
26
{
31
27
/* We don't need to save all of the syndrome so we mask and shift
32
frame_size = 0;
28
* out unneeded bits to help the sleb128 encoder do a better job.
33
--
29
--
34
2.7.4
30
2.7.4
35
31
36
32
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
ldxp loads two consecutive doublewords from memory regardless of CPU
3
Rather than passing regnos to the helpers, pass pointers to the
4
endianness. On store, stlxp currently assumes to work with a 128bit
4
vector registers directly. This eliminates the need to pass in
5
value and consequently switches order in big-endian mode. With this
5
the environment pointer and reduces the number of places that
6
change it packs the doublewords in reverse order in anticipation of the
6
directly access env->vfp.regs[].
7
128bit big-endian store operation interposing them so they end up in
8
memory in the right order. This makes it work for both MTTCG and !MTTCG.
9
It effectively implements the ARM ARM STLXP operation pseudo-code:
10
7
11
data = if BigEndian() then el1:el2 else el2:el1;
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
With this change an aarch64_be Linux 4.14.4 kernel succeeds to boot up
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
in system emulation mode.
11
Message-id: 20180119045438.28582-3-richard.henderson@linaro.org
15
16
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
13
---
20
target/arm/helper-a64.c | 7 +++++--
14
target/arm/helper.h | 18 ++---
21
1 file changed, 5 insertions(+), 2 deletions(-)
15
target/arm/crypto_helper.c | 184 +++++++++++++++++----------------------------
16
target/arm/translate-a64.c | 75 ++++++++++--------
17
target/arm/translate.c | 68 +++++++++--------
18
4 files changed, 161 insertions(+), 184 deletions(-)
22
19
23
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
24
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-a64.c
22
--- a/target/arm/helper.h
26
+++ b/target/arm/helper-a64.c
23
+++ b/target/arm/helper.h
27
@@ -XXX,XX +XXX,XX @@ static uint64_t do_paired_cmpxchg64_be(CPUARMState *env, uint64_t addr,
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(neon_qzip8, void, env, i32, i32)
28
Int128 oldv, cmpv, newv;
25
DEF_HELPER_3(neon_qzip16, void, env, i32, i32)
29
bool success;
26
DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
30
27
31
- cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
28
-DEF_HELPER_4(crypto_aese, void, env, i32, i32, i32)
32
- newv = int128_make128(new_lo, new_hi);
29
-DEF_HELPER_4(crypto_aesmc, void, env, i32, i32, i32)
33
+ /* high and low need to be switched here because this is not actually a
30
+DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
34
+ * 128bit store but two doublewords stored consecutively
31
+DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
35
+ */
32
36
+ cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
33
-DEF_HELPER_5(crypto_sha1_3reg, void, env, i32, i32, i32, i32)
37
+ newv = int128_make128(new_hi, new_lo);
34
-DEF_HELPER_3(crypto_sha1h, void, env, i32, i32)
38
35
-DEF_HELPER_3(crypto_sha1su1, void, env, i32, i32)
39
if (parallel) {
36
+DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
40
#ifndef CONFIG_ATOMIC128
37
+DEF_HELPER_FLAGS_2(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr)
38
+DEF_HELPER_FLAGS_2(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr)
39
40
-DEF_HELPER_4(crypto_sha256h, void, env, i32, i32, i32)
41
-DEF_HELPER_4(crypto_sha256h2, void, env, i32, i32, i32)
42
-DEF_HELPER_3(crypto_sha256su0, void, env, i32, i32)
43
-DEF_HELPER_4(crypto_sha256su1, void, env, i32, i32, i32)
44
+DEF_HELPER_FLAGS_3(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
45
+DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
46
+DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr)
47
+DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
48
49
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
50
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
51
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/crypto_helper.c
54
+++ b/target/arm/crypto_helper.c
55
@@ -XXX,XX +XXX,XX @@ union CRYPTO_STATE {
56
#define CR_ST_WORD(state, i) (state.words[i])
57
#endif
58
59
-void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
60
- uint32_t decrypt)
61
+void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt)
62
{
63
static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
64
static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
65
-
66
- union CRYPTO_STATE rk = { .l = {
67
- float64_val(env->vfp.regs[rm]),
68
- float64_val(env->vfp.regs[rm + 1])
69
- } };
70
- union CRYPTO_STATE st = { .l = {
71
- float64_val(env->vfp.regs[rd]),
72
- float64_val(env->vfp.regs[rd + 1])
73
- } };
74
+ uint64_t *rd = vd;
75
+ uint64_t *rm = vm;
76
+ union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } };
77
+ union CRYPTO_STATE st = { .l = { rd[0], rd[1] } };
78
int i;
79
80
assert(decrypt < 2);
81
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
82
CR_ST_BYTE(st, i) = sbox[decrypt][CR_ST_BYTE(rk, shift[decrypt][i])];
83
}
84
85
- env->vfp.regs[rd] = make_float64(st.l[0]);
86
- env->vfp.regs[rd + 1] = make_float64(st.l[1]);
87
+ rd[0] = st.l[0];
88
+ rd[1] = st.l[1];
89
}
90
91
-void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
92
- uint32_t decrypt)
93
+void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
94
{
95
static uint32_t const mc[][256] = { {
96
/* MixColumns lookup table */
97
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
98
0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5,
99
0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
100
} };
101
- union CRYPTO_STATE st = { .l = {
102
- float64_val(env->vfp.regs[rm]),
103
- float64_val(env->vfp.regs[rm + 1])
104
- } };
105
+
106
+ uint64_t *rd = vd;
107
+ uint64_t *rm = vm;
108
+ union CRYPTO_STATE st = { .l = { rm[0], rm[1] } };
109
int i;
110
111
assert(decrypt < 2);
112
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
113
rol32(mc[decrypt][CR_ST_BYTE(st, i + 3)], 24);
114
}
115
116
- env->vfp.regs[rd] = make_float64(st.l[0]);
117
- env->vfp.regs[rd + 1] = make_float64(st.l[1]);
118
+ rd[0] = st.l[0];
119
+ rd[1] = st.l[1];
120
}
121
122
/*
123
@@ -XXX,XX +XXX,XX @@ static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
124
return (x & y) | ((x | y) & z);
125
}
126
127
-void HELPER(crypto_sha1_3reg)(CPUARMState *env, uint32_t rd, uint32_t rn,
128
- uint32_t rm, uint32_t op)
129
+void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, uint32_t op)
130
{
131
- union CRYPTO_STATE d = { .l = {
132
- float64_val(env->vfp.regs[rd]),
133
- float64_val(env->vfp.regs[rd + 1])
134
- } };
135
- union CRYPTO_STATE n = { .l = {
136
- float64_val(env->vfp.regs[rn]),
137
- float64_val(env->vfp.regs[rn + 1])
138
- } };
139
- union CRYPTO_STATE m = { .l = {
140
- float64_val(env->vfp.regs[rm]),
141
- float64_val(env->vfp.regs[rm + 1])
142
- } };
143
+ uint64_t *rd = vd;
144
+ uint64_t *rn = vn;
145
+ uint64_t *rm = vm;
146
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
147
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
148
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
149
150
if (op == 3) { /* sha1su0 */
151
d.l[0] ^= d.l[1] ^ m.l[0];
152
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha1_3reg)(CPUARMState *env, uint32_t rd, uint32_t rn,
153
CR_ST_WORD(d, 0) = t;
154
}
155
}
156
- env->vfp.regs[rd] = make_float64(d.l[0]);
157
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
158
+ rd[0] = d.l[0];
159
+ rd[1] = d.l[1];
160
}
161
162
-void HELPER(crypto_sha1h)(CPUARMState *env, uint32_t rd, uint32_t rm)
163
+void HELPER(crypto_sha1h)(void *vd, void *vm)
164
{
165
- union CRYPTO_STATE m = { .l = {
166
- float64_val(env->vfp.regs[rm]),
167
- float64_val(env->vfp.regs[rm + 1])
168
- } };
169
+ uint64_t *rd = vd;
170
+ uint64_t *rm = vm;
171
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
172
173
CR_ST_WORD(m, 0) = ror32(CR_ST_WORD(m, 0), 2);
174
CR_ST_WORD(m, 1) = CR_ST_WORD(m, 2) = CR_ST_WORD(m, 3) = 0;
175
176
- env->vfp.regs[rd] = make_float64(m.l[0]);
177
- env->vfp.regs[rd + 1] = make_float64(m.l[1]);
178
+ rd[0] = m.l[0];
179
+ rd[1] = m.l[1];
180
}
181
182
-void HELPER(crypto_sha1su1)(CPUARMState *env, uint32_t rd, uint32_t rm)
183
+void HELPER(crypto_sha1su1)(void *vd, void *vm)
184
{
185
- union CRYPTO_STATE d = { .l = {
186
- float64_val(env->vfp.regs[rd]),
187
- float64_val(env->vfp.regs[rd + 1])
188
- } };
189
- union CRYPTO_STATE m = { .l = {
190
- float64_val(env->vfp.regs[rm]),
191
- float64_val(env->vfp.regs[rm + 1])
192
- } };
193
+ uint64_t *rd = vd;
194
+ uint64_t *rm = vm;
195
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
196
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
197
198
CR_ST_WORD(d, 0) = rol32(CR_ST_WORD(d, 0) ^ CR_ST_WORD(m, 1), 1);
199
CR_ST_WORD(d, 1) = rol32(CR_ST_WORD(d, 1) ^ CR_ST_WORD(m, 2), 1);
200
CR_ST_WORD(d, 2) = rol32(CR_ST_WORD(d, 2) ^ CR_ST_WORD(m, 3), 1);
201
CR_ST_WORD(d, 3) = rol32(CR_ST_WORD(d, 3) ^ CR_ST_WORD(d, 0), 1);
202
203
- env->vfp.regs[rd] = make_float64(d.l[0]);
204
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
205
+ rd[0] = d.l[0];
206
+ rd[1] = d.l[1];
207
}
208
209
/*
210
@@ -XXX,XX +XXX,XX @@ static uint32_t s1(uint32_t x)
211
return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
212
}
213
214
-void HELPER(crypto_sha256h)(CPUARMState *env, uint32_t rd, uint32_t rn,
215
- uint32_t rm)
216
+void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm)
217
{
218
- union CRYPTO_STATE d = { .l = {
219
- float64_val(env->vfp.regs[rd]),
220
- float64_val(env->vfp.regs[rd + 1])
221
- } };
222
- union CRYPTO_STATE n = { .l = {
223
- float64_val(env->vfp.regs[rn]),
224
- float64_val(env->vfp.regs[rn + 1])
225
- } };
226
- union CRYPTO_STATE m = { .l = {
227
- float64_val(env->vfp.regs[rm]),
228
- float64_val(env->vfp.regs[rm + 1])
229
- } };
230
+ uint64_t *rd = vd;
231
+ uint64_t *rn = vn;
232
+ uint64_t *rm = vm;
233
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
234
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
235
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
236
int i;
237
238
for (i = 0; i < 4; i++) {
239
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256h)(CPUARMState *env, uint32_t rd, uint32_t rn,
240
CR_ST_WORD(d, 0) = t;
241
}
242
243
- env->vfp.regs[rd] = make_float64(d.l[0]);
244
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
245
+ rd[0] = d.l[0];
246
+ rd[1] = d.l[1];
247
}
248
249
-void HELPER(crypto_sha256h2)(CPUARMState *env, uint32_t rd, uint32_t rn,
250
- uint32_t rm)
251
+void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm)
252
{
253
- union CRYPTO_STATE d = { .l = {
254
- float64_val(env->vfp.regs[rd]),
255
- float64_val(env->vfp.regs[rd + 1])
256
- } };
257
- union CRYPTO_STATE n = { .l = {
258
- float64_val(env->vfp.regs[rn]),
259
- float64_val(env->vfp.regs[rn + 1])
260
- } };
261
- union CRYPTO_STATE m = { .l = {
262
- float64_val(env->vfp.regs[rm]),
263
- float64_val(env->vfp.regs[rm + 1])
264
- } };
265
+ uint64_t *rd = vd;
266
+ uint64_t *rn = vn;
267
+ uint64_t *rm = vm;
268
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
269
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
270
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
271
int i;
272
273
for (i = 0; i < 4; i++) {
274
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256h2)(CPUARMState *env, uint32_t rd, uint32_t rn,
275
CR_ST_WORD(d, 0) = CR_ST_WORD(n, 3 - i) + t;
276
}
277
278
- env->vfp.regs[rd] = make_float64(d.l[0]);
279
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
280
+ rd[0] = d.l[0];
281
+ rd[1] = d.l[1];
282
}
283
284
-void HELPER(crypto_sha256su0)(CPUARMState *env, uint32_t rd, uint32_t rm)
285
+void HELPER(crypto_sha256su0)(void *vd, void *vm)
286
{
287
- union CRYPTO_STATE d = { .l = {
288
- float64_val(env->vfp.regs[rd]),
289
- float64_val(env->vfp.regs[rd + 1])
290
- } };
291
- union CRYPTO_STATE m = { .l = {
292
- float64_val(env->vfp.regs[rm]),
293
- float64_val(env->vfp.regs[rm + 1])
294
- } };
295
+ uint64_t *rd = vd;
296
+ uint64_t *rm = vm;
297
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
298
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
299
300
CR_ST_WORD(d, 0) += s0(CR_ST_WORD(d, 1));
301
CR_ST_WORD(d, 1) += s0(CR_ST_WORD(d, 2));
302
CR_ST_WORD(d, 2) += s0(CR_ST_WORD(d, 3));
303
CR_ST_WORD(d, 3) += s0(CR_ST_WORD(m, 0));
304
305
- env->vfp.regs[rd] = make_float64(d.l[0]);
306
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
307
+ rd[0] = d.l[0];
308
+ rd[1] = d.l[1];
309
}
310
311
-void HELPER(crypto_sha256su1)(CPUARMState *env, uint32_t rd, uint32_t rn,
312
- uint32_t rm)
313
+void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
314
{
315
- union CRYPTO_STATE d = { .l = {
316
- float64_val(env->vfp.regs[rd]),
317
- float64_val(env->vfp.regs[rd + 1])
318
- } };
319
- union CRYPTO_STATE n = { .l = {
320
- float64_val(env->vfp.regs[rn]),
321
- float64_val(env->vfp.regs[rn + 1])
322
- } };
323
- union CRYPTO_STATE m = { .l = {
324
- float64_val(env->vfp.regs[rm]),
325
- float64_val(env->vfp.regs[rm + 1])
326
- } };
327
+ uint64_t *rd = vd;
328
+ uint64_t *rn = vn;
329
+ uint64_t *rm = vm;
330
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
331
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
332
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
333
334
CR_ST_WORD(d, 0) += s1(CR_ST_WORD(m, 2)) + CR_ST_WORD(n, 1);
335
CR_ST_WORD(d, 1) += s1(CR_ST_WORD(m, 3)) + CR_ST_WORD(n, 2);
336
CR_ST_WORD(d, 2) += s1(CR_ST_WORD(d, 0)) + CR_ST_WORD(n, 3);
337
CR_ST_WORD(d, 3) += s1(CR_ST_WORD(d, 1)) + CR_ST_WORD(m, 0);
338
339
- env->vfp.regs[rd] = make_float64(d.l[0]);
340
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
341
+ rd[0] = d.l[0];
342
+ rd[1] = d.l[1];
343
}
344
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
345
index XXXXXXX..XXXXXXX 100644
346
--- a/target/arm/translate-a64.c
347
+++ b/target/arm/translate-a64.c
348
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
349
typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
350
typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
351
typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
352
-typedef void CryptoTwoOpEnvFn(TCGv_ptr, TCGv_i32, TCGv_i32);
353
-typedef void CryptoThreeOpEnvFn(TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32);
354
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
355
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
356
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
357
358
/* initialize TCG globals. */
359
void a64_translate_init(void)
360
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
361
return offs;
362
}
363
364
+/* Return the offset info CPUARMState of the "whole" vector register Qn. */
365
+static inline int vec_full_reg_offset(DisasContext *s, int regno)
366
+{
367
+ assert_fp_access_checked(s);
368
+ return offsetof(CPUARMState, vfp.regs[regno * 2]);
369
+}
370
+
371
+/* Return a newly allocated pointer to the vector register. */
372
+static TCGv_ptr vec_full_reg_ptr(DisasContext *s, int regno)
373
+{
374
+ TCGv_ptr ret = tcg_temp_new_ptr();
375
+ tcg_gen_addi_ptr(ret, cpu_env, vec_full_reg_offset(s, regno));
376
+ return ret;
377
+}
378
+
379
/* Return the offset into CPUARMState of a slice (from
380
* the least significant end) of FP register Qn (ie
381
* Dn, Sn, Hn or Bn).
382
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
383
int rn = extract32(insn, 5, 5);
384
int rd = extract32(insn, 0, 5);
385
int decrypt;
386
- TCGv_i32 tcg_rd_regno, tcg_rn_regno, tcg_decrypt;
387
- CryptoThreeOpEnvFn *genfn;
388
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
389
+ TCGv_i32 tcg_decrypt;
390
+ CryptoThreeOpIntFn *genfn;
391
392
if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
393
|| size != 0) {
394
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
395
return;
396
}
397
398
- /* Note that we convert the Vx register indexes into the
399
- * index within the vfp.regs[] array, so we can share the
400
- * helper with the AArch32 instructions.
401
- */
402
- tcg_rd_regno = tcg_const_i32(rd << 1);
403
- tcg_rn_regno = tcg_const_i32(rn << 1);
404
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
405
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
406
tcg_decrypt = tcg_const_i32(decrypt);
407
408
- genfn(cpu_env, tcg_rd_regno, tcg_rn_regno, tcg_decrypt);
409
+ genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_decrypt);
410
411
- tcg_temp_free_i32(tcg_rd_regno);
412
- tcg_temp_free_i32(tcg_rn_regno);
413
+ tcg_temp_free_ptr(tcg_rd_ptr);
414
+ tcg_temp_free_ptr(tcg_rn_ptr);
415
tcg_temp_free_i32(tcg_decrypt);
416
}
417
418
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
419
int rm = extract32(insn, 16, 5);
420
int rn = extract32(insn, 5, 5);
421
int rd = extract32(insn, 0, 5);
422
- CryptoThreeOpEnvFn *genfn;
423
- TCGv_i32 tcg_rd_regno, tcg_rn_regno, tcg_rm_regno;
424
+ CryptoThreeOpFn *genfn;
425
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
426
int feature = ARM_FEATURE_V8_SHA256;
427
428
if (size != 0) {
429
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
430
return;
431
}
432
433
- tcg_rd_regno = tcg_const_i32(rd << 1);
434
- tcg_rn_regno = tcg_const_i32(rn << 1);
435
- tcg_rm_regno = tcg_const_i32(rm << 1);
436
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
437
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
438
+ tcg_rm_ptr = vec_full_reg_ptr(s, rm);
439
440
if (genfn) {
441
- genfn(cpu_env, tcg_rd_regno, tcg_rn_regno, tcg_rm_regno);
442
+ genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr);
443
} else {
444
TCGv_i32 tcg_opcode = tcg_const_i32(opcode);
445
446
- gen_helper_crypto_sha1_3reg(cpu_env, tcg_rd_regno,
447
- tcg_rn_regno, tcg_rm_regno, tcg_opcode);
448
+ gen_helper_crypto_sha1_3reg(tcg_rd_ptr, tcg_rn_ptr,
449
+ tcg_rm_ptr, tcg_opcode);
450
tcg_temp_free_i32(tcg_opcode);
451
}
452
453
- tcg_temp_free_i32(tcg_rd_regno);
454
- tcg_temp_free_i32(tcg_rn_regno);
455
- tcg_temp_free_i32(tcg_rm_regno);
456
+ tcg_temp_free_ptr(tcg_rd_ptr);
457
+ tcg_temp_free_ptr(tcg_rn_ptr);
458
+ tcg_temp_free_ptr(tcg_rm_ptr);
459
}
460
461
/* Crypto two-reg SHA
462
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
463
int opcode = extract32(insn, 12, 5);
464
int rn = extract32(insn, 5, 5);
465
int rd = extract32(insn, 0, 5);
466
- CryptoTwoOpEnvFn *genfn;
467
+ CryptoTwoOpFn *genfn;
468
int feature;
469
- TCGv_i32 tcg_rd_regno, tcg_rn_regno;
470
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
471
472
if (size != 0) {
473
unallocated_encoding(s);
474
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
475
return;
476
}
477
478
- tcg_rd_regno = tcg_const_i32(rd << 1);
479
- tcg_rn_regno = tcg_const_i32(rn << 1);
480
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
481
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
482
483
- genfn(cpu_env, tcg_rd_regno, tcg_rn_regno);
484
+ genfn(tcg_rd_ptr, tcg_rn_ptr);
485
486
- tcg_temp_free_i32(tcg_rd_regno);
487
- tcg_temp_free_i32(tcg_rn_regno);
488
+ tcg_temp_free_ptr(tcg_rd_ptr);
489
+ tcg_temp_free_ptr(tcg_rn_ptr);
490
}
491
492
/* C3.6 Data processing - SIMD, inc Crypto
493
diff --git a/target/arm/translate.c b/target/arm/translate.c
494
index XXXXXXX..XXXXXXX 100644
495
--- a/target/arm/translate.c
496
+++ b/target/arm/translate.c
497
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg64(TCGv_i64 var, int reg)
498
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
499
}
500
501
+static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
502
+{
503
+ TCGv_ptr ret = tcg_temp_new_ptr();
504
+ tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
505
+ return ret;
506
+}
507
+
508
#define tcg_gen_ld_f32 tcg_gen_ld_i32
509
#define tcg_gen_ld_f64 tcg_gen_ld_i64
510
#define tcg_gen_st_f32 tcg_gen_st_i32
511
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
512
int u;
513
uint32_t imm, mask;
514
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
515
+ TCGv_ptr ptr1, ptr2, ptr3;
516
TCGv_i64 tmp64;
517
518
/* FIXME: this access check should not take precedence over UNDEF
519
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
520
if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
521
return 1;
522
}
523
- tmp = tcg_const_i32(rd);
524
- tmp2 = tcg_const_i32(rn);
525
- tmp3 = tcg_const_i32(rm);
526
+ ptr1 = vfp_reg_ptr(true, rd);
527
+ ptr2 = vfp_reg_ptr(true, rn);
528
+ ptr3 = vfp_reg_ptr(true, rm);
529
tmp4 = tcg_const_i32(size);
530
- gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
531
+ gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
532
tcg_temp_free_i32(tmp4);
533
} else { /* SHA-256 */
534
if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
535
return 1;
536
}
537
- tmp = tcg_const_i32(rd);
538
- tmp2 = tcg_const_i32(rn);
539
- tmp3 = tcg_const_i32(rm);
540
+ ptr1 = vfp_reg_ptr(true, rd);
541
+ ptr2 = vfp_reg_ptr(true, rn);
542
+ ptr3 = vfp_reg_ptr(true, rm);
543
switch (size) {
544
case 0:
545
- gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
546
+ gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
547
break;
548
case 1:
549
- gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
550
+ gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
551
break;
552
case 2:
553
- gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
554
+ gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
555
break;
556
}
557
}
558
- tcg_temp_free_i32(tmp);
559
- tcg_temp_free_i32(tmp2);
560
- tcg_temp_free_i32(tmp3);
561
+ tcg_temp_free_ptr(ptr1);
562
+ tcg_temp_free_ptr(ptr2);
563
+ tcg_temp_free_ptr(ptr3);
564
return 0;
565
}
566
if (size == 3 && op != NEON_3R_LOGIC) {
567
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
568
|| ((rm | rd) & 1)) {
569
return 1;
570
}
571
- tmp = tcg_const_i32(rd);
572
- tmp2 = tcg_const_i32(rm);
573
+ ptr1 = vfp_reg_ptr(true, rd);
574
+ ptr2 = vfp_reg_ptr(true, rm);
575
576
/* Bit 6 is the lowest opcode bit; it distinguishes between
577
* encryption (AESE/AESMC) and decryption (AESD/AESIMC)
578
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
579
tmp3 = tcg_const_i32(extract32(insn, 6, 1));
580
581
if (op == NEON_2RM_AESE) {
582
- gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
583
+ gen_helper_crypto_aese(ptr1, ptr2, tmp3);
584
} else {
585
- gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
586
+ gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
587
}
588
- tcg_temp_free_i32(tmp);
589
- tcg_temp_free_i32(tmp2);
590
+ tcg_temp_free_ptr(ptr1);
591
+ tcg_temp_free_ptr(ptr2);
592
tcg_temp_free_i32(tmp3);
593
break;
594
case NEON_2RM_SHA1H:
595
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
596
|| ((rm | rd) & 1)) {
597
return 1;
598
}
599
- tmp = tcg_const_i32(rd);
600
- tmp2 = tcg_const_i32(rm);
601
+ ptr1 = vfp_reg_ptr(true, rd);
602
+ ptr2 = vfp_reg_ptr(true, rm);
603
604
- gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
605
+ gen_helper_crypto_sha1h(ptr1, ptr2);
606
607
- tcg_temp_free_i32(tmp);
608
- tcg_temp_free_i32(tmp2);
609
+ tcg_temp_free_ptr(ptr1);
610
+ tcg_temp_free_ptr(ptr2);
611
break;
612
case NEON_2RM_SHA1SU1:
613
if ((rm | rd) & 1) {
614
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
615
} else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
616
return 1;
617
}
618
- tmp = tcg_const_i32(rd);
619
- tmp2 = tcg_const_i32(rm);
620
+ ptr1 = vfp_reg_ptr(true, rd);
621
+ ptr2 = vfp_reg_ptr(true, rm);
622
if (q) {
623
- gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
624
+ gen_helper_crypto_sha256su0(ptr1, ptr2);
625
} else {
626
- gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
627
+ gen_helper_crypto_sha1su1(ptr1, ptr2);
628
}
629
- tcg_temp_free_i32(tmp);
630
- tcg_temp_free_i32(tmp2);
631
+ tcg_temp_free_ptr(ptr1);
632
+ tcg_temp_free_ptr(ptr2);
633
break;
634
default:
635
elementwise:
41
--
636
--
42
2.7.4
637
2.7.4
43
638
44
639
diff view generated by jsdifflib
1
Refactor disas_thumb2_insn() so that it generates the code for raising
1
From: Richard Henderson <richard.henderson@linaro.org>
2
an UNDEF exception for invalid insns, rather than returning a flag
3
which the caller must check to see if it needs to generate the UNDEF
4
code. This brings the function in to line with the behaviour of
5
disas_thumb_insn() and disas_arm_insn().
6
2
3
Rather than passing regnos to the helpers, pass pointers to the
4
vector registers directly. This eliminates the need to pass in
5
the environment pointer and reduces the number of places that
6
directly access env->vfp.regs[].
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Message-id: 20180119045438.28582-4-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1513080506-17703-1-git-send-email-peter.maydell@linaro.org
10
---
13
---
11
target/arm/translate.c | 23 ++++++++++-------------
14
target/arm/helper.h | 20 +++---
12
1 file changed, 10 insertions(+), 13 deletions(-)
15
target/arm/neon_helper.c | 162 +++++++++++++++++++++++++----------------------
16
target/arm/translate.c | 42 ++++++------
17
3 files changed, 120 insertions(+), 104 deletions(-)
13
18
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
22
+++ b/target/arm/helper.h
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(iwmmxt_muladdsl, i64, i64, i32, i32)
24
DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32)
25
DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
26
27
-DEF_HELPER_3(neon_unzip8, void, env, i32, i32)
28
-DEF_HELPER_3(neon_unzip16, void, env, i32, i32)
29
-DEF_HELPER_3(neon_qunzip8, void, env, i32, i32)
30
-DEF_HELPER_3(neon_qunzip16, void, env, i32, i32)
31
-DEF_HELPER_3(neon_qunzip32, void, env, i32, i32)
32
-DEF_HELPER_3(neon_zip8, void, env, i32, i32)
33
-DEF_HELPER_3(neon_zip16, void, env, i32, i32)
34
-DEF_HELPER_3(neon_qzip8, void, env, i32, i32)
35
-DEF_HELPER_3(neon_qzip16, void, env, i32, i32)
36
-DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
37
+DEF_HELPER_FLAGS_2(neon_unzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
38
+DEF_HELPER_FLAGS_2(neon_unzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
39
+DEF_HELPER_FLAGS_2(neon_qunzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
40
+DEF_HELPER_FLAGS_2(neon_qunzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
41
+DEF_HELPER_FLAGS_2(neon_qunzip32, TCG_CALL_NO_RWG, void, ptr, ptr)
42
+DEF_HELPER_FLAGS_2(neon_zip8, TCG_CALL_NO_RWG, void, ptr, ptr)
43
+DEF_HELPER_FLAGS_2(neon_zip16, TCG_CALL_NO_RWG, void, ptr, ptr)
44
+DEF_HELPER_FLAGS_2(neon_qzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
45
+DEF_HELPER_FLAGS_2(neon_qzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
46
+DEF_HELPER_FLAGS_2(neon_qzip32, TCG_CALL_NO_RWG, void, ptr, ptr)
47
48
DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
49
DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
50
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/neon_helper.c
53
+++ b/target/arm/neon_helper.c
54
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_acgt_f64)(uint64_t a, uint64_t b, void *fpstp)
55
56
#define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1))
57
58
-void HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
59
+void HELPER(neon_qunzip8)(void *vd, void *vm)
60
{
61
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
62
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
63
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
64
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
65
+ uint64_t *rd = vd, *rm = vm;
66
+ uint64_t zd0 = rd[0], zd1 = rd[1];
67
+ uint64_t zm0 = rm[0], zm1 = rm[1];
68
+
69
uint64_t d0 = ELEM(zd0, 0, 8) | (ELEM(zd0, 2, 8) << 8)
70
| (ELEM(zd0, 4, 8) << 16) | (ELEM(zd0, 6, 8) << 24)
71
| (ELEM(zd1, 0, 8) << 32) | (ELEM(zd1, 2, 8) << 40)
72
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
73
| (ELEM(zm0, 5, 8) << 16) | (ELEM(zm0, 7, 8) << 24)
74
| (ELEM(zm1, 1, 8) << 32) | (ELEM(zm1, 3, 8) << 40)
75
| (ELEM(zm1, 5, 8) << 48) | (ELEM(zm1, 7, 8) << 56);
76
- env->vfp.regs[rm] = make_float64(m0);
77
- env->vfp.regs[rm + 1] = make_float64(m1);
78
- env->vfp.regs[rd] = make_float64(d0);
79
- env->vfp.regs[rd + 1] = make_float64(d1);
80
+
81
+ rm[0] = m0;
82
+ rm[1] = m1;
83
+ rd[0] = d0;
84
+ rd[1] = d1;
85
}
86
87
-void HELPER(neon_qunzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
88
+void HELPER(neon_qunzip16)(void *vd, void *vm)
89
{
90
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
91
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
92
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
93
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
94
+ uint64_t *rd = vd, *rm = vm;
95
+ uint64_t zd0 = rd[0], zd1 = rd[1];
96
+ uint64_t zm0 = rm[0], zm1 = rm[1];
97
+
98
uint64_t d0 = ELEM(zd0, 0, 16) | (ELEM(zd0, 2, 16) << 16)
99
| (ELEM(zd1, 0, 16) << 32) | (ELEM(zd1, 2, 16) << 48);
100
uint64_t d1 = ELEM(zm0, 0, 16) | (ELEM(zm0, 2, 16) << 16)
101
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_qunzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
102
| (ELEM(zd1, 1, 16) << 32) | (ELEM(zd1, 3, 16) << 48);
103
uint64_t m1 = ELEM(zm0, 1, 16) | (ELEM(zm0, 3, 16) << 16)
104
| (ELEM(zm1, 1, 16) << 32) | (ELEM(zm1, 3, 16) << 48);
105
- env->vfp.regs[rm] = make_float64(m0);
106
- env->vfp.regs[rm + 1] = make_float64(m1);
107
- env->vfp.regs[rd] = make_float64(d0);
108
- env->vfp.regs[rd + 1] = make_float64(d1);
109
+
110
+ rm[0] = m0;
111
+ rm[1] = m1;
112
+ rd[0] = d0;
113
+ rd[1] = d1;
114
}
115
116
-void HELPER(neon_qunzip32)(CPUARMState *env, uint32_t rd, uint32_t rm)
117
+void HELPER(neon_qunzip32)(void *vd, void *vm)
118
{
119
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
120
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
121
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
122
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
123
+ uint64_t *rd = vd, *rm = vm;
124
+ uint64_t zd0 = rd[0], zd1 = rd[1];
125
+ uint64_t zm0 = rm[0], zm1 = rm[1];
126
+
127
uint64_t d0 = ELEM(zd0, 0, 32) | (ELEM(zd1, 0, 32) << 32);
128
uint64_t d1 = ELEM(zm0, 0, 32) | (ELEM(zm1, 0, 32) << 32);
129
uint64_t m0 = ELEM(zd0, 1, 32) | (ELEM(zd1, 1, 32) << 32);
130
uint64_t m1 = ELEM(zm0, 1, 32) | (ELEM(zm1, 1, 32) << 32);
131
- env->vfp.regs[rm] = make_float64(m0);
132
- env->vfp.regs[rm + 1] = make_float64(m1);
133
- env->vfp.regs[rd] = make_float64(d0);
134
- env->vfp.regs[rd + 1] = make_float64(d1);
135
+
136
+ rm[0] = m0;
137
+ rm[1] = m1;
138
+ rd[0] = d0;
139
+ rd[1] = d1;
140
}
141
142
-void HELPER(neon_unzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
143
+void HELPER(neon_unzip8)(void *vd, void *vm)
144
{
145
- uint64_t zm = float64_val(env->vfp.regs[rm]);
146
- uint64_t zd = float64_val(env->vfp.regs[rd]);
147
+ uint64_t *rd = vd, *rm = vm;
148
+ uint64_t zd = rd[0], zm = rm[0];
149
+
150
uint64_t d0 = ELEM(zd, 0, 8) | (ELEM(zd, 2, 8) << 8)
151
| (ELEM(zd, 4, 8) << 16) | (ELEM(zd, 6, 8) << 24)
152
| (ELEM(zm, 0, 8) << 32) | (ELEM(zm, 2, 8) << 40)
153
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_unzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
154
| (ELEM(zd, 5, 8) << 16) | (ELEM(zd, 7, 8) << 24)
155
| (ELEM(zm, 1, 8) << 32) | (ELEM(zm, 3, 8) << 40)
156
| (ELEM(zm, 5, 8) << 48) | (ELEM(zm, 7, 8) << 56);
157
- env->vfp.regs[rm] = make_float64(m0);
158
- env->vfp.regs[rd] = make_float64(d0);
159
+
160
+ rm[0] = m0;
161
+ rd[0] = d0;
162
}
163
164
-void HELPER(neon_unzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
165
+void HELPER(neon_unzip16)(void *vd, void *vm)
166
{
167
- uint64_t zm = float64_val(env->vfp.regs[rm]);
168
- uint64_t zd = float64_val(env->vfp.regs[rd]);
169
+ uint64_t *rd = vd, *rm = vm;
170
+ uint64_t zd = rd[0], zm = rm[0];
171
+
172
uint64_t d0 = ELEM(zd, 0, 16) | (ELEM(zd, 2, 16) << 16)
173
| (ELEM(zm, 0, 16) << 32) | (ELEM(zm, 2, 16) << 48);
174
uint64_t m0 = ELEM(zd, 1, 16) | (ELEM(zd, 3, 16) << 16)
175
| (ELEM(zm, 1, 16) << 32) | (ELEM(zm, 3, 16) << 48);
176
- env->vfp.regs[rm] = make_float64(m0);
177
- env->vfp.regs[rd] = make_float64(d0);
178
+
179
+ rm[0] = m0;
180
+ rd[0] = d0;
181
}
182
183
-void HELPER(neon_qzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
184
+void HELPER(neon_qzip8)(void *vd, void *vm)
185
{
186
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
187
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
188
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
189
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
190
+ uint64_t *rd = vd, *rm = vm;
191
+ uint64_t zd0 = rd[0], zd1 = rd[1];
192
+ uint64_t zm0 = rm[0], zm1 = rm[1];
193
+
194
uint64_t d0 = ELEM(zd0, 0, 8) | (ELEM(zm0, 0, 8) << 8)
195
| (ELEM(zd0, 1, 8) << 16) | (ELEM(zm0, 1, 8) << 24)
196
| (ELEM(zd0, 2, 8) << 32) | (ELEM(zm0, 2, 8) << 40)
197
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_qzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
198
| (ELEM(zd1, 5, 8) << 16) | (ELEM(zm1, 5, 8) << 24)
199
| (ELEM(zd1, 6, 8) << 32) | (ELEM(zm1, 6, 8) << 40)
200
| (ELEM(zd1, 7, 8) << 48) | (ELEM(zm1, 7, 8) << 56);
201
- env->vfp.regs[rm] = make_float64(m0);
202
- env->vfp.regs[rm + 1] = make_float64(m1);
203
- env->vfp.regs[rd] = make_float64(d0);
204
- env->vfp.regs[rd + 1] = make_float64(d1);
205
+
206
+ rm[0] = m0;
207
+ rm[1] = m1;
208
+ rd[0] = d0;
209
+ rd[1] = d1;
210
}
211
212
-void HELPER(neon_qzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
213
+void HELPER(neon_qzip16)(void *vd, void *vm)
214
{
215
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
216
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
217
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
218
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
219
+ uint64_t *rd = vd, *rm = vm;
220
+ uint64_t zd0 = rd[0], zd1 = rd[1];
221
+ uint64_t zm0 = rm[0], zm1 = rm[1];
222
+
223
uint64_t d0 = ELEM(zd0, 0, 16) | (ELEM(zm0, 0, 16) << 16)
224
| (ELEM(zd0, 1, 16) << 32) | (ELEM(zm0, 1, 16) << 48);
225
uint64_t d1 = ELEM(zd0, 2, 16) | (ELEM(zm0, 2, 16) << 16)
226
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_qzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
227
| (ELEM(zd1, 1, 16) << 32) | (ELEM(zm1, 1, 16) << 48);
228
uint64_t m1 = ELEM(zd1, 2, 16) | (ELEM(zm1, 2, 16) << 16)
229
| (ELEM(zd1, 3, 16) << 32) | (ELEM(zm1, 3, 16) << 48);
230
- env->vfp.regs[rm] = make_float64(m0);
231
- env->vfp.regs[rm + 1] = make_float64(m1);
232
- env->vfp.regs[rd] = make_float64(d0);
233
- env->vfp.regs[rd + 1] = make_float64(d1);
234
+
235
+ rm[0] = m0;
236
+ rm[1] = m1;
237
+ rd[0] = d0;
238
+ rd[1] = d1;
239
}
240
241
-void HELPER(neon_qzip32)(CPUARMState *env, uint32_t rd, uint32_t rm)
242
+void HELPER(neon_qzip32)(void *vd, void *vm)
243
{
244
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
245
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
246
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
247
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
248
+ uint64_t *rd = vd, *rm = vm;
249
+ uint64_t zd0 = rd[0], zd1 = rd[1];
250
+ uint64_t zm0 = rm[0], zm1 = rm[1];
251
+
252
uint64_t d0 = ELEM(zd0, 0, 32) | (ELEM(zm0, 0, 32) << 32);
253
uint64_t d1 = ELEM(zd0, 1, 32) | (ELEM(zm0, 1, 32) << 32);
254
uint64_t m0 = ELEM(zd1, 0, 32) | (ELEM(zm1, 0, 32) << 32);
255
uint64_t m1 = ELEM(zd1, 1, 32) | (ELEM(zm1, 1, 32) << 32);
256
- env->vfp.regs[rm] = make_float64(m0);
257
- env->vfp.regs[rm + 1] = make_float64(m1);
258
- env->vfp.regs[rd] = make_float64(d0);
259
- env->vfp.regs[rd + 1] = make_float64(d1);
260
+
261
+ rm[0] = m0;
262
+ rm[1] = m1;
263
+ rd[0] = d0;
264
+ rd[1] = d1;
265
}
266
267
-void HELPER(neon_zip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
268
+void HELPER(neon_zip8)(void *vd, void *vm)
269
{
270
- uint64_t zm = float64_val(env->vfp.regs[rm]);
271
- uint64_t zd = float64_val(env->vfp.regs[rd]);
272
+ uint64_t *rd = vd, *rm = vm;
273
+ uint64_t zd = rd[0], zm = rm[0];
274
+
275
uint64_t d0 = ELEM(zd, 0, 8) | (ELEM(zm, 0, 8) << 8)
276
| (ELEM(zd, 1, 8) << 16) | (ELEM(zm, 1, 8) << 24)
277
| (ELEM(zd, 2, 8) << 32) | (ELEM(zm, 2, 8) << 40)
278
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_zip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
279
| (ELEM(zd, 5, 8) << 16) | (ELEM(zm, 5, 8) << 24)
280
| (ELEM(zd, 6, 8) << 32) | (ELEM(zm, 6, 8) << 40)
281
| (ELEM(zd, 7, 8) << 48) | (ELEM(zm, 7, 8) << 56);
282
- env->vfp.regs[rm] = make_float64(m0);
283
- env->vfp.regs[rd] = make_float64(d0);
284
+
285
+ rm[0] = m0;
286
+ rd[0] = d0;
287
}
288
289
-void HELPER(neon_zip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
290
+void HELPER(neon_zip16)(void *vd, void *vm)
291
{
292
- uint64_t zm = float64_val(env->vfp.regs[rm]);
293
- uint64_t zd = float64_val(env->vfp.regs[rd]);
294
+ uint64_t *rd = vd, *rm = vm;
295
+ uint64_t zd = rd[0], zm = rm[0];
296
+
297
uint64_t d0 = ELEM(zd, 0, 16) | (ELEM(zm, 0, 16) << 16)
298
| (ELEM(zd, 1, 16) << 32) | (ELEM(zm, 1, 16) << 48);
299
uint64_t m0 = ELEM(zd, 2, 16) | (ELEM(zm, 2, 16) << 16)
300
| (ELEM(zd, 3, 16) << 32) | (ELEM(zm, 3, 16) << 48);
301
- env->vfp.regs[rm] = make_float64(m0);
302
- env->vfp.regs[rd] = make_float64(d0);
303
+
304
+ rm[0] = m0;
305
+ rd[0] = d0;
306
}
307
308
/* Helper function for 64 bit polynomial multiply case:
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
309
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
310
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
311
--- a/target/arm/translate.c
17
+++ b/target/arm/translate.c
312
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
313
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 neon_get_scalar(int size, int reg)
314
315
static int gen_neon_unzip(int rd, int rm, int size, int q)
316
{
317
- TCGv_i32 tmp, tmp2;
318
+ TCGv_ptr pd, pm;
319
+
320
if (!q && size == 2) {
321
return 1;
322
}
323
- tmp = tcg_const_i32(rd);
324
- tmp2 = tcg_const_i32(rm);
325
+ pd = vfp_reg_ptr(true, rd);
326
+ pm = vfp_reg_ptr(true, rm);
327
if (q) {
328
switch (size) {
329
case 0:
330
- gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
331
+ gen_helper_neon_qunzip8(pd, pm);
332
break;
333
case 1:
334
- gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
335
+ gen_helper_neon_qunzip16(pd, pm);
336
break;
337
case 2:
338
- gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
339
+ gen_helper_neon_qunzip32(pd, pm);
340
break;
341
default:
342
abort();
343
@@ -XXX,XX +XXX,XX @@ static int gen_neon_unzip(int rd, int rm, int size, int q)
344
} else {
345
switch (size) {
346
case 0:
347
- gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
348
+ gen_helper_neon_unzip8(pd, pm);
349
break;
350
case 1:
351
- gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
352
+ gen_helper_neon_unzip16(pd, pm);
353
break;
354
default:
355
abort();
356
}
357
}
358
- tcg_temp_free_i32(tmp);
359
- tcg_temp_free_i32(tmp2);
360
+ tcg_temp_free_ptr(pd);
361
+ tcg_temp_free_ptr(pm);
19
return 0;
362
return 0;
20
}
363
}
21
364
22
-/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
365
static int gen_neon_zip(int rd, int rm, int size, int q)
23
- is not legal. */
366
{
24
-static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
367
- TCGv_i32 tmp, tmp2;
25
+/* Translate a 32-bit thumb instruction. */
368
+ TCGv_ptr pd, pm;
26
+static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
369
+
27
{
370
if (!q && size == 2) {
28
uint32_t imm, shift, offset;
371
return 1;
29
uint32_t rd, rn, rm, rs;
372
}
30
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
373
- tmp = tcg_const_i32(rd);
31
/* UNPREDICTABLE, unallocated hint or
374
- tmp2 = tcg_const_i32(rm);
32
* PLD/PLDW/PLI (literal)
375
+ pd = vfp_reg_ptr(true, rd);
33
*/
376
+ pm = vfp_reg_ptr(true, rm);
34
- return 0;
377
if (q) {
35
+ return;
378
switch (size) {
36
}
379
case 0:
37
if (op1 & 1) {
380
- gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
38
- return 0; /* PLD/PLDW/PLI or unallocated hint */
381
+ gen_helper_neon_qzip8(pd, pm);
39
+ return; /* PLD/PLDW/PLI or unallocated hint */
382
break;
40
}
383
case 1:
41
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
384
- gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
42
- return 0; /* PLD/PLDW/PLI or unallocated hint */
385
+ gen_helper_neon_qzip16(pd, pm);
43
+ return; /* PLD/PLDW/PLI or unallocated hint */
386
break;
44
}
387
case 2:
45
/* UNDEF space, or an UNPREDICTABLE */
388
- gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
46
- return 1;
389
+ gen_helper_neon_qzip32(pd, pm);
47
+ goto illegal_op;
390
break;
48
}
391
default:
392
abort();
393
@@ -XXX,XX +XXX,XX @@ static int gen_neon_zip(int rd, int rm, int size, int q)
394
} else {
395
switch (size) {
396
case 0:
397
- gen_helper_neon_zip8(cpu_env, tmp, tmp2);
398
+ gen_helper_neon_zip8(pd, pm);
399
break;
400
case 1:
401
- gen_helper_neon_zip16(cpu_env, tmp, tmp2);
402
+ gen_helper_neon_zip16(pd, pm);
403
break;
404
default:
405
abort();
49
}
406
}
50
memidx = get_mem_index(s);
51
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
52
default:
53
goto illegal_op;
54
}
407
}
55
- return 0;
408
- tcg_temp_free_i32(tmp);
56
+ return;
409
- tcg_temp_free_i32(tmp2);
57
illegal_op:
410
+ tcg_temp_free_ptr(pd);
58
- return 1;
411
+ tcg_temp_free_ptr(pm);
59
+ gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
412
return 0;
60
+ default_exception_el(s));
413
}
61
}
414
62
63
static void disas_thumb_insn(DisasContext *s, uint32_t insn)
64
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
65
if (is_16bit) {
66
disas_thumb_insn(dc, insn);
67
} else {
68
- if (disas_thumb2_insn(dc, insn)) {
69
- gen_exception_insn(dc, 4, EXCP_UDEF, syn_uncategorized(),
70
- default_exception_el(dc));
71
- }
72
+ disas_thumb2_insn(dc, insn);
73
}
74
75
/* Advance the Thumb condexec condition. */
76
--
415
--
77
2.7.4
416
2.7.4
78
417
79
418
diff view generated by jsdifflib
1
Our copy of the nwfpe code for emulating of the old FPA11 floating
1
From: Richard Henderson <richard.henderson@linaro.org>
2
point unit doesn't check the coprocessor number in the instruction
3
when it emulates it. This means that we might treat some
4
instructions which should really UNDEF as being FPA11 instructions by
5
accident.
6
2
7
The kernel's copy of the nwfpe code doesn't make this error; I suspect
3
Rather than passing a regno to the helper, pass pointers to the
8
the bug was noticed and fixed as part of the process of mainlining
4
vector register directly. This eliminates the need to pass in
9
the nwfpe code more than a decade ago.
5
the environment pointer and reduces the number of places that
6
directly access env->vfp.regs[].
10
7
11
Add a check that the coprocessor number (which is always in bits
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
[11:8] of the instruction) is either 1 or 2, which is where the
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
FPA11 lives.
10
Message-id: 20180119045438.28582-5-richard.henderson@linaro.org
14
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Reported-by: Richard Henderson <richard.henderson@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
13
---
18
linux-user/arm/nwfpe/fpa11.c | 9 +++++++++
14
target/arm/helper.h | 2 +-
19
1 file changed, 9 insertions(+)
15
target/arm/op_helper.c | 17 +++++++----------
16
target/arm/translate.c | 8 ++++----
17
3 files changed, 12 insertions(+), 15 deletions(-)
20
18
21
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
23
--- a/linux-user/arm/nwfpe/fpa11.c
21
--- a/target/arm/helper.h
24
+++ b/linux-user/arm/nwfpe/fpa11.c
22
+++ b/target/arm/helper.h
25
@@ -XXX,XX +XXX,XX @@ unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
26
unsigned int nRc = 0;
24
DEF_HELPER_FLAGS_2(rsqrte_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
27
// unsigned long flags;
25
DEF_HELPER_2(recpe_u32, i32, i32, ptr)
28
FPA11 *fpa11;
26
DEF_HELPER_FLAGS_2(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32, ptr)
29
+ unsigned int cp;
27
-DEF_HELPER_5(neon_tbl, i32, env, i32, i32, i32, i32)
30
// save_flags(flags); sti();
28
+DEF_HELPER_FLAGS_4(neon_tbl, TCG_CALL_NO_RWG, i32, i32, i32, ptr, i32)
31
29
32
+ /* Check that this is really an FPA11 instruction: the coprocessor
30
DEF_HELPER_3(shl_cc, i32, env, i32, i32)
33
+ * field in bits [11:8] must be 1 or 2.
31
DEF_HELPER_3(shr_cc, i32, env, i32, i32)
34
+ */
32
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
35
+ cp = (opcode >> 8) & 0xf;
33
index XXXXXXX..XXXXXXX 100644
36
+ if (cp != 1 && cp != 2) {
34
--- a/target/arm/op_helper.c
37
+ return 0;
35
+++ b/target/arm/op_helper.c
38
+ }
36
@@ -XXX,XX +XXX,XX @@ static int exception_target_el(CPUARMState *env)
37
return target_el;
38
}
39
40
-uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
41
- uint32_t rn, uint32_t maxindex)
42
+uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
43
+ uint32_t maxindex)
44
{
45
- uint32_t val;
46
- uint32_t tmp;
47
- int index;
48
- int shift;
49
- uint64_t *table;
50
- table = (uint64_t *)&env->vfp.regs[rn];
51
+ uint32_t val, shift;
52
+ uint64_t *table = vn;
39
+
53
+
40
qemufpa=qfpa;
54
val = 0;
41
user_registers=qregs;
55
for (shift = 0; shift < 32; shift += 8) {
42
56
- index = (ireg >> shift) & 0xff;
57
+ uint32_t index = (ireg >> shift) & 0xff;
58
if (index < maxindex) {
59
- tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff;
60
+ uint32_t tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff;
61
val |= tmp << shift;
62
} else {
63
val |= def & (0xff << shift);
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
69
tcg_gen_movi_i32(tmp, 0);
70
}
71
tmp2 = neon_load_reg(rm, 0);
72
- tmp4 = tcg_const_i32(rn);
73
+ ptr1 = vfp_reg_ptr(true, rn);
74
tmp5 = tcg_const_i32(n);
75
- gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
76
+ gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
77
tcg_temp_free_i32(tmp);
78
if (insn & (1 << 6)) {
79
tmp = neon_load_reg(rd, 1);
80
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
81
tcg_gen_movi_i32(tmp, 0);
82
}
83
tmp3 = neon_load_reg(rm, 1);
84
- gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
85
+ gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
86
tcg_temp_free_i32(tmp5);
87
- tcg_temp_free_i32(tmp4);
88
+ tcg_temp_free_ptr(ptr1);
89
neon_store_reg(rd, 0, tmp2);
90
neon_store_reg(rd, 1, tmp3);
91
tcg_temp_free_i32(tmp);
43
--
92
--
44
2.7.4
93
2.7.4
45
94
46
95
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In current implementation, packet queue flushing logic seem to suffer
3
All direct users of this field want an integral value. Drop all
4
from a deadlock like scenario if a packet is received by the interface
4
of the extra casting between uint64_t and float64.
5
before before Rx ring is initialized by Guest's driver. Consider the
6
following sequence of events:
7
5
8
    1. A QEMU instance is started against a TAP device on Linux
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
     host, running Linux guest, e. g., something to the effect
7
Message-id: 20180119045438.28582-6-richard.henderson@linaro.org
10
     of:
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
12
     qemu-system-arm \
13
     -net nic,model=imx.fec,netdev=lan0 \
14
     netdev tap,id=lan0,ifname=tap0,script=no,downscript=no \
15
     ... rest of the arguments ...
16
17
    2. Once QEMU starts, but before guest reaches the point where
18
     FEC deriver is done initializing the HW, Guest, via TAP
19
     interface, receives a number of multicast MDNS packets from
20
     Host (not necessarily true for every OS, but it happens at
21
     least on Fedora 25)
22
23
    3. Recieving a packet in such a state results in
24
     imx_eth_can_receive() returning '0', which in turn causes
25
     tap_send() to disable corresponding event (tap.c:203)
26
27
    4. Once Guest's driver reaches the point where it is ready to
28
     recieve packets it prepares Rx ring descriptors and writes
29
     ENET_RDAR_RDAR to ENET_RDAR register to indicate to HW that
30
     more descriptors are ready. And at this points emulation
31
     layer does this:
32
33
          s->regs[index] = ENET_RDAR_RDAR;
34
imx_eth_enable_rx(s);
35
36
     which, combined with:
37
38
          if (!s->regs[ENET_RDAR]) {
39
         qemu_flush_queued_packets(qemu_get_queue(s->nic));
40
         }
41
42
     results in Rx queue never being flushed and corresponding
43
     I/O event beign disabled.
44
45
To prevent the problem, change the code to always flush packet queue
46
when ENET_RDAR transitions 0 -> ENET_RDAR_RDAR.
47
48
Cc: Peter Maydell <peter.maydell@linaro.org>
49
Cc: Jason Wang <jasowang@redhat.com>
50
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
51
Cc: qemu-devel@nongnu.org
52
Cc: qemu-arm@nongnu.org
53
Cc: yurovsky@gmail.com
54
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
55
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
56
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
57
---
10
---
58
hw/net/imx_fec.c | 12 ++++++------
11
target/arm/cpu.h | 2 +-
59
1 file changed, 6 insertions(+), 6 deletions(-)
12
target/arm/arch_dump.c | 4 ++--
13
target/arm/helper.c | 20 ++++++++++----------
14
target/arm/machine.c | 2 +-
15
target/arm/translate-a64.c | 8 ++++----
16
target/arm/translate.c | 2 +-
17
6 files changed, 19 insertions(+), 19 deletions(-)
60
18
61
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
62
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/net/imx_fec.c
21
--- a/target/arm/cpu.h
64
+++ b/hw/net/imx_fec.c
22
+++ b/target/arm/cpu.h
65
@@ -XXX,XX +XXX,XX @@ static void imx_eth_do_tx(IMXFECState *s)
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
24
* the two execution states, and means we do not need to explicitly
25
* map these registers when changing states.
26
*/
27
- float64 regs[64];
28
+ uint64_t regs[64];
29
30
uint32_t xregs[16];
31
/* We store these fpcsr fields separately for convenience. */
32
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/arch_dump.c
35
+++ b/target/arm/arch_dump.c
36
@@ -XXX,XX +XXX,XX @@ static int aarch64_write_elf64_prfpreg(WriteCoreDumpFunction f,
37
aarch64_note_init(&note, s, "CORE", 5, NT_PRFPREG, sizeof(note.vfp));
38
39
for (i = 0; i < 64; ++i) {
40
- note.vfp.vregs[i] = cpu_to_dump64(s, float64_val(env->vfp.regs[i]));
41
+ note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
66
}
42
}
67
}
43
68
44
if (s->dump_info.d_endian == ELFDATA2MSB) {
69
-static void imx_eth_enable_rx(IMXFECState *s)
45
@@ -XXX,XX +XXX,XX @@ static int arm_write_elf32_vfp(WriteCoreDumpFunction f, CPUARMState *env,
70
+static void imx_eth_enable_rx(IMXFECState *s, bool flush)
46
arm_note_init(&note, s, "LINUX", 6, NT_ARM_VFP, sizeof(note.vfp));
71
{
47
72
IMXFECBufDesc bd;
48
for (i = 0; i < 32; ++i) {
73
bool rx_ring_full;
49
- note.vfp.vregs[i] = cpu_to_dump64(s, float64_val(env->vfp.regs[i]));
74
@@ -XXX,XX +XXX,XX @@ static void imx_eth_enable_rx(IMXFECState *s)
50
+ note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
75
76
if (rx_ring_full) {
77
FEC_PRINTF("RX buffer full\n");
78
- } else if (!s->regs[ENET_RDAR]) {
79
+ } else if (flush) {
80
qemu_flush_queued_packets(qemu_get_queue(s->nic));
81
}
51
}
82
52
83
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
53
note.vfp.fpscr = cpu_to_dump32(s, vfp_get_fpscr(env));
84
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
if (!s->regs[index]) {
55
index XXXXXXX..XXXXXXX 100644
86
s->regs[index] = ENET_RDAR_RDAR;
56
--- a/target/arm/helper.c
87
- imx_eth_enable_rx(s);
57
+++ b/target/arm/helper.c
88
+ imx_eth_enable_rx(s, true);
58
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
89
}
59
/* VFP data registers are always little-endian. */
90
} else {
60
nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
91
s->regs[index] = 0;
61
if (reg < nregs) {
92
@@ -XXX,XX +XXX,XX @@ static int imx_eth_can_receive(NetClientState *nc)
62
- stfq_le_p(buf, env->vfp.regs[reg]);
93
63
+ stq_le_p(buf, env->vfp.regs[reg]);
94
FEC_PRINTF("\n");
64
return 8;
95
65
}
96
- return s->regs[ENET_RDAR] ? 1 : 0;
66
if (arm_feature(env, ARM_FEATURE_NEON)) {
97
+ return !!s->regs[ENET_RDAR];
67
/* Aliases for Q regs. */
98
}
68
nregs += 16;
99
69
if (reg < nregs) {
100
static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
70
- stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
101
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
71
- stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
72
+ stq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
73
+ stq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
74
return 16;
102
}
75
}
103
}
76
}
104
s->rx_descriptor = addr;
77
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
105
- imx_eth_enable_rx(s);
78
106
+ imx_eth_enable_rx(s, false);
79
nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
107
imx_eth_update(s);
80
if (reg < nregs) {
108
return len;
81
- env->vfp.regs[reg] = ldfq_le_p(buf);
109
}
82
+ env->vfp.regs[reg] = ldq_le_p(buf);
110
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
83
return 8;
84
}
85
if (arm_feature(env, ARM_FEATURE_NEON)) {
86
nregs += 16;
87
if (reg < nregs) {
88
- env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf);
89
- env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8);
90
+ env->vfp.regs[(reg - 32) * 2] = ldq_le_p(buf);
91
+ env->vfp.regs[(reg - 32) * 2 + 1] = ldq_le_p(buf + 8);
92
return 16;
111
}
93
}
112
}
94
}
113
s->rx_descriptor = addr;
95
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
114
- imx_eth_enable_rx(s);
96
switch (reg) {
115
+ imx_eth_enable_rx(s, false);
97
case 0 ... 31:
116
imx_eth_update(s);
98
/* 128 bit FP register */
117
return len;
99
- stfq_le_p(buf, env->vfp.regs[reg * 2]);
118
}
100
- stfq_le_p(buf + 8, env->vfp.regs[reg * 2 + 1]);
101
+ stq_le_p(buf, env->vfp.regs[reg * 2]);
102
+ stq_le_p(buf + 8, env->vfp.regs[reg * 2 + 1]);
103
return 16;
104
case 32:
105
/* FPSR */
106
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
107
switch (reg) {
108
case 0 ... 31:
109
/* 128 bit FP register */
110
- env->vfp.regs[reg * 2] = ldfq_le_p(buf);
111
- env->vfp.regs[reg * 2 + 1] = ldfq_le_p(buf + 8);
112
+ env->vfp.regs[reg * 2] = ldq_le_p(buf);
113
+ env->vfp.regs[reg * 2 + 1] = ldq_le_p(buf + 8);
114
return 16;
115
case 32:
116
/* FPSR */
117
diff --git a/target/arm/machine.c b/target/arm/machine.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/machine.c
120
+++ b/target/arm/machine.c
121
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_vfp = {
122
.minimum_version_id = 3,
123
.needed = vfp_needed,
124
.fields = (VMStateField[]) {
125
- VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 64),
126
+ VMSTATE_UINT64_ARRAY(env.vfp.regs, ARMCPU, 64),
127
/* The xregs array is a little awkward because element 1 (FPSCR)
128
* requires a specific accessor, so we have to split it up in
129
* the vmstate:
130
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/translate-a64.c
133
+++ b/target/arm/translate-a64.c
134
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
135
if (flags & CPU_DUMP_FPU) {
136
int numvfpregs = 32;
137
for (i = 0; i < numvfpregs; i += 2) {
138
- uint64_t vlo = float64_val(env->vfp.regs[i * 2]);
139
- uint64_t vhi = float64_val(env->vfp.regs[(i * 2) + 1]);
140
+ uint64_t vlo = env->vfp.regs[i * 2];
141
+ uint64_t vhi = env->vfp.regs[(i * 2) + 1];
142
cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
143
i, vhi, vlo);
144
- vlo = float64_val(env->vfp.regs[(i + 1) * 2]);
145
- vhi = float64_val(env->vfp.regs[((i + 1) * 2) + 1]);
146
+ vlo = env->vfp.regs[(i + 1) * 2];
147
+ vhi = env->vfp.regs[((i + 1) * 2) + 1];
148
cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
149
i + 1, vhi, vlo);
150
}
151
diff --git a/target/arm/translate.c b/target/arm/translate.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/target/arm/translate.c
154
+++ b/target/arm/translate.c
155
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
156
numvfpregs += 16;
157
}
158
for (i = 0; i < numvfpregs; i++) {
159
- uint64_t v = float64_val(env->vfp.regs[i]);
160
+ uint64_t v = env->vfp.regs[i];
161
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
162
i * 2, (uint32_t)v,
163
i * 2 + 1, (uint32_t)(v >> 32),
119
--
164
--
120
2.7.4
165
2.7.4
121
166
122
167
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Helpers that return a pointer into env->vfp.regs so that we isolate
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
4
the logic of how to index the regs array for different cpu modes.
5
Message-id: 20180104000156.30932-1-f4bug@amsat.org
5
6
[PMM: add missing include]
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180119045438.28582-7-richard.henderson@linaro.org
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
hw/sd/pxa2xx_mmci.c | 78 ++++++++++++++++++++++++++++++++++-------------------
11
target/arm/cpu.h | 27 +++++++++++++++++++++++++++
10
hw/sd/trace-events | 4 +++
12
linux-user/signal.c | 22 ++++++++++++----------
11
2 files changed, 54 insertions(+), 28 deletions(-)
13
target/arm/arch_dump.c | 8 +++++---
14
target/arm/helper-a64.c | 5 +++--
15
target/arm/helper.c | 32 ++++++++++++++++++++------------
16
target/arm/kvm32.c | 4 ++--
17
target/arm/kvm64.c | 31 ++++++++++---------------------
18
target/arm/translate-a64.c | 25 ++++++++-----------------
19
target/arm/translate.c | 16 +++++++++-------
20
9 files changed, 96 insertions(+), 74 deletions(-)
12
21
13
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/sd/pxa2xx_mmci.c
24
--- a/target/arm/cpu.h
16
+++ b/hw/sd/pxa2xx_mmci.c
25
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
18
#include "hw/qdev.h"
27
return cpu->el_change_hook_opaque;
19
#include "hw/qdev-properties.h"
28
}
20
#include "qemu/error-report.h"
29
21
+#include "qemu/log.h"
30
+/**
22
+#include "trace.h"
31
+ * aa32_vfp_dreg:
23
32
+ * Return a pointer to the Dn register within env in 32-bit mode.
24
#define TYPE_PXA2XX_MMCI "pxa2xx-mmci"
33
+ */
25
#define PXA2XX_MMCI(obj) OBJECT_CHECK(PXA2xxMMCIState, (obj), TYPE_PXA2XX_MMCI)
34
+static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
26
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_wakequeues(PXA2xxMMCIState *s)
35
+{
27
static uint64_t pxa2xx_mmci_read(void *opaque, hwaddr offset, unsigned size)
36
+ return &env->vfp.regs[regno];
37
+}
38
+
39
+/**
40
+ * aa32_vfp_qreg:
41
+ * Return a pointer to the Qn register within env in 32-bit mode.
42
+ */
43
+static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
44
+{
45
+ return &env->vfp.regs[2 * regno];
46
+}
47
+
48
+/**
49
+ * aa64_vfp_qreg:
50
+ * Return a pointer to the Qn register within env in 64-bit mode.
51
+ */
52
+static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
53
+{
54
+ return &env->vfp.regs[2 * regno];
55
+}
56
+
57
#endif
58
diff --git a/linux-user/signal.c b/linux-user/signal.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/linux-user/signal.c
61
+++ b/linux-user/signal.c
62
@@ -XXX,XX +XXX,XX @@ static int target_setup_sigframe(struct target_rt_sigframe *sf,
63
}
64
65
for (i = 0; i < 32; i++) {
66
+ uint64_t *q = aa64_vfp_qreg(env, i);
67
#ifdef TARGET_WORDS_BIGENDIAN
68
- __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
69
- __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
70
+ __put_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
71
+ __put_user(q[1], &aux->fpsimd.vregs[i * 2]);
72
#else
73
- __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
74
- __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
75
+ __put_user(q[0], &aux->fpsimd.vregs[i * 2]);
76
+ __put_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
77
#endif
78
}
79
__put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
80
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
81
}
82
83
for (i = 0; i < 32; i++) {
84
+ uint64_t *q = aa64_vfp_qreg(env, i);
85
#ifdef TARGET_WORDS_BIGENDIAN
86
- __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
87
- __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
88
+ __get_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
89
+ __get_user(q[1], &aux->fpsimd.vregs[i * 2]);
90
#else
91
- __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
92
- __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
93
+ __get_user(q[0], &aux->fpsimd.vregs[i * 2]);
94
+ __get_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
95
#endif
96
}
97
__get_user(fpsr, &aux->fpsimd.fpsr);
98
@@ -XXX,XX +XXX,XX @@ static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
99
__put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
100
__put_user(sizeof(*vfpframe), &vfpframe->size);
101
for (i = 0; i < 32; i++) {
102
- __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
103
+ __put_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]);
104
}
105
__put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
106
__put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
107
@@ -XXX,XX +XXX,XX @@ static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
108
return 0;
109
}
110
for (i = 0; i < 32; i++) {
111
- __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
112
+ __get_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]);
113
}
114
__get_user(fpscr, &vfpframe->ufp.fpscr);
115
vfp_set_fpscr(env, fpscr);
116
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/arch_dump.c
119
+++ b/target/arm/arch_dump.c
120
@@ -XXX,XX +XXX,XX @@ static int aarch64_write_elf64_prfpreg(WriteCoreDumpFunction f,
121
122
aarch64_note_init(&note, s, "CORE", 5, NT_PRFPREG, sizeof(note.vfp));
123
124
- for (i = 0; i < 64; ++i) {
125
- note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
126
+ for (i = 0; i < 32; ++i) {
127
+ uint64_t *q = aa64_vfp_qreg(env, i);
128
+ note.vfp.vregs[2*i + 0] = cpu_to_dump64(s, q[0]);
129
+ note.vfp.vregs[2*i + 1] = cpu_to_dump64(s, q[1]);
130
}
131
132
if (s->dump_info.d_endian == ELFDATA2MSB) {
133
@@ -XXX,XX +XXX,XX @@ static int arm_write_elf32_vfp(WriteCoreDumpFunction f, CPUARMState *env,
134
arm_note_init(&note, s, "LINUX", 6, NT_ARM_VFP, sizeof(note.vfp));
135
136
for (i = 0; i < 32; ++i) {
137
- note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
138
+ note.vfp.vregs[i] = cpu_to_dump64(s, *aa32_vfp_dreg(env, i));
139
}
140
141
note.vfp.fpscr = cpu_to_dump32(s, vfp_get_fpscr(env));
142
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/target/arm/helper-a64.c
145
+++ b/target/arm/helper-a64.c
146
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
147
if (index < 16 * numregs) {
148
/* Convert index (a byte offset into the virtual table
149
* which is a series of 128-bit vectors concatenated)
150
- * into the correct vfp.regs[] element plus a bit offset
151
+ * into the correct register element plus a bit offset
152
* into that element, bearing in mind that the table
153
* can wrap around from V31 to V0.
154
*/
155
int elt = (rn * 2 + (index >> 3)) % 64;
156
int bitidx = (index & 7) * 8;
157
- uint64_t val = extract64(env->vfp.regs[elt], bitidx, 8);
158
+ uint64_t *q = aa64_vfp_qreg(env, elt >> 1);
159
+ uint64_t val = extract64(q[elt & 1], bitidx, 8);
160
161
result = deposit64(result, shift, 8, val);
162
}
163
diff --git a/target/arm/helper.c b/target/arm/helper.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/helper.c
166
+++ b/target/arm/helper.c
167
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
168
/* VFP data registers are always little-endian. */
169
nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
170
if (reg < nregs) {
171
- stq_le_p(buf, env->vfp.regs[reg]);
172
+ stq_le_p(buf, *aa32_vfp_dreg(env, reg));
173
return 8;
174
}
175
if (arm_feature(env, ARM_FEATURE_NEON)) {
176
/* Aliases for Q regs. */
177
nregs += 16;
178
if (reg < nregs) {
179
- stq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
180
- stq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
181
+ uint64_t *q = aa32_vfp_qreg(env, reg - 32);
182
+ stq_le_p(buf, q[0]);
183
+ stq_le_p(buf + 8, q[1]);
184
return 16;
185
}
186
}
187
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
188
189
nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
190
if (reg < nregs) {
191
- env->vfp.regs[reg] = ldq_le_p(buf);
192
+ *aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
193
return 8;
194
}
195
if (arm_feature(env, ARM_FEATURE_NEON)) {
196
nregs += 16;
197
if (reg < nregs) {
198
- env->vfp.regs[(reg - 32) * 2] = ldq_le_p(buf);
199
- env->vfp.regs[(reg - 32) * 2 + 1] = ldq_le_p(buf + 8);
200
+ uint64_t *q = aa32_vfp_qreg(env, reg - 32);
201
+ q[0] = ldq_le_p(buf);
202
+ q[1] = ldq_le_p(buf + 8);
203
return 16;
204
}
205
}
206
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
207
switch (reg) {
208
case 0 ... 31:
209
/* 128 bit FP register */
210
- stq_le_p(buf, env->vfp.regs[reg * 2]);
211
- stq_le_p(buf + 8, env->vfp.regs[reg * 2 + 1]);
212
- return 16;
213
+ {
214
+ uint64_t *q = aa64_vfp_qreg(env, reg);
215
+ stq_le_p(buf, q[0]);
216
+ stq_le_p(buf + 8, q[1]);
217
+ return 16;
218
+ }
219
case 32:
220
/* FPSR */
221
stl_p(buf, vfp_get_fpsr(env));
222
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
223
switch (reg) {
224
case 0 ... 31:
225
/* 128 bit FP register */
226
- env->vfp.regs[reg * 2] = ldq_le_p(buf);
227
- env->vfp.regs[reg * 2 + 1] = ldq_le_p(buf + 8);
228
- return 16;
229
+ {
230
+ uint64_t *q = aa64_vfp_qreg(env, reg);
231
+ q[0] = ldq_le_p(buf);
232
+ q[1] = ldq_le_p(buf + 8);
233
+ return 16;
234
+ }
235
case 32:
236
/* FPSR */
237
vfp_set_fpsr(env, ldl_p(buf));
238
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
239
index XXXXXXX..XXXXXXX 100644
240
--- a/target/arm/kvm32.c
241
+++ b/target/arm/kvm32.c
242
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
243
/* VFP registers */
244
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
245
for (i = 0; i < 32; i++) {
246
- r.addr = (uintptr_t)(&env->vfp.regs[i]);
247
+ r.addr = (uintptr_t)aa32_vfp_dreg(env, i);
248
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
249
if (ret) {
250
return ret;
251
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
252
/* VFP registers */
253
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
254
for (i = 0; i < 32; i++) {
255
- r.addr = (uintptr_t)(&env->vfp.regs[i]);
256
+ r.addr = (uintptr_t)aa32_vfp_dreg(env, i);
257
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
258
if (ret) {
259
return ret;
260
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
261
index XXXXXXX..XXXXXXX 100644
262
--- a/target/arm/kvm64.c
263
+++ b/target/arm/kvm64.c
264
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
265
}
266
}
267
268
- /* Advanced SIMD and FP registers
269
- * We map Qn = regs[2n+1]:regs[2n]
270
- */
271
+ /* Advanced SIMD and FP registers. */
272
for (i = 0; i < 32; i++) {
273
- int rd = i << 1;
274
- uint64_t fp_val[2];
275
+ uint64_t *q = aa64_vfp_qreg(env, i);
276
#ifdef HOST_WORDS_BIGENDIAN
277
- fp_val[0] = env->vfp.regs[rd + 1];
278
- fp_val[1] = env->vfp.regs[rd];
279
+ uint64_t fp_val[2] = { q[1], q[0] };
280
+ reg.addr = (uintptr_t)fp_val;
281
#else
282
- fp_val[1] = env->vfp.regs[rd + 1];
283
- fp_val[0] = env->vfp.regs[rd];
284
+ reg.addr = (uintptr_t)q;
285
#endif
286
reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
287
- reg.addr = (uintptr_t)(&fp_val);
288
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
289
if (ret) {
290
return ret;
291
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
292
env->spsr = env->banked_spsr[i];
293
}
294
295
- /* Advanced SIMD and FP registers
296
- * We map Qn = regs[2n+1]:regs[2n]
297
- */
298
+ /* Advanced SIMD and FP registers */
299
for (i = 0; i < 32; i++) {
300
- uint64_t fp_val[2];
301
+ uint64_t *q = aa64_vfp_qreg(env, i);
302
reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
303
- reg.addr = (uintptr_t)(&fp_val);
304
+ reg.addr = (uintptr_t)q;
305
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
306
if (ret) {
307
return ret;
308
} else {
309
- int rd = i << 1;
310
#ifdef HOST_WORDS_BIGENDIAN
311
- env->vfp.regs[rd + 1] = fp_val[0];
312
- env->vfp.regs[rd] = fp_val[1];
313
-#else
314
- env->vfp.regs[rd + 1] = fp_val[1];
315
- env->vfp.regs[rd] = fp_val[0];
316
+ uint64_t t;
317
+ t = q[0], q[0] = q[1], q[1] = t;
318
#endif
319
}
320
}
321
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
322
index XXXXXXX..XXXXXXX 100644
323
--- a/target/arm/translate-a64.c
324
+++ b/target/arm/translate-a64.c
325
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
326
327
if (flags & CPU_DUMP_FPU) {
328
int numvfpregs = 32;
329
- for (i = 0; i < numvfpregs; i += 2) {
330
- uint64_t vlo = env->vfp.regs[i * 2];
331
- uint64_t vhi = env->vfp.regs[(i * 2) + 1];
332
- cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
333
- i, vhi, vlo);
334
- vlo = env->vfp.regs[(i + 1) * 2];
335
- vhi = env->vfp.regs[((i + 1) * 2) + 1];
336
- cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
337
- i + 1, vhi, vlo);
338
+ for (i = 0; i < numvfpregs; i++) {
339
+ uint64_t *q = aa64_vfp_qreg(env, i);
340
+ uint64_t vlo = q[0];
341
+ uint64_t vhi = q[1];
342
+ cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "%c",
343
+ i, vhi, vlo, (i & 1 ? '\n' : ' '));
344
}
345
cpu_fprintf(f, "FPCR: %08x FPSR: %08x\n",
346
vfp_get_fpcr(env), vfp_get_fpsr(env));
347
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vec_full_reg_ptr(DisasContext *s, int regno)
348
*/
349
static inline int fp_reg_offset(DisasContext *s, int regno, TCGMemOp size)
28
{
350
{
29
PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
351
- int offs = offsetof(CPUARMState, vfp.regs[regno * 2]);
30
- uint32_t ret;
352
-#ifdef HOST_WORDS_BIGENDIAN
31
+ uint32_t ret = 0;
353
- offs += (8 - (1 << size));
32
354
-#endif
33
switch (offset) {
355
- assert_fp_access_checked(s);
34
case MMC_STRPCL:
356
- return offs;
35
- return 0;
357
+ return vec_reg_offset(s, regno, 0, size);
36
+ break;
37
case MMC_STAT:
38
- return s->status;
39
+ ret = s->status;
40
+ break;
41
case MMC_CLKRT:
42
- return s->clkrt;
43
+ ret = s->clkrt;
44
+ break;
45
case MMC_SPI:
46
- return s->spi;
47
+ ret = s->spi;
48
+ break;
49
case MMC_CMDAT:
50
- return s->cmdat;
51
+ ret = s->cmdat;
52
+ break;
53
case MMC_RESTO:
54
- return s->resp_tout;
55
+ ret = s->resp_tout;
56
+ break;
57
case MMC_RDTO:
58
- return s->read_tout;
59
+ ret = s->read_tout;
60
+ break;
61
case MMC_BLKLEN:
62
- return s->blklen;
63
+ ret = s->blklen;
64
+ break;
65
case MMC_NUMBLK:
66
- return s->numblk;
67
+ ret = s->numblk;
68
+ break;
69
case MMC_PRTBUF:
70
- return 0;
71
+ break;
72
case MMC_I_MASK:
73
- return s->intmask;
74
+ ret = s->intmask;
75
+ break;
76
case MMC_I_REG:
77
- return s->intreq;
78
+ ret = s->intreq;
79
+ break;
80
case MMC_CMD:
81
- return s->cmd | 0x40;
82
+ ret = s->cmd | 0x40;
83
+ break;
84
case MMC_ARGH:
85
- return s->arg >> 16;
86
+ ret = s->arg >> 16;
87
+ break;
88
case MMC_ARGL:
89
- return s->arg & 0xffff;
90
+ ret = s->arg & 0xffff;
91
+ break;
92
case MMC_RES:
93
- if (s->resp_len < 9)
94
- return s->resp_fifo[s->resp_len ++];
95
- return 0;
96
+ ret = (s->resp_len < 9) ? s->resp_fifo[s->resp_len++] : 0;
97
+ break;
98
case MMC_RXFIFO:
99
- ret = 0;
100
while (size-- && s->rx_len) {
101
ret |= s->rx_fifo[s->rx_start++] << (size << 3);
102
s->rx_start &= 0x1f;
103
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_mmci_read(void *opaque, hwaddr offset, unsigned size)
104
}
105
s->intreq &= ~INT_RXFIFO_REQ;
106
pxa2xx_mmci_fifo_update(s);
107
- return ret;
108
+ break;
109
case MMC_RDWAIT:
110
- return 0;
111
+ break;
112
case MMC_BLKS_REM:
113
- return s->numblk;
114
+ ret = s->numblk;
115
+ break;
116
default:
117
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
118
+ qemu_log_mask(LOG_GUEST_ERROR,
119
+ "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
120
+ __func__, offset);
121
}
122
+ trace_pxa2xx_mmci_read(size, offset, ret);
123
124
- return 0;
125
+ return ret;
126
}
358
}
127
359
128
static void pxa2xx_mmci_write(void *opaque,
360
/* Offset of the high half of the 128 bit vector Qn */
129
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_write(void *opaque,
361
static inline int fp_reg_hi_offset(DisasContext *s, int regno)
130
{
362
{
131
PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
363
- assert_fp_access_checked(s);
132
364
- return offsetof(CPUARMState, vfp.regs[regno * 2 + 1]);
133
+ trace_pxa2xx_mmci_write(size, offset, value);
365
+ return vec_reg_offset(s, regno, 1, MO_64);
134
switch (offset) {
366
}
135
case MMC_STRPCL:
367
136
if (value & STRPCL_STRT_CLK) {
368
/* Convenience accessors for reading and writing single and double
137
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_write(void *opaque,
369
diff --git a/target/arm/translate.c b/target/arm/translate.c
138
370
index XXXXXXX..XXXXXXX 100644
139
case MMC_SPI:
371
--- a/target/arm/translate.c
140
s->spi = value & 0xf;
372
+++ b/target/arm/translate.c
141
- if (value & SPI_SPI_MODE)
373
@@ -XXX,XX +XXX,XX @@ static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
142
- printf("%s: attempted to use card in SPI mode\n", __FUNCTION__);
374
static inline long
143
+ if (value & SPI_SPI_MODE) {
375
vfp_reg_offset (int dp, int reg)
144
+ qemu_log_mask(LOG_GUEST_ERROR,
376
{
145
+ "%s: attempted to use card in SPI mode\n", __func__);
377
- if (dp)
378
+ if (dp) {
379
return offsetof(CPUARMState, vfp.regs[reg]);
380
- else if (reg & 1) {
381
- return offsetof(CPUARMState, vfp.regs[reg >> 1])
382
- + offsetof(CPU_DoubleU, l.upper);
383
} else {
384
- return offsetof(CPUARMState, vfp.regs[reg >> 1])
385
- + offsetof(CPU_DoubleU, l.lower);
386
+ long ofs = offsetof(CPUARMState, vfp.regs[reg >> 1]);
387
+ if (reg & 1) {
388
+ ofs += offsetof(CPU_DoubleU, l.upper);
389
+ } else {
390
+ ofs += offsetof(CPU_DoubleU, l.lower);
146
+ }
391
+ }
147
break;
392
+ return ofs;
148
149
case MMC_CMDAT:
150
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_write(void *opaque,
151
break;
152
153
default:
154
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
155
+ qemu_log_mask(LOG_GUEST_ERROR,
156
+ "%s: incorrect reg 0x%02" HWADDR_PRIx " "
157
+ "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
158
}
393
}
159
}
394
}
160
395
161
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
396
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
162
index XXXXXXX..XXXXXXX 100644
397
numvfpregs += 16;
163
--- a/hw/sd/trace-events
398
}
164
+++ b/hw/sd/trace-events
399
for (i = 0; i < numvfpregs; i++) {
165
@@ -XXX,XX +XXX,XX @@
400
- uint64_t v = env->vfp.regs[i];
166
# hw/sd/milkymist-memcard.c
401
+ uint64_t v = *aa32_vfp_dreg(env, i);
167
milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
402
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
168
milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
403
i * 2, (uint32_t)v,
169
+
404
i * 2 + 1, (uint32_t)(v >> 32),
170
+# hw/sd/pxa2xx_mmci.c
171
+pxa2xx_mmci_read(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
172
+pxa2xx_mmci_write(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
173
--
405
--
174
2.7.4
406
2.7.4
175
407
176
408
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Give big-endian arm and aarch64 CPUs their own family in
3
At the same time, move VMSTATE_UINT32_SUB_ARRAY
4
qemu-binfmt-conf.sh to make sure we register qemu-user for binaries of
4
beside the other UINT32 definitions.
5
the opposite endianness on arm and aarch64. Apart from the family
6
assignments of the magic values, qemu_get_family() needs to be able to
7
distinguish the two and recognise aarch64{,_be} as well.
8
5
9
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20171220212308.12614-7-michael.weiser@gmx.de
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180119045438.28582-8-richard.henderson@linaro.org
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
12
---
14
scripts/qemu-binfmt-conf.sh | 9 ++++++---
13
include/migration/vmstate.h | 9 ++++++---
15
1 file changed, 6 insertions(+), 3 deletions(-)
14
1 file changed, 6 insertions(+), 3 deletions(-)
16
15
17
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
16
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
18
index XXXXXXX..XXXXXXX 100755
17
index XXXXXXX..XXXXXXX 100644
19
--- a/scripts/qemu-binfmt-conf.sh
18
--- a/include/migration/vmstate.h
20
+++ b/scripts/qemu-binfmt-conf.sh
19
+++ b/include/migration/vmstate.h
21
@@ -XXX,XX +XXX,XX @@ arm_family=arm
20
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
22
21
#define VMSTATE_UINT32_ARRAY(_f, _s, _n) \
23
armeb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
22
VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0)
24
armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
23
25
-armeb_family=arm
24
+#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
26
+armeb_family=armeb
25
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
27
26
+
28
sparc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
27
#define VMSTATE_UINT32_2DARRAY(_f, _s, _n1, _n2) \
29
sparc_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
28
VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, 0)
30
@@ -XXX,XX +XXX,XX @@ aarch64_family=arm
29
31
30
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
32
aarch64_be_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7'
31
#define VMSTATE_UINT64_ARRAY(_f, _s, _n) \
33
aarch64_be_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
32
VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0)
34
-aarch64_be_family=arm
33
35
+aarch64_be_family=armeb
34
+#define VMSTATE_UINT64_SUB_ARRAY(_f, _s, _start, _num) \
36
35
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint64, uint64_t)
37
hppa_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f'
36
+
38
hppa_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
37
#define VMSTATE_UINT64_2DARRAY(_f, _s, _n1, _n2) \
39
@@ -XXX,XX +XXX,XX @@ qemu_get_family() {
38
VMSTATE_UINT64_2DARRAY_V(_f, _s, _n1, _n2, 0)
40
ppc64el|ppc64le)
39
41
echo "ppcle"
40
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
42
;;
41
#define VMSTATE_INT32_ARRAY(_f, _s, _n) \
43
- arm|armel|armhf|arm64|armv[4-9]*)
42
VMSTATE_INT32_ARRAY_V(_f, _s, _n, 0)
44
+ arm|armel|armhf|arm64|armv[4-9]*l|aarch64)
43
45
echo "arm"
44
-#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
46
;;
45
- VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
47
+ armeb|armv[4-9]*b|aarch64_be)
46
-
48
+ echo "armeb"
47
#define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v) \
49
+ ;;
48
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t)
50
sparc*)
49
51
echo "sparc"
52
;;
53
--
50
--
54
2.7.4
51
2.7.4
55
52
56
53
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Make big-endian aarch64 systems identify as aarch64_be as expected by
3
Not enabled anywhere so far.
4
big-endian userland and toolchains.
5
4
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180119045438.28582-11-richard.henderson@linaro.org
8
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20171220212308.12614-3-michael.weiser@gmx.de
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
linux-user/aarch64/target_syscall.h | 4 ++++
11
target/arm/cpu.h | 1 +
13
1 file changed, 4 insertions(+)
12
1 file changed, 1 insertion(+)
14
13
15
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/aarch64/target_syscall.h
16
--- a/target/arm/cpu.h
18
+++ b/linux-user/aarch64/target_syscall.h
17
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
18
@@ -XXX,XX +XXX,XX @@ enum arm_features {
20
uint64_t pstate;
19
ARM_FEATURE_VBAR, /* has cp15 VBAR */
20
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
21
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
22
+ ARM_FEATURE_SVE, /* has Scalable Vector Extension */
21
};
23
};
22
24
23
+#if defined(TARGET_WORDS_BIGENDIAN)
25
static inline int arm_feature(CPUARMState *env, int feature)
24
+#define UNAME_MACHINE "aarch64_be"
25
+#else
26
#define UNAME_MACHINE "aarch64"
27
+#endif
28
#define UNAME_MINIMUM_RELEASE "3.8.0"
29
#define TARGET_CLONE_BACKWARDS
30
#define TARGET_MINSIGSTKSZ 2048
31
--
26
--
32
2.7.4
27
2.7.4
33
28
34
29
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
Since for aarch64 the signal trampoline is synthesized directly into the
4
signal frame we need to make sure the instructions end up little-endian.
5
Otherwise the wrong endianness will cause a SIGILL upon return from the
6
signal handler on big-endian targets.
7
8
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20171220212308.12614-4-michael.weiser@gmx.de
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
linux-user/signal.c | 10 +++++++---
14
1 file changed, 7 insertions(+), 3 deletions(-)
15
16
diff --git a/linux-user/signal.c b/linux-user/signal.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/linux-user/signal.c
19
+++ b/linux-user/signal.c
20
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
21
if (ka->sa_flags & TARGET_SA_RESTORER) {
22
return_addr = ka->sa_restorer;
23
} else {
24
- /* mov x8,#__NR_rt_sigreturn; svc #0 */
25
- __put_user(0xd2801168, &frame->tramp[0]);
26
- __put_user(0xd4000001, &frame->tramp[1]);
27
+ /*
28
+ * mov x8,#__NR_rt_sigreturn; svc #0
29
+ * Since these are instructions they need to be put as little-endian
30
+ * regardless of target default or current CPU endianness.
31
+ */
32
+ __put_user_e(0xd2801168, &frame->tramp[0], le);
33
+ __put_user_e(0xd4000001, &frame->tramp[1], le);
34
return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
35
}
36
env->xregs[0] = usig;
37
--
38
2.7.4
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
Add target aarch64_be-linux-user. This allows a qemu-aarch64_be binary
4
to be built that will run big-endian aarch64 binaries.
5
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
9
Message-id: 20171220212308.12614-5-michael.weiser@gmx.de
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
configure | 5 +++--
13
default-configs/aarch64_be-linux-user.mak | 1 +
14
2 files changed, 4 insertions(+), 2 deletions(-)
15
create mode 100644 default-configs/aarch64_be-linux-user.mak
16
17
diff --git a/configure b/configure
18
index XXXXXXX..XXXXXXX 100755
19
--- a/configure
20
+++ b/configure
21
@@ -XXX,XX +XXX,XX @@ target_name=$(echo $target | cut -d '-' -f 1)
22
target_bigendian="no"
23
24
case "$target_name" in
25
- armeb|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
26
+ armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
27
target_bigendian=yes
28
;;
29
esac
30
@@ -XXX,XX +XXX,XX @@ case "$target_name" in
31
mttcg="yes"
32
gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
33
;;
34
- aarch64)
35
+ aarch64|aarch64_be)
36
+ TARGET_ARCH=aarch64
37
TARGET_BASE_ARCH=arm
38
bflt="yes"
39
mttcg="yes"
40
diff --git a/default-configs/aarch64_be-linux-user.mak b/default-configs/aarch64_be-linux-user.mak
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/default-configs/aarch64_be-linux-user.mak
45
@@ -0,0 +1 @@
46
+# Default configuration for aarch64_be-linux-user
47
--
48
2.7.4
49
50
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
As we now have a linux-user aarch64_be target, we can add it to the list
4
of supported targets in qemu-binfmt-conf.sh
5
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
7
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
8
Message-id: 20171220212308.12614-6-michael.weiser@gmx.de
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
scripts/qemu-binfmt-conf.sh | 6 +++++-
12
1 file changed, 5 insertions(+), 1 deletion(-)
13
14
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
15
index XXXXXXX..XXXXXXX 100755
16
--- a/scripts/qemu-binfmt-conf.sh
17
+++ b/scripts/qemu-binfmt-conf.sh
18
@@ -XXX,XX +XXX,XX @@
19
20
qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le m68k \
21
mips mipsel mipsn32 mipsn32el mips64 mips64el \
22
-sh4 sh4eb s390x aarch64 hppa"
23
+sh4 sh4eb s390x aarch64 aarch64_be hppa"
24
25
i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
26
i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
27
@@ -XXX,XX +XXX,XX @@ aarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x
28
aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
29
aarch64_family=arm
30
31
+aarch64_be_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7'
32
+aarch64_be_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
33
+aarch64_be_family=arm
34
+
35
hppa_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f'
36
hppa_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
37
hppa_family=hppa
38
--
39
2.7.4
40
41
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Some i.MX SoCs (e.g. i.MX7) have FEC registers going as far as offset
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
0x614, so to avoid getting aborts when accessing those on QEMU, extend
4
Message-id: 20180119045438.28582-14-richard.henderson@linaro.org
5
the register file to cover FSL_IMX25_FEC_SIZE(16K) of address space
6
instead of just 1K.
7
8
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Cc: Jason Wang <jasowang@redhat.com>
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
7
---
18
include/hw/arm/fsl-imx25.h | 1 -
8
target/arm/cpu.h | 127 +---------------------------------------------------
19
include/hw/net/imx_fec.h | 1 +
9
target/arm/helper.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
20
hw/net/imx_fec.c | 2 +-
10
2 files changed, 128 insertions(+), 125 deletions(-)
21
3 files changed, 2 insertions(+), 2 deletions(-)
11
22
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
24
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/fsl-imx25.h
14
--- a/target/arm/cpu.h
26
+++ b/include/hw/arm/fsl-imx25.h
15
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
16
@@ -XXX,XX +XXX,XX @@ static inline bool bswap_code(bool sctlr_b)
28
#define FSL_IMX25_UART5_ADDR 0x5002C000
17
#endif
29
#define FSL_IMX25_UART5_SIZE 0x4000
18
}
30
#define FSL_IMX25_FEC_ADDR 0x50038000
19
31
-#define FSL_IMX25_FEC_SIZE 0x4000
20
-/* Return the exception level to which FP-disabled exceptions should
32
#define FSL_IMX25_CCM_ADDR 0x53F80000
21
- * be taken, or 0 if FP is enabled.
33
#define FSL_IMX25_CCM_SIZE 0x4000
22
- */
34
#define FSL_IMX25_GPT4_ADDR 0x53F84000
23
-static inline int fp_exception_el(CPUARMState *env)
35
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
24
-{
25
- int fpen;
26
- int cur_el = arm_current_el(env);
27
-
28
- /* CPACR and the CPTR registers don't exist before v6, so FP is
29
- * always accessible
30
- */
31
- if (!arm_feature(env, ARM_FEATURE_V6)) {
32
- return 0;
33
- }
34
-
35
- /* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
36
- * 0, 2 : trap EL0 and EL1/PL1 accesses
37
- * 1 : trap only EL0 accesses
38
- * 3 : trap no accesses
39
- */
40
- fpen = extract32(env->cp15.cpacr_el1, 20, 2);
41
- switch (fpen) {
42
- case 0:
43
- case 2:
44
- if (cur_el == 0 || cur_el == 1) {
45
- /* Trap to PL1, which might be EL1 or EL3 */
46
- if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
47
- return 3;
48
- }
49
- return 1;
50
- }
51
- if (cur_el == 3 && !is_a64(env)) {
52
- /* Secure PL1 running at EL3 */
53
- return 3;
54
- }
55
- break;
56
- case 1:
57
- if (cur_el == 0) {
58
- return 1;
59
- }
60
- break;
61
- case 3:
62
- break;
63
- }
64
-
65
- /* For the CPTR registers we don't need to guard with an ARM_FEATURE
66
- * check because zero bits in the registers mean "don't trap".
67
- */
68
-
69
- /* CPTR_EL2 : present in v7VE or v8 */
70
- if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1)
71
- && !arm_is_secure_below_el3(env)) {
72
- /* Trap FP ops at EL2, NS-EL1 or NS-EL0 to EL2 */
73
- return 2;
74
- }
75
-
76
- /* CPTR_EL3 : present in v8 */
77
- if (extract32(env->cp15.cptr_el[3], 10, 1)) {
78
- /* Trap all FP ops to EL3 */
79
- return 3;
80
- }
81
-
82
- return 0;
83
-}
84
-
85
#ifdef CONFIG_USER_ONLY
86
static inline bool arm_cpu_bswap_data(CPUARMState *env)
87
{
88
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
89
}
90
#endif
91
92
-static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
93
- target_ulong *cs_base, uint32_t *flags)
94
-{
95
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
96
- if (is_a64(env)) {
97
- *pc = env->pc;
98
- *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
99
- /* Get control bits for tagged addresses */
100
- *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
101
- *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
102
- } else {
103
- *pc = env->regs[15];
104
- *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
105
- | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
106
- | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
107
- | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
108
- | (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
109
- if (!(access_secure_reg(env))) {
110
- *flags |= ARM_TBFLAG_NS_MASK;
111
- }
112
- if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
113
- || arm_el_is_aa64(env, 1)) {
114
- *flags |= ARM_TBFLAG_VFPEN_MASK;
115
- }
116
- *flags |= (extract32(env->cp15.c15_cpar, 0, 2)
117
- << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
118
- }
119
-
120
- *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
121
-
122
- /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
123
- * states defined in the ARM ARM for software singlestep:
124
- * SS_ACTIVE PSTATE.SS State
125
- * 0 x Inactive (the TB flag for SS is always 0)
126
- * 1 0 Active-pending
127
- * 1 1 Active-not-pending
128
- */
129
- if (arm_singlestep_active(env)) {
130
- *flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
131
- if (is_a64(env)) {
132
- if (env->pstate & PSTATE_SS) {
133
- *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
134
- }
135
- } else {
136
- if (env->uncached_cpsr & PSTATE_SS) {
137
- *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
138
- }
139
- }
140
- }
141
- if (arm_cpu_data_is_big_endian(env)) {
142
- *flags |= ARM_TBFLAG_BE_DATA_MASK;
143
- }
144
- *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
145
-
146
- if (arm_v7m_is_handler_mode(env)) {
147
- *flags |= ARM_TBFLAG_HANDLER_MASK;
148
- }
149
-
150
- *cs_base = 0;
151
-}
152
+void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
153
+ target_ulong *cs_base, uint32_t *flags);
154
155
enum {
156
QEMU_PSCI_CONDUIT_DISABLED = 0,
157
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
158
index XXXXXXX..XXXXXXX 100644
37
--- a/include/hw/net/imx_fec.h
159
--- a/target/arm/helper.c
38
+++ b/include/hw/net/imx_fec.h
160
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ typedef struct {
161
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
40
162
/* Linux crc32c converts the output to one's complement. */
41
#define ENET_TX_RING_NUM 3
163
return crc32c(acc, buf, bytes) ^ 0xffffffff;
42
164
}
43
+#define FSL_IMX25_FEC_SIZE 0x4000
165
+
44
166
+/* Return the exception level to which FP-disabled exceptions should
45
typedef struct IMXFECState {
167
+ * be taken, or 0 if FP is enabled.
46
/*< private >*/
168
+ */
47
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
169
+static inline int fp_exception_el(CPUARMState *env)
48
index XXXXXXX..XXXXXXX 100644
170
+{
49
--- a/hw/net/imx_fec.c
171
+ int fpen;
50
+++ b/hw/net/imx_fec.c
172
+ int cur_el = arm_current_el(env);
51
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
173
+
52
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
174
+ /* CPACR and the CPTR registers don't exist before v6, so FP is
53
175
+ * always accessible
54
memory_region_init_io(&s->iomem, OBJECT(dev), &imx_eth_ops, s,
176
+ */
55
- TYPE_IMX_FEC, 0x400);
177
+ if (!arm_feature(env, ARM_FEATURE_V6)) {
56
+ TYPE_IMX_FEC, FSL_IMX25_FEC_SIZE);
178
+ return 0;
57
sysbus_init_mmio(sbd, &s->iomem);
179
+ }
58
sysbus_init_irq(sbd, &s->irq[0]);
180
+
59
sysbus_init_irq(sbd, &s->irq[1]);
181
+ /* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
182
+ * 0, 2 : trap EL0 and EL1/PL1 accesses
183
+ * 1 : trap only EL0 accesses
184
+ * 3 : trap no accesses
185
+ */
186
+ fpen = extract32(env->cp15.cpacr_el1, 20, 2);
187
+ switch (fpen) {
188
+ case 0:
189
+ case 2:
190
+ if (cur_el == 0 || cur_el == 1) {
191
+ /* Trap to PL1, which might be EL1 or EL3 */
192
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
193
+ return 3;
194
+ }
195
+ return 1;
196
+ }
197
+ if (cur_el == 3 && !is_a64(env)) {
198
+ /* Secure PL1 running at EL3 */
199
+ return 3;
200
+ }
201
+ break;
202
+ case 1:
203
+ if (cur_el == 0) {
204
+ return 1;
205
+ }
206
+ break;
207
+ case 3:
208
+ break;
209
+ }
210
+
211
+ /* For the CPTR registers we don't need to guard with an ARM_FEATURE
212
+ * check because zero bits in the registers mean "don't trap".
213
+ */
214
+
215
+ /* CPTR_EL2 : present in v7VE or v8 */
216
+ if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1)
217
+ && !arm_is_secure_below_el3(env)) {
218
+ /* Trap FP ops at EL2, NS-EL1 or NS-EL0 to EL2 */
219
+ return 2;
220
+ }
221
+
222
+ /* CPTR_EL3 : present in v8 */
223
+ if (extract32(env->cp15.cptr_el[3], 10, 1)) {
224
+ /* Trap all FP ops to EL3 */
225
+ return 3;
226
+ }
227
+
228
+ return 0;
229
+}
230
+
231
+void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
232
+ target_ulong *cs_base, uint32_t *flags)
233
+{
234
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
235
+ if (is_a64(env)) {
236
+ *pc = env->pc;
237
+ *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
238
+ /* Get control bits for tagged addresses */
239
+ *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
240
+ *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
241
+ } else {
242
+ *pc = env->regs[15];
243
+ *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
244
+ | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
245
+ | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
246
+ | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
247
+ | (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
248
+ if (!(access_secure_reg(env))) {
249
+ *flags |= ARM_TBFLAG_NS_MASK;
250
+ }
251
+ if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
252
+ || arm_el_is_aa64(env, 1)) {
253
+ *flags |= ARM_TBFLAG_VFPEN_MASK;
254
+ }
255
+ *flags |= (extract32(env->cp15.c15_cpar, 0, 2)
256
+ << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
257
+ }
258
+
259
+ *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
260
+
261
+ /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
262
+ * states defined in the ARM ARM for software singlestep:
263
+ * SS_ACTIVE PSTATE.SS State
264
+ * 0 x Inactive (the TB flag for SS is always 0)
265
+ * 1 0 Active-pending
266
+ * 1 1 Active-not-pending
267
+ */
268
+ if (arm_singlestep_active(env)) {
269
+ *flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
270
+ if (is_a64(env)) {
271
+ if (env->pstate & PSTATE_SS) {
272
+ *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
273
+ }
274
+ } else {
275
+ if (env->uncached_cpsr & PSTATE_SS) {
276
+ *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
277
+ }
278
+ }
279
+ }
280
+ if (arm_cpu_data_is_big_endian(env)) {
281
+ *flags |= ARM_TBFLAG_BE_DATA_MASK;
282
+ }
283
+ *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
284
+
285
+ if (arm_v7m_is_handler_mode(env)) {
286
+ *flags |= ARM_TBFLAG_HANDLER_MASK;
287
+ }
288
+
289
+ *cs_base = 0;
290
+}
60
--
291
--
61
2.7.4
292
2.7.4
62
293
63
294
diff view generated by jsdifflib
1
From: Zhaoshenglong <zhaoshenglong@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
acpi_data_push uses g_array_set_size to resize the memory size. If there
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
is no enough contiguous memory, the address will be changed. If we use
4
Message-id: 20180119045438.28582-15-richard.henderson@linaro.org
5
the old value, it will assert.
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
qemu-kvm: hw/acpi/bios-linker-loader.c:214: bios_linker_loader_add_checksum:
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Assertion `start_offset < file->blob->len' failed.`
8
9
This issue only happens in building SRAT table now but here we unify the
10
pattern for other tables as well to avoid possible issues in the future.
11
12
Signed-off-by: Zhaoshenglong <zhaoshenglong@huawei.com>
13
Reviewed-by: Andrew Jones <drjones@redhat.com>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
8
---
16
hw/arm/virt-acpi-build.c | 18 +++++++++++-------
9
target/arm/helper.c | 35 +++++++++++++++++++----------------
17
1 file changed, 11 insertions(+), 7 deletions(-)
10
1 file changed, 19 insertions(+), 16 deletions(-)
18
11
19
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/virt-acpi-build.c
14
--- a/target/arm/helper.c
22
+++ b/hw/arm/virt-acpi-build.c
15
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
16
@@ -XXX,XX +XXX,XX @@ static inline int fp_exception_el(CPUARMState *env)
24
AcpiSerialPortConsoleRedirection *spcr;
25
const MemMapEntry *uart_memmap = &vms->memmap[VIRT_UART];
26
int irq = vms->irqmap[VIRT_UART] + ARM_SPI_BASE;
27
+ int spcr_start = table_data->len;
28
29
spcr = acpi_data_push(table_data, sizeof(*spcr));
30
31
@@ -XXX,XX +XXX,XX @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
32
spcr->pci_device_id = 0xffff; /* PCI Device ID: not a PCI device */
33
spcr->pci_vendor_id = 0xffff; /* PCI Vendor ID: not a PCI device */
34
35
- build_header(linker, table_data, (void *)spcr, "SPCR", sizeof(*spcr), 2,
36
- NULL, NULL);
37
+ build_header(linker, table_data, (void *)(table_data->data + spcr_start),
38
+ "SPCR", table_data->len - spcr_start, 2, NULL, NULL);
39
}
17
}
40
18
41
static void
19
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
42
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
20
- target_ulong *cs_base, uint32_t *flags)
43
mem_base += numa_info[i].node_mem;
21
+ target_ulong *cs_base, uint32_t *pflags)
22
{
23
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
24
+ uint32_t flags;
25
+
26
if (is_a64(env)) {
27
*pc = env->pc;
28
- *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
29
+ flags = ARM_TBFLAG_AARCH64_STATE_MASK;
30
/* Get control bits for tagged addresses */
31
- *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
32
- *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
33
+ flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
34
+ flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
35
} else {
36
*pc = env->regs[15];
37
- *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
38
+ flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
39
| (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
40
| (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
41
| (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
42
| (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
43
if (!(access_secure_reg(env))) {
44
- *flags |= ARM_TBFLAG_NS_MASK;
45
+ flags |= ARM_TBFLAG_NS_MASK;
46
}
47
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
48
|| arm_el_is_aa64(env, 1)) {
49
- *flags |= ARM_TBFLAG_VFPEN_MASK;
50
+ flags |= ARM_TBFLAG_VFPEN_MASK;
51
}
52
- *flags |= (extract32(env->cp15.c15_cpar, 0, 2)
53
- << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
54
+ flags |= (extract32(env->cp15.c15_cpar, 0, 2)
55
+ << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
44
}
56
}
45
57
46
- build_header(linker, table_data, (void *)srat, "SRAT",
58
- *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
47
- table_data->len - srat_start, 3, NULL, NULL);
59
+ flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
48
+ build_header(linker, table_data, (void *)(table_data->data + srat_start),
60
49
+ "SRAT", table_data->len - srat_start, 3, NULL, NULL);
61
/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
62
* states defined in the ARM ARM for software singlestep:
63
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
64
* 1 1 Active-not-pending
65
*/
66
if (arm_singlestep_active(env)) {
67
- *flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
68
+ flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
69
if (is_a64(env)) {
70
if (env->pstate & PSTATE_SS) {
71
- *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
72
+ flags |= ARM_TBFLAG_PSTATE_SS_MASK;
73
}
74
} else {
75
if (env->uncached_cpsr & PSTATE_SS) {
76
- *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
77
+ flags |= ARM_TBFLAG_PSTATE_SS_MASK;
78
}
79
}
80
}
81
if (arm_cpu_data_is_big_endian(env)) {
82
- *flags |= ARM_TBFLAG_BE_DATA_MASK;
83
+ flags |= ARM_TBFLAG_BE_DATA_MASK;
84
}
85
- *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
86
+ flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
87
88
if (arm_v7m_is_handler_mode(env)) {
89
- *flags |= ARM_TBFLAG_HANDLER_MASK;
90
+ flags |= ARM_TBFLAG_HANDLER_MASK;
91
}
92
93
+ *pflags = flags;
94
*cs_base = 0;
50
}
95
}
51
52
static void
53
@@ -XXX,XX +XXX,XX @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
54
AcpiTableMcfg *mcfg;
55
const MemMapEntry *memmap = vms->memmap;
56
int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
57
+ int mcfg_start = table_data->len;
58
59
mcfg = acpi_data_push(table_data, len);
60
mcfg->allocation[0].address = cpu_to_le64(memmap[VIRT_PCIE_ECAM].base);
61
@@ -XXX,XX +XXX,XX @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
62
mcfg->allocation[0].end_bus_number = (memmap[VIRT_PCIE_ECAM].size
63
/ PCIE_MMCFG_SIZE_MIN) - 1;
64
65
- build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
66
+ build_header(linker, table_data, (void *)(table_data->data + mcfg_start),
67
+ "MCFG", table_data->len - mcfg_start, 1, NULL, NULL);
68
}
69
70
/* GTDT */
71
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
72
static void build_fadt(GArray *table_data, BIOSLinker *linker,
73
VirtMachineState *vms, unsigned dsdt_tbl_offset)
74
{
75
+ int fadt_start = table_data->len;
76
AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
77
unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
78
uint16_t bootflags;
79
@@ -XXX,XX +XXX,XX @@ static void build_fadt(GArray *table_data, BIOSLinker *linker,
80
ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
81
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
82
83
- build_header(linker, table_data,
84
- (void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);
85
+ build_header(linker, table_data, (void *)(table_data->data + fadt_start),
86
+ "FACP", table_data->len - fadt_start, 5, NULL, NULL);
87
}
88
89
/* DSDT */
90
--
96
--
91
2.7.4
97
2.7.4
92
98
93
99
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Cc: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Cc: Jason Wang <jasowang@redhat.com>
4
Message-id: 20180119045438.28582-16-richard.henderson@linaro.org
5
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Cc: qemu-devel@nongnu.org
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Cc: qemu-arm@nongnu.org
8
Cc: yurovsky@gmail.com
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
8
---
13
hw/net/imx_fec.c | 2 +-
9
target/arm/helper.c | 3 ++-
14
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 2 insertions(+), 1 deletion(-)
15
11
16
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/imx_fec.c
14
--- a/target/arm/helper.c
19
+++ b/hw/net/imx_fec.c
15
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
16
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
21
TYPE_IMX_FEC, __func__);
17
*/
22
break;
18
static inline int fp_exception_el(CPUARMState *env)
23
}
19
{
24
- buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];
20
+#ifndef CONFIG_USER_ONLY
25
+ buf_len = MIN(size, s->regs[ENET_MRBR]);
21
int fpen;
26
bd.length = buf_len;
22
int cur_el = arm_current_el(env);
27
size -= buf_len;
23
24
@@ -XXX,XX +XXX,XX @@ static inline int fp_exception_el(CPUARMState *env)
25
/* Trap all FP ops to EL3 */
26
return 3;
27
}
28
-
29
+#endif
30
return 0;
31
}
28
32
29
--
33
--
30
2.7.4
34
2.7.4
31
35
32
36
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
2
3
Frame truncation length, TRUNC_FL, is determined by the contents of
3
In the GIC, when an IRQ is acknowledged, its state goes from "pending"
4
ENET_FTRL register, so convert the code to use it instead of a
4
to:
5
hardcoded constant.
5
- "active" if the corresponding IRQ pin has been de-asserted
6
- "active and pending" otherwise.
7
The GICv2 manual states that when a IRQ becomes active (or active and
8
pending), the GIC should either signal another (higher priority) IRQ to
9
the CPU if there is one, or de-assert the CPU IRQ pin.
6
10
7
To avoid the case where TRUNC_FL is greater that ENET_MAX_FRAME_SIZE,
11
The current implementation of the GIC in QEMU does not check if the
8
increase the value of the latter to its theoretical maximum of 16K.
12
IRQ is already active when looking for pending interrupts with
13
sufficient priority in gic_update(). This can lead to signaling an
14
interrupt that is already active.
9
15
10
Cc: Peter Maydell <peter.maydell@linaro.org>
16
This usually happens when splitting priority drop and interrupt
11
Cc: Jason Wang <jasowang@redhat.com>
17
deactivation. On priority drop, the IRQ stays active until deactivation.
12
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
If it becomes pending again, chances are that it will be incorrectly
13
Cc: qemu-devel@nongnu.org
19
selected as best_irq in gic_update().
14
Cc: qemu-arm@nongnu.org
20
15
Cc: yurovsky@gmail.com
21
This commit fixes this by checking if the IRQ is not already active when
16
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
22
looking for best_irq in gic_update().
23
24
Note that regarding the ARM11MPCore GIC version, the corresponding
25
manual is not clear on that point, but it has has no priority
26
drop/interrupt deactivation separation, so this case should not happen.
27
28
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
29
Message-id: 20180119145756.7629-3-luc.michel@greensocs.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
32
---
20
include/hw/net/imx_fec.h | 3 ++-
33
hw/intc/arm_gic.c | 1 +
21
hw/net/imx_fec.c | 4 ++--
34
1 file changed, 1 insertion(+)
22
2 files changed, 4 insertions(+), 3 deletions(-)
23
35
24
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
36
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
25
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/net/imx_fec.h
38
--- a/hw/intc/arm_gic.c
27
+++ b/include/hw/net/imx_fec.h
39
+++ b/hw/intc/arm_gic.c
28
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@ void gic_update(GICState *s)
29
#define ENET_TCCR3 393
41
best_irq = 1023;
30
#define ENET_MAX 400
42
for (irq = 0; irq < s->num_irq; irq++) {
31
43
if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm) &&
32
-#define ENET_MAX_FRAME_SIZE 2032
44
+ (!GIC_TEST_ACTIVE(irq, cm)) &&
33
45
(irq < GIC_INTERNAL || GIC_TARGET(irq) & cm)) {
34
/* EIR and EIMR */
46
if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
35
#define ENET_INT_HB (1 << 31)
47
best_prio = GIC_GET_PRIORITY(irq, cpu);
36
@@ -XXX,XX +XXX,XX @@
37
#define ENET_RCR_NLC (1 << 30)
38
#define ENET_RCR_GRS (1 << 31)
39
40
+#define ENET_MAX_FRAME_SIZE (1 << ENET_RCR_MAX_FL_LENGTH)
41
+
42
/* TCR */
43
#define ENET_TCR_GTS (1 << 0)
44
#define ENET_TCR_FDEN (1 << 2)
45
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/net/imx_fec.c
48
+++ b/hw/net/imx_fec.c
49
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
50
crc_ptr = (uint8_t *) &crc;
51
52
/* Huge frames are truncted. */
53
- if (size > ENET_MAX_FRAME_SIZE) {
54
- size = ENET_MAX_FRAME_SIZE;
55
+ if (size > s->regs[ENET_FTRL]) {
56
+ size = s->regs[ENET_FTRL];
57
flags |= ENET_BD_TR | ENET_BD_LG;
58
}
59
60
--
48
--
61
2.7.4
49
2.7.4
62
50
63
51
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
2
3
Make Tx frame assembly buffer to be a paort of IMXFECState structure
3
When there is no active interrupts in the GIC, a read to the C_RPR
4
to avoid a concern about having large data buffer on the stack.
4
register should return the value of the "Idle priority", which is either
5
the maximum value an IRQ priority field can be set to, or 0xff.
5
6
6
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Since the QEMU GIC model implements all the 8 priority bits, the Idle
7
Cc: Jason Wang <jasowang@redhat.com>
8
priority is 0xff.
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
9
Cc: qemu-devel@nongnu.org
10
Internally, when there is no active interrupt, the running priority
10
Cc: qemu-arm@nongnu.org
11
value is 0x100. The gic_get_running_priority function returns an uint8_t
11
Cc: yurovsky@gmail.com
12
and thus, truncate this value to 0x00 when returning it. This is wrong since
12
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
13
a value of 0x00 correspond to the maximum possible priority.
14
15
This commit fixes the returned value when the internal value is 0x100.
16
17
Note that it is correct for the Non-Secure view to return 0xff even
18
though from the NS world point of view, only 7 priority bits are
19
implemented. The specification states that the Idle priority can be 0xff
20
even when not all the 8 priority bits are implemented. This has been
21
verified against a real GICv2 hardware on a Xilinx ZynqMP based board.
22
23
Regarding the ARM11MPCore version of the GIC, the specification is not
24
clear on that point, so this commit does not alter its behavior.
25
26
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
27
Message-id: 20180119145756.7629-4-luc.michel@greensocs.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
30
---
16
include/hw/net/imx_fec.h | 3 +++
31
hw/intc/arm_gic.c | 5 +++++
17
hw/net/imx_fec.c | 22 +++++++++++-----------
32
1 file changed, 5 insertions(+)
18
2 files changed, 14 insertions(+), 11 deletions(-)
19
33
20
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
34
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
21
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/net/imx_fec.h
36
--- a/hw/intc/arm_gic.c
23
+++ b/include/hw/net/imx_fec.h
37
+++ b/hw/intc/arm_gic.c
24
@@ -XXX,XX +XXX,XX @@ typedef struct IMXFECState {
38
@@ -XXX,XX +XXX,XX @@ static void gic_set_cpu_control(GICState *s, int cpu, uint32_t value,
25
uint32_t phy_int_mask;
39
26
40
static uint8_t gic_get_running_priority(GICState *s, int cpu, MemTxAttrs attrs)
27
bool is_fec;
41
{
42
+ if ((s->revision != REV_11MPCORE) && (s->running_priority[cpu] > 0xff)) {
43
+ /* Idle priority */
44
+ return 0xff;
45
+ }
28
+
46
+
29
+ /* Buffer used to assemble a Tx frame */
47
if (s->security_extn && !attrs.secure) {
30
+ uint8_t frame[ENET_MAX_FRAME_SIZE];
48
if (s->running_priority[cpu] & 0x80) {
31
} IMXFECState;
49
/* Running priority in upper half of range: return the Non-secure
32
33
#endif
34
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/net/imx_fec.c
37
+++ b/hw/net/imx_fec.c
38
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s)
39
static void imx_fec_do_tx(IMXFECState *s)
40
{
41
int frame_size = 0, descnt = 0;
42
- uint8_t frame[ENET_MAX_FRAME_SIZE];
43
- uint8_t *ptr = frame;
44
+ uint8_t *ptr = s->frame;
45
uint32_t addr = s->tx_descriptor;
46
47
while (descnt++ < IMX_MAX_DESC) {
48
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
49
frame_size += len;
50
if (bd.flags & ENET_BD_L) {
51
/* Last buffer in frame. */
52
- qemu_send_packet(qemu_get_queue(s->nic), frame, frame_size);
53
- ptr = frame;
54
+ qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
55
+ ptr = s->frame;
56
frame_size = 0;
57
s->regs[ENET_EIR] |= ENET_INT_TXF;
58
}
59
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
60
static void imx_enet_do_tx(IMXFECState *s)
61
{
62
int frame_size = 0, descnt = 0;
63
- uint8_t frame[ENET_MAX_FRAME_SIZE];
64
- uint8_t *ptr = frame;
65
+ uint8_t *ptr = s->frame;
66
uint32_t addr = s->tx_descriptor;
67
68
while (descnt++ < IMX_MAX_DESC) {
69
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s)
70
frame_size += len;
71
if (bd.flags & ENET_BD_L) {
72
if (bd.option & ENET_BD_PINS) {
73
- struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
74
+ struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
75
if (IP_HEADER_VERSION(ip_hd) == 4) {
76
- net_checksum_calculate(frame, frame_size);
77
+ net_checksum_calculate(s->frame, frame_size);
78
}
79
}
80
if (bd.option & ENET_BD_IINS) {
81
- struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
82
+ struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
83
/* We compute checksum only for IPv4 frames */
84
if (IP_HEADER_VERSION(ip_hd) == 4) {
85
uint16_t csum;
86
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s)
87
}
88
}
89
/* Last buffer in frame. */
90
- qemu_send_packet(qemu_get_queue(s->nic), frame, len);
91
- ptr = frame;
92
+
93
+ qemu_send_packet(qemu_get_queue(s->nic), s->frame, len);
94
+ ptr = s->frame;
95
+
96
frame_size = 0;
97
if (bd.option & ENET_BD_TX_INT) {
98
s->regs[ENET_EIR] |= ENET_INT_TXF;
99
--
50
--
100
2.7.4
51
2.7.4
101
52
102
53
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
2
3
Binding to a particular netdev doesn't seem to belong to this layer
3
When determining the group priority of a group 1 IRQ, if C_CTRL.CBPR is
4
and should probably be done as a part of board or SoC specific code.
4
0, the non-secure BPR value is used. However, this value must be
5
incremented by one so that it matches the secure world number of
6
implemented priority bits (NS world has one less priority bit compared
7
to the Secure world).
5
8
6
Convert all of the users of this IP block to use
9
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
7
qdev_set_nic_properties() instead.
10
Message-id: 20180119145756.7629-5-luc.michel@greensocs.com
8
9
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Jason Wang <jasowang@redhat.com>
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Cc: qemu-devel@nongnu.org
13
Cc: qemu-arm@nongnu.org
14
Cc: yurovsky@gmail.com
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
12
[PMM: add assert, as the gicv3 code has]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
14
---
19
hw/arm/fsl-imx6.c | 1 +
15
hw/intc/arm_gic.c | 3 ++-
20
hw/net/imx_fec.c | 2 --
16
1 file changed, 2 insertions(+), 1 deletion(-)
21
2 files changed, 1 insertion(+), 2 deletions(-)
22
17
23
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
18
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
24
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/fsl-imx6.c
20
--- a/hw/intc/arm_gic.c
26
+++ b/hw/arm/fsl-imx6.c
21
+++ b/hw/intc/arm_gic.c
27
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
22
@@ -XXX,XX +XXX,XX @@ static int gic_get_group_priority(GICState *s, int cpu, int irq)
28
spi_table[i].irq));
23
if (gic_has_groups(s) &&
24
!(s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) &&
25
GIC_TEST_GROUP(irq, (1 << cpu))) {
26
- bpr = s->abpr[cpu];
27
+ bpr = s->abpr[cpu] - 1;
28
+ assert(bpr >= 0);
29
} else {
30
bpr = s->bpr[cpu];
29
}
31
}
30
31
+ qdev_set_nic_properties(DEVICE(&s->eth), &nd_table[0]);
32
object_property_set_bool(OBJECT(&s->eth), true, "realized", &err);
33
if (err) {
34
error_propagate(errp, err);
35
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/net/imx_fec.c
38
+++ b/hw/net/imx_fec.c
39
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
40
41
qemu_macaddr_default_if_unset(&s->conf.macaddr);
42
43
- s->conf.peers.ncs[0] = nd_table[0].netdev;
44
-
45
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
46
object_get_typename(OBJECT(dev)),
47
DEVICE(dev)->id, s);
48
--
32
--
49
2.7.4
33
2.7.4
50
34
51
35
diff view generated by jsdifflib
1
The GICv2 specification says that reserved register addresses
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
must RAZ/WI; now that we implement external abort handling
3
for Arm CPUs this means we must return MEMTX_OK rather than
4
MEMTX_ERROR, to avoid generating a spurious guest data abort.
5
2
6
Cc: qemu-stable@nongnu.org
3
When C_CTRL.CBPR is 1, the Non-Secure view of C_BPR is altered:
4
- A Non-Secure read of C_BPR should return the BPR value plus 1,
5
saturated to 7,
6
- A Non-Secure write should be ignored.
7
8
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
9
Message-id: 20180119145756.7629-6-luc.michel@greensocs.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: fixed comment typo]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1513183941-24300-3-git-send-email-peter.maydell@linaro.org
9
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
10
---
13
---
11
hw/intc/arm_gic.c | 5 +++--
14
hw/intc/arm_gic.c | 16 +++++++++++++---
12
1 file changed, 3 insertions(+), 2 deletions(-)
15
1 file changed, 13 insertions(+), 3 deletions(-)
13
16
14
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
17
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gic.c
19
--- a/hw/intc/arm_gic.c
17
+++ b/hw/intc/arm_gic.c
20
+++ b/hw/intc/arm_gic.c
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
21
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
19
default:
22
break;
20
qemu_log_mask(LOG_GUEST_ERROR,
23
case 0x08: /* Binary Point */
21
"gic_cpu_read: Bad offset %x\n", (int)offset);
24
if (s->security_extn && !attrs.secure) {
22
- return MEMTX_ERROR;
25
- /* BPR is banked. Non-secure copy stored in ABPR. */
23
+ *data = 0;
26
- *data = s->abpr[cpu];
24
+ break;
27
+ if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
25
}
28
+ /* NS view of BPR when CBPR is 1 */
26
return MEMTX_OK;
29
+ *data = MIN(s->bpr[cpu] + 1, 7);
27
}
30
+ } else {
31
+ /* BPR is banked. Non-secure copy stored in ABPR. */
32
+ *data = s->abpr[cpu];
33
+ }
34
} else {
35
*data = s->bpr[cpu];
36
}
28
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
37
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
29
default:
38
break;
30
qemu_log_mask(LOG_GUEST_ERROR,
39
case 0x08: /* Binary Point */
31
"gic_cpu_write: Bad offset %x\n", (int)offset);
40
if (s->security_extn && !attrs.secure) {
32
- return MEMTX_ERROR;
41
- s->abpr[cpu] = MAX(value & 0x7, GIC_MIN_ABPR);
33
+ return MEMTX_OK;
42
+ if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
34
}
43
+ /* WI when CBPR is 1 */
35
gic_update(s);
44
+ return MEMTX_OK;
36
return MEMTX_OK;
45
+ } else {
46
+ s->abpr[cpu] = MAX(value & 0x7, GIC_MIN_ABPR);
47
+ }
48
} else {
49
s->bpr[cpu] = MAX(value & 0x7, GIC_MIN_BPR);
50
}
37
--
51
--
38
2.7.4
52
2.7.4
39
53
40
54
diff view generated by jsdifflib
1
From: Michael Weiser <michael.weiser@gmx.de>
1
We were passing a NULL error pointer to the object_property_set_bool()
2
call that realizes the CPU object. This meant that we wouldn't detect
3
failure, and would plough blindly on to crash later trying to use a
4
NULL CPU object pointer. Detect errors and fail instead.
2
5
3
armeb is missing from the target list in qemu-binfmt-conf.sh. Add it so
6
In particular, this will be necessary to detect the user error
4
the handler for those binaries gets registered by the script.
7
of using "-cpu host" without "-enable-kvm" once we make the host
8
CPU type be registered unconditionally rather than only in
9
kvm_arch_init().
5
10
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
7
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
8
Message-id: 20171220212308.12614-8-michael.weiser@gmx.de
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
scripts/qemu-binfmt-conf.sh | 2 +-
13
hw/arm/virt.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
13
15
14
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
16
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100755
17
index XXXXXXX..XXXXXXX 100644
16
--- a/scripts/qemu-binfmt-conf.sh
18
--- a/hw/arm/virt.c
17
+++ b/scripts/qemu-binfmt-conf.sh
19
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
19
# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390/HPPA
21
"secure-memory", &error_abort);
20
# program execution by the kernel
22
}
21
23
22
-qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le m68k \
24
- object_property_set_bool(cpuobj, true, "realized", NULL);
23
+qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k \
25
+ object_property_set_bool(cpuobj, true, "realized", &error_fatal);
24
mips mipsel mipsn32 mipsn32el mips64 mips64el \
26
object_unref(cpuobj);
25
sh4 sh4eb s390x aarch64 aarch64_be hppa"
27
}
26
28
fdt_add_timer_nodes(vms);
27
--
29
--
28
2.7.4
30
2.7.4
29
31
30
32
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
missed in 60765b6ceeb4.
4
5
Thread 1 "qemu-system-aarch64" received signal SIGSEGV, Segmentation fault.
6
address_space_init (as=0x0, root=0x55555726e410, name=name@entry=0x555555e3f0a7 "sdhci-dma") at memory.c:3050
7
3050     as->root = root;
8
(gdb) bt
9
#0 address_space_init (as=0x0, root=0x55555726e410, name=name@entry=0x555555e3f0a7 "sdhci-dma") at memory.c:3050
10
#1 0x0000555555af62c3 in sdhci_sysbus_realize (dev=<optimized out>, errp=0x7fff7f931150) at hw/sd/sdhci.c:1564
11
#2 0x00005555558b25e5 in zynqmp_sdhci_realize (dev=0x555557051520, errp=0x7fff7f931150) at hw/sd/zynqmp-sdhci.c:151
12
#3 0x0000555555a2e7f3 in device_set_realized (obj=0x555557051520, value=<optimized out>, errp=0x7fff7f931270) at hw/core/qdev.c:966
13
#4 0x0000555555ba3f74 in property_set_bool (obj=0x555557051520, v=<optimized out>, name=<optimized out>, opaque=0x555556e04a20,
14
errp=0x7fff7f931270) at qom/object.c:1906
15
#5 0x0000555555ba51f4 in object_property_set (obj=obj@entry=0x555557051520, v=v@entry=0x5555576dbd60,
16
name=name@entry=0x555555dd6306 "realized", errp=errp@entry=0x7fff7f931270) at qom/object.c:1102
17
18
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
20
Message-id: 20180123132051.24448-1-f4bug@amsat.org
5
Message-id: 20180103224208.30291-2-f4bug@amsat.org
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
23
---
8
hw/timer/pxa2xx_timer.c | 17 +++++++++++++++--
24
include/hw/sd/sdhci.h | 1 +
9
1 file changed, 15 insertions(+), 2 deletions(-)
25
hw/sd/sdhci.c | 1 +
26
2 files changed, 2 insertions(+)
10
27
11
diff --git a/hw/timer/pxa2xx_timer.c b/hw/timer/pxa2xx_timer.c
28
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
12
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/timer/pxa2xx_timer.c
30
--- a/include/hw/sd/sdhci.h
14
+++ b/hw/timer/pxa2xx_timer.c
31
+++ b/include/hw/sd/sdhci.h
15
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
16
#include "sysemu/sysemu.h"
33
/*< public >*/
17
#include "hw/arm/pxa.h"
34
SDBus sdbus;
18
#include "hw/sysbus.h"
35
MemoryRegion iomem;
19
+#include "qemu/log.h"
36
+ AddressSpace sysbus_dma_as;
20
37
AddressSpace *dma_as;
21
#define OSMR0    0x00
38
MemoryRegion *dma_mr;
22
#define OSMR1    0x04
39
23
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
40
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
24
case OSNR:
41
index XXXXXXX..XXXXXXX 100644
25
return s->snapshot;
42
--- a/hw/sd/sdhci.c
26
default:
43
+++ b/hw/sd/sdhci.c
27
+ qemu_log_mask(LOG_UNIMP,
44
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
28
+ "%s: unknown register 0x%02" HWADDR_PRIx "\n",
29
+ __func__, offset);
30
+ break;
31
badreg:
32
- hw_error("pxa2xx_timer_read: Bad offset " REG_FMT "\n", offset);
33
+ qemu_log_mask(LOG_GUEST_ERROR,
34
+ "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
35
+ __func__, offset);
36
}
45
}
37
46
38
return 0;
47
if (s->dma_mr) {
39
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
48
+ s->dma_as = &s->sysbus_dma_as;
40
}
49
address_space_init(s->dma_as, s->dma_mr, "sdhci-dma");
41
break;
50
} else {
42
default:
51
/* use system_memory() if property "dma" not set */
43
+ qemu_log_mask(LOG_UNIMP,
44
+ "%s: unknown register 0x%02" HWADDR_PRIx " "
45
+ "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
46
+ break;
47
badreg:
48
- hw_error("pxa2xx_timer_write: Bad offset " REG_FMT "\n", offset);
49
+ qemu_log_mask(LOG_GUEST_ERROR,
50
+ "%s: incorrect register 0x%02" HWADDR_PRIx " "
51
+ "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
52
}
53
}
54
55
--
52
--
56
2.7.4
53
2.7.4
57
54
58
55
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
2
2
3
Needed to support latest Linux kernel driver which relies on that
3
Coverity found that the variable tx_rx in the function
4
functionality.
4
xilinx_spips_flush_txfifo was being used uninitialized (CID 1383841). This
5
patch corrects this by always initializing tx_rx to zeros.
5
6
6
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Cc: Jason Wang <jasowang@redhat.com>
8
Message-id: 20180124215708.30400-1-frasse.iglesias@gmail.com
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: yurovsky@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
11
---
16
include/hw/net/imx_fec.h | 2 ++
12
hw/ssi/xilinx_spips.c | 18 +++++++++++++++++-
17
hw/net/imx_fec.c | 23 +++++++++++++++++++++++
13
1 file changed, 17 insertions(+), 1 deletion(-)
18
2 files changed, 25 insertions(+)
19
14
20
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/net/imx_fec.h
17
--- a/hw/ssi/xilinx_spips.c
23
+++ b/include/hw/net/imx_fec.h
18
+++ b/hw/ssi/xilinx_spips.c
24
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
25
#define ENET_TWFR_TFWR_LENGTH (6)
20
#define SNOOP_NONE 0xEE
26
#define ENET_TWFR_STRFWD (1 << 8)
21
#define SNOOP_STRIPING 0
27
22
28
+#define ENET_RACC_SHIFT16 BIT(7)
23
+#define MIN_NUM_BUSSES 1
24
+#define MAX_NUM_BUSSES 2
29
+
25
+
30
/* Buffer Descriptor. */
26
static inline int num_effective_busses(XilinxSPIPS *s)
31
typedef struct {
27
{
32
uint16_t length;
28
return (s->regs[R_LQSPI_CFG] & LQSPI_CFG_SEP_BUS &&
33
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
29
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
34
index XXXXXXX..XXXXXXX 100644
30
for (;;) {
35
--- a/hw/net/imx_fec.c
31
int i;
36
+++ b/hw/net/imx_fec.c
32
uint8_t tx = 0;
37
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
33
- uint8_t tx_rx[num_effective_busses(s)];
38
uint8_t *crc_ptr;
34
+ uint8_t tx_rx[MAX_NUM_BUSSES] = { 0 };
39
unsigned int buf_len;
35
uint8_t dummy_cycles = 0;
40
size_t size = len;
36
uint8_t addr_length;
41
+ bool shift16 = s->regs[ENET_RACC] & ENET_RACC_SHIFT16;
37
42
38
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
43
FEC_PRINTF("len %d\n", (int)size);
39
44
40
DB_PRINT_L(0, "realized spips\n");
45
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
41
46
crc = cpu_to_be32(crc32(~0, buf, size));
42
+ if (s->num_busses > MAX_NUM_BUSSES) {
47
crc_ptr = (uint8_t *) &crc;
43
+ error_setg(errp,
48
44
+ "requested number of SPI busses %u exceeds maximum %d",
49
+ if (shift16) {
45
+ s->num_busses, MAX_NUM_BUSSES);
50
+ size += 2;
46
+ return;
47
+ }
48
+ if (s->num_busses < MIN_NUM_BUSSES) {
49
+ error_setg(errp,
50
+ "requested number of SPI busses %u is below minimum %d",
51
+ s->num_busses, MIN_NUM_BUSSES);
52
+ return;
51
+ }
53
+ }
52
+
54
+
53
/* Huge frames are truncted. */
55
s->spi = g_new(SSIBus *, s->num_busses);
54
if (size > s->regs[ENET_FTRL]) {
56
for (i = 0; i < s->num_busses; ++i) {
55
size = s->regs[ENET_FTRL];
57
char bus_name[16];
56
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
57
buf_len += size - 4;
58
}
59
buf_addr = bd.data;
60
+
61
+ if (shift16) {
62
+ /*
63
+ * If SHIFT16 bit of ENETx_RACC register is set we need to
64
+ * align the payload to 4-byte boundary.
65
+ */
66
+ const uint8_t zeros[2] = { 0 };
67
+
68
+ dma_memory_write(&address_space_memory, buf_addr,
69
+ zeros, sizeof(zeros));
70
+
71
+ buf_addr += sizeof(zeros);
72
+ buf_len -= sizeof(zeros);
73
+
74
+ /* We only do this once per Ethernet frame */
75
+ shift16 = false;
76
+ }
77
+
78
dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
79
buf += buf_len;
80
if (size < 4) {
81
--
58
--
82
2.7.4
59
2.7.4
83
60
84
61
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Linus Walleij <linus.walleij@linaro.org>
2
2
3
More recent version of the IP block support more than one Tx DMA ring,
3
This implements rudimentary support for interrupt generation on the
4
so add the code implementing that feature.
4
PL110. I am working on a new DRI/KMS driver for Linux and since that
5
uses the blanking interrupt, we need something to fire here. Without
6
any interrupt support Linux waits for a while and then gives ugly
7
messages about the vblank not working in the console (it does not
8
hang perpetually or anything though, DRI is pretty forgiving).
9
10
I solved it for now by setting up a timer to fire at 60Hz and pull
11
the interrupts for "vertical compare" and "next memory base"
12
at this interval. This works fine and fires roughly the same number
13
of IRQs on QEMU as on the hardware and leaves the console clean
14
and nice.
15
16
People who want to create more accurate emulation can probably work
17
on top of this if need be. It is certainly closer to the hardware
18
behaviour than what we have today anyway.
5
19
6
Cc: Peter Maydell <peter.maydell@linaro.org>
20
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Cc: Jason Wang <jasowang@redhat.com>
21
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Message-id: 20180123225654.5764-1-linus.walleij@linaro.org
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: yurovsky@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
24
[PMM: folded long lines]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
26
---
16
include/hw/net/imx_fec.h | 18 ++++++-
27
hw/display/pl110.c | 30 +++++++++++++++++++++++++++++-
17
hw/net/imx_fec.c | 133 ++++++++++++++++++++++++++++++++++++++++-------
28
1 file changed, 29 insertions(+), 1 deletion(-)
18
2 files changed, 130 insertions(+), 21 deletions(-)
19
29
20
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
30
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
21
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/net/imx_fec.h
32
--- a/hw/display/pl110.c
23
+++ b/include/hw/net/imx_fec.h
33
+++ b/hw/display/pl110.c
24
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
25
#define ENET_TFWR 81
35
#include "ui/console.h"
26
#define ENET_FRBR 83
36
#include "framebuffer.h"
27
#define ENET_FRSR 84
37
#include "ui/pixel_ops.h"
28
+#define ENET_TDSR1 89
38
+#include "qemu/timer.h"
29
+#define ENET_TDSR2 92
39
#include "qemu/log.h"
30
#define ENET_RDSR 96
40
31
#define ENET_TDSR 97
41
#define PL110_CR_EN 0x001
32
#define ENET_MRBR 98
33
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@
34
#define ENET_FTRL 108
43
#define PL110_CR_BEBO 0x200
35
#define ENET_TACC 112
44
#define PL110_CR_BEPO 0x400
36
#define ENET_RACC 113
45
#define PL110_CR_PWR 0x800
37
+#define ENET_TDAR1 121
46
+#define PL110_IE_NB 0x004
38
+#define ENET_TDAR2 123
47
+#define PL110_IE_VC 0x008
39
#define ENET_MIIGSK_CFGR 192
48
40
#define ENET_MIIGSK_ENR 194
49
enum pl110_bppmode
41
#define ENET_ATCR 256
50
{
42
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@ typedef struct PL110State {
43
#define ENET_INT_WAKEUP (1 << 17)
52
MemoryRegion iomem;
44
#define ENET_INT_TS_AVAIL (1 << 16)
53
MemoryRegionSection fbsection;
45
#define ENET_INT_TS_TIMER (1 << 15)
54
QemuConsole *con;
46
+#define ENET_INT_TXF2 (1 << 7)
55
+ QEMUTimer *vblank_timer;
47
+#define ENET_INT_TXB2 (1 << 6)
56
48
+#define ENET_INT_TXF1 (1 << 3)
57
int version;
49
+#define ENET_INT_TXB1 (1 << 2)
58
uint32_t timing[4];
50
59
@@ -XXX,XX +XXX,XX @@ static void pl110_resize(PL110State *s, int width, int height)
51
#define ENET_INT_MAC (ENET_INT_HB | ENET_INT_BABR | ENET_INT_BABT | \
60
/* Update interrupts. */
52
ENET_INT_GRA | ENET_INT_TXF | ENET_INT_TXB | \
61
static void pl110_update(PL110State *s)
53
ENET_INT_RXF | ENET_INT_RXB | ENET_INT_MII | \
62
{
54
ENET_INT_EBERR | ENET_INT_LC | ENET_INT_RL | \
63
- /* TODO: Implement interrupts. */
55
ENET_INT_UN | ENET_INT_PLR | ENET_INT_WAKEUP | \
64
+ /* Raise IRQ if enabled and any status bit is 1 */
56
- ENET_INT_TS_AVAIL)
65
+ if (s->int_status & s->int_mask) {
57
+ ENET_INT_TS_AVAIL | ENET_INT_TXF1 | \
66
+ qemu_irq_raise(s->irq);
58
+ ENET_INT_TXB1 | ENET_INT_TXF2 | ENET_INT_TXB2)
67
+ } else {
59
68
+ qemu_irq_lower(s->irq);
60
/* RDAR */
69
+ }
61
#define ENET_RDAR_RDAR (1 << 24)
62
@@ -XXX,XX +XXX,XX @@ typedef struct {
63
64
#define ENET_BD_BDU (1 << 31)
65
66
+#define ENET_TX_RING_NUM 3
67
+
68
+
69
typedef struct IMXFECState {
70
/*< private >*/
71
SysBusDevice parent_obj;
72
@@ -XXX,XX +XXX,XX @@ typedef struct IMXFECState {
73
74
uint32_t regs[ENET_MAX];
75
uint32_t rx_descriptor;
76
- uint32_t tx_descriptor;
77
+
78
+ uint32_t tx_descriptor[ENET_TX_RING_NUM];
79
+ uint32_t tx_ring_num;
80
81
uint32_t phy_status;
82
uint32_t phy_control;
83
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/net/imx_fec.c
86
+++ b/hw/net/imx_fec.c
87
@@ -XXX,XX +XXX,XX @@ static const char *imx_eth_reg_name(IMXFECState *s, uint32_t index)
88
}
89
}
90
91
+/*
92
+ * Versions of this device with more than one TX descriptor save the
93
+ * 2nd and 3rd descriptors in a subsection, to maintain migration
94
+ * compatibility with previous versions of the device that only
95
+ * supported a single descriptor.
96
+ */
97
+static bool imx_eth_is_multi_tx_ring(void *opaque)
98
+{
99
+ IMXFECState *s = IMX_FEC(opaque);
100
+
101
+ return s->tx_ring_num > 1;
102
+}
70
+}
103
+
71
+
104
+static const VMStateDescription vmstate_imx_eth_txdescs = {
72
+static void pl110_vblank_interrupt(void *opaque)
105
+ .name = "imx.fec/txdescs",
73
+{
106
+ .version_id = 1,
74
+ PL110State *s = opaque;
107
+ .minimum_version_id = 1,
108
+ .needed = imx_eth_is_multi_tx_ring,
109
+ .fields = (VMStateField[]) {
110
+ VMSTATE_UINT32(tx_descriptor[1], IMXFECState),
111
+ VMSTATE_UINT32(tx_descriptor[2], IMXFECState),
112
+ VMSTATE_END_OF_LIST()
113
+ }
114
+};
115
+
75
+
116
static const VMStateDescription vmstate_imx_eth = {
76
+ /* Fire the vertical compare and next base IRQs and re-arm */
117
.name = TYPE_IMX_FEC,
77
+ s->int_status |= (PL110_IE_NB | PL110_IE_VC);
118
.version_id = 2,
78
+ timer_mod(s->vblank_timer,
119
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
79
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
120
.fields = (VMStateField[]) {
80
+ NANOSECONDS_PER_SECOND / 60);
121
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
81
+ pl110_update(s);
122
VMSTATE_UINT32(rx_descriptor, IMXFECState),
123
- VMSTATE_UINT32(tx_descriptor, IMXFECState),
124
-
125
+ VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
126
VMSTATE_UINT32(phy_status, IMXFECState),
127
VMSTATE_UINT32(phy_control, IMXFECState),
128
VMSTATE_UINT32(phy_advertise, IMXFECState),
129
VMSTATE_UINT32(phy_int, IMXFECState),
130
VMSTATE_UINT32(phy_int_mask, IMXFECState),
131
VMSTATE_END_OF_LIST()
132
- }
133
+ },
134
+ .subsections = (const VMStateDescription * []) {
135
+ &vmstate_imx_eth_txdescs,
136
+ NULL
137
+ },
138
};
139
140
#define PHY_INT_ENERGYON (1 << 7)
141
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
142
{
143
int frame_size = 0, descnt = 0;
144
uint8_t *ptr = s->frame;
145
- uint32_t addr = s->tx_descriptor;
146
+ uint32_t addr = s->tx_descriptor[0];
147
148
while (descnt++ < IMX_MAX_DESC) {
149
IMXFECBufDesc bd;
150
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
151
}
152
}
153
154
- s->tx_descriptor = addr;
155
+ s->tx_descriptor[0] = addr;
156
157
imx_eth_update(s);
158
}
82
}
159
83
160
-static void imx_enet_do_tx(IMXFECState *s)
84
static uint64_t pl110_read(void *opaque, hwaddr offset,
161
+static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
85
@@ -XXX,XX +XXX,XX @@ static void pl110_write(void *opaque, hwaddr offset,
162
{
86
s->bpp = (val >> 1) & 7;
163
int frame_size = 0, descnt = 0;
87
if (pl110_enabled(s)) {
164
+
88
qemu_console_resize(s->con, s->cols, s->rows);
165
uint8_t *ptr = s->frame;
89
+ timer_mod(s->vblank_timer,
166
- uint32_t addr = s->tx_descriptor;
90
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
167
+ uint32_t addr, int_txb, int_txf, tdsr;
91
+ NANOSECONDS_PER_SECOND / 60);
168
+ size_t ring;
92
+ } else {
169
+
93
+ timer_del(s->vblank_timer);
170
+ switch (index) {
171
+ case ENET_TDAR:
172
+ ring = 0;
173
+ int_txb = ENET_INT_TXB;
174
+ int_txf = ENET_INT_TXF;
175
+ tdsr = ENET_TDSR;
176
+ break;
177
+ case ENET_TDAR1:
178
+ ring = 1;
179
+ int_txb = ENET_INT_TXB1;
180
+ int_txf = ENET_INT_TXF1;
181
+ tdsr = ENET_TDSR1;
182
+ break;
183
+ case ENET_TDAR2:
184
+ ring = 2;
185
+ int_txb = ENET_INT_TXB2;
186
+ int_txf = ENET_INT_TXF2;
187
+ tdsr = ENET_TDSR2;
188
+ break;
189
+ default:
190
+ qemu_log_mask(LOG_GUEST_ERROR,
191
+ "%s: bogus value for index %x\n",
192
+ __func__, index);
193
+ abort();
194
+ break;
195
+ }
196
+
197
+ addr = s->tx_descriptor[ring];
198
199
while (descnt++ < IMX_MAX_DESC) {
200
IMXENETBufDesc bd;
201
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s)
202
203
frame_size = 0;
204
if (bd.option & ENET_BD_TX_INT) {
205
- s->regs[ENET_EIR] |= ENET_INT_TXF;
206
+ s->regs[ENET_EIR] |= int_txf;
207
}
208
}
209
if (bd.option & ENET_BD_TX_INT) {
210
- s->regs[ENET_EIR] |= ENET_INT_TXB;
211
+ s->regs[ENET_EIR] |= int_txb;
212
}
213
bd.flags &= ~ENET_BD_R;
214
/* Write back the modified descriptor. */
215
imx_enet_write_bd(&bd, addr);
216
/* Advance to the next descriptor. */
217
if ((bd.flags & ENET_BD_W) != 0) {
218
- addr = s->regs[ENET_TDSR];
219
+ addr = s->regs[tdsr];
220
} else {
221
addr += sizeof(bd);
222
}
223
}
224
225
- s->tx_descriptor = addr;
226
+ s->tx_descriptor[ring] = addr;
227
228
imx_eth_update(s);
229
}
230
231
-static void imx_eth_do_tx(IMXFECState *s)
232
+static void imx_eth_do_tx(IMXFECState *s, uint32_t index)
233
{
234
if (!s->is_fec && (s->regs[ENET_ECR] & ENET_ECR_EN1588)) {
235
- imx_enet_do_tx(s);
236
+ imx_enet_do_tx(s, index);
237
} else {
238
imx_fec_do_tx(s);
239
}
240
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
241
}
242
243
s->rx_descriptor = 0;
244
- s->tx_descriptor = 0;
245
+ memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
246
247
/* We also reset the PHY */
248
phy_reset(s);
249
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
250
unsigned size)
251
{
252
IMXFECState *s = IMX_FEC(opaque);
253
+ const bool single_tx_ring = !imx_eth_is_multi_tx_ring(s);
254
uint32_t index = offset >> 2;
255
256
FEC_PRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_eth_reg_name(s, index),
257
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
258
s->regs[index] = 0;
259
}
94
}
260
break;
95
break;
261
- case ENET_TDAR:
96
case 10: /* LCDICR */
262
+ case ENET_TDAR1: /* FALLTHROUGH */
97
@@ -XXX,XX +XXX,XX @@ static void pl110_realize(DeviceState *dev, Error **errp)
263
+ case ENET_TDAR2: /* FALLTHROUGH */
98
memory_region_init_io(&s->iomem, OBJECT(s), &pl110_ops, s, "pl110", 0x1000);
264
+ if (unlikely(single_tx_ring)) {
99
sysbus_init_mmio(sbd, &s->iomem);
265
+ qemu_log_mask(LOG_GUEST_ERROR,
100
sysbus_init_irq(sbd, &s->irq);
266
+ "[%s]%s: trying to access TDAR2 or TDAR1\n",
101
+ s->vblank_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
267
+ TYPE_IMX_FEC, __func__);
102
+ pl110_vblank_interrupt, s);
268
+ return;
103
qdev_init_gpio_in(dev, pl110_mux_ctrl_set, 1);
269
+ }
104
s->con = graphic_console_init(dev, 0, &pl110_gfx_ops, s);
270
+ case ENET_TDAR: /* FALLTHROUGH */
105
}
271
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
272
s->regs[index] = ENET_TDAR_TDAR;
273
- imx_eth_do_tx(s);
274
+ imx_eth_do_tx(s, index);
275
}
276
s->regs[index] = 0;
277
break;
278
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
279
if ((s->regs[index] & ENET_ECR_ETHEREN) == 0) {
280
s->regs[ENET_RDAR] = 0;
281
s->rx_descriptor = s->regs[ENET_RDSR];
282
- s->regs[ENET_TDAR] = 0;
283
- s->tx_descriptor = s->regs[ENET_TDSR];
284
+ s->regs[ENET_TDAR] = 0;
285
+ s->regs[ENET_TDAR1] = 0;
286
+ s->regs[ENET_TDAR2] = 0;
287
+ s->tx_descriptor[0] = s->regs[ENET_TDSR];
288
+ s->tx_descriptor[1] = s->regs[ENET_TDSR1];
289
+ s->tx_descriptor[2] = s->regs[ENET_TDSR2];
290
}
291
break;
292
case ENET_MMFR:
293
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
294
} else {
295
s->regs[index] = value & ~7;
296
}
297
- s->tx_descriptor = s->regs[index];
298
+ s->tx_descriptor[0] = s->regs[index];
299
+ break;
300
+ case ENET_TDSR1:
301
+ if (unlikely(single_tx_ring)) {
302
+ qemu_log_mask(LOG_GUEST_ERROR,
303
+ "[%s]%s: trying to access TDSR1\n",
304
+ TYPE_IMX_FEC, __func__);
305
+ return;
306
+ }
307
+
308
+ s->regs[index] = value & ~7;
309
+ s->tx_descriptor[1] = s->regs[index];
310
+ break;
311
+ case ENET_TDSR2:
312
+ if (unlikely(single_tx_ring)) {
313
+ qemu_log_mask(LOG_GUEST_ERROR,
314
+ "[%s]%s: trying to access TDSR2\n",
315
+ TYPE_IMX_FEC, __func__);
316
+ return;
317
+ }
318
+
319
+ s->regs[index] = value & ~7;
320
+ s->tx_descriptor[2] = s->regs[index];
321
break;
322
case ENET_MRBR:
323
s->regs[index] = value & 0x00003ff0;
324
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
325
326
static Property imx_eth_properties[] = {
327
DEFINE_NIC_PROPERTIES(IMXFECState, conf),
328
+ DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1),
329
DEFINE_PROP_END_OF_LIST(),
330
};
331
332
--
106
--
333
2.7.4
107
2.7.4
334
108
335
109
diff view generated by jsdifflib
Deleted patch
1
The GICv3 specification says that reserved register addresses
2
should RAZ/WI. This means we need to return MEMTX_OK, not MEMTX_ERROR,
3
because now that we support generating external aborts the
4
latter will cause an abort on new board models.
5
1
6
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1513183941-24300-2-git-send-email-peter.maydell@linaro.org
9
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
10
---
11
hw/intc/arm_gicv3_dist.c | 13 +++++++++++++
12
hw/intc/arm_gicv3_its_common.c | 8 +++-----
13
hw/intc/arm_gicv3_redist.c | 13 +++++++++++++
14
3 files changed, 29 insertions(+), 5 deletions(-)
15
16
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/arm_gicv3_dist.c
19
+++ b/hw/intc/arm_gicv3_dist.c
20
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_dist_read(void *opaque, hwaddr offset, uint64_t *data,
21
"%s: invalid guest read at offset " TARGET_FMT_plx
22
"size %u\n", __func__, offset, size);
23
trace_gicv3_dist_badread(offset, size, attrs.secure);
24
+ /* The spec requires that reserved registers are RAZ/WI;
25
+ * so use MEMTX_ERROR returns from leaf functions as a way to
26
+ * trigger the guest-error logging but don't return it to
27
+ * the caller, or we'll cause a spurious guest data abort.
28
+ */
29
+ r = MEMTX_OK;
30
+ *data = 0;
31
} else {
32
trace_gicv3_dist_read(offset, *data, size, attrs.secure);
33
}
34
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_dist_write(void *opaque, hwaddr offset, uint64_t data,
35
"%s: invalid guest write at offset " TARGET_FMT_plx
36
"size %u\n", __func__, offset, size);
37
trace_gicv3_dist_badwrite(offset, data, size, attrs.secure);
38
+ /* The spec requires that reserved registers are RAZ/WI;
39
+ * so use MEMTX_ERROR returns from leaf functions as a way to
40
+ * trigger the guest-error logging but don't return it to
41
+ * the caller, or we'll cause a spurious guest data abort.
42
+ */
43
+ r = MEMTX_OK;
44
} else {
45
trace_gicv3_dist_write(offset, data, size, attrs.secure);
46
}
47
diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/intc/arm_gicv3_its_common.c
50
+++ b/hw/intc/arm_gicv3_its_common.c
51
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_trans_read(void *opaque, hwaddr offset,
52
MemTxAttrs attrs)
53
{
54
qemu_log_mask(LOG_GUEST_ERROR, "ITS read at offset 0x%"PRIx64"\n", offset);
55
- return MEMTX_ERROR;
56
+ *data = 0;
57
+ return MEMTX_OK;
58
}
59
60
static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,
61
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,
62
if (ret <= 0) {
63
qemu_log_mask(LOG_GUEST_ERROR,
64
"ITS: Error sending MSI: %s\n", strerror(-ret));
65
- return MEMTX_DECODE_ERROR;
66
}
67
-
68
- return MEMTX_OK;
69
} else {
70
qemu_log_mask(LOG_GUEST_ERROR,
71
"ITS write at bad offset 0x%"PRIx64"\n", offset);
72
- return MEMTX_DECODE_ERROR;
73
}
74
+ return MEMTX_OK;
75
}
76
77
static const MemoryRegionOps gicv3_its_trans_ops = {
78
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/intc/arm_gicv3_redist.c
81
+++ b/hw/intc/arm_gicv3_redist.c
82
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
83
"size %u\n", __func__, offset, size);
84
trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
85
size, attrs.secure);
86
+ /* The spec requires that reserved registers are RAZ/WI;
87
+ * so use MEMTX_ERROR returns from leaf functions as a way to
88
+ * trigger the guest-error logging but don't return it to
89
+ * the caller, or we'll cause a spurious guest data abort.
90
+ */
91
+ r = MEMTX_OK;
92
+ *data = 0;
93
} else {
94
trace_gicv3_redist_read(gicv3_redist_affid(cs), offset, *data,
95
size, attrs.secure);
96
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
97
"size %u\n", __func__, offset, size);
98
trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data,
99
size, attrs.secure);
100
+ /* The spec requires that reserved registers are RAZ/WI;
101
+ * so use MEMTX_ERROR returns from leaf functions as a way to
102
+ * trigger the guest-error logging but don't return it to
103
+ * the caller, or we'll cause a spurious guest data abort.
104
+ */
105
+ r = MEMTX_OK;
106
} else {
107
trace_gicv3_redist_write(gicv3_redist_affid(cs), offset, data,
108
size, attrs.secure);
109
--
110
2.7.4
111
112
diff view generated by jsdifflib