1
Arm queue built up to a point where it seems worth sending:
1
The following changes since commit adf2e451f357e993f173ba9b4176dbf3e65fee7e:
2
various bug fixes, plus RTH's refactoring in preparation for SVE.
3
2
4
thanks
3
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2019-02-26 19:04:47 +0000)
5
-- PMM
6
7
8
The following changes since commit 0f79bfe38a2cf0f43c7ea4959da7f8ebd7858f3d:
9
4
10
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-2.12-pull-request' into staging (2018-01-25 09:53:53 +0000)
5
are available in the Git repository at:
11
6
12
are available in the git repository at:
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190228-1
13
8
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180125
9
for you to fetch changes up to 1c9af3a9e05c1607a36df4943f8f5393d7621a91:
15
10
16
for you to fetch changes up to 24da047af0e99a83fcc0d50b86c0f2627f7418b3:
11
linux-user: Enable HWCAP_ASIMDFHM, HWCAP_JSCVT (2019-02-28 11:03:05 +0000)
17
18
pl110: Implement vertical compare/next base interrupts (2018-01-25 11:45:30 +0000)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
target-arm queue:
14
target-arm queue:
22
* target/arm: Fix address truncation in 64-bit pagetable walks
15
* add MHU and dual-core support to Musca boards
23
* i.MX: Fix FEC/ENET receive functions
16
* refactor some VFP insns to be gated by ID registers
24
* target/arm: preparatory refactoring for SVE emulation
17
* Revert "arm: Allow system registers for KVM guests to be changed by QEMU code"
25
* hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
18
* Implement ARMv8.2-FHM extension
26
* hw/intc/arm_gic: Fix C_RPR value on idle priority
19
* Advertise JSCVT via HWCAP for linux-user
27
* hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
28
* hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
29
* hw/arm/virt: Check that the CPU realize method succeeded
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
33
20
34
----------------------------------------------------------------
21
----------------------------------------------------------------
35
Ard Biesheuvel (1):
22
Peter Maydell (11):
36
target/arm: Fix 32-bit address truncation
23
hw/misc/armsse-mhu.c: Model the SSE-200 Message Handling Unit
24
hw/arm/armsse: Wire up the MHUs
25
target/arm/cpu: Allow init-svtor property to be set after realize
26
target/arm/arm-powerctl: Add new arm_set_cpu_on_and_reset()
27
hw/misc/iotkit-sysctl: Correct typo in INITSVTOR0 register name
28
hw/arm/iotkit-sysctl: Add SSE-200 registers
29
hw/arm/iotkit-sysctl: Implement CPUWAIT and INITSVTOR*
30
hw/arm/armsse: Unify init-svtor and cpuwait handling
31
target/arm: Use MVFR1 feature bits to gate A32/T32 FP16 instructions
32
target/arm: Gate "miscellaneous FP" insns by ID register field
33
Revert "arm: Allow system registers for KVM guests to be changed by QEMU code"
37
34
38
Francisco Iglesias (1):
35
Richard Henderson (5):
39
xilinx_spips: Correct usage of an uninitialized local variable
36
target/arm: Add helpers for FMLAL
37
target/arm: Implement FMLAL and FMLSL for aarch64
38
target/arm: Implement VFMAL and VFMSL for aarch32
39
target/arm: Enable ARMv8.2-FHM for -cpu max
40
linux-user: Enable HWCAP_ASIMDFHM, HWCAP_JSCVT
40
41
41
Jean-Christophe Dubois (1):
42
hw/misc/Makefile.objs | 1 +
42
i.MX: Fix FEC/ENET receive funtions
43
include/hw/arm/armsse.h | 3 +-
44
include/hw/misc/armsse-mhu.h | 44 ++++++
45
include/hw/misc/iotkit-sysctl.h | 25 +++-
46
target/arm/arm-powerctl.h | 16 +++
47
target/arm/cpu.h | 76 +++++++++--
48
target/arm/helper.h | 9 ++
49
hw/arm/armsse.c | 91 +++++++++----
50
hw/misc/armsse-mhu.c | 198 +++++++++++++++++++++++++++
51
hw/misc/iotkit-sysctl.c | 294 ++++++++++++++++++++++++++++++++++++++--
52
linux-user/elfload.c | 2 +
53
target/arm/arm-powerctl.c | 56 ++++++++
54
target/arm/cpu.c | 32 ++++-
55
target/arm/cpu64.c | 2 +
56
target/arm/helper.c | 27 +---
57
target/arm/kvm32.c | 23 +++-
58
target/arm/kvm64.c | 2 -
59
target/arm/machine.c | 2 +-
60
target/arm/translate-a64.c | 49 ++++++-
61
target/arm/translate.c | 180 ++++++++++++++++--------
62
target/arm/vec_helper.c | 148 ++++++++++++++++++++
63
MAINTAINERS | 2 +
64
default-configs/arm-softmmu.mak | 1 +
65
hw/misc/trace-events | 4 +
66
24 files changed, 1139 insertions(+), 148 deletions(-)
67
create mode 100644 include/hw/misc/armsse-mhu.h
68
create mode 100644 hw/misc/armsse-mhu.c
43
69
44
Linus Walleij (1):
45
pl110: Implement vertical compare/next base interrupts
46
47
Luc MICHEL (4):
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
52
53
Peter Maydell (1):
54
hw/arm/virt: Check that the CPU realize method succeeded
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: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2
1
3
Commit ("3b39d734141a target/arm: Handle page table walk load failures
4
correctly") modified both versions of the page table walking code (i.e.,
5
arm_ldl_ptw and arm_ldq_ptw) to record the result of the translation in
6
a temporary 'data' variable so that it can be inspected before being
7
returned. However, arm_ldq_ptw() returns an uint64_t, and using a
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
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/helper.c | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
25
MemTxAttrs attrs = {};
26
MemTxResult result = MEMTX_OK;
27
AddressSpace *as;
28
- uint32_t data;
29
+ uint64_t data;
30
31
attrs.secure = is_secure;
32
as = arm_addressspace(cs, attrs);
33
--
34
2.7.4
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
1
3
The actual imx_eth_enable_rx() function is buggy.
4
5
It updates s->regs[ENET_RDAR] after calling qemu_flush_queued_packets().
6
7
qemu_flush_queued_packets() is going to call imx_XXX_receive() which itself
8
is going to call imx_eth_enable_rx().
9
10
By updating s->regs[ENET_RDAR] after calling qemu_flush_queued_packets()
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
22
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Andrey Smirnov <andrew.smirnov@gmail.com>
24
Tested-by: Andrey Smirnov <andrew.smirnov@gmail.com>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
27
hw/net/imx_fec.c | 8 ++------
28
1 file changed, 2 insertions(+), 6 deletions(-)
29
30
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/net/imx_fec.c
33
+++ b/hw/net/imx_fec.c
34
@@ -XXX,XX +XXX,XX @@ static void imx_eth_do_tx(IMXFECState *s, uint32_t index)
35
static void imx_eth_enable_rx(IMXFECState *s, bool flush)
36
{
37
IMXFECBufDesc bd;
38
- bool rx_ring_full;
39
40
imx_fec_read_bd(&bd, s->rx_descriptor);
41
42
- rx_ring_full = !(bd.flags & ENET_BD_E);
43
+ s->regs[ENET_RDAR] = (bd.flags & ENET_BD_E) ? ENET_RDAR_RDAR : 0;
44
45
- if (rx_ring_full) {
46
+ if (!s->regs[ENET_RDAR]) {
47
FEC_PRINTF("RX buffer full\n");
48
} else if (flush) {
49
qemu_flush_queued_packets(qemu_get_queue(s->nic));
50
}
51
-
52
- s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
53
}
54
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 {
64
--
65
2.7.4
66
67
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
Implement a model of the Message Handling Unit (MHU) found in
2
the Arm SSE-200. This is a simple device which just contains
3
some registers which allow the two cores of the SSE-200
4
to raise interrupts on each other.
2
5
3
Coverity found that the variable tx_rx in the function
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
xilinx_spips_flush_txfifo was being used uninitialized (CID 1383841). This
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
patch corrects this by always initializing tx_rx to zeros.
8
Message-id: 20190219125808.25174-2-peter.maydell@linaro.org
9
---
10
hw/misc/Makefile.objs | 1 +
11
include/hw/misc/armsse-mhu.h | 44 +++++++
12
hw/misc/armsse-mhu.c | 198 ++++++++++++++++++++++++++++++++
13
MAINTAINERS | 2 +
14
default-configs/arm-softmmu.mak | 1 +
15
hw/misc/trace-events | 4 +
16
6 files changed, 250 insertions(+)
17
create mode 100644 include/hw/misc/armsse-mhu.h
18
create mode 100644 hw/misc/armsse-mhu.c
6
19
7
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
20
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
8
Message-id: 20180124215708.30400-1-frasse.iglesias@gmail.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/ssi/xilinx_spips.c | 18 +++++++++++++++++-
13
1 file changed, 17 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
22
--- a/hw/misc/Makefile.objs
18
+++ b/hw/ssi/xilinx_spips.c
23
+++ b/hw/misc/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
25
obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
26
obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
27
obj-$(CONFIG_ARMSSE_CPUID) += armsse-cpuid.o
28
+obj-$(CONFIG_ARMSSE_MHU) += armsse-mhu.o
29
30
obj-$(CONFIG_PVPANIC) += pvpanic.o
31
obj-$(CONFIG_AUX) += auxbus.o
32
diff --git a/include/hw/misc/armsse-mhu.h b/include/hw/misc/armsse-mhu.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/misc/armsse-mhu.h
19
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
20
#define SNOOP_NONE 0xEE
38
+/*
21
#define SNOOP_STRIPING 0
39
+ * ARM SSE-200 Message Handling Unit (MHU)
22
40
+ *
23
+#define MIN_NUM_BUSSES 1
41
+ * Copyright (c) 2019 Linaro Limited
24
+#define MAX_NUM_BUSSES 2
42
+ * Written by Peter Maydell
25
+
43
+ *
26
static inline int num_effective_busses(XilinxSPIPS *s)
44
+ * This program is free software; you can redistribute it and/or modify
27
{
45
+ * it under the terms of the GNU General Public License version 2 or
28
return (s->regs[R_LQSPI_CFG] & LQSPI_CFG_SEP_BUS &&
46
+ * (at your option) any later version.
29
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
47
+ */
30
for (;;) {
48
+
31
int i;
49
+/*
32
uint8_t tx = 0;
50
+ * This is a model of the Message Handling Unit (MHU) which is part of the
33
- uint8_t tx_rx[num_effective_busses(s)];
51
+ * Arm SSE-200 and documented in
34
+ uint8_t tx_rx[MAX_NUM_BUSSES] = { 0 };
52
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
35
uint8_t dummy_cycles = 0;
53
+ *
36
uint8_t addr_length;
54
+ * QEMU interface:
37
55
+ * + sysbus MMIO region 0: the system information register bank
38
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
56
+ * + sysbus IRQ 0: interrupt for CPU 0
39
57
+ * + sysbus IRQ 1: interrupt for CPU 1
40
DB_PRINT_L(0, "realized spips\n");
58
+ */
41
59
+
42
+ if (s->num_busses > MAX_NUM_BUSSES) {
60
+#ifndef HW_MISC_SSE_MHU_H
43
+ error_setg(errp,
61
+#define HW_MISC_SSE_MHU_H
44
+ "requested number of SPI busses %u exceeds maximum %d",
62
+
45
+ s->num_busses, MAX_NUM_BUSSES);
63
+#include "hw/sysbus.h"
46
+ return;
64
+
65
+#define TYPE_ARMSSE_MHU "armsse-mhu"
66
+#define ARMSSE_MHU(obj) OBJECT_CHECK(ARMSSEMHU, (obj), TYPE_ARMSSE_MHU)
67
+
68
+typedef struct ARMSSEMHU {
69
+ /*< private >*/
70
+ SysBusDevice parent_obj;
71
+
72
+ /*< public >*/
73
+ MemoryRegion iomem;
74
+ qemu_irq cpu0irq;
75
+ qemu_irq cpu1irq;
76
+
77
+ uint32_t cpu0intr;
78
+ uint32_t cpu1intr;
79
+} ARMSSEMHU;
80
+
81
+#endif
82
diff --git a/hw/misc/armsse-mhu.c b/hw/misc/armsse-mhu.c
83
new file mode 100644
84
index XXXXXXX..XXXXXXX
85
--- /dev/null
86
+++ b/hw/misc/armsse-mhu.c
87
@@ -XXX,XX +XXX,XX @@
88
+/*
89
+ * ARM SSE-200 Message Handling Unit (MHU)
90
+ *
91
+ * Copyright (c) 2019 Linaro Limited
92
+ * Written by Peter Maydell
93
+ *
94
+ * This program is free software; you can redistribute it and/or modify
95
+ * it under the terms of the GNU General Public License version 2 or
96
+ * (at your option) any later version.
97
+ */
98
+
99
+/*
100
+ * This is a model of the Message Handling Unit (MHU) which is part of the
101
+ * Arm SSE-200 and documented in
102
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
103
+ */
104
+
105
+#include "qemu/osdep.h"
106
+#include "qemu/log.h"
107
+#include "trace.h"
108
+#include "qapi/error.h"
109
+#include "sysemu/sysemu.h"
110
+#include "hw/sysbus.h"
111
+#include "hw/registerfields.h"
112
+#include "hw/misc/armsse-mhu.h"
113
+
114
+REG32(CPU0INTR_STAT, 0x0)
115
+REG32(CPU0INTR_SET, 0x4)
116
+REG32(CPU0INTR_CLR, 0x8)
117
+REG32(CPU1INTR_STAT, 0x10)
118
+REG32(CPU1INTR_SET, 0x14)
119
+REG32(CPU1INTR_CLR, 0x18)
120
+REG32(PID4, 0xfd0)
121
+REG32(PID5, 0xfd4)
122
+REG32(PID6, 0xfd8)
123
+REG32(PID7, 0xfdc)
124
+REG32(PID0, 0xfe0)
125
+REG32(PID1, 0xfe4)
126
+REG32(PID2, 0xfe8)
127
+REG32(PID3, 0xfec)
128
+REG32(CID0, 0xff0)
129
+REG32(CID1, 0xff4)
130
+REG32(CID2, 0xff8)
131
+REG32(CID3, 0xffc)
132
+
133
+/* Valid bits in the interrupt registers. If any are set the IRQ is raised */
134
+#define INTR_MASK 0xf
135
+
136
+/* PID/CID values */
137
+static const int armsse_mhu_id[] = {
138
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
139
+ 0x56, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
140
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
141
+};
142
+
143
+static void armsse_mhu_update(ARMSSEMHU *s)
144
+{
145
+ qemu_set_irq(s->cpu0irq, s->cpu0intr != 0);
146
+ qemu_set_irq(s->cpu1irq, s->cpu1intr != 0);
147
+}
148
+
149
+static uint64_t armsse_mhu_read(void *opaque, hwaddr offset, unsigned size)
150
+{
151
+ ARMSSEMHU *s = ARMSSE_MHU(opaque);
152
+ uint64_t r;
153
+
154
+ switch (offset) {
155
+ case A_CPU0INTR_STAT:
156
+ r = s->cpu0intr;
157
+ break;
158
+
159
+ case A_CPU1INTR_STAT:
160
+ r = s->cpu1intr;
161
+ break;
162
+
163
+ case A_PID4 ... A_CID3:
164
+ r = armsse_mhu_id[(offset - A_PID4) / 4];
165
+ break;
166
+
167
+ case A_CPU0INTR_SET:
168
+ case A_CPU0INTR_CLR:
169
+ case A_CPU1INTR_SET:
170
+ case A_CPU1INTR_CLR:
171
+ qemu_log_mask(LOG_GUEST_ERROR,
172
+ "SSE MHU: read of write-only register at offset 0x%x\n",
173
+ (int)offset);
174
+ r = 0;
175
+ break;
176
+
177
+ default:
178
+ qemu_log_mask(LOG_GUEST_ERROR,
179
+ "SSE MHU read: bad offset 0x%x\n", (int)offset);
180
+ r = 0;
181
+ break;
47
+ }
182
+ }
48
+ if (s->num_busses < MIN_NUM_BUSSES) {
183
+ trace_armsse_mhu_read(offset, r, size);
49
+ error_setg(errp,
184
+ return r;
50
+ "requested number of SPI busses %u is below minimum %d",
185
+}
51
+ s->num_busses, MIN_NUM_BUSSES);
186
+
52
+ return;
187
+static void armsse_mhu_write(void *opaque, hwaddr offset,
188
+ uint64_t value, unsigned size)
189
+{
190
+ ARMSSEMHU *s = ARMSSE_MHU(opaque);
191
+
192
+ trace_armsse_mhu_write(offset, value, size);
193
+
194
+ switch (offset) {
195
+ case A_CPU0INTR_SET:
196
+ s->cpu0intr |= (value & INTR_MASK);
197
+ break;
198
+ case A_CPU0INTR_CLR:
199
+ s->cpu0intr &= ~(value & INTR_MASK);
200
+ break;
201
+ case A_CPU1INTR_SET:
202
+ s->cpu1intr |= (value & INTR_MASK);
203
+ break;
204
+ case A_CPU1INTR_CLR:
205
+ s->cpu1intr &= ~(value & INTR_MASK);
206
+ break;
207
+
208
+ case A_CPU0INTR_STAT:
209
+ case A_CPU1INTR_STAT:
210
+ case A_PID4 ... A_CID3:
211
+ qemu_log_mask(LOG_GUEST_ERROR,
212
+ "SSE MHU: write to read-only register at offset 0x%x\n",
213
+ (int)offset);
214
+ break;
215
+
216
+ default:
217
+ qemu_log_mask(LOG_GUEST_ERROR,
218
+ "SSE MHU write: bad offset 0x%x\n", (int)offset);
219
+ break;
53
+ }
220
+ }
54
+
221
+
55
s->spi = g_new(SSIBus *, s->num_busses);
222
+ armsse_mhu_update(s);
56
for (i = 0; i < s->num_busses; ++i) {
223
+}
57
char bus_name[16];
224
+
225
+static const MemoryRegionOps armsse_mhu_ops = {
226
+ .read = armsse_mhu_read,
227
+ .write = armsse_mhu_write,
228
+ .endianness = DEVICE_LITTLE_ENDIAN,
229
+ .valid.min_access_size = 4,
230
+ .valid.max_access_size = 4,
231
+};
232
+
233
+static void armsse_mhu_reset(DeviceState *dev)
234
+{
235
+ ARMSSEMHU *s = ARMSSE_MHU(dev);
236
+
237
+ s->cpu0intr = 0;
238
+ s->cpu1intr = 0;
239
+}
240
+
241
+static const VMStateDescription armsse_mhu_vmstate = {
242
+ .name = "armsse-mhu",
243
+ .version_id = 1,
244
+ .minimum_version_id = 1,
245
+ .fields = (VMStateField[]) {
246
+ VMSTATE_UINT32(cpu0intr, ARMSSEMHU),
247
+ VMSTATE_UINT32(cpu1intr, ARMSSEMHU),
248
+ VMSTATE_END_OF_LIST()
249
+ },
250
+};
251
+
252
+static void armsse_mhu_init(Object *obj)
253
+{
254
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
255
+ ARMSSEMHU *s = ARMSSE_MHU(obj);
256
+
257
+ memory_region_init_io(&s->iomem, obj, &armsse_mhu_ops,
258
+ s, "armsse-mhu", 0x1000);
259
+ sysbus_init_mmio(sbd, &s->iomem);
260
+ sysbus_init_irq(sbd, &s->cpu0irq);
261
+ sysbus_init_irq(sbd, &s->cpu1irq);
262
+}
263
+
264
+static void armsse_mhu_class_init(ObjectClass *klass, void *data)
265
+{
266
+ DeviceClass *dc = DEVICE_CLASS(klass);
267
+
268
+ dc->reset = armsse_mhu_reset;
269
+ dc->vmsd = &armsse_mhu_vmstate;
270
+}
271
+
272
+static const TypeInfo armsse_mhu_info = {
273
+ .name = TYPE_ARMSSE_MHU,
274
+ .parent = TYPE_SYS_BUS_DEVICE,
275
+ .instance_size = sizeof(ARMSSEMHU),
276
+ .instance_init = armsse_mhu_init,
277
+ .class_init = armsse_mhu_class_init,
278
+};
279
+
280
+static void armsse_mhu_register_types(void)
281
+{
282
+ type_register_static(&armsse_mhu_info);
283
+}
284
+
285
+type_init(armsse_mhu_register_types);
286
diff --git a/MAINTAINERS b/MAINTAINERS
287
index XXXXXXX..XXXXXXX 100644
288
--- a/MAINTAINERS
289
+++ b/MAINTAINERS
290
@@ -XXX,XX +XXX,XX @@ F: hw/misc/iotkit-sysinfo.c
291
F: include/hw/misc/iotkit-sysinfo.h
292
F: hw/misc/armsse-cpuid.c
293
F: include/hw/misc/armsse-cpuid.h
294
+F: hw/misc/armsse-mhu.c
295
+F: include/hw/misc/armsse-mhu.h
296
297
Musca
298
M: Peter Maydell <peter.maydell@linaro.org>
299
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
300
index XXXXXXX..XXXXXXX 100644
301
--- a/default-configs/arm-softmmu.mak
302
+++ b/default-configs/arm-softmmu.mak
303
@@ -XXX,XX +XXX,XX @@ CONFIG_IOTKIT_SECCTL=y
304
CONFIG_IOTKIT_SYSCTL=y
305
CONFIG_IOTKIT_SYSINFO=y
306
CONFIG_ARMSSE_CPUID=y
307
+CONFIG_ARMSSE_MHU=y
308
309
CONFIG_VERSATILE=y
310
CONFIG_VERSATILE_PCI=y
311
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
312
index XXXXXXX..XXXXXXX 100644
313
--- a/hw/misc/trace-events
314
+++ b/hw/misc/trace-events
315
@@ -XXX,XX +XXX,XX @@ iotkit_sysctl_reset(void) "IoTKit SysCtl: reset"
316
# hw/misc/armsse-cpuid.c
317
armsse_cpuid_read(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
318
armsse_cpuid_write(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
319
+
320
+# hw/misc/armsse-mhu.c
321
+armsse_mhu_read(uint64_t offset, uint64_t data, unsigned size) "SSE-200 MHU read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
322
+armsse_mhu_write(uint64_t offset, uint64_t data, unsigned size) "SSE-200 MHU write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
58
--
323
--
59
2.7.4
324
2.20.1
60
325
61
326
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Create and connect the MHUs in the SSE-200.
2
2
3
Rather than passing regnos to the helpers, pass pointers to the
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
vector registers directly. This eliminates the need to pass in
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
the environment pointer and reduces the number of places that
5
Message-id: 20190219125808.25174-3-peter.maydell@linaro.org
6
directly access env->vfp.regs[].
6
---
7
include/hw/arm/armsse.h | 3 ++-
8
hw/arm/armsse.c | 40 ++++++++++++++++++++++++++++++----------
9
2 files changed, 32 insertions(+), 11 deletions(-)
7
10
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
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
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/helper.h | 20 +++---
15
target/arm/neon_helper.c | 162 +++++++++++++++++++++++++----------------------
16
target/arm/translate.c | 42 ++++++------
17
3 files changed, 120 insertions(+), 104 deletions(-)
18
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
13
--- a/include/hw/arm/armsse.h
22
+++ b/target/arm/helper.h
14
+++ b/include/hw/arm/armsse.h
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(iwmmxt_muladdsl, i64, i64, i32, i32)
15
@@ -XXX,XX +XXX,XX @@
24
DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32)
16
#include "hw/misc/iotkit-sysctl.h"
25
DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
17
#include "hw/misc/iotkit-sysinfo.h"
26
18
#include "hw/misc/armsse-cpuid.h"
27
-DEF_HELPER_3(neon_unzip8, void, env, i32, i32)
19
+#include "hw/misc/armsse-mhu.h"
28
-DEF_HELPER_3(neon_unzip16, void, env, i32, i32)
20
#include "hw/misc/unimp.h"
29
-DEF_HELPER_3(neon_qunzip8, void, env, i32, i32)
21
#include "hw/or-irq.h"
30
-DEF_HELPER_3(neon_qunzip16, void, env, i32, i32)
22
#include "hw/core/split-irq.h"
31
-DEF_HELPER_3(neon_qunzip32, void, env, i32, i32)
23
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
32
-DEF_HELPER_3(neon_zip8, void, env, i32, i32)
24
IoTKitSysCtl sysctl;
33
-DEF_HELPER_3(neon_zip16, void, env, i32, i32)
25
IoTKitSysCtl sysinfo;
34
-DEF_HELPER_3(neon_qzip8, void, env, i32, i32)
26
35
-DEF_HELPER_3(neon_qzip16, void, env, i32, i32)
27
- UnimplementedDeviceState mhu[2];
36
-DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
28
+ ARMSSEMHU mhu[2];
37
+DEF_HELPER_FLAGS_2(neon_unzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
29
UnimplementedDeviceState ppu[NUM_PPUS];
38
+DEF_HELPER_FLAGS_2(neon_unzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
30
UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
39
+DEF_HELPER_FLAGS_2(neon_qunzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
31
UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
40
+DEF_HELPER_FLAGS_2(neon_qunzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
32
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
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
33
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/neon_helper.c
34
--- a/hw/arm/armsse.c
53
+++ b/target/arm/neon_helper.c
35
+++ b/hw/arm/armsse.c
54
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_acgt_f64)(uint64_t a, uint64_t b, void *fpstp)
36
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
55
37
sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
56
#define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1))
38
if (info->has_mhus) {
57
39
sysbus_init_child_obj(obj, "mhu0", &s->mhu[0], sizeof(s->mhu[0]),
58
-void HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
40
- TYPE_UNIMPLEMENTED_DEVICE);
59
+void HELPER(neon_qunzip8)(void *vd, void *vm)
41
+ TYPE_ARMSSE_MHU);
60
{
42
sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
61
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
43
- TYPE_UNIMPLEMENTED_DEVICE);
62
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
44
+ TYPE_ARMSSE_MHU);
63
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
45
}
64
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
46
if (info->has_ppus) {
65
+ uint64_t *rd = vd, *rm = vm;
47
for (i = 0; i < info->num_cpus; i++) {
66
+ uint64_t zd0 = rd[0], zd1 = rd[1];
48
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
67
+ uint64_t zm0 = rm[0], zm1 = rm[1];
49
}
50
51
if (info->has_mhus) {
52
- for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
53
- char *name;
54
- char *port;
55
+ /*
56
+ * An SSE-200 with only one CPU should have only one MHU created,
57
+ * with the region where the second MHU usually is being RAZ/WI.
58
+ * We don't implement that SSE-200 config; if we want to support
59
+ * it then this code needs to be enhanced to handle creating the
60
+ * RAZ/WI region instead of the second MHU.
61
+ */
62
+ assert(info->num_cpus == ARRAY_SIZE(s->mhu));
68
+
63
+
69
uint64_t d0 = ELEM(zd0, 0, 8) | (ELEM(zd0, 2, 8) << 8)
64
+ for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
70
| (ELEM(zd0, 4, 8) << 16) | (ELEM(zd0, 6, 8) << 24)
65
+ char *port;
71
| (ELEM(zd1, 0, 8) << 32) | (ELEM(zd1, 2, 8) << 40)
66
+ int cpunum;
72
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
67
+ SysBusDevice *mhu_sbd = SYS_BUS_DEVICE(&s->mhu[i]);
73
| (ELEM(zm0, 5, 8) << 16) | (ELEM(zm0, 7, 8) << 24)
68
74
| (ELEM(zm1, 1, 8) << 32) | (ELEM(zm1, 3, 8) << 40)
69
- name = g_strdup_printf("MHU%d", i);
75
| (ELEM(zm1, 5, 8) << 48) | (ELEM(zm1, 7, 8) << 56);
70
- qdev_prop_set_string(DEVICE(&s->mhu[i]), "name", name);
76
- env->vfp.regs[rm] = make_float64(m0);
71
- qdev_prop_set_uint64(DEVICE(&s->mhu[i]), "size", 0x1000);
77
- env->vfp.regs[rm + 1] = make_float64(m1);
72
object_property_set_bool(OBJECT(&s->mhu[i]), true,
78
- env->vfp.regs[rd] = make_float64(d0);
73
"realized", &err);
79
- env->vfp.regs[rd + 1] = make_float64(d1);
74
- g_free(name);
75
if (err) {
76
error_propagate(errp, err);
77
return;
78
}
79
port = g_strdup_printf("port[%d]", i + 3);
80
- mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mhu[i]), 0);
81
+ mr = sysbus_mmio_get_region(mhu_sbd, 0);
82
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr),
83
port, &err);
84
g_free(port);
85
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
86
error_propagate(errp, err);
87
return;
88
}
80
+
89
+
81
+ rm[0] = m0;
90
+ /*
82
+ rm[1] = m1;
91
+ * Each MHU has an irq line for each CPU:
83
+ rd[0] = d0;
92
+ * MHU 0 irq line 0 -> CPU 0 IRQ 6
84
+ rd[1] = d1;
93
+ * MHU 0 irq line 1 -> CPU 1 IRQ 6
85
}
94
+ * MHU 1 irq line 0 -> CPU 0 IRQ 7
86
95
+ * MHU 1 irq line 1 -> CPU 1 IRQ 7
87
-void HELPER(neon_qunzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
96
+ */
88
+void HELPER(neon_qunzip16)(void *vd, void *vm)
97
+ for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
89
{
98
+ DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
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
+
99
+
98
uint64_t d0 = ELEM(zd0, 0, 16) | (ELEM(zd0, 2, 16) << 16)
100
+ sysbus_connect_irq(mhu_sbd, cpunum,
99
| (ELEM(zd1, 0, 16) << 32) | (ELEM(zd1, 2, 16) << 48);
101
+ qdev_get_gpio_in(cpudev, 6 + i));
100
uint64_t d1 = ELEM(zm0, 0, 16) | (ELEM(zm0, 2, 16) << 16)
102
+ }
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:
309
diff --git a/target/arm/translate.c b/target/arm/translate.c
310
index XXXXXXX..XXXXXXX 100644
311
--- a/target/arm/translate.c
312
+++ b/target/arm/translate.c
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
}
103
}
357
}
104
}
358
- tcg_temp_free_i32(tmp);
359
- tcg_temp_free_i32(tmp2);
360
+ tcg_temp_free_ptr(pd);
361
+ tcg_temp_free_ptr(pm);
362
return 0;
363
}
364
365
static int gen_neon_zip(int rd, int rm, int size, int q)
366
{
367
- TCGv_i32 tmp, tmp2;
368
+ TCGv_ptr pd, pm;
369
+
370
if (!q && size == 2) {
371
return 1;
372
}
373
- tmp = tcg_const_i32(rd);
374
- tmp2 = tcg_const_i32(rm);
375
+ pd = vfp_reg_ptr(true, rd);
376
+ pm = vfp_reg_ptr(true, rm);
377
if (q) {
378
switch (size) {
379
case 0:
380
- gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
381
+ gen_helper_neon_qzip8(pd, pm);
382
break;
383
case 1:
384
- gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
385
+ gen_helper_neon_qzip16(pd, pm);
386
break;
387
case 2:
388
- gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
389
+ gen_helper_neon_qzip32(pd, pm);
390
break;
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();
406
}
407
}
408
- tcg_temp_free_i32(tmp);
409
- tcg_temp_free_i32(tmp2);
410
+ tcg_temp_free_ptr(pd);
411
+ tcg_temp_free_ptr(pm);
412
return 0;
413
}
414
105
415
--
106
--
416
2.7.4
107
2.20.1
417
108
418
109
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Make the M-profile "init-svtor" property be settable after realize.
2
This matches the hardware, where this is a config signal which
3
is sampled on CPU reset and can thus be changed between one
4
reset and another. To do this we have to change the API we
5
use to add the property.
2
6
3
missed in 60765b6ceeb4.
7
(We will need this capability for the SSE-200.)
4
8
5
Thread 1 "qemu-system-aarch64" received signal SIGSEGV, Segmentation fault.
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
address_space_init (as=0x0, root=0x55555726e410, name=name@entry=0x555555e3f0a7 "sdhci-dma") at memory.c:3050
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
3050     as->root = root;
11
Message-id: 20190219125808.25174-4-peter.maydell@linaro.org
8
(gdb) bt
12
---
9
#0 address_space_init (as=0x0, root=0x55555726e410, name=name@entry=0x555555e3f0a7 "sdhci-dma") at memory.c:3050
13
target/arm/cpu.c | 29 ++++++++++++++++++++++++-----
10
#1 0x0000555555af62c3 in sdhci_sysbus_realize (dev=<optimized out>, errp=0x7fff7f931150) at hw/sd/sdhci.c:1564
14
1 file changed, 24 insertions(+), 5 deletions(-)
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
15
18
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
16
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Message-id: 20180123132051.24448-1-f4bug@amsat.org
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
24
include/hw/sd/sdhci.h | 1 +
25
hw/sd/sdhci.c | 1 +
26
2 files changed, 2 insertions(+)
27
28
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
29
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/sd/sdhci.h
18
--- a/target/arm/cpu.c
31
+++ b/include/hw/sd/sdhci.h
19
+++ b/target/arm/cpu.c
32
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
20
@@ -XXX,XX +XXX,XX @@
33
/*< public >*/
21
#include "target/arm/idau.h"
34
SDBus sdbus;
22
#include "qemu/error-report.h"
35
MemoryRegion iomem;
23
#include "qapi/error.h"
36
+ AddressSpace sysbus_dma_as;
24
+#include "qapi/visitor.h"
37
AddressSpace *dma_as;
25
#include "cpu.h"
38
MemoryRegion *dma_mr;
26
#include "internals.h"
39
27
#include "qemu-common.h"
40
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
28
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_pmsav7_dregion_property =
41
index XXXXXXX..XXXXXXX 100644
29
pmsav7_dregion,
42
--- a/hw/sd/sdhci.c
30
qdev_prop_uint32, uint32_t);
43
+++ b/hw/sd/sdhci.c
31
44
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
32
-/* M profile: initial value of the Secure VTOR */
33
-static Property arm_cpu_initsvtor_property =
34
- DEFINE_PROP_UINT32("init-svtor", ARMCPU, init_svtor, 0);
35
+static void arm_get_init_svtor(Object *obj, Visitor *v, const char *name,
36
+ void *opaque, Error **errp)
37
+{
38
+ ARMCPU *cpu = ARM_CPU(obj);
39
+
40
+ visit_type_uint32(v, name, &cpu->init_svtor, errp);
41
+}
42
+
43
+static void arm_set_init_svtor(Object *obj, Visitor *v, const char *name,
44
+ void *opaque, Error **errp)
45
+{
46
+ ARMCPU *cpu = ARM_CPU(obj);
47
+
48
+ visit_type_uint32(v, name, &cpu->init_svtor, errp);
49
+}
50
51
void arm_cpu_post_init(Object *obj)
52
{
53
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
54
qdev_prop_allow_set_link_before_realize,
55
OBJ_PROP_LINK_STRONG,
56
&error_abort);
57
- qdev_property_add_static(DEVICE(obj), &arm_cpu_initsvtor_property,
58
- &error_abort);
59
+ /*
60
+ * M profile: initial value of the Secure VTOR. We can't just use
61
+ * a simple DEFINE_PROP_UINT32 for this because we want to permit
62
+ * the property to be set after realize.
63
+ */
64
+ object_property_add(obj, "init-svtor", "uint32",
65
+ arm_get_init_svtor, arm_set_init_svtor,
66
+ NULL, NULL, &error_abort);
45
}
67
}
46
68
47
if (s->dma_mr) {
69
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
48
+ s->dma_as = &s->sysbus_dma_as;
49
address_space_init(s->dma_as, s->dma_mr, "sdhci-dma");
50
} else {
51
/* use system_memory() if property "dma" not set */
52
--
70
--
53
2.7.4
71
2.20.1
54
72
55
73
diff view generated by jsdifflib
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
1
Currently the Arm arm-powerctl.h APIs allow:
2
* arm_set_cpu_on(), which powers on a CPU and sets its
3
initial PC and other startup state
4
* arm_reset_cpu(), which resets a CPU which is already on
5
(and fails if the CPU is powered off)
2
6
3
When there is no active interrupts in the GIC, a read to the C_RPR
7
but there is no way to say "power on a CPU as if it had
4
register should return the value of the "Idle priority", which is either
8
just come out of reset and don't do anything else to it".
5
the maximum value an IRQ priority field can be set to, or 0xff.
6
9
7
Since the QEMU GIC model implements all the 8 priority bits, the Idle
10
Add a new function arm_set_cpu_on_and_reset(), which does this.
8
priority is 0xff.
9
11
10
Internally, when there is no active interrupt, the running priority
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
value is 0x100. The gic_get_running_priority function returns an uint8_t
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
and thus, truncate this value to 0x00 when returning it. This is wrong since
14
Message-id: 20190219125808.25174-5-peter.maydell@linaro.org
13
a value of 0x00 correspond to the maximum possible priority.
15
---
16
target/arm/arm-powerctl.h | 16 +++++++++++
17
target/arm/arm-powerctl.c | 56 +++++++++++++++++++++++++++++++++++++++
18
2 files changed, 72 insertions(+)
14
19
15
This commit fixes the returned value when the internal value is 0x100.
20
diff --git a/target/arm/arm-powerctl.h b/target/arm/arm-powerctl.h
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
28
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
---
31
hw/intc/arm_gic.c | 5 +++++
32
1 file changed, 5 insertions(+)
33
34
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
35
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/intc/arm_gic.c
22
--- a/target/arm/arm-powerctl.h
37
+++ b/hw/intc/arm_gic.c
23
+++ b/target/arm/arm-powerctl.h
38
@@ -XXX,XX +XXX,XX @@ static void gic_set_cpu_control(GICState *s, int cpu, uint32_t value,
24
@@ -XXX,XX +XXX,XX @@ int arm_set_cpu_off(uint64_t cpuid);
39
25
*/
40
static uint8_t gic_get_running_priority(GICState *s, int cpu, MemTxAttrs attrs)
26
int arm_reset_cpu(uint64_t cpuid);
41
{
27
42
+ if ((s->revision != REV_11MPCORE) && (s->running_priority[cpu] > 0xff)) {
28
+/*
43
+ /* Idle priority */
29
+ * arm_set_cpu_on_and_reset:
44
+ return 0xff;
30
+ * @cpuid: the id of the CPU we want to star
31
+ *
32
+ * Start the cpu designated by @cpuid and put it through its normal
33
+ * CPU reset process. The CPU will start in the way it is architected
34
+ * to start after a power-on reset.
35
+ *
36
+ * Returns: QEMU_ARM_POWERCTL_RET_SUCCESS on success.
37
+ * QEMU_ARM_POWERCTL_INVALID_PARAM if there is no CPU with that ID.
38
+ * QEMU_ARM_POWERCTL_ALREADY_ON if the CPU is already on.
39
+ * QEMU_ARM_POWERCTL_ON_PENDING if the CPU is already partway through
40
+ * powering on.
41
+ */
42
+int arm_set_cpu_on_and_reset(uint64_t cpuid);
43
+
44
#endif
45
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/arm-powerctl.c
48
+++ b/target/arm/arm-powerctl.c
49
@@ -XXX,XX +XXX,XX @@ int arm_set_cpu_on(uint64_t cpuid, uint64_t entry, uint64_t context_id,
50
return QEMU_ARM_POWERCTL_RET_SUCCESS;
51
}
52
53
+static void arm_set_cpu_on_and_reset_async_work(CPUState *target_cpu_state,
54
+ run_on_cpu_data data)
55
+{
56
+ ARMCPU *target_cpu = ARM_CPU(target_cpu_state);
57
+
58
+ /* Initialize the cpu we are turning on */
59
+ cpu_reset(target_cpu_state);
60
+ target_cpu_state->halted = 0;
61
+
62
+ /* Finally set the power status */
63
+ assert(qemu_mutex_iothread_locked());
64
+ target_cpu->power_state = PSCI_ON;
65
+}
66
+
67
+int arm_set_cpu_on_and_reset(uint64_t cpuid)
68
+{
69
+ CPUState *target_cpu_state;
70
+ ARMCPU *target_cpu;
71
+
72
+ assert(qemu_mutex_iothread_locked());
73
+
74
+ /* Retrieve the cpu we are powering up */
75
+ target_cpu_state = arm_get_cpu_by_id(cpuid);
76
+ if (!target_cpu_state) {
77
+ /* The cpu was not found */
78
+ return QEMU_ARM_POWERCTL_INVALID_PARAM;
45
+ }
79
+ }
46
+
80
+
47
if (s->security_extn && !attrs.secure) {
81
+ target_cpu = ARM_CPU(target_cpu_state);
48
if (s->running_priority[cpu] & 0x80) {
82
+ if (target_cpu->power_state == PSCI_ON) {
49
/* Running priority in upper half of range: return the Non-secure
83
+ qemu_log_mask(LOG_GUEST_ERROR,
84
+ "[ARM]%s: CPU %" PRId64 " is already on\n",
85
+ __func__, cpuid);
86
+ return QEMU_ARM_POWERCTL_ALREADY_ON;
87
+ }
88
+
89
+ /*
90
+ * If another CPU has powered the target on we are in the state
91
+ * ON_PENDING and additional attempts to power on the CPU should
92
+ * fail (see 6.6 Implementation CPU_ON/CPU_OFF races in the PSCI
93
+ * spec)
94
+ */
95
+ if (target_cpu->power_state == PSCI_ON_PENDING) {
96
+ qemu_log_mask(LOG_GUEST_ERROR,
97
+ "[ARM]%s: CPU %" PRId64 " is already powering on\n",
98
+ __func__, cpuid);
99
+ return QEMU_ARM_POWERCTL_ON_PENDING;
100
+ }
101
+
102
+ async_run_on_cpu(target_cpu_state, arm_set_cpu_on_and_reset_async_work,
103
+ RUN_ON_CPU_NULL);
104
+
105
+ /* We are good to go */
106
+ return QEMU_ARM_POWERCTL_RET_SUCCESS;
107
+}
108
+
109
static void arm_set_cpu_off_async_work(CPUState *target_cpu_state,
110
run_on_cpu_data data)
111
{
50
--
112
--
51
2.7.4
113
2.20.1
52
114
53
115
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The iotkit-sysctl device has a register it names INITSVRTOR0.
2
This is actually a typo present in the IoTKit documentation
3
and also in part of the SSE-200 documentation: it should be
4
INITSVTOR0 because it is specifying the initial value of the
5
Secure VTOR register in the CPU. Correct the typo.
2
6
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20180119045438.28582-15-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190219125808.25174-6-peter.maydell@linaro.org
8
---
10
---
9
target/arm/helper.c | 35 +++++++++++++++++++----------------
11
include/hw/misc/iotkit-sysctl.h | 2 +-
10
1 file changed, 19 insertions(+), 16 deletions(-)
12
hw/misc/iotkit-sysctl.c | 16 ++++++++--------
13
2 files changed, 9 insertions(+), 9 deletions(-)
11
14
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
17
--- a/include/hw/misc/iotkit-sysctl.h
15
+++ b/target/arm/helper.c
18
+++ b/include/hw/misc/iotkit-sysctl.h
16
@@ -XXX,XX +XXX,XX @@ static inline int fp_exception_el(CPUARMState *env)
19
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKitSysCtl {
20
uint32_t reset_syndrome;
21
uint32_t reset_mask;
22
uint32_t gretreg;
23
- uint32_t initsvrtor0;
24
+ uint32_t initsvtor0;
25
uint32_t cpuwait;
26
uint32_t wicctrl;
27
} IoTKitSysCtl;
28
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/misc/iotkit-sysctl.c
31
+++ b/hw/misc/iotkit-sysctl.c
32
@@ -XXX,XX +XXX,XX @@ REG32(RESET_MASK, 0x104)
33
REG32(SWRESET, 0x108)
34
FIELD(SWRESET, SWRESETREQ, 9, 1)
35
REG32(GRETREG, 0x10c)
36
-REG32(INITSVRTOR0, 0x110)
37
+REG32(INITSVTOR0, 0x110)
38
REG32(CPUWAIT, 0x118)
39
REG32(BUSWAIT, 0x11c)
40
REG32(WICCTRL, 0x120)
41
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
42
case A_GRETREG:
43
r = s->gretreg;
44
break;
45
- case A_INITSVRTOR0:
46
- r = s->initsvrtor0;
47
+ case A_INITSVTOR0:
48
+ r = s->initsvtor0;
49
break;
50
case A_CPUWAIT:
51
r = s->cpuwait;
52
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
53
*/
54
s->gretreg = value;
55
break;
56
- case A_INITSVRTOR0:
57
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVRTOR0 unimplemented\n");
58
- s->initsvrtor0 = value;
59
+ case A_INITSVTOR0:
60
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVTOR0 unimplemented\n");
61
+ s->initsvtor0 = value;
62
break;
63
case A_CPUWAIT:
64
qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CPUWAIT unimplemented\n");
65
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
66
s->reset_syndrome = 1;
67
s->reset_mask = 0;
68
s->gretreg = 0;
69
- s->initsvrtor0 = 0x10000000;
70
+ s->initsvtor0 = 0x10000000;
71
s->cpuwait = 0;
72
s->wicctrl = 0;
17
}
73
}
18
74
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_vmstate = {
19
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
75
VMSTATE_UINT32(reset_syndrome, IoTKitSysCtl),
20
- target_ulong *cs_base, uint32_t *flags)
76
VMSTATE_UINT32(reset_mask, IoTKitSysCtl),
21
+ target_ulong *cs_base, uint32_t *pflags)
77
VMSTATE_UINT32(gretreg, IoTKitSysCtl),
22
{
78
- VMSTATE_UINT32(initsvrtor0, IoTKitSysCtl),
23
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
79
+ VMSTATE_UINT32(initsvtor0, IoTKitSysCtl),
24
+ uint32_t flags;
80
VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
25
+
81
VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
26
if (is_a64(env)) {
82
VMSTATE_END_OF_LIST()
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);
56
}
57
58
- *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
59
+ flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
60
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;
95
}
96
--
83
--
97
2.7.4
84
2.20.1
98
85
99
86
diff view generated by jsdifflib
1
From: Linus Walleij <linus.walleij@linaro.org>
1
The SYSCTL block in the SSE-200 has some extra registers that
2
are not present in the IoTKit version. Add these registers
3
(as reads-as-written stubs), enabled by a new QOM property.
2
4
3
This implements rudimentary support for interrupt generation on the
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
PL110. I am working on a new DRI/KMS driver for Linux and since that
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
uses the blanking interrupt, we need something to fire here. Without
7
Message-id: 20190219125808.25174-7-peter.maydell@linaro.org
6
any interrupt support Linux waits for a while and then gives ugly
8
---
7
messages about the vblank not working in the console (it does not
9
include/hw/misc/iotkit-sysctl.h | 20 +++
8
hang perpetually or anything though, DRI is pretty forgiving).
10
hw/arm/armsse.c | 2 +
11
hw/misc/iotkit-sysctl.c | 245 +++++++++++++++++++++++++++++++-
12
3 files changed, 262 insertions(+), 5 deletions(-)
9
13
10
I solved it for now by setting up a timer to fire at 60Hz and pull
14
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
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.
19
20
Cc: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
22
Message-id: 20180123225654.5764-1-linus.walleij@linaro.org
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
[PMM: folded long lines]
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
27
hw/display/pl110.c | 30 +++++++++++++++++++++++++++++-
28
1 file changed, 29 insertions(+), 1 deletion(-)
29
30
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
31
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/display/pl110.c
16
--- a/include/hw/misc/iotkit-sysctl.h
33
+++ b/hw/display/pl110.c
17
+++ b/include/hw/misc/iotkit-sysctl.h
34
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
35
#include "ui/console.h"
19
* "system control register" blocks.
36
#include "framebuffer.h"
20
*
37
#include "ui/pixel_ops.h"
21
* QEMU interface:
38
+#include "qemu/timer.h"
22
+ * + QOM property "SYS_VERSION": value of the SYS_VERSION register of the
23
+ * system information block of the SSE
24
+ * (used to identify whether to provide SSE-200-only registers)
25
* + sysbus MMIO region 0: the system information register bank
26
* + sysbus MMIO region 1: the system control register bank
27
*/
28
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKitSysCtl {
29
uint32_t initsvtor0;
30
uint32_t cpuwait;
31
uint32_t wicctrl;
32
+ uint32_t scsecctrl;
33
+ uint32_t fclk_div;
34
+ uint32_t sysclk_div;
35
+ uint32_t clock_force;
36
+ uint32_t initsvtor1;
37
+ uint32_t nmi_enable;
38
+ uint32_t ewctrl;
39
+ uint32_t pdcm_pd_sys_sense;
40
+ uint32_t pdcm_pd_sram0_sense;
41
+ uint32_t pdcm_pd_sram1_sense;
42
+ uint32_t pdcm_pd_sram2_sense;
43
+ uint32_t pdcm_pd_sram3_sense;
44
+
45
+ /* Properties */
46
+ uint32_t sys_version;
47
+
48
+ bool is_sse200;
49
} IoTKitSysCtl;
50
51
#endif
52
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/arm/armsse.c
55
+++ b/hw/arm/armsse.c
56
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
57
/* System information registers */
58
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000);
59
/* System control registers */
60
+ object_property_set_int(OBJECT(&s->sysctl), info->sys_version,
61
+ "SYS_VERSION", &err);
62
object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
63
if (err) {
64
error_propagate(errp, err);
65
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/misc/iotkit-sysctl.c
68
+++ b/hw/misc/iotkit-sysctl.c
69
@@ -XXX,XX +XXX,XX @@
70
*/
71
72
#include "qemu/osdep.h"
73
+#include "qemu/bitops.h"
39
#include "qemu/log.h"
74
#include "qemu/log.h"
40
75
#include "trace.h"
41
#define PL110_CR_EN 0x001
76
#include "qapi/error.h"
42
@@ -XXX,XX +XXX,XX @@
77
@@ -XXX,XX +XXX,XX @@
43
#define PL110_CR_BEBO 0x200
78
REG32(SECDBGSTAT, 0x0)
44
#define PL110_CR_BEPO 0x400
79
REG32(SECDBGSET, 0x4)
45
#define PL110_CR_PWR 0x800
80
REG32(SECDBGCLR, 0x8)
46
+#define PL110_IE_NB 0x004
81
+REG32(SCSECCTRL, 0xc)
47
+#define PL110_IE_VC 0x008
82
+REG32(FCLK_DIV, 0x10)
48
83
+REG32(SYSCLK_DIV, 0x14)
49
enum pl110_bppmode
84
+REG32(CLOCK_FORCE, 0x18)
50
{
85
REG32(RESET_SYNDROME, 0x100)
51
@@ -XXX,XX +XXX,XX @@ typedef struct PL110State {
86
REG32(RESET_MASK, 0x104)
52
MemoryRegion iomem;
87
REG32(SWRESET, 0x108)
53
MemoryRegionSection fbsection;
88
FIELD(SWRESET, SWRESETREQ, 9, 1)
54
QemuConsole *con;
89
REG32(GRETREG, 0x10c)
55
+ QEMUTimer *vblank_timer;
90
REG32(INITSVTOR0, 0x110)
56
91
+REG32(INITSVTOR1, 0x114)
57
int version;
92
REG32(CPUWAIT, 0x118)
58
uint32_t timing[4];
93
-REG32(BUSWAIT, 0x11c)
59
@@ -XXX,XX +XXX,XX @@ static void pl110_resize(PL110State *s, int width, int height)
94
+REG32(NMI_ENABLE, 0x11c) /* BUSWAIT in IoTKit */
60
/* Update interrupts. */
95
REG32(WICCTRL, 0x120)
61
static void pl110_update(PL110State *s)
96
+REG32(EWCTRL, 0x124)
62
{
97
+REG32(PDCM_PD_SYS_SENSE, 0x200)
63
- /* TODO: Implement interrupts. */
98
+REG32(PDCM_PD_SRAM0_SENSE, 0x20c)
64
+ /* Raise IRQ if enabled and any status bit is 1 */
99
+REG32(PDCM_PD_SRAM1_SENSE, 0x210)
65
+ if (s->int_status & s->int_mask) {
100
+REG32(PDCM_PD_SRAM2_SENSE, 0x214)
66
+ qemu_irq_raise(s->irq);
101
+REG32(PDCM_PD_SRAM3_SENSE, 0x218)
67
+ } else {
102
REG32(PID4, 0xfd0)
68
+ qemu_irq_lower(s->irq);
103
REG32(PID5, 0xfd4)
104
REG32(PID6, 0xfd8)
105
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
106
case A_SECDBGSTAT:
107
r = s->secure_debug;
108
break;
109
+ case A_SCSECCTRL:
110
+ if (!s->is_sse200) {
111
+ goto bad_offset;
112
+ }
113
+ r = s->scsecctrl;
114
+ break;
115
+ case A_FCLK_DIV:
116
+ if (!s->is_sse200) {
117
+ goto bad_offset;
118
+ }
119
+ r = s->fclk_div;
120
+ break;
121
+ case A_SYSCLK_DIV:
122
+ if (!s->is_sse200) {
123
+ goto bad_offset;
124
+ }
125
+ r = s->sysclk_div;
126
+ break;
127
+ case A_CLOCK_FORCE:
128
+ if (!s->is_sse200) {
129
+ goto bad_offset;
130
+ }
131
+ r = s->clock_force;
132
+ break;
133
case A_RESET_SYNDROME:
134
r = s->reset_syndrome;
135
break;
136
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
137
case A_INITSVTOR0:
138
r = s->initsvtor0;
139
break;
140
+ case A_INITSVTOR1:
141
+ if (!s->is_sse200) {
142
+ goto bad_offset;
143
+ }
144
+ r = s->initsvtor1;
145
+ break;
146
case A_CPUWAIT:
147
r = s->cpuwait;
148
break;
149
- case A_BUSWAIT:
150
- /* In IoTKit BUSWAIT is reserved, R/O, zero */
151
- r = 0;
152
+ case A_NMI_ENABLE:
153
+ /* In IoTKit this is named BUSWAIT but is marked reserved, R/O, zero */
154
+ if (!s->is_sse200) {
155
+ r = 0;
156
+ break;
157
+ }
158
+ r = s->nmi_enable;
159
break;
160
case A_WICCTRL:
161
r = s->wicctrl;
162
break;
163
+ case A_EWCTRL:
164
+ if (!s->is_sse200) {
165
+ goto bad_offset;
166
+ }
167
+ r = s->ewctrl;
168
+ break;
169
+ case A_PDCM_PD_SYS_SENSE:
170
+ if (!s->is_sse200) {
171
+ goto bad_offset;
172
+ }
173
+ r = s->pdcm_pd_sys_sense;
174
+ break;
175
+ case A_PDCM_PD_SRAM0_SENSE:
176
+ if (!s->is_sse200) {
177
+ goto bad_offset;
178
+ }
179
+ r = s->pdcm_pd_sram0_sense;
180
+ break;
181
+ case A_PDCM_PD_SRAM1_SENSE:
182
+ if (!s->is_sse200) {
183
+ goto bad_offset;
184
+ }
185
+ r = s->pdcm_pd_sram1_sense;
186
+ break;
187
+ case A_PDCM_PD_SRAM2_SENSE:
188
+ if (!s->is_sse200) {
189
+ goto bad_offset;
190
+ }
191
+ r = s->pdcm_pd_sram2_sense;
192
+ break;
193
+ case A_PDCM_PD_SRAM3_SENSE:
194
+ if (!s->is_sse200) {
195
+ goto bad_offset;
196
+ }
197
+ r = s->pdcm_pd_sram3_sense;
198
+ break;
199
case A_PID4 ... A_CID3:
200
r = sysctl_id[(offset - A_PID4) / 4];
201
break;
202
@@ -XXX,XX +XXX,XX @@ static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
203
r = 0;
204
break;
205
default:
206
+ bad_offset:
207
qemu_log_mask(LOG_GUEST_ERROR,
208
"IoTKit SysCtl read: bad offset %x\n", (int)offset);
209
r = 0;
210
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
211
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
212
}
213
break;
214
- case A_BUSWAIT: /* In IoTKit BUSWAIT is reserved, R/O, zero */
215
+ case A_SCSECCTRL:
216
+ if (!s->is_sse200) {
217
+ goto bad_offset;
218
+ }
219
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SCSECCTRL unimplemented\n");
220
+ s->scsecctrl = value;
221
+ break;
222
+ case A_FCLK_DIV:
223
+ if (!s->is_sse200) {
224
+ goto bad_offset;
225
+ }
226
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl FCLK_DIV unimplemented\n");
227
+ s->fclk_div = value;
228
+ break;
229
+ case A_SYSCLK_DIV:
230
+ if (!s->is_sse200) {
231
+ goto bad_offset;
232
+ }
233
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl SYSCLK_DIV unimplemented\n");
234
+ s->sysclk_div = value;
235
+ break;
236
+ case A_CLOCK_FORCE:
237
+ if (!s->is_sse200) {
238
+ goto bad_offset;
239
+ }
240
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CLOCK_FORCE unimplemented\n");
241
+ s->clock_force = value;
242
+ break;
243
+ case A_INITSVTOR1:
244
+ if (!s->is_sse200) {
245
+ goto bad_offset;
246
+ }
247
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVTOR1 unimplemented\n");
248
+ s->initsvtor1 = value;
249
+ break;
250
+ case A_EWCTRL:
251
+ if (!s->is_sse200) {
252
+ goto bad_offset;
253
+ }
254
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl EWCTRL unimplemented\n");
255
+ s->ewctrl = value;
256
+ break;
257
+ case A_PDCM_PD_SYS_SENSE:
258
+ if (!s->is_sse200) {
259
+ goto bad_offset;
260
+ }
261
+ qemu_log_mask(LOG_UNIMP,
262
+ "IoTKit SysCtl PDCM_PD_SYS_SENSE unimplemented\n");
263
+ s->pdcm_pd_sys_sense = value;
264
+ break;
265
+ case A_PDCM_PD_SRAM0_SENSE:
266
+ if (!s->is_sse200) {
267
+ goto bad_offset;
268
+ }
269
+ qemu_log_mask(LOG_UNIMP,
270
+ "IoTKit SysCtl PDCM_PD_SRAM0_SENSE unimplemented\n");
271
+ s->pdcm_pd_sram0_sense = value;
272
+ break;
273
+ case A_PDCM_PD_SRAM1_SENSE:
274
+ if (!s->is_sse200) {
275
+ goto bad_offset;
276
+ }
277
+ qemu_log_mask(LOG_UNIMP,
278
+ "IoTKit SysCtl PDCM_PD_SRAM1_SENSE unimplemented\n");
279
+ s->pdcm_pd_sram1_sense = value;
280
+ break;
281
+ case A_PDCM_PD_SRAM2_SENSE:
282
+ if (!s->is_sse200) {
283
+ goto bad_offset;
284
+ }
285
+ qemu_log_mask(LOG_UNIMP,
286
+ "IoTKit SysCtl PDCM_PD_SRAM2_SENSE unimplemented\n");
287
+ s->pdcm_pd_sram2_sense = value;
288
+ break;
289
+ case A_PDCM_PD_SRAM3_SENSE:
290
+ if (!s->is_sse200) {
291
+ goto bad_offset;
292
+ }
293
+ qemu_log_mask(LOG_UNIMP,
294
+ "IoTKit SysCtl PDCM_PD_SRAM3_SENSE unimplemented\n");
295
+ s->pdcm_pd_sram3_sense = value;
296
+ break;
297
+ case A_NMI_ENABLE:
298
+ /* In IoTKit this is BUSWAIT: reserved, R/O, zero */
299
+ if (!s->is_sse200) {
300
+ goto ro_offset;
301
+ }
302
+ qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl NMI_ENABLE unimplemented\n");
303
+ s->nmi_enable = value;
304
+ break;
305
case A_SECDBGSTAT:
306
case A_PID4 ... A_CID3:
307
+ ro_offset:
308
qemu_log_mask(LOG_GUEST_ERROR,
309
"IoTKit SysCtl write: write of RO offset %x\n",
310
(int)offset);
311
break;
312
default:
313
+ bad_offset:
314
qemu_log_mask(LOG_GUEST_ERROR,
315
"IoTKit SysCtl write: bad offset %x\n", (int)offset);
316
break;
317
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
318
s->reset_mask = 0;
319
s->gretreg = 0;
320
s->initsvtor0 = 0x10000000;
321
+ s->initsvtor1 = 0x10000000;
322
s->cpuwait = 0;
323
s->wicctrl = 0;
324
+ s->scsecctrl = 0;
325
+ s->fclk_div = 0;
326
+ s->sysclk_div = 0;
327
+ s->clock_force = 0;
328
+ s->nmi_enable = 0;
329
+ s->ewctrl = 0;
330
+ s->pdcm_pd_sys_sense = 0x7f;
331
+ s->pdcm_pd_sram0_sense = 0;
332
+ s->pdcm_pd_sram1_sense = 0;
333
+ s->pdcm_pd_sram2_sense = 0;
334
+ s->pdcm_pd_sram3_sense = 0;
335
}
336
337
static void iotkit_sysctl_init(Object *obj)
338
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_init(Object *obj)
339
sysbus_init_mmio(sbd, &s->iomem);
340
}
341
342
+static void iotkit_sysctl_realize(DeviceState *dev, Error **errp)
343
+{
344
+ IoTKitSysCtl *s = IOTKIT_SYSCTL(dev);
345
+
346
+ /* The top 4 bits of the SYS_VERSION register tell us if we're an SSE-200 */
347
+ if (extract32(s->sys_version, 28, 4) == 2) {
348
+ s->is_sse200 = true;
69
+ }
349
+ }
70
+}
350
+}
71
+
351
+
72
+static void pl110_vblank_interrupt(void *opaque)
352
+static bool sse200_needed(void *opaque)
73
+{
353
+{
74
+ PL110State *s = opaque;
354
+ IoTKitSysCtl *s = IOTKIT_SYSCTL(opaque);
75
+
355
+
76
+ /* Fire the vertical compare and next base IRQs and re-arm */
356
+ return s->is_sse200;
77
+ s->int_status |= (PL110_IE_NB | PL110_IE_VC);
357
+}
78
+ timer_mod(s->vblank_timer,
358
+
79
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
359
+static const VMStateDescription iotkit_sysctl_sse200_vmstate = {
80
+ NANOSECONDS_PER_SECOND / 60);
360
+ .name = "iotkit-sysctl/sse-200",
81
+ pl110_update(s);
361
+ .version_id = 1,
362
+ .minimum_version_id = 1,
363
+ .needed = sse200_needed,
364
+ .fields = (VMStateField[]) {
365
+ VMSTATE_UINT32(scsecctrl, IoTKitSysCtl),
366
+ VMSTATE_UINT32(fclk_div, IoTKitSysCtl),
367
+ VMSTATE_UINT32(sysclk_div, IoTKitSysCtl),
368
+ VMSTATE_UINT32(clock_force, IoTKitSysCtl),
369
+ VMSTATE_UINT32(initsvtor1, IoTKitSysCtl),
370
+ VMSTATE_UINT32(nmi_enable, IoTKitSysCtl),
371
+ VMSTATE_UINT32(pdcm_pd_sys_sense, IoTKitSysCtl),
372
+ VMSTATE_UINT32(pdcm_pd_sram0_sense, IoTKitSysCtl),
373
+ VMSTATE_UINT32(pdcm_pd_sram1_sense, IoTKitSysCtl),
374
+ VMSTATE_UINT32(pdcm_pd_sram2_sense, IoTKitSysCtl),
375
+ VMSTATE_UINT32(pdcm_pd_sram3_sense, IoTKitSysCtl),
376
+ VMSTATE_END_OF_LIST()
377
+ }
378
+};
379
+
380
static const VMStateDescription iotkit_sysctl_vmstate = {
381
.name = "iotkit-sysctl",
382
.version_id = 1,
383
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_vmstate = {
384
VMSTATE_UINT32(cpuwait, IoTKitSysCtl),
385
VMSTATE_UINT32(wicctrl, IoTKitSysCtl),
386
VMSTATE_END_OF_LIST()
387
+ },
388
+ .subsections = (const VMStateDescription*[]) {
389
+ &iotkit_sysctl_sse200_vmstate,
390
+ NULL
391
}
392
};
393
394
+static Property iotkit_sysctl_props[] = {
395
+ DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
396
+ DEFINE_PROP_END_OF_LIST()
397
+};
398
+
399
static void iotkit_sysctl_class_init(ObjectClass *klass, void *data)
400
{
401
DeviceClass *dc = DEVICE_CLASS(klass);
402
403
dc->vmsd = &iotkit_sysctl_vmstate;
404
dc->reset = iotkit_sysctl_reset;
405
+ dc->props = iotkit_sysctl_props;
406
+ dc->realize = iotkit_sysctl_realize;
82
}
407
}
83
408
84
static uint64_t pl110_read(void *opaque, hwaddr offset,
409
static const TypeInfo iotkit_sysctl_info = {
85
@@ -XXX,XX +XXX,XX @@ static void pl110_write(void *opaque, hwaddr offset,
86
s->bpp = (val >> 1) & 7;
87
if (pl110_enabled(s)) {
88
qemu_console_resize(s->con, s->cols, s->rows);
89
+ timer_mod(s->vblank_timer,
90
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
91
+ NANOSECONDS_PER_SECOND / 60);
92
+ } else {
93
+ timer_del(s->vblank_timer);
94
}
95
break;
96
case 10: /* LCDICR */
97
@@ -XXX,XX +XXX,XX @@ static void pl110_realize(DeviceState *dev, Error **errp)
98
memory_region_init_io(&s->iomem, OBJECT(s), &pl110_ops, s, "pl110", 0x1000);
99
sysbus_init_mmio(sbd, &s->iomem);
100
sysbus_init_irq(sbd, &s->irq);
101
+ s->vblank_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
102
+ pl110_vblank_interrupt, s);
103
qdev_init_gpio_in(dev, pl110_mux_ctrl_set, 1);
104
s->con = graphic_console_init(dev, 0, &pl110_gfx_ops, s);
105
}
106
--
410
--
107
2.7.4
411
2.20.1
108
412
109
413
diff view generated by jsdifflib
1
We were passing a NULL error pointer to the object_property_set_bool()
1
The CPUWAIT register acts as a sort of power-control: if a bit
2
call that realizes the CPU object. This meant that we wouldn't detect
2
in it is 1 then the CPU will have been forced into waiting
3
failure, and would plough blindly on to crash later trying to use a
3
when the system was reset (which in QEMU we model as the
4
NULL CPU object pointer. Detect errors and fail instead.
4
CPU starting powered off). Writing a 0 to the register will
5
allow the CPU to boot (for QEMU, we model this as powering
6
it on). Note that writing 0 to the register does not power
7
off a CPU.
5
8
6
In particular, this will be necessary to detect the user error
9
For this to work correctly we need to also honour the
7
of using "-cpu host" without "-enable-kvm" once we make the host
10
INITSVTOR* registers, which let the guest control where the
8
CPU type be registered unconditionally rather than only in
11
CPU will load its SP and PC from when it comes out of reset.
9
kvm_arch_init().
10
12
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190219125808.25174-8-peter.maydell@linaro.org
12
---
16
---
13
hw/arm/virt.c | 2 +-
17
hw/misc/iotkit-sysctl.c | 41 +++++++++++++++++++++++++++++++++++++----
14
1 file changed, 1 insertion(+), 1 deletion(-)
18
1 file changed, 37 insertions(+), 4 deletions(-)
15
19
16
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
20
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/virt.c
22
--- a/hw/misc/iotkit-sysctl.c
19
+++ b/hw/arm/virt.c
23
+++ b/hw/misc/iotkit-sysctl.c
20
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
24
@@ -XXX,XX +XXX,XX @@
21
"secure-memory", &error_abort);
25
#include "hw/sysbus.h"
26
#include "hw/registerfields.h"
27
#include "hw/misc/iotkit-sysctl.h"
28
+#include "target/arm/arm-powerctl.h"
29
+#include "target/arm/cpu.h"
30
31
REG32(SECDBGSTAT, 0x0)
32
REG32(SECDBGSET, 0x4)
33
@@ -XXX,XX +XXX,XX @@ static const int sysctl_id[] = {
34
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
35
};
36
37
+/*
38
+ * Set the initial secure vector table offset address for the core.
39
+ * This will take effect when the CPU next resets.
40
+ */
41
+static void set_init_vtor(uint64_t cpuid, uint32_t vtor)
42
+{
43
+ Object *cpuobj = OBJECT(arm_get_cpu_by_id(cpuid));
44
+
45
+ if (cpuobj) {
46
+ if (object_property_find(cpuobj, "init-svtor", NULL)) {
47
+ object_property_set_uint(cpuobj, vtor, "init-svtor", &error_abort);
48
+ }
49
+ }
50
+}
51
+
52
static uint64_t iotkit_sysctl_read(void *opaque, hwaddr offset,
53
unsigned size)
54
{
55
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
56
s->gretreg = value;
57
break;
58
case A_INITSVTOR0:
59
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVTOR0 unimplemented\n");
60
s->initsvtor0 = value;
61
+ set_init_vtor(0, s->initsvtor0);
62
break;
63
case A_CPUWAIT:
64
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl CPUWAIT unimplemented\n");
65
+ if ((s->cpuwait & 1) && !(value & 1)) {
66
+ /* Powering up CPU 0 */
67
+ arm_set_cpu_on_and_reset(0);
68
+ }
69
+ if ((s->cpuwait & 2) && !(value & 2)) {
70
+ /* Powering up CPU 1 */
71
+ arm_set_cpu_on_and_reset(1);
72
+ }
73
s->cpuwait = value;
74
break;
75
case A_WICCTRL:
76
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_write(void *opaque, hwaddr offset,
77
if (!s->is_sse200) {
78
goto bad_offset;
22
}
79
}
23
80
- qemu_log_mask(LOG_UNIMP, "IoTKit SysCtl INITSVTOR1 unimplemented\n");
24
- object_property_set_bool(cpuobj, true, "realized", NULL);
81
s->initsvtor1 = value;
25
+ object_property_set_bool(cpuobj, true, "realized", &error_fatal);
82
+ set_init_vtor(1, s->initsvtor1);
26
object_unref(cpuobj);
83
break;
27
}
84
case A_EWCTRL:
28
fdt_add_timer_nodes(vms);
85
if (!s->is_sse200) {
86
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
87
s->gretreg = 0;
88
s->initsvtor0 = 0x10000000;
89
s->initsvtor1 = 0x10000000;
90
- s->cpuwait = 0;
91
+ if (s->is_sse200) {
92
+ /*
93
+ * CPU 0 starts on, CPU 1 starts off. In real hardware this is
94
+ * configurable by the SoC integrator as a verilog parameter.
95
+ */
96
+ s->cpuwait = 2;
97
+ } else {
98
+ /* CPU 0 starts on */
99
+ s->cpuwait = 0;
100
+ }
101
s->wicctrl = 0;
102
s->scsecctrl = 0;
103
s->fclk_div = 0;
29
--
104
--
30
2.7.4
105
2.20.1
31
106
32
107
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
At the moment the handling of init-svtor and cpuwait initial
2
values is split between armsse.c and iotkit-sysctl.c:
3
the code in armsse.c sets the initial state of the CPU
4
object by setting the init-svtor and start-powered-off
5
properties, but the iotkit-sysctl.c code has its own
6
code setting the reset values of its registers (which are
7
then used when updating the CPU when the guest makes
8
runtime changes).
2
9
3
At the same time, move VMSTATE_UINT32_SUB_ARRAY
10
Clean this up by making the armsse.c code set properties on the
4
beside the other UINT32 definitions.
11
iotkit-sysctl object to define the initial values of the
12
registers, so they always match the initial CPU state,
13
and update the comments in armsse.c accordingly.
5
14
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190219125808.25174-9-peter.maydell@linaro.org
12
---
18
---
13
include/migration/vmstate.h | 9 ++++++---
19
include/hw/misc/iotkit-sysctl.h | 3 ++
14
1 file changed, 6 insertions(+), 3 deletions(-)
20
hw/arm/armsse.c | 49 +++++++++++++++++++++------------
21
hw/misc/iotkit-sysctl.c | 20 ++++++--------
22
3 files changed, 42 insertions(+), 30 deletions(-)
15
23
16
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
24
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
17
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
18
--- a/include/migration/vmstate.h
26
--- a/include/hw/misc/iotkit-sysctl.h
19
+++ b/include/migration/vmstate.h
27
+++ b/include/hw/misc/iotkit-sysctl.h
20
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
28
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKitSysCtl {
21
#define VMSTATE_UINT32_ARRAY(_f, _s, _n) \
29
22
VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0)
30
/* Properties */
23
31
uint32_t sys_version;
24
+#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
32
+ uint32_t cpuwait_rst;
25
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
33
+ uint32_t initsvtor0_rst;
26
+
34
+ uint32_t initsvtor1_rst;
27
#define VMSTATE_UINT32_2DARRAY(_f, _s, _n1, _n2) \
35
28
VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, 0)
36
bool is_sse200;
29
37
} IoTKitSysCtl;
30
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
38
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
31
#define VMSTATE_UINT64_ARRAY(_f, _s, _n) \
39
index XXXXXXX..XXXXXXX 100644
32
VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0)
40
--- a/hw/arm/armsse.c
33
41
+++ b/hw/arm/armsse.c
34
+#define VMSTATE_UINT64_SUB_ARRAY(_f, _s, _start, _num) \
42
@@ -XXX,XX +XXX,XX @@
35
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint64, uint64_t)
43
36
+
44
#include "qemu/osdep.h"
37
#define VMSTATE_UINT64_2DARRAY(_f, _s, _n1, _n2) \
45
#include "qemu/log.h"
38
VMSTATE_UINT64_2DARRAY_V(_f, _s, _n1, _n2, 0)
46
+#include "qemu/bitops.h"
39
47
#include "qapi/error.h"
40
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
48
#include "trace.h"
41
#define VMSTATE_INT32_ARRAY(_f, _s, _n) \
49
#include "hw/sysbus.h"
42
VMSTATE_INT32_ARRAY_V(_f, _s, _n, 0)
50
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
43
51
int sram_banks;
44
-#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
52
int num_cpus;
45
- VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
53
uint32_t sys_version;
46
-
54
+ uint32_t cpuwait_rst;
47
#define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v) \
55
SysConfigFormat sys_config_format;
48
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t)
56
bool has_mhus;
57
bool has_ppus;
58
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
59
.sram_banks = 1,
60
.num_cpus = 1,
61
.sys_version = 0x41743,
62
+ .cpuwait_rst = 0,
63
.sys_config_format = IoTKitFormat,
64
.has_mhus = false,
65
.has_ppus = false,
66
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
67
.sram_banks = 4,
68
.num_cpus = 2,
69
.sys_version = 0x22041743,
70
+ .cpuwait_rst = 2,
71
.sys_config_format = SSE200Format,
72
.has_mhus = true,
73
.has_ppus = true,
74
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
75
76
qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
77
/*
78
- * In real hardware the initial Secure VTOR is set from the INITSVTOR0
79
- * register in the IoT Kit System Control Register block, and the
80
- * initial value of that is in turn specifiable by the FPGA that
81
- * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
82
- * and simply set the CPU's init-svtor to the IoT Kit default value.
83
- * In SSE-200 the situation is similar, except that the default value
84
- * is a reset-time signal input. Typically a board using the SSE-200
85
- * will have a system control processor whose boot firmware initializes
86
- * the INITSVTOR* registers before powering up the CPUs in any case,
87
- * so the hardware's default value doesn't matter. QEMU doesn't emulate
88
+ * In real hardware the initial Secure VTOR is set from the INITSVTOR*
89
+ * registers in the IoT Kit System Control Register block. In QEMU
90
+ * we set the initial value here, and also the reset value of the
91
+ * sysctl register, from this object's QOM init-svtor property.
92
+ * If the guest changes the INITSVTOR* registers at runtime then the
93
+ * code in iotkit-sysctl.c will update the CPU init-svtor property
94
+ * (which will then take effect on the next CPU warm-reset).
95
+ *
96
+ * Note that typically a board using the SSE-200 will have a system
97
+ * control processor whose boot firmware initializes the INITSVTOR*
98
+ * registers before powering up the CPUs. QEMU doesn't emulate
99
* the control processor, so instead we behave in the way that the
100
- * firmware does. The initial value is configurable by the board code
101
- * to match whatever its firmware does.
102
+ * firmware does: the initial value should be set by the board code
103
+ * (using the init-svtor property on the ARMSSE object) to match
104
+ * whatever its firmware does.
105
*/
106
qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
107
/*
108
- * Start all CPUs except CPU0 powered down. In real hardware it is
109
- * a configurable property of the SSE-200 which CPUs start powered up
110
- * (via the CPUWAIT0_RST and CPUWAIT1_RST parameters), but since all
111
- * the boards we care about start CPU0 and leave CPU1 powered off,
112
- * we hard-code that for now. We can add QOM properties for this
113
+ * CPUs start powered down if the corresponding bit in the CPUWAIT
114
+ * register is 1. In real hardware the CPUWAIT register reset value is
115
+ * a configurable property of the SSE-200 (via the CPUWAIT0_RST and
116
+ * CPUWAIT1_RST parameters), but since all the boards we care about
117
+ * start CPU0 and leave CPU1 powered off, we hard-code that in
118
+ * info->cpuwait_rst for now. We can add QOM properties for this
119
* later if necessary.
120
*/
121
- if (i > 0) {
122
+ if (extract32(info->cpuwait_rst, i, 1)) {
123
object_property_set_bool(cpuobj, true, "start-powered-off", &err);
124
if (err) {
125
error_propagate(errp, err);
126
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
127
/* System control registers */
128
object_property_set_int(OBJECT(&s->sysctl), info->sys_version,
129
"SYS_VERSION", &err);
130
+ object_property_set_int(OBJECT(&s->sysctl), info->cpuwait_rst,
131
+ "CPUWAIT_RST", &err);
132
+ object_property_set_int(OBJECT(&s->sysctl), s->init_svtor,
133
+ "INITSVTOR0_RST", &err);
134
+ object_property_set_int(OBJECT(&s->sysctl), s->init_svtor,
135
+ "INITSVTOR1_RST", &err);
136
object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err);
137
if (err) {
138
error_propagate(errp, err);
139
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/hw/misc/iotkit-sysctl.c
142
+++ b/hw/misc/iotkit-sysctl.c
143
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysctl_reset(DeviceState *dev)
144
s->reset_syndrome = 1;
145
s->reset_mask = 0;
146
s->gretreg = 0;
147
- s->initsvtor0 = 0x10000000;
148
- s->initsvtor1 = 0x10000000;
149
- if (s->is_sse200) {
150
- /*
151
- * CPU 0 starts on, CPU 1 starts off. In real hardware this is
152
- * configurable by the SoC integrator as a verilog parameter.
153
- */
154
- s->cpuwait = 2;
155
- } else {
156
- /* CPU 0 starts on */
157
- s->cpuwait = 0;
158
- }
159
+ s->initsvtor0 = s->initsvtor0_rst;
160
+ s->initsvtor1 = s->initsvtor1_rst;
161
+ s->cpuwait = s->cpuwait_rst;
162
s->wicctrl = 0;
163
s->scsecctrl = 0;
164
s->fclk_div = 0;
165
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_sysctl_vmstate = {
166
167
static Property iotkit_sysctl_props[] = {
168
DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysCtl, sys_version, 0),
169
+ DEFINE_PROP_UINT32("CPUWAIT_RST", IoTKitSysCtl, cpuwait_rst, 0),
170
+ DEFINE_PROP_UINT32("INITSVTOR0_RST", IoTKitSysCtl, initsvtor0_rst,
171
+ 0x10000000),
172
+ DEFINE_PROP_UINT32("INITSVTOR1_RST", IoTKitSysCtl, initsvtor1_rst,
173
+ 0x10000000),
174
DEFINE_PROP_END_OF_LIST()
175
};
49
176
50
--
177
--
51
2.7.4
178
2.20.1
52
179
53
180
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Instead of gating the A32/T32 FP16 conversion instructions on
2
the ARM_FEATURE_VFP_FP16 flag, switch to our new approach of
3
looking at ID register bits. In this case MVFR1 fields FPHP
4
and SIMDHP indicate the presence of these insns.
2
5
3
Helpers that return a pointer into env->vfp.regs so that we isolate
6
This change doesn't alter behaviour for any of our CPUs.
4
the logic of how to index the regs array for different cpu modes.
5
7
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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190222170936.13268-2-peter.maydell@linaro.org
10
---
11
---
11
target/arm/cpu.h | 27 +++++++++++++++++++++++++++
12
target/arm/cpu.h | 37 ++++++++++++++++++++++++++++++++++++-
12
linux-user/signal.c | 22 ++++++++++++----------
13
target/arm/cpu.c | 2 --
13
target/arm/arch_dump.c | 8 +++++---
14
target/arm/kvm32.c | 3 ---
14
target/arm/helper-a64.c | 5 +++--
15
target/arm/translate.c | 26 ++++++++++++++++++--------
15
target/arm/helper.c | 32 ++++++++++++++++++++------------
16
4 files changed, 54 insertions(+), 14 deletions(-)
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(-)
21
17
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
22
@@ -XXX,XX +XXX,XX @@ FIELD(ID_DFR0, MPROFDBG, 20, 4)
27
return cpu->el_change_hook_opaque;
23
FIELD(ID_DFR0, PERFMON, 24, 4)
24
FIELD(ID_DFR0, TRACEFILT, 28, 4)
25
26
+FIELD(MVFR0, SIMDREG, 0, 4)
27
+FIELD(MVFR0, FPSP, 4, 4)
28
+FIELD(MVFR0, FPDP, 8, 4)
29
+FIELD(MVFR0, FPTRAP, 12, 4)
30
+FIELD(MVFR0, FPDIVIDE, 16, 4)
31
+FIELD(MVFR0, FPSQRT, 20, 4)
32
+FIELD(MVFR0, FPSHVEC, 24, 4)
33
+FIELD(MVFR0, FPROUND, 28, 4)
34
+
35
+FIELD(MVFR1, FPFTZ, 0, 4)
36
+FIELD(MVFR1, FPDNAN, 4, 4)
37
+FIELD(MVFR1, SIMDLS, 8, 4)
38
+FIELD(MVFR1, SIMDINT, 12, 4)
39
+FIELD(MVFR1, SIMDSP, 16, 4)
40
+FIELD(MVFR1, SIMDHP, 20, 4)
41
+FIELD(MVFR1, FPHP, 24, 4)
42
+FIELD(MVFR1, SIMDFMAC, 28, 4)
43
+
44
+FIELD(MVFR2, SIMDMISC, 0, 4)
45
+FIELD(MVFR2, FPMISC, 4, 4)
46
+
47
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
48
49
/* If adding a feature bit which corresponds to a Linux ELF
50
@@ -XXX,XX +XXX,XX @@ enum arm_features {
51
ARM_FEATURE_THUMB2,
52
ARM_FEATURE_PMSA, /* no MMU; may have Memory Protection Unit */
53
ARM_FEATURE_VFP3,
54
- ARM_FEATURE_VFP_FP16,
55
ARM_FEATURE_NEON,
56
ARM_FEATURE_M, /* Microcontroller profile. */
57
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
58
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
59
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
28
}
60
}
29
61
30
+/**
62
+/*
31
+ * aa32_vfp_dreg:
63
+ * We always set the FP and SIMD FP16 fields to indicate identical
32
+ * Return a pointer to the Dn register within env in 32-bit mode.
64
+ * levels of support (assuming SIMD is implemented at all), so
65
+ * we only need one set of accessors.
33
+ */
66
+ */
34
+static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
67
+static inline bool isar_feature_aa32_fp16_spconv(const ARMISARegisters *id)
35
+{
68
+{
36
+ return &env->vfp.regs[regno];
69
+ return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 0;
37
+}
70
+}
38
+
71
+
39
+/**
72
+static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
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
+{
73
+{
45
+ return &env->vfp.regs[2 * regno];
74
+ return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 1;
46
+}
75
+}
47
+
76
+
48
+/**
77
/*
49
+ * aa64_vfp_qreg:
78
* 64-bit feature tests via id registers.
50
+ * Return a pointer to the Qn register within env in 64-bit mode.
79
*/
51
+ */
80
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
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
81
index XXXXXXX..XXXXXXX 100644
60
--- a/linux-user/signal.c
82
--- a/target/arm/cpu.c
61
+++ b/linux-user/signal.c
83
+++ b/target/arm/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static int target_setup_sigframe(struct target_rt_sigframe *sf,
84
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
63
}
85
}
64
86
if (arm_feature(env, ARM_FEATURE_VFP4)) {
65
for (i = 0; i < 32; i++) {
87
set_feature(env, ARM_FEATURE_VFP3);
66
+ uint64_t *q = aa64_vfp_qreg(env, i);
88
- set_feature(env, ARM_FEATURE_VFP_FP16);
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
}
89
}
79
__put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
90
if (arm_feature(env, ARM_FEATURE_VFP3)) {
80
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
91
set_feature(env, ARM_FEATURE_VFP);
81
}
92
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
82
93
cpu->dtb_compatible = "arm,cortex-a9";
83
for (i = 0; i < 32; i++) {
94
set_feature(&cpu->env, ARM_FEATURE_V7);
84
+ uint64_t *q = aa64_vfp_qreg(env, i);
95
set_feature(&cpu->env, ARM_FEATURE_VFP3);
85
#ifdef TARGET_WORDS_BIGENDIAN
96
- set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
86
- __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
97
set_feature(&cpu->env, ARM_FEATURE_NEON);
87
- __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
98
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
88
+ __get_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
99
set_feature(&cpu->env, ARM_FEATURE_EL3);
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
100
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
239
index XXXXXXX..XXXXXXX 100644
101
index XXXXXXX..XXXXXXX 100644
240
--- a/target/arm/kvm32.c
102
--- a/target/arm/kvm32.c
241
+++ b/target/arm/kvm32.c
103
+++ b/target/arm/kvm32.c
242
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
104
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
243
/* VFP registers */
105
if (extract32(id_pfr0, 12, 4) == 1) {
244
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
106
set_feature(&features, ARM_FEATURE_THUMB2EE);
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
}
107
}
267
108
- if (extract32(ahcf->isar.mvfr1, 20, 4) == 1) {
268
- /* Advanced SIMD and FP registers
109
- set_feature(&features, ARM_FEATURE_VFP_FP16);
269
- * We map Qn = regs[2n+1]:regs[2n]
110
- }
270
- */
111
if (extract32(ahcf->isar.mvfr1, 12, 4) == 1) {
271
+ /* Advanced SIMD and FP registers. */
112
set_feature(&features, ARM_FEATURE_NEON);
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
}
113
}
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)
350
{
351
- int offs = offsetof(CPUARMState, vfp.regs[regno * 2]);
352
-#ifdef HOST_WORDS_BIGENDIAN
353
- offs += (8 - (1 << size));
354
-#endif
355
- assert_fp_access_checked(s);
356
- return offs;
357
+ return vec_reg_offset(s, regno, 0, size);
358
}
359
360
/* Offset of the high half of the 128 bit vector Qn */
361
static inline int fp_reg_hi_offset(DisasContext *s, int regno)
362
{
363
- assert_fp_access_checked(s);
364
- return offsetof(CPUARMState, vfp.regs[regno * 2 + 1]);
365
+ return vec_reg_offset(s, regno, 1, MO_64);
366
}
367
368
/* Convenience accessors for reading and writing single and double
369
diff --git a/target/arm/translate.c b/target/arm/translate.c
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
370
index XXXXXXX..XXXXXXX 100644
115
index XXXXXXX..XXXXXXX 100644
371
--- a/target/arm/translate.c
116
--- a/target/arm/translate.c
372
+++ b/target/arm/translate.c
117
+++ b/target/arm/translate.c
373
@@ -XXX,XX +XXX,XX @@ static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
118
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
374
static inline long
119
* UNPREDICTABLE if bit 8 is set prior to ARMv8
375
vfp_reg_offset (int dp, int reg)
120
* (we choose to UNDEF)
376
{
121
*/
377
- if (dp)
122
- if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
378
+ if (dp) {
123
- !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
379
return offsetof(CPUARMState, vfp.regs[reg]);
124
- return 1;
380
- else if (reg & 1) {
125
+ if (dp) {
381
- return offsetof(CPUARMState, vfp.regs[reg >> 1])
126
+ if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
382
- + offsetof(CPU_DoubleU, l.upper);
127
+ return 1;
383
} else {
128
+ }
384
- return offsetof(CPUARMState, vfp.regs[reg >> 1])
129
+ } else {
385
- + offsetof(CPU_DoubleU, l.lower);
130
+ if (!dc_isar_feature(aa32_fp16_spconv, s)) {
386
+ long ofs = offsetof(CPUARMState, vfp.regs[reg >> 1]);
131
+ return 1;
387
+ if (reg & 1) {
132
+ }
388
+ ofs += offsetof(CPU_DoubleU, l.upper);
133
}
389
+ } else {
134
rm_is_dp = false;
390
+ ofs += offsetof(CPU_DoubleU, l.lower);
135
break;
391
+ }
136
case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
392
+ return ofs;
137
case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
393
}
138
- if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
394
}
139
- !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
395
140
- return 1;
396
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
141
+ if (dp) {
397
numvfpregs += 16;
142
+ if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
398
}
143
+ return 1;
399
for (i = 0; i < numvfpregs; i++) {
144
+ }
400
- uint64_t v = env->vfp.regs[i];
145
+ } else {
401
+ uint64_t v = *aa32_vfp_dreg(env, i);
146
+ if (!dc_isar_feature(aa32_fp16_spconv, s)) {
402
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
147
+ return 1;
403
i * 2, (uint32_t)v,
148
+ }
404
i * 2 + 1, (uint32_t)(v >> 32),
149
}
150
rd_is_dp = false;
151
break;
152
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
153
TCGv_ptr fpst;
154
TCGv_i32 ahp;
155
156
- if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
157
+ if (!dc_isar_feature(aa32_fp16_spconv, s) ||
158
q || (rm & 1)) {
159
return 1;
160
}
161
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
162
{
163
TCGv_ptr fpst;
164
TCGv_i32 ahp;
165
- if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
166
+ if (!dc_isar_feature(aa32_fp16_spconv, s) ||
167
q || (rd & 1)) {
168
return 1;
169
}
405
--
170
--
406
2.7.4
171
2.20.1
407
172
408
173
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
There is a set of VFP instructions which we implement in
2
disas_vfp_v8_insn() and gate on the ARM_FEATURE_V8 bit.
3
These were all first introduced in v8 for A-profile, but in
4
M-profile they appeared in v7M. Gate them on the MVFR2
5
FPMisc field instead, and rename the function appropriately.
2
6
3
Not enabled anywhere so far.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180119045438.28582-11-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190222170936.13268-3-peter.maydell@linaro.org
10
---
10
---
11
target/arm/cpu.h | 1 +
11
target/arm/cpu.h | 20 ++++++++++++++++++++
12
1 file changed, 1 insertion(+)
12
target/arm/translate.c | 25 +++++++++++++------------
13
2 files changed, 33 insertions(+), 12 deletions(-)
13
14
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ enum arm_features {
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
19
ARM_FEATURE_VBAR, /* has cp15 VBAR */
20
return FIELD_EX64(id->mvfr1, MVFR1, FPHP) > 1;
20
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
21
}
21
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
22
22
+ ARM_FEATURE_SVE, /* has Scalable Vector Extension */
23
+static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
24
+{
25
+ return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 1;
26
+}
27
+
28
+static inline bool isar_feature_aa32_vcvt_dr(const ARMISARegisters *id)
29
+{
30
+ return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 2;
31
+}
32
+
33
+static inline bool isar_feature_aa32_vrint(const ARMISARegisters *id)
34
+{
35
+ return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 3;
36
+}
37
+
38
+static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
39
+{
40
+ return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4;
41
+}
42
+
43
/*
44
* 64-bit feature tests via id registers.
45
*/
46
diff --git a/target/arm/translate.c b/target/arm/translate.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.c
49
+++ b/target/arm/translate.c
50
@@ -XXX,XX +XXX,XX @@ static const uint8_t fp_decode_rm[] = {
51
FPROUNDING_NEGINF,
23
};
52
};
24
53
25
static inline int arm_feature(CPUARMState *env, int feature)
54
-static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
55
+static int disas_vfp_misc_insn(DisasContext *s, uint32_t insn)
56
{
57
uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
58
59
- if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
60
- return 1;
61
- }
62
-
63
if (dp) {
64
VFP_DREG_D(rd, insn);
65
VFP_DREG_N(rn, insn);
66
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
67
rm = VFP_SREG_M(insn);
68
}
69
70
- if ((insn & 0x0f800e50) == 0x0e000a00) {
71
+ if ((insn & 0x0f800e50) == 0x0e000a00 && dc_isar_feature(aa32_vsel, s)) {
72
return handle_vsel(insn, rd, rn, rm, dp);
73
- } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
74
+ } else if ((insn & 0x0fb00e10) == 0x0e800a00 &&
75
+ dc_isar_feature(aa32_vminmaxnm, s)) {
76
return handle_vminmaxnm(insn, rd, rn, rm, dp);
77
- } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
78
+ } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40 &&
79
+ dc_isar_feature(aa32_vrint, s)) {
80
/* VRINTA, VRINTN, VRINTP, VRINTM */
81
int rounding = fp_decode_rm[extract32(insn, 16, 2)];
82
return handle_vrint(insn, rd, rm, dp, rounding);
83
- } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
84
+ } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40 &&
85
+ dc_isar_feature(aa32_vcvt_dr, s)) {
86
/* VCVTA, VCVTN, VCVTP, VCVTM */
87
int rounding = fp_decode_rm[extract32(insn, 16, 2)];
88
return handle_vcvt(insn, rd, rm, dp, rounding);
89
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
90
}
91
92
if (extract32(insn, 28, 4) == 0xf) {
93
- /* Encodings with T=1 (Thumb) or unconditional (ARM):
94
- * only used in v8 and above.
95
+ /*
96
+ * Encodings with T=1 (Thumb) or unconditional (ARM):
97
+ * only used for the "miscellaneous VFP features" added in v8A
98
+ * and v7M (and gated on the MVFR2.FPMisc field).
99
*/
100
- return disas_vfp_v8_insn(s, insn);
101
+ return disas_vfp_misc_insn(s, insn);
102
}
103
104
dp = ((insn & 0xf00) == 0xb00);
26
--
105
--
27
2.7.4
106
2.20.1
28
107
29
108
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
This reverts commit 823e1b3818f9b10b824ddcd756983b6e2fa68730,
2
which introduces a regression running EDK2 guest firmware
3
under KVM:
2
4
3
All direct users of this field want an integral value. Drop all
5
error: kvm run failed Function not implemented
4
of the extra casting between uint64_t and float64.
6
PC=000000013f5a6208 X00=00000000404003c4 X01=000000000000003a
7
X02=0000000000000000 X03=00000000404003c4 X04=0000000000000000
8
X05=0000000096000046 X06=000000013d2ef270 X07=000000013e3d1710
9
X08=09010755ffaf8ba8 X09=ffaf8b9cfeeb5468 X10=feeb546409010756
10
X11=09010757ffaf8b90 X12=feeb50680903068b X13=090306a1ffaf8bc0
11
X14=0000000000000000 X15=0000000000000000 X16=000000013f872da0
12
X17=00000000ffffa6ab X18=0000000000000000 X19=000000013f5a92d0
13
X20=000000013f5a7a78 X21=000000000000003a X22=000000013f5a7ab2
14
X23=000000013f5a92e8 X24=000000013f631090 X25=0000000000000010
15
X26=0000000000000100 X27=000000013f89501b X28=000000013e3d14e0
16
X29=000000013e3d12a0 X30=000000013f5a2518 SP=000000013b7be0b0
17
PSTATE=404003c4 -Z-- EL1t
5
18
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
with
7
Message-id: 20180119045438.28582-6-richard.henderson@linaro.org
20
[ 3507.926571] kvm [35042]: load/store instruction decoding not implemented
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
21
in the host dmesg.
22
23
Revert the change for the moment until we can investigate the
24
cause of the regression.
25
26
Reported-by: Eric Auger <eric.auger@redhat.com>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
28
---
11
target/arm/cpu.h | 2 +-
29
target/arm/cpu.h | 9 +--------
12
target/arm/arch_dump.c | 4 ++--
30
target/arm/helper.c | 27 ++-------------------------
13
target/arm/helper.c | 20 ++++++++++----------
31
target/arm/kvm32.c | 20 ++++++++++++++++++--
14
target/arm/machine.c | 2 +-
32
target/arm/kvm64.c | 2 --
15
target/arm/translate-a64.c | 8 ++++----
33
target/arm/machine.c | 2 +-
16
target/arm/translate.c | 2 +-
34
5 files changed, 22 insertions(+), 38 deletions(-)
17
6 files changed, 19 insertions(+), 19 deletions(-)
18
35
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
38
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
39
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
40
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu);
24
* the two execution states, and means we do not need to explicitly
41
/**
25
* map these registers when changing states.
42
* write_cpustate_to_list:
26
*/
43
* @cpu: ARMCPU
27
- float64 regs[64];
44
- * @kvm_sync: true if this is for syncing back to KVM
28
+ uint64_t regs[64];
45
*
29
46
* For each register listed in the ARMCPU cpreg_indexes list, write
30
uint32_t xregs[16];
47
* its value from the ARMCPUState structure into the cpreg_values list.
31
/* We store these fpcsr fields separately for convenience. */
48
* This is used to copy info from TCG's working data structures into
32
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
49
* KVM or for outbound migration.
33
index XXXXXXX..XXXXXXX 100644
50
*
34
--- a/target/arm/arch_dump.c
51
- * @kvm_sync is true if we are doing this in order to sync the
35
+++ b/target/arm/arch_dump.c
52
- * register state back to KVM. In this case we will only update
36
@@ -XXX,XX +XXX,XX @@ static int aarch64_write_elf64_prfpreg(WriteCoreDumpFunction f,
53
- * values in the list if the previous list->cpustate sync actually
37
aarch64_note_init(&note, s, "CORE", 5, NT_PRFPREG, sizeof(note.vfp));
54
- * successfully wrote the CPU state. Otherwise we will keep the value
38
55
- * that is in the list.
39
for (i = 0; i < 64; ++i) {
56
- *
40
- note.vfp.vregs[i] = cpu_to_dump64(s, float64_val(env->vfp.regs[i]));
57
* Returns: true if all register values were read correctly,
41
+ note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
58
* false if some register was unknown or could not be read.
42
}
59
* Note that we do not stop early on failure -- we will attempt
43
60
* reading all registers in the list.
44
if (s->dump_info.d_endian == ELFDATA2MSB) {
61
*/
45
@@ -XXX,XX +XXX,XX @@ static int arm_write_elf32_vfp(WriteCoreDumpFunction f, CPUARMState *env,
62
-bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
46
arm_note_init(&note, s, "LINUX", 6, NT_ARM_VFP, sizeof(note.vfp));
63
+bool write_cpustate_to_list(ARMCPU *cpu);
47
64
48
for (i = 0; i < 32; ++i) {
65
#define ARM_CPUID_TI915T 0x54029152
49
- note.vfp.vregs[i] = cpu_to_dump64(s, float64_val(env->vfp.regs[i]));
66
#define ARM_CPUID_TI925T 0x54029252
50
+ note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
51
}
52
53
note.vfp.fpscr = cpu_to_dump32(s, vfp_get_fpscr(env));
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
67
diff --git a/target/arm/helper.c b/target/arm/helper.c
55
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/helper.c
69
--- a/target/arm/helper.c
57
+++ b/target/arm/helper.c
70
+++ b/target/arm/helper.c
58
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
71
@@ -XXX,XX +XXX,XX @@ static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
59
/* VFP data registers are always little-endian. */
72
return true;
60
nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
73
}
61
if (reg < nregs) {
74
62
- stfq_le_p(buf, env->vfp.regs[reg]);
75
-bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
63
+ stq_le_p(buf, env->vfp.regs[reg]);
76
+bool write_cpustate_to_list(ARMCPU *cpu)
64
return 8;
77
{
78
/* Write the coprocessor state from cpu->env to the (index,value) list. */
79
int i;
80
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
81
for (i = 0; i < cpu->cpreg_array_len; i++) {
82
uint32_t regidx = kvm_to_cpreg_id(cpu->cpreg_indexes[i]);
83
const ARMCPRegInfo *ri;
84
- uint64_t newval;
85
86
ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
87
if (!ri) {
88
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync)
89
if (ri->type & ARM_CP_NO_RAW) {
90
continue;
91
}
92
-
93
- newval = read_raw_cp_reg(&cpu->env, ri);
94
- if (kvm_sync) {
95
- /*
96
- * Only sync if the previous list->cpustate sync succeeded.
97
- * Rather than tracking the success/failure state for every
98
- * item in the list, we just recheck "does the raw write we must
99
- * have made in write_list_to_cpustate() read back OK" here.
100
- */
101
- uint64_t oldval = cpu->cpreg_values[i];
102
-
103
- if (oldval == newval) {
104
- continue;
105
- }
106
-
107
- write_raw_cp_reg(&cpu->env, ri, oldval);
108
- if (read_raw_cp_reg(&cpu->env, ri) != oldval) {
109
- continue;
110
- }
111
-
112
- write_raw_cp_reg(&cpu->env, ri, newval);
113
- }
114
- cpu->cpreg_values[i] = newval;
115
+ cpu->cpreg_values[i] = read_raw_cp_reg(&cpu->env, ri);
65
}
116
}
66
if (arm_feature(env, ARM_FEATURE_NEON)) {
117
return ok;
67
/* Aliases for Q regs. */
118
}
68
nregs += 16;
119
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
69
if (reg < nregs) {
120
index XXXXXXX..XXXXXXX 100644
70
- stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
121
--- a/target/arm/kvm32.c
71
- stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
122
+++ b/target/arm/kvm32.c
72
+ stq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
123
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
73
+ stq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
124
return ret;
74
return 16;
75
}
76
}
125
}
77
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
126
78
127
- write_cpustate_to_list(cpu, true);
79
nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
128
-
80
if (reg < nregs) {
129
+ /* Note that we do not call write_cpustate_to_list()
81
- env->vfp.regs[reg] = ldfq_le_p(buf);
130
+ * here, so we are only writing the tuple list back to
82
+ env->vfp.regs[reg] = ldq_le_p(buf);
131
+ * KVM. This is safe because nothing can change the
83
return 8;
132
+ * CPUARMState cp15 fields (in particular gdb accesses cannot)
133
+ * and so there are no changes to sync. In fact syncing would
134
+ * be wrong at this point: for a constant register where TCG and
135
+ * KVM disagree about its value, the preceding write_list_to_cpustate()
136
+ * would not have had any effect on the CPUARMState value (since the
137
+ * register is read-only), and a write_cpustate_to_list() here would
138
+ * then try to write the TCG value back into KVM -- this would either
139
+ * fail or incorrectly change the value the guest sees.
140
+ *
141
+ * If we ever want to allow the user to modify cp15 registers via
142
+ * the gdb stub, we would need to be more clever here (for instance
143
+ * tracking the set of registers kvm_arch_get_registers() successfully
144
+ * managed to update the CPUARMState with, and only allowing those
145
+ * to be written back up into the kernel).
146
+ */
147
if (!write_list_to_kvmstate(cpu, level)) {
148
return EINVAL;
84
}
149
}
85
if (arm_feature(env, ARM_FEATURE_NEON)) {
150
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
86
nregs += 16;
151
index XXXXXXX..XXXXXXX 100644
87
if (reg < nregs) {
152
--- a/target/arm/kvm64.c
88
- env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf);
153
+++ b/target/arm/kvm64.c
89
- env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8);
154
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
90
+ env->vfp.regs[(reg - 32) * 2] = ldq_le_p(buf);
155
return ret;
91
+ env->vfp.regs[(reg - 32) * 2 + 1] = ldq_le_p(buf + 8);
92
return 16;
93
}
94
}
156
}
95
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
157
96
switch (reg) {
158
- write_cpustate_to_list(cpu, true);
97
case 0 ... 31:
159
-
98
/* 128 bit FP register */
160
if (!write_list_to_kvmstate(cpu, level)) {
99
- stfq_le_p(buf, env->vfp.regs[reg * 2]);
161
return EINVAL;
100
- stfq_le_p(buf + 8, env->vfp.regs[reg * 2 + 1]);
162
}
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
163
diff --git a/target/arm/machine.c b/target/arm/machine.c
118
index XXXXXXX..XXXXXXX 100644
164
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/machine.c
165
--- a/target/arm/machine.c
120
+++ b/target/arm/machine.c
166
+++ b/target/arm/machine.c
121
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_vfp = {
167
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
122
.minimum_version_id = 3,
168
abort();
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
}
169
}
151
diff --git a/target/arm/translate.c b/target/arm/translate.c
170
} else {
152
index XXXXXXX..XXXXXXX 100644
171
- if (!write_cpustate_to_list(cpu, false)) {
153
--- a/target/arm/translate.c
172
+ if (!write_cpustate_to_list(cpu)) {
154
+++ b/target/arm/translate.c
173
/* This should never fail. */
155
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
174
abort();
156
numvfpregs += 16;
157
}
175
}
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),
164
--
176
--
165
2.7.4
177
2.20.1
166
178
167
179
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Rather than passing regnos to the helpers, pass pointers to the
3
Note that float16_to_float32 rightly squashes SNaN to QNaN.
4
vector registers directly. This eliminates the need to pass in
4
But of course pickNaNMulAdd, for ARM, selects SNaNs first.
5
the environment pointer and reduces the number of places that
5
So we have to preserve SNaN long enough for the correct NaN
6
directly access env->vfp.regs[].
6
to be selected. Thus float16_to_float32_by_bits.
7
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190219222952.22183-2-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
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-3-richard.henderson@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
target/arm/helper.h | 18 ++---
13
target/arm/helper.h | 9 +++
15
target/arm/crypto_helper.c | 184 +++++++++++++++++----------------------------
14
target/arm/vec_helper.c | 148 ++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate-a64.c | 75 ++++++++++--------
15
2 files changed, 157 insertions(+)
17
target/arm/translate.c | 68 +++++++++--------
18
4 files changed, 161 insertions(+), 184 deletions(-)
19
16
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
19
--- a/target/arm/helper.h
23
+++ b/target/arm/helper.h
20
+++ b/target/arm/helper.h
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(neon_qzip8, void, env, i32, i32)
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_sqsub_s, TCG_CALL_NO_RWG,
25
DEF_HELPER_3(neon_qzip16, void, env, i32, i32)
22
DEF_HELPER_FLAGS_5(gvec_sqsub_d, TCG_CALL_NO_RWG,
26
DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
23
void, ptr, ptr, ptr, ptr, i32)
27
24
28
-DEF_HELPER_4(crypto_aese, void, env, i32, i32, i32)
25
+DEF_HELPER_FLAGS_5(gvec_fmlal_a32, TCG_CALL_NO_RWG,
29
-DEF_HELPER_4(crypto_aesmc, void, env, i32, i32, i32)
26
+ void, ptr, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(gvec_fmlal_a64, TCG_CALL_NO_RWG,
31
+DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
+ void, ptr, ptr, ptr, ptr, i32)
32
29
+DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a32, TCG_CALL_NO_RWG,
33
-DEF_HELPER_5(crypto_sha1_3reg, void, env, i32, i32, i32, i32)
30
+ void, ptr, ptr, ptr, ptr, i32)
34
-DEF_HELPER_3(crypto_sha1h, void, env, i32, i32)
31
+DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a64, TCG_CALL_NO_RWG,
35
-DEF_HELPER_3(crypto_sha1su1, void, env, i32, i32)
32
+ void, ptr, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+
37
+DEF_HELPER_FLAGS_2(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr)
34
#ifdef TARGET_AARCH64
38
+DEF_HELPER_FLAGS_2(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr)
35
#include "helper-a64.h"
39
36
#include "helper-sve.h"
40
-DEF_HELPER_4(crypto_sha256h, void, env, i32, i32, i32)
37
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
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
38
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/crypto_helper.c
39
--- a/target/arm/vec_helper.c
54
+++ b/target/arm/crypto_helper.c
40
+++ b/target/arm/vec_helper.c
55
@@ -XXX,XX +XXX,XX @@ union CRYPTO_STATE {
41
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sqsub_d)(void *vd, void *vq, void *vn,
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
}
42
}
84
43
clear_tail(d, oprsz, simd_maxsz(desc));
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
}
44
}
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
+
45
+
106
+ uint64_t *rd = vd;
46
+/*
107
+ uint64_t *rm = vm;
47
+ * Convert float16 to float32, raising no exceptions and
108
+ union CRYPTO_STATE st = { .l = { rm[0], rm[1] } };
48
+ * preserving exceptional values, including SNaN.
109
int i;
49
+ * This is effectively an unpack+repack operation.
110
50
+ */
111
assert(decrypt < 2);
51
+static float32 float16_to_float32_by_bits(uint32_t f16, bool fz16)
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
+{
52
+{
367
+ assert_fp_access_checked(s);
53
+ const int f16_bias = 15;
368
+ return offsetof(CPUARMState, vfp.regs[regno * 2]);
54
+ const int f32_bias = 127;
55
+ uint32_t sign = extract32(f16, 15, 1);
56
+ uint32_t exp = extract32(f16, 10, 5);
57
+ uint32_t frac = extract32(f16, 0, 10);
58
+
59
+ if (exp == 0x1f) {
60
+ /* Inf or NaN */
61
+ exp = 0xff;
62
+ } else if (exp == 0) {
63
+ /* Zero or denormal. */
64
+ if (frac != 0) {
65
+ if (fz16) {
66
+ frac = 0;
67
+ } else {
68
+ /*
69
+ * Denormal; these are all normal float32.
70
+ * Shift the fraction so that the msb is at bit 11,
71
+ * then remove bit 11 as the implicit bit of the
72
+ * normalized float32. Note that we still go through
73
+ * the shift for normal numbers below, to put the
74
+ * float32 fraction at the right place.
75
+ */
76
+ int shift = clz32(frac) - 21;
77
+ frac = (frac << shift) & 0x3ff;
78
+ exp = f32_bias - f16_bias - shift + 1;
79
+ }
80
+ }
81
+ } else {
82
+ /* Normal number; adjust the bias. */
83
+ exp += f32_bias - f16_bias;
84
+ }
85
+ sign <<= 31;
86
+ exp <<= 23;
87
+ frac <<= 23 - 10;
88
+
89
+ return sign | exp | frac;
369
+}
90
+}
370
+
91
+
371
+/* Return a newly allocated pointer to the vector register. */
92
+static uint64_t load4_f16(uint64_t *ptr, int is_q, int is_2)
372
+static TCGv_ptr vec_full_reg_ptr(DisasContext *s, int regno)
373
+{
93
+{
374
+ TCGv_ptr ret = tcg_temp_new_ptr();
94
+ /*
375
+ tcg_gen_addi_ptr(ret, cpu_env, vec_full_reg_offset(s, regno));
95
+ * Branchless load of u32[0], u64[0], u32[1], or u64[1].
376
+ return ret;
96
+ * Load the 2nd qword iff is_q & is_2.
97
+ * Shift to the 2nd dword iff !is_q & is_2.
98
+ * For !is_q & !is_2, the upper bits of the result are garbage.
99
+ */
100
+ return ptr[is_q & is_2] >> ((is_2 & ~is_q) << 5);
377
+}
101
+}
378
+
102
+
379
/* Return the offset into CPUARMState of a slice (from
103
+/*
380
* the least significant end) of FP register Qn (ie
104
+ * Note that FMLAL requires oprsz == 8 or oprsz == 16,
381
* Dn, Sn, Hn or Bn).
105
+ * as there is not yet SVE versions that might use blocking.
382
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
106
+ */
383
int rn = extract32(insn, 5, 5);
107
+
384
int rd = extract32(insn, 0, 5);
108
+static void do_fmlal(float32 *d, void *vn, void *vm, float_status *fpst,
385
int decrypt;
109
+ uint32_t desc, bool fz16)
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
+{
110
+{
503
+ TCGv_ptr ret = tcg_temp_new_ptr();
111
+ intptr_t i, oprsz = simd_oprsz(desc);
504
+ tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
112
+ int is_s = extract32(desc, SIMD_DATA_SHIFT, 1);
505
+ return ret;
113
+ int is_2 = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
114
+ int is_q = oprsz == 16;
115
+ uint64_t n_4, m_4;
116
+
117
+ /* Pre-load all of the f16 data, avoiding overlap issues. */
118
+ n_4 = load4_f16(vn, is_q, is_2);
119
+ m_4 = load4_f16(vm, is_q, is_2);
120
+
121
+ /* Negate all inputs for FMLSL at once. */
122
+ if (is_s) {
123
+ n_4 ^= 0x8000800080008000ull;
124
+ }
125
+
126
+ for (i = 0; i < oprsz / 4; i++) {
127
+ float32 n_1 = float16_to_float32_by_bits(n_4 >> (i * 16), fz16);
128
+ float32 m_1 = float16_to_float32_by_bits(m_4 >> (i * 16), fz16);
129
+ d[H4(i)] = float32_muladd(n_1, m_1, d[H4(i)], 0, fpst);
130
+ }
131
+ clear_tail(d, oprsz, simd_maxsz(desc));
506
+}
132
+}
507
+
133
+
508
#define tcg_gen_ld_f32 tcg_gen_ld_i32
134
+void HELPER(gvec_fmlal_a32)(void *vd, void *vn, void *vm,
509
#define tcg_gen_ld_f64 tcg_gen_ld_i64
135
+ void *venv, uint32_t desc)
510
#define tcg_gen_st_f32 tcg_gen_st_i32
136
+{
511
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
137
+ CPUARMState *env = venv;
512
int u;
138
+ do_fmlal(vd, vn, vm, &env->vfp.standard_fp_status, desc,
513
uint32_t imm, mask;
139
+ get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
514
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
140
+}
515
+ TCGv_ptr ptr1, ptr2, ptr3;
141
+
516
TCGv_i64 tmp64;
142
+void HELPER(gvec_fmlal_a64)(void *vd, void *vn, void *vm,
517
143
+ void *venv, uint32_t desc)
518
/* FIXME: this access check should not take precedence over UNDEF
144
+{
519
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
145
+ CPUARMState *env = venv;
520
if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
146
+ do_fmlal(vd, vn, vm, &env->vfp.fp_status, desc,
521
return 1;
147
+ get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
522
}
148
+}
523
- tmp = tcg_const_i32(rd);
149
+
524
- tmp2 = tcg_const_i32(rn);
150
+static void do_fmlal_idx(float32 *d, void *vn, void *vm, float_status *fpst,
525
- tmp3 = tcg_const_i32(rm);
151
+ uint32_t desc, bool fz16)
526
+ ptr1 = vfp_reg_ptr(true, rd);
152
+{
527
+ ptr2 = vfp_reg_ptr(true, rn);
153
+ intptr_t i, oprsz = simd_oprsz(desc);
528
+ ptr3 = vfp_reg_ptr(true, rm);
154
+ int is_s = extract32(desc, SIMD_DATA_SHIFT, 1);
529
tmp4 = tcg_const_i32(size);
155
+ int is_2 = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
530
- gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
156
+ int index = extract32(desc, SIMD_DATA_SHIFT + 2, 3);
531
+ gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
157
+ int is_q = oprsz == 16;
532
tcg_temp_free_i32(tmp4);
158
+ uint64_t n_4;
533
} else { /* SHA-256 */
159
+ float32 m_1;
534
if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
160
+
535
return 1;
161
+ /* Pre-load all of the f16 data, avoiding overlap issues. */
536
}
162
+ n_4 = load4_f16(vn, is_q, is_2);
537
- tmp = tcg_const_i32(rd);
163
+
538
- tmp2 = tcg_const_i32(rn);
164
+ /* Negate all inputs for FMLSL at once. */
539
- tmp3 = tcg_const_i32(rm);
165
+ if (is_s) {
540
+ ptr1 = vfp_reg_ptr(true, rd);
166
+ n_4 ^= 0x8000800080008000ull;
541
+ ptr2 = vfp_reg_ptr(true, rn);
167
+ }
542
+ ptr3 = vfp_reg_ptr(true, rm);
168
+
543
switch (size) {
169
+ m_1 = float16_to_float32_by_bits(((float16 *)vm)[H2(index)], fz16);
544
case 0:
170
+
545
- gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
171
+ for (i = 0; i < oprsz / 4; i++) {
546
+ gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
172
+ float32 n_1 = float16_to_float32_by_bits(n_4 >> (i * 16), fz16);
547
break;
173
+ d[H4(i)] = float32_muladd(n_1, m_1, d[H4(i)], 0, fpst);
548
case 1:
174
+ }
549
- gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
175
+ clear_tail(d, oprsz, simd_maxsz(desc));
550
+ gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
176
+}
551
break;
177
+
552
case 2:
178
+void HELPER(gvec_fmlal_idx_a32)(void *vd, void *vn, void *vm,
553
- gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
179
+ void *venv, uint32_t desc)
554
+ gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
180
+{
555
break;
181
+ CPUARMState *env = venv;
556
}
182
+ do_fmlal_idx(vd, vn, vm, &env->vfp.standard_fp_status, desc,
557
}
183
+ get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
558
- tcg_temp_free_i32(tmp);
184
+}
559
- tcg_temp_free_i32(tmp2);
185
+
560
- tcg_temp_free_i32(tmp3);
186
+void HELPER(gvec_fmlal_idx_a64)(void *vd, void *vn, void *vm,
561
+ tcg_temp_free_ptr(ptr1);
187
+ void *venv, uint32_t desc)
562
+ tcg_temp_free_ptr(ptr2);
188
+{
563
+ tcg_temp_free_ptr(ptr3);
189
+ CPUARMState *env = venv;
564
return 0;
190
+ do_fmlal_idx(vd, vn, vm, &env->vfp.fp_status, desc,
565
}
191
+ get_flush_inputs_to_zero(&env->vfp.fp_status_f16));
566
if (size == 3 && op != NEON_3R_LOGIC) {
192
+}
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:
636
--
193
--
637
2.7.4
194
2.20.1
638
195
639
196
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20180119045438.28582-14-richard.henderson@linaro.org
4
Message-id: 20190219222952.22183-3-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/cpu.h | 127 +---------------------------------------------------
8
target/arm/cpu.h | 5 ++++
9
target/arm/helper.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
9
target/arm/translate-a64.c | 49 +++++++++++++++++++++++++++++++++++++-
10
2 files changed, 128 insertions(+), 125 deletions(-)
10
2 files changed, 53 insertions(+), 1 deletion(-)
11
11
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
14
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool bswap_code(bool sctlr_b)
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
17
#endif
17
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0;
18
}
18
}
19
19
20
-/* Return the exception level to which FP-disabled exceptions should
20
+static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
21
- * be taken, or 0 if FP is enabled.
22
- */
23
-static inline int fp_exception_el(CPUARMState *env)
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
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/helper.c
160
+++ b/target/arm/helper.c
161
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
162
/* Linux crc32c converts the output to one's complement. */
163
return crc32c(acc, buf, bytes) ^ 0xffffffff;
164
}
165
+
166
+/* Return the exception level to which FP-disabled exceptions should
167
+ * be taken, or 0 if FP is enabled.
168
+ */
169
+static inline int fp_exception_el(CPUARMState *env)
170
+{
21
+{
171
+ int fpen;
22
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0;
172
+ int cur_el = arm_current_el(env);
173
+
174
+ /* CPACR and the CPTR registers don't exist before v6, so FP is
175
+ * always accessible
176
+ */
177
+ if (!arm_feature(env, ARM_FEATURE_V6)) {
178
+ return 0;
179
+ }
180
+
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
+}
23
+}
230
+
24
+
231
+void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
25
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
232
+ target_ulong *cs_base, uint32_t *flags)
26
{
233
+{
27
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
234
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
235
+ if (is_a64(env)) {
29
index XXXXXXX..XXXXXXX 100644
236
+ *pc = env->pc;
30
--- a/target/arm/translate-a64.c
237
+ *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
31
+++ b/target/arm/translate-a64.c
238
+ /* Get control bits for tagged addresses */
32
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
239
+ *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
33
if (!fp_access_check(s)) {
240
+ *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
34
return;
241
+ } else {
35
}
242
+ *pc = env->regs[15];
36
-
243
+ *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
37
handle_3same_float(s, size, elements, fpopcode, rd, rn, rm);
244
+ | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
38
return;
245
+ | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
39
+
246
+ | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
40
+ case 0x1d: /* FMLAL */
247
+ | (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
41
+ case 0x3d: /* FMLSL */
248
+ if (!(access_secure_reg(env))) {
42
+ case 0x59: /* FMLAL2 */
249
+ *flags |= ARM_TBFLAG_NS_MASK;
43
+ case 0x79: /* FMLSL2 */
44
+ if (size & 1 || !dc_isar_feature(aa64_fhm, s)) {
45
+ unallocated_encoding(s);
46
+ return;
250
+ }
47
+ }
251
+ if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
48
+ if (fp_access_check(s)) {
252
+ || arm_el_is_aa64(env, 1)) {
49
+ int is_s = extract32(insn, 23, 1);
253
+ *flags |= ARM_TBFLAG_VFPEN_MASK;
50
+ int is_2 = extract32(insn, 29, 1);
51
+ int data = (is_2 << 1) | is_s;
52
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
53
+ vec_full_reg_offset(s, rn),
54
+ vec_full_reg_offset(s, rm), cpu_env,
55
+ is_q ? 16 : 8, vec_full_reg_size(s),
56
+ data, gen_helper_gvec_fmlal_a64);
254
+ }
57
+ }
255
+ *flags |= (extract32(env->cp15.c15_cpar, 0, 2)
58
+ return;
256
+ << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
257
+ }
258
+
59
+
259
+ *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
60
default:
61
unallocated_encoding(s);
62
return;
63
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
64
}
65
is_fp = 2;
66
break;
67
+ case 0x00: /* FMLAL */
68
+ case 0x04: /* FMLSL */
69
+ case 0x18: /* FMLAL2 */
70
+ case 0x1c: /* FMLSL2 */
71
+ if (is_scalar || size != MO_32 || !dc_isar_feature(aa64_fhm, s)) {
72
+ unallocated_encoding(s);
73
+ return;
74
+ }
75
+ size = MO_16;
76
+ /* is_fp, but we pass cpu_env not fp_status. */
77
+ break;
78
default:
79
unallocated_encoding(s);
80
return;
81
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
82
tcg_temp_free_ptr(fpst);
83
}
84
return;
260
+
85
+
261
+ /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
86
+ case 0x00: /* FMLAL */
262
+ * states defined in the ARM ARM for software singlestep:
87
+ case 0x04: /* FMLSL */
263
+ * SS_ACTIVE PSTATE.SS State
88
+ case 0x18: /* FMLAL2 */
264
+ * 0 x Inactive (the TB flag for SS is always 0)
89
+ case 0x1c: /* FMLSL2 */
265
+ * 1 0 Active-pending
90
+ {
266
+ * 1 1 Active-not-pending
91
+ int is_s = extract32(opcode, 2, 1);
267
+ */
92
+ int is_2 = u;
268
+ if (arm_singlestep_active(env)) {
93
+ int data = (index << 2) | (is_2 << 1) | is_s;
269
+ *flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
94
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
270
+ if (is_a64(env)) {
95
+ vec_full_reg_offset(s, rn),
271
+ if (env->pstate & PSTATE_SS) {
96
+ vec_full_reg_offset(s, rm), cpu_env,
272
+ *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
97
+ is_q ? 16 : 8, vec_full_reg_size(s),
273
+ }
98
+ data, gen_helper_gvec_fmlal_idx_a64);
274
+ } else {
275
+ if (env->uncached_cpsr & PSTATE_SS) {
276
+ *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
277
+ }
278
+ }
99
+ }
279
+ }
100
+ return;
280
+ if (arm_cpu_data_is_big_endian(env)) {
101
}
281
+ *flags |= ARM_TBFLAG_BE_DATA_MASK;
102
282
+ }
103
if (size == 3) {
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
+}
291
--
104
--
292
2.7.4
105
2.20.1
293
106
294
107
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Rather than passing a regno to the helper, pass pointers to the
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
vector register directly. This eliminates the need to pass in
4
Message-id: 20190219222952.22183-4-richard.henderson@linaro.org
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>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180119045438.28582-5-richard.henderson@linaro.org
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
7
---
14
target/arm/helper.h | 2 +-
8
target/arm/cpu.h | 5 ++
15
target/arm/op_helper.c | 17 +++++++----------
9
target/arm/translate.c | 129 ++++++++++++++++++++++++++++++-----------
16
target/arm/translate.c | 8 ++++----
10
2 files changed, 101 insertions(+), 33 deletions(-)
17
3 files changed, 12 insertions(+), 15 deletions(-)
11
18
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
14
--- a/target/arm/cpu.h
22
+++ b/target/arm/helper.h
15
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
24
DEF_HELPER_FLAGS_2(rsqrte_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
17
return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
25
DEF_HELPER_2(recpe_u32, i32, i32, ptr)
26
DEF_HELPER_FLAGS_2(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32, ptr)
27
-DEF_HELPER_5(neon_tbl, i32, env, i32, i32, i32, i32)
28
+DEF_HELPER_FLAGS_4(neon_tbl, TCG_CALL_NO_RWG, i32, i32, i32, ptr, i32)
29
30
DEF_HELPER_3(shl_cc, i32, env, i32, i32)
31
DEF_HELPER_3(shr_cc, i32, env, i32, i32)
32
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/op_helper.c
35
+++ b/target/arm/op_helper.c
36
@@ -XXX,XX +XXX,XX @@ static int exception_target_el(CPUARMState *env)
37
return target_el;
38
}
18
}
39
19
40
-uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
20
+static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
41
- uint32_t rn, uint32_t maxindex)
21
+{
42
+uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
22
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0;
43
+ uint32_t maxindex)
23
+}
24
+
25
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
44
{
26
{
45
- uint32_t val;
27
/*
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;
53
+
54
val = 0;
55
for (shift = 0; shift < 32; shift += 8) {
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
28
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
30
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
31
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
32
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
69
tcg_gen_movi_i32(tmp, 0);
33
gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
70
}
34
int rd, rn, rm, opr_sz;
71
tmp2 = neon_load_reg(rm, 0);
35
int data = 0;
72
- tmp4 = tcg_const_i32(rn);
36
- bool q;
73
+ ptr1 = vfp_reg_ptr(true, rn);
37
-
74
tmp5 = tcg_const_i32(n);
38
- q = extract32(insn, 6, 1);
75
- gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
39
- VFP_DREG_D(rd, insn);
76
+ gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
40
- VFP_DREG_N(rn, insn);
77
tcg_temp_free_i32(tmp);
41
- VFP_DREG_M(rm, insn);
78
if (insn & (1 << 6)) {
42
- if ((rd | rn | rm) & q) {
79
tmp = neon_load_reg(rd, 1);
43
- return 1;
80
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
44
- }
81
tcg_gen_movi_i32(tmp, 0);
45
+ int off_rn, off_rm;
82
}
46
+ bool is_long = false, q = extract32(insn, 6, 1);
83
tmp3 = neon_load_reg(rm, 1);
47
+ bool ptr_is_env = false;
84
- gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
48
85
+ gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
49
if ((insn & 0xfe200f10) == 0xfc200800) {
86
tcg_temp_free_i32(tmp5);
50
/* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
87
- tcg_temp_free_i32(tmp4);
51
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
88
+ tcg_temp_free_ptr(ptr1);
52
return 1;
89
neon_store_reg(rd, 0, tmp2);
53
}
90
neon_store_reg(rd, 1, tmp3);
54
fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
91
tcg_temp_free_i32(tmp);
55
+ } else if ((insn & 0xff300f10) == 0xfc200810) {
56
+ /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
57
+ int is_s = extract32(insn, 23, 1);
58
+ if (!dc_isar_feature(aa32_fhm, s)) {
59
+ return 1;
60
+ }
61
+ is_long = true;
62
+ data = is_s; /* is_2 == 0 */
63
+ fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
64
+ ptr_is_env = true;
65
} else {
66
return 1;
67
}
68
69
+ VFP_DREG_D(rd, insn);
70
+ if (rd & q) {
71
+ return 1;
72
+ }
73
+ if (q || !is_long) {
74
+ VFP_DREG_N(rn, insn);
75
+ VFP_DREG_M(rm, insn);
76
+ if ((rn | rm) & q & !is_long) {
77
+ return 1;
78
+ }
79
+ off_rn = vfp_reg_offset(1, rn);
80
+ off_rm = vfp_reg_offset(1, rm);
81
+ } else {
82
+ rn = VFP_SREG_N(insn);
83
+ rm = VFP_SREG_M(insn);
84
+ off_rn = vfp_reg_offset(0, rn);
85
+ off_rm = vfp_reg_offset(0, rm);
86
+ }
87
+
88
if (s->fp_excp_el) {
89
gen_exception_insn(s, 4, EXCP_UDEF,
90
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
91
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
92
93
opr_sz = (1 + q) * 8;
94
if (fn_gvec_ptr) {
95
- TCGv_ptr fpst = get_fpstatus_ptr(1);
96
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
97
- vfp_reg_offset(1, rn),
98
- vfp_reg_offset(1, rm), fpst,
99
+ TCGv_ptr ptr;
100
+ if (ptr_is_env) {
101
+ ptr = cpu_env;
102
+ } else {
103
+ ptr = get_fpstatus_ptr(1);
104
+ }
105
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
106
opr_sz, opr_sz, data, fn_gvec_ptr);
107
- tcg_temp_free_ptr(fpst);
108
+ if (!ptr_is_env) {
109
+ tcg_temp_free_ptr(ptr);
110
+ }
111
} else {
112
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
113
- vfp_reg_offset(1, rn),
114
- vfp_reg_offset(1, rm),
115
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
116
opr_sz, opr_sz, data, fn_gvec);
117
}
118
return 0;
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
120
gen_helper_gvec_3 *fn_gvec = NULL;
121
gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
122
int rd, rn, rm, opr_sz, data;
123
- bool q;
124
-
125
- q = extract32(insn, 6, 1);
126
- VFP_DREG_D(rd, insn);
127
- VFP_DREG_N(rn, insn);
128
- if ((rd | rn) & q) {
129
- return 1;
130
- }
131
+ int off_rn, off_rm;
132
+ bool is_long = false, q = extract32(insn, 6, 1);
133
+ bool ptr_is_env = false;
134
135
if ((insn & 0xff000f10) == 0xfe000800) {
136
/* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
137
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
138
} else if ((insn & 0xffb00f00) == 0xfe200d00) {
139
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
140
int u = extract32(insn, 4, 1);
141
+
142
if (!dc_isar_feature(aa32_dp, s)) {
143
return 1;
144
}
145
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
146
/* rm is just Vm, and index is M. */
147
data = extract32(insn, 5, 1); /* index */
148
rm = extract32(insn, 0, 4);
149
+ } else if ((insn & 0xffa00f10) == 0xfe000810) {
150
+ /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
151
+ int is_s = extract32(insn, 20, 1);
152
+ int vm20 = extract32(insn, 0, 3);
153
+ int vm3 = extract32(insn, 3, 1);
154
+ int m = extract32(insn, 5, 1);
155
+ int index;
156
+
157
+ if (!dc_isar_feature(aa32_fhm, s)) {
158
+ return 1;
159
+ }
160
+ if (q) {
161
+ rm = vm20;
162
+ index = m * 2 + vm3;
163
+ } else {
164
+ rm = vm20 * 2 + m;
165
+ index = vm3;
166
+ }
167
+ is_long = true;
168
+ data = (index << 2) | is_s; /* is_2 == 0 */
169
+ fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
170
+ ptr_is_env = true;
171
} else {
172
return 1;
173
}
174
175
+ VFP_DREG_D(rd, insn);
176
+ if (rd & q) {
177
+ return 1;
178
+ }
179
+ if (q || !is_long) {
180
+ VFP_DREG_N(rn, insn);
181
+ if (rn & q & !is_long) {
182
+ return 1;
183
+ }
184
+ off_rn = vfp_reg_offset(1, rn);
185
+ off_rm = vfp_reg_offset(1, rm);
186
+ } else {
187
+ rn = VFP_SREG_N(insn);
188
+ off_rn = vfp_reg_offset(0, rn);
189
+ off_rm = vfp_reg_offset(0, rm);
190
+ }
191
if (s->fp_excp_el) {
192
gen_exception_insn(s, 4, EXCP_UDEF,
193
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
194
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
195
196
opr_sz = (1 + q) * 8;
197
if (fn_gvec_ptr) {
198
- TCGv_ptr fpst = get_fpstatus_ptr(1);
199
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
200
- vfp_reg_offset(1, rn),
201
- vfp_reg_offset(1, rm), fpst,
202
+ TCGv_ptr ptr;
203
+ if (ptr_is_env) {
204
+ ptr = cpu_env;
205
+ } else {
206
+ ptr = get_fpstatus_ptr(1);
207
+ }
208
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
209
opr_sz, opr_sz, data, fn_gvec_ptr);
210
- tcg_temp_free_ptr(fpst);
211
+ if (!ptr_is_env) {
212
+ tcg_temp_free_ptr(ptr);
213
+ }
214
} else {
215
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
216
- vfp_reg_offset(1, rn),
217
- vfp_reg_offset(1, rm),
218
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
219
opr_sz, opr_sz, data, fn_gvec);
220
}
221
return 0;
92
--
222
--
93
2.7.4
223
2.20.1
94
224
95
225
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
If it isn't used when translate.h is included,
4
we'll get a compiler Werror.
5
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Message-id: 20190219222952.22183-5-richard.henderson@linaro.org
10
Message-id: 20180119045438.28582-2-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
7
---
13
target/arm/translate.h | 2 +-
8
target/arm/cpu.c | 1 +
14
1 file changed, 1 insertion(+), 1 deletion(-)
9
target/arm/cpu64.c | 2 ++
10
2 files changed, 3 insertions(+)
15
11
16
diff --git a/target/arm/translate.h b/target/arm/translate.h
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.h
14
--- a/target/arm/cpu.c
19
+++ b/target/arm/translate.h
15
+++ b/target/arm/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static inline int default_exception_el(DisasContext *s)
16
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
21
? 3 : MAX(1, s->current_el);
17
t = cpu->isar.id_isar6;
22
}
18
t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
23
19
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
24
-static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
20
+ t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
25
+static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
21
cpu->isar.id_isar6 = t;
26
{
22
27
/* We don't need to save all of the syndrome so we mask and shift
23
t = cpu->id_mmfr4;
28
* out unneeded bits to help the sleb128 encoder do a better job.
24
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu64.c
27
+++ b/target/arm/cpu64.c
28
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
29
t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1);
30
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
31
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
32
+ t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
33
cpu->isar.id_aa64isar0 = t;
34
35
t = cpu->isar.id_aa64isar1;
36
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
37
u = cpu->isar.id_isar6;
38
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1);
39
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
40
+ u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
41
cpu->isar.id_isar6 = u;
42
43
/*
29
--
44
--
30
2.7.4
45
2.20.1
31
46
32
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20180119045438.28582-16-richard.henderson@linaro.org
4
Message-id: 20190219222952.22183-6-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
7
---
9
target/arm/helper.c | 3 ++-
8
linux-user/elfload.c | 2 ++
10
1 file changed, 2 insertions(+), 1 deletion(-)
9
1 file changed, 2 insertions(+)
11
10
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
13
--- a/linux-user/elfload.c
15
+++ b/target/arm/helper.c
14
+++ b/linux-user/elfload.c
16
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
15
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
17
*/
16
GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
18
static inline int fp_exception_el(CPUARMState *env)
17
GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
19
{
18
GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
20
+#ifndef CONFIG_USER_ONLY
19
+ GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
21
int fpen;
20
+ GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
22
int cur_el = arm_current_el(env);
21
23
22
#undef GET_FEATURE_ID
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
}
32
23
33
--
24
--
34
2.7.4
25
2.20.1
35
26
36
27
diff view generated by jsdifflib
Deleted patch
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
1
3
In the GIC, when an IRQ is acknowledged, its state goes from "pending"
4
to:
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.
10
11
The current implementation of the GIC in QEMU does not check if the
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.
15
16
This usually happens when splitting priority drop and interrupt
17
deactivation. On priority drop, the IRQ stays active until deactivation.
18
If it becomes pending again, chances are that it will be incorrectly
19
selected as best_irq in gic_update().
20
21
This commit fixes this by checking if the IRQ is not already active when
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
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
33
hw/intc/arm_gic.c | 1 +
34
1 file changed, 1 insertion(+)
35
36
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/arm_gic.c
39
+++ b/hw/intc/arm_gic.c
40
@@ -XXX,XX +XXX,XX @@ void gic_update(GICState *s)
41
best_irq = 1023;
42
for (irq = 0; irq < s->num_irq; irq++) {
43
if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm) &&
44
+ (!GIC_TEST_ACTIVE(irq, cm)) &&
45
(irq < GIC_INTERNAL || GIC_TARGET(irq) & cm)) {
46
if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
47
best_prio = GIC_GET_PRIORITY(irq, cpu);
48
--
49
2.7.4
50
51
diff view generated by jsdifflib
Deleted patch
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
1
3
When determining the group priority of a group 1 IRQ, if C_CTRL.CBPR is
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).
8
9
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
10
Message-id: 20180119145756.7629-5-luc.michel@greensocs.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
[PMM: add assert, as the gicv3 code has]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/intc/arm_gic.c | 3 ++-
16
1 file changed, 2 insertions(+), 1 deletion(-)
17
18
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gic.c
21
+++ b/hw/intc/arm_gic.c
22
@@ -XXX,XX +XXX,XX @@ static int gic_get_group_priority(GICState *s, int cpu, int 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];
31
}
32
--
33
2.7.4
34
35
diff view generated by jsdifflib
Deleted patch
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
1
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]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/intc/arm_gic.c | 16 +++++++++++++---
15
1 file changed, 13 insertions(+), 3 deletions(-)
16
17
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gic.c
20
+++ b/hw/intc/arm_gic.c
21
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
22
break;
23
case 0x08: /* Binary Point */
24
if (s->security_extn && !attrs.secure) {
25
- /* BPR is banked. Non-secure copy stored in ABPR. */
26
- *data = s->abpr[cpu];
27
+ if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
28
+ /* NS view of BPR when CBPR is 1 */
29
+ *data = MIN(s->bpr[cpu] + 1, 7);
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
}
37
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
38
break;
39
case 0x08: /* Binary Point */
40
if (s->security_extn && !attrs.secure) {
41
- s->abpr[cpu] = MAX(value & 0x7, GIC_MIN_ABPR);
42
+ if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
43
+ /* WI when CBPR is 1 */
44
+ 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
}
51
--
52
2.7.4
53
54
diff view generated by jsdifflib