1
Another lump of target-arm patches. I still have some patches in
1
The following changes since commit 003ba52a8b327180e284630b289c6ece5a3e08b9:
2
my to-review queue, but this is a big enough set that I wanted
3
to send it out.
4
2
5
thanks
3
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2023-02-16 11:16:39 +0000)
6
-- PMM
7
8
The following changes since commit 04bb7fe2bf55bdf66d5b7a5a719b40bbb4048178:
9
10
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20180208' into staging (2018-02-08 17:41:15 +0000)
11
4
12
are available in the Git repository at:
5
are available in the Git repository at:
13
6
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180209
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230216
15
8
16
for you to fetch changes up to bbba7757bacc9f890a3f028d328b4b429dbe78ec:
9
for you to fetch changes up to caf01d6a435d9f4a95aeae2f9fc6cb8b889b1fb8:
17
10
18
hw/core/generic-loader: Allow PC to be set on command line (2018-02-09 10:55:40 +0000)
11
tests/qtest: Restrict tpm-tis-devices-{swtpm}-test to CONFIG_TCG (2023-02-16 16:28:53 +0000)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
target-arm queue:
14
target-arm queue:
22
* Support M profile derived exceptions on exception entry and exit
15
* Some mostly M-profile-related code cleanups
23
* Implement AArch64 v8.2 crypto insns (SHA-512, SHA-3, SM3, SM4)
16
* avocado: Retire the boot_linux.py AArch64 TCG tests
24
* Implement working i.MX6 SD controller
17
* hw/arm/smmuv3: Add GBPA register
25
* Various devices preparatory to i.MX7 support
18
* arm/virt: don't try to spell out the accelerator
26
* Preparatory patches for SVE emulation
19
* hw/arm: Attach PSPI module to NPCM7XX SoC
27
* v8M: Fix bug in implementation of 'TT' insn
20
* Some cleanup/refactoring patches aiming towards
28
* Give useful error if user tries to use userspace GICv3 with KVM
21
allowing building Arm targets without CONFIG_TCG
29
22
30
----------------------------------------------------------------
23
----------------------------------------------------------------
31
Andrey Smirnov (10):
24
Alex Bennée (1):
32
sdhci: Add i.MX specific subtype of SDHCI
25
tests/avocado: retire the Aarch64 TCG tests from boot_linux.py
33
hw: i.MX: Convert i.MX6 to use TYPE_IMX_USDHC
34
i.MX: Add code to emulate i.MX7 CCM, PMU and ANALOG IP blocks
35
i.MX: Add code to emulate i.MX2 watchdog IP block
36
i.MX: Add code to emulate i.MX7 SNVS IP-block
37
i.MX: Add code to emulate GPCv2 IP block
38
i.MX: Add i.MX7 GPT variant
39
i.MX: Add implementation of i.MX7 GPR IP block
40
usb: Add basic code to emulate Chipidea USB IP
41
hw/arm: Move virt's PSCI DT fixup code to arm/boot.c
42
26
43
Ard Biesheuvel (5):
27
Claudio Fontana (3):
44
target/arm: implement SHA-512 instructions
28
target/arm: rename handle_semihosting to tcg_handle_semihosting
45
target/arm: implement SHA-3 instructions
29
target/arm: wrap psci call with tcg_enabled
46
target/arm: implement SM3 instructions
30
target/arm: wrap call to aarch64_sve_change_el in tcg_enabled()
47
target/arm: implement SM4 instructions
48
target/arm: enable user-mode SHA-3, SM3, SM4 and SHA-512 instruction support
49
31
50
Christoffer Dall (1):
32
Cornelia Huck (1):
51
target/arm/kvm: gic: Prevent creating userspace GICv3 with KVM
33
arm/virt: don't try to spell out the accelerator
52
34
53
Peter Maydell (9):
35
Fabiano Rosas (7):
54
target/arm: Add armv7m_nvic_set_pending_derived()
36
target/arm: Move PC alignment check
55
target/arm: Split "get pending exception info" from "acknowledge it"
37
target/arm: Move cpregs code out of cpu.h
56
target/arm: Add ignore_stackfaults argument to v7m_exception_taken()
38
tests/avocado: Skip tests that require a missing accelerator
57
target/arm: Make v7M exception entry stack push check MPU
39
tests/avocado: Tag TCG tests with accel:tcg
58
target/arm: Make v7m_push_callee_stack() honour MPU
40
target/arm: Use "max" as default cpu for the virt machine with KVM
59
target/arm: Make exception vector loads honour the SAU
41
tests/qtest: arm-cpu-features: Match tests to required accelerators
60
target/arm: Handle exceptions during exception stack pop
42
tests/qtest: Restrict tpm-tis-devices-{swtpm}-test to CONFIG_TCG
61
target/arm/translate.c: Fix missing 'break' for TT insns
62
hw/core/generic-loader: Allow PC to be set on command line
63
43
64
Richard Henderson (5):
44
Hao Wu (3):
65
target/arm: Expand vector registers for SVE
45
MAINTAINERS: Add myself to maintainers and remove Havard
66
target/arm: Add predicate registers for SVE
46
hw/ssi: Add Nuvoton PSPI Module
67
target/arm: Add SVE to migration state
47
hw/arm: Attach PSPI module to NPCM7XX SoC
68
target/arm: Add ZCR_ELx
69
target/arm: Add SVE state to TB->FLAGS
70
48
71
hw/intc/Makefile.objs | 2 +-
49
Jean-Philippe Brucker (2):
72
hw/misc/Makefile.objs | 4 +
50
hw/arm/smmu-common: Support 64-bit addresses
73
hw/usb/Makefile.objs | 1 +
51
hw/arm/smmu-common: Fix TTB1 handling
74
hw/sd/sdhci-internal.h | 23 ++
75
include/hw/intc/imx_gpcv2.h | 22 ++
76
include/hw/misc/imx2_wdt.h | 33 +++
77
include/hw/misc/imx7_ccm.h | 139 +++++++++++
78
include/hw/misc/imx7_gpr.h | 28 +++
79
include/hw/misc/imx7_snvs.h | 35 +++
80
include/hw/sd/sdhci.h | 13 ++
81
include/hw/timer/imx_gpt.h | 1 +
82
include/hw/usb/chipidea.h | 16 ++
83
target/arm/cpu.h | 120 ++++++++--
84
target/arm/helper.h | 12 +
85
target/arm/kvm_arm.h | 4 +
86
target/arm/translate.h | 2 +
87
hw/arm/boot.c | 65 ++++++
88
hw/arm/fsl-imx6.c | 2 +-
89
hw/arm/virt.c | 61 -----
90
hw/core/generic-loader.c | 2 +-
91
hw/intc/armv7m_nvic.c | 98 +++++++-
92
hw/intc/imx_gpcv2.c | 125 ++++++++++
93
hw/misc/imx2_wdt.c | 89 +++++++
94
hw/misc/imx7_ccm.c | 277 ++++++++++++++++++++++
95
hw/misc/imx7_gpr.c | 124 ++++++++++
96
hw/misc/imx7_snvs.c | 83 +++++++
97
hw/sd/sdhci.c | 230 ++++++++++++++++++-
98
hw/timer/imx_gpt.c | 25 ++
99
hw/usb/chipidea.c | 176 ++++++++++++++
100
linux-user/elfload.c | 19 ++
101
target/arm/cpu64.c | 4 +
102
target/arm/crypto_helper.c | 277 +++++++++++++++++++++-
103
target/arm/helper.c | 548 +++++++++++++++++++++++++++++++++++++-------
104
target/arm/machine.c | 88 ++++++-
105
target/arm/translate-a64.c | 350 +++++++++++++++++++++++++++-
106
target/arm/translate.c | 8 +-
107
hw/intc/trace-events | 5 +-
108
hw/misc/trace-events | 4 +
109
38 files changed, 2928 insertions(+), 187 deletions(-)
110
create mode 100644 include/hw/intc/imx_gpcv2.h
111
create mode 100644 include/hw/misc/imx2_wdt.h
112
create mode 100644 include/hw/misc/imx7_ccm.h
113
create mode 100644 include/hw/misc/imx7_gpr.h
114
create mode 100644 include/hw/misc/imx7_snvs.h
115
create mode 100644 include/hw/usb/chipidea.h
116
create mode 100644 hw/intc/imx_gpcv2.c
117
create mode 100644 hw/misc/imx2_wdt.c
118
create mode 100644 hw/misc/imx7_ccm.c
119
create mode 100644 hw/misc/imx7_gpr.c
120
create mode 100644 hw/misc/imx7_snvs.c
121
create mode 100644 hw/usb/chipidea.c
122
52
53
Mostafa Saleh (1):
54
hw/arm/smmuv3: Add GBPA register
55
56
Philippe Mathieu-Daudé (12):
57
hw/intc/armv7m_nvic: Use OBJECT_DECLARE_SIMPLE_TYPE() macro
58
target/arm: Simplify arm_v7m_mmu_idx_for_secstate() for user emulation
59
target/arm: Reduce arm_v7m_mmu_idx_[all/for_secstate_and_priv]() scope
60
target/arm: Constify ID_PFR1 on user emulation
61
target/arm: Convert CPUARMState::eabi to boolean
62
target/arm: Avoid resetting CPUARMState::eabi field
63
target/arm: Restrict CPUARMState::gicv3state to sysemu
64
target/arm: Restrict CPUARMState::arm_boot_info to sysemu
65
target/arm: Restrict CPUARMState::nvic to sysemu
66
target/arm: Store CPUARMState::nvic as NVICState*
67
target/arm: Declare CPU <-> NVIC helpers in 'hw/intc/armv7m_nvic.h'
68
hw/arm: Add missing XLNX_ZYNQMP_ARM -> USB_DWC3 Kconfig dependency
69
70
MAINTAINERS | 8 +-
71
docs/system/arm/nuvoton.rst | 2 +-
72
hw/arm/smmuv3-internal.h | 7 +
73
include/hw/arm/npcm7xx.h | 2 +
74
include/hw/arm/smmu-common.h | 2 -
75
include/hw/arm/smmuv3.h | 1 +
76
include/hw/intc/armv7m_nvic.h | 128 +++++++++++++++++-
77
include/hw/ssi/npcm_pspi.h | 53 ++++++++
78
linux-user/user-internals.h | 2 +-
79
target/arm/cpregs.h | 98 ++++++++++++++
80
target/arm/cpu.h | 228 ++-------------------------------
81
target/arm/internals.h | 14 --
82
hw/arm/npcm7xx.c | 25 +++-
83
hw/arm/smmu-common.c | 4 +-
84
hw/arm/smmuv3.c | 43 ++++++-
85
hw/arm/virt.c | 10 +-
86
hw/intc/armv7m_nvic.c | 38 ++----
87
hw/ssi/npcm_pspi.c | 221 ++++++++++++++++++++++++++++++++
88
linux-user/arm/cpu_loop.c | 4 +-
89
target/arm/cpu.c | 5 +-
90
target/arm/cpu_tcg.c | 3 +
91
target/arm/helper.c | 31 +++--
92
target/arm/m_helper.c | 86 +++++++------
93
target/arm/machine.c | 18 +--
94
tests/qtest/arm-cpu-features.c | 28 ++--
95
hw/arm/Kconfig | 1 +
96
hw/ssi/meson.build | 2 +-
97
hw/ssi/trace-events | 5 +
98
tests/avocado/avocado_qemu/__init__.py | 4 +
99
tests/avocado/boot_linux.py | 48 ++-----
100
tests/avocado/boot_linux_console.py | 1 +
101
tests/avocado/machine_aarch64_virt.py | 63 ++++++++-
102
tests/avocado/reverse_debugging.py | 8 ++
103
tests/qtest/meson.build | 4 +-
104
34 files changed, 798 insertions(+), 399 deletions(-)
105
create mode 100644 include/hw/ssi/npcm_pspi.h
106
create mode 100644 hw/ssi/npcm_pspi.c
107
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add code to emulate Chipidea USB IP (used in i.MX SoCs). Tested to
3
Manually convert to OBJECT_DECLARE_SIMPLE_TYPE() macro,
4
work against:
4
similarly to automatic conversion from commit 8063396bf3
5
("Use OBJECT_DECLARE_SIMPLE_TYPE when possible").
5
6
6
-usb -drive if=none,id=stick,file=usb.img,format=raw -device \
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
usb-storage,bus=usb-bus.0,drive=stick
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
9
Message-id: 20230206223502.25122-2-philmd@linaro.org
9
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Jason Wang <jasowang@redhat.com>
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
13
Cc: Michael S. Tsirkin <mst@redhat.com>
14
Cc: qemu-devel@nongnu.org
15
Cc: qemu-arm@nongnu.org
16
Cc: yurovsky@gmail.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
11
---
21
hw/usb/Makefile.objs | 1 +
12
include/hw/intc/armv7m_nvic.h | 5 +----
22
include/hw/usb/chipidea.h | 16 +++++
13
1 file changed, 1 insertion(+), 4 deletions(-)
23
hw/usb/chipidea.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++
24
3 files changed, 193 insertions(+)
25
create mode 100644 include/hw/usb/chipidea.h
26
create mode 100644 hw/usb/chipidea.c
27
14
28
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
15
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
29
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/usb/Makefile.objs
17
--- a/include/hw/intc/armv7m_nvic.h
31
+++ b/hw/usb/Makefile.objs
18
+++ b/include/hw/intc/armv7m_nvic.h
32
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_USB_XHCI_NEC) += hcd-xhci-nec.o
33
common-obj-$(CONFIG_USB_MUSB) += hcd-musb.o
34
35
obj-$(CONFIG_TUSB6010) += tusb6010.o
36
+obj-$(CONFIG_IMX) += chipidea.o
37
38
# emulated usb devices
39
common-obj-$(CONFIG_USB) += dev-hub.o
40
diff --git a/include/hw/usb/chipidea.h b/include/hw/usb/chipidea.h
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/include/hw/usb/chipidea.h
45
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
46
+#ifndef CHIPIDEA_H
20
#include "qom/object.h"
47
+#define CHIPIDEA_H
21
48
+
22
#define TYPE_NVIC "armv7m_nvic"
49
+#include "hw/usb/hcd-ehci.h"
23
-
50
+
24
-typedef struct NVICState NVICState;
51
+typedef struct ChipideaState {
25
-DECLARE_INSTANCE_CHECKER(NVICState, NVIC,
52
+ /*< private >*/
26
- TYPE_NVIC)
53
+ EHCISysBusState parent_obj;
27
+OBJECT_DECLARE_SIMPLE_TYPE(NVICState, NVIC)
54
+
28
55
+ MemoryRegion iomem[3];
29
/* Highest permitted number of exceptions (architectural limit) */
56
+} ChipideaState;
30
#define NVIC_MAX_VECTORS 512
57
+
58
+#define TYPE_CHIPIDEA "usb-chipidea"
59
+#define CHIPIDEA(obj) OBJECT_CHECK(ChipideaState, (obj), TYPE_CHIPIDEA)
60
+
61
+#endif /* CHIPIDEA_H */
62
diff --git a/hw/usb/chipidea.c b/hw/usb/chipidea.c
63
new file mode 100644
64
index XXXXXXX..XXXXXXX
65
--- /dev/null
66
+++ b/hw/usb/chipidea.c
67
@@ -XXX,XX +XXX,XX @@
68
+/*
69
+ * Copyright (c) 2018, Impinj, Inc.
70
+ *
71
+ * Chipidea USB block emulation code
72
+ *
73
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
74
+ *
75
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
76
+ * See the COPYING file in the top-level directory.
77
+ */
78
+
79
+#include "qemu/osdep.h"
80
+#include "hw/usb/hcd-ehci.h"
81
+#include "hw/usb/chipidea.h"
82
+#include "qemu/log.h"
83
+
84
+enum {
85
+ CHIPIDEA_USBx_DCIVERSION = 0x000,
86
+ CHIPIDEA_USBx_DCCPARAMS = 0x004,
87
+ CHIPIDEA_USBx_DCCPARAMS_HC = BIT(8),
88
+};
89
+
90
+static uint64_t chipidea_read(void *opaque, hwaddr offset,
91
+ unsigned size)
92
+{
93
+ return 0;
94
+}
95
+
96
+static void chipidea_write(void *opaque, hwaddr offset,
97
+ uint64_t value, unsigned size)
98
+{
99
+}
100
+
101
+static const struct MemoryRegionOps chipidea_ops = {
102
+ .read = chipidea_read,
103
+ .write = chipidea_write,
104
+ .endianness = DEVICE_NATIVE_ENDIAN,
105
+ .impl = {
106
+ /*
107
+ * Our device would not work correctly if the guest was doing
108
+ * unaligned access. This might not be a limitation on the
109
+ * real device but in practice there is no reason for a guest
110
+ * to access this device unaligned.
111
+ */
112
+ .min_access_size = 4,
113
+ .max_access_size = 4,
114
+ .unaligned = false,
115
+ },
116
+};
117
+
118
+static uint64_t chipidea_dc_read(void *opaque, hwaddr offset,
119
+ unsigned size)
120
+{
121
+ switch (offset) {
122
+ case CHIPIDEA_USBx_DCIVERSION:
123
+ return 0x1;
124
+ case CHIPIDEA_USBx_DCCPARAMS:
125
+ /*
126
+ * Real hardware (at least i.MX7) will also report the
127
+ * controller as "Device Capable" (and 8 supported endpoints),
128
+ * but there doesn't seem to be much point in doing so, since
129
+ * we don't emulate that part.
130
+ */
131
+ return CHIPIDEA_USBx_DCCPARAMS_HC;
132
+ }
133
+
134
+ return 0;
135
+}
136
+
137
+static void chipidea_dc_write(void *opaque, hwaddr offset,
138
+ uint64_t value, unsigned size)
139
+{
140
+}
141
+
142
+static const struct MemoryRegionOps chipidea_dc_ops = {
143
+ .read = chipidea_dc_read,
144
+ .write = chipidea_dc_write,
145
+ .endianness = DEVICE_NATIVE_ENDIAN,
146
+ .impl = {
147
+ /*
148
+ * Our device would not work correctly if the guest was doing
149
+ * unaligned access. This might not be a limitation on the real
150
+ * device but in practice there is no reason for a guest to access
151
+ * this device unaligned.
152
+ */
153
+ .min_access_size = 4,
154
+ .max_access_size = 4,
155
+ .unaligned = false,
156
+ },
157
+};
158
+
159
+static void chipidea_init(Object *obj)
160
+{
161
+ EHCIState *ehci = &SYS_BUS_EHCI(obj)->ehci;
162
+ ChipideaState *ci = CHIPIDEA(obj);
163
+ int i;
164
+
165
+ for (i = 0; i < ARRAY_SIZE(ci->iomem); i++) {
166
+ const struct {
167
+ const char *name;
168
+ hwaddr offset;
169
+ uint64_t size;
170
+ const struct MemoryRegionOps *ops;
171
+ } regions[ARRAY_SIZE(ci->iomem)] = {
172
+ /*
173
+ * Registers located between offsets 0x000 and 0xFC
174
+ */
175
+ {
176
+ .name = TYPE_CHIPIDEA ".misc",
177
+ .offset = 0x000,
178
+ .size = 0x100,
179
+ .ops = &chipidea_ops,
180
+ },
181
+ /*
182
+ * Registers located between offsets 0x1A4 and 0x1DC
183
+ */
184
+ {
185
+ .name = TYPE_CHIPIDEA ".endpoints",
186
+ .offset = 0x1A4,
187
+ .size = 0x1DC - 0x1A4 + 4,
188
+ .ops = &chipidea_ops,
189
+ },
190
+ /*
191
+ * USB_x_DCIVERSION and USB_x_DCCPARAMS
192
+ */
193
+ {
194
+ .name = TYPE_CHIPIDEA ".dc",
195
+ .offset = 0x120,
196
+ .size = 8,
197
+ .ops = &chipidea_dc_ops,
198
+ },
199
+ };
200
+
201
+ memory_region_init_io(&ci->iomem[i],
202
+ obj,
203
+ regions[i].ops,
204
+ ci,
205
+ regions[i].name,
206
+ regions[i].size);
207
+
208
+ memory_region_add_subregion(&ehci->mem,
209
+ regions[i].offset,
210
+ &ci->iomem[i]);
211
+ }
212
+}
213
+
214
+static void chipidea_class_init(ObjectClass *klass, void *data)
215
+{
216
+ DeviceClass *dc = DEVICE_CLASS(klass);
217
+ SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(klass);
218
+
219
+ /*
220
+ * Offsets used were taken from i.MX7Dual Applications Processor
221
+ * Reference Manual, Rev 0.1, p. 3177, Table 11-59
222
+ */
223
+ sec->capsbase = 0x100;
224
+ sec->opregbase = 0x140;
225
+ sec->portnr = 1;
226
+
227
+ set_bit(DEVICE_CATEGORY_USB, dc->categories);
228
+ dc->desc = "Chipidea USB Module";
229
+}
230
+
231
+static const TypeInfo chipidea_info = {
232
+ .name = TYPE_CHIPIDEA,
233
+ .parent = TYPE_SYS_BUS_EHCI,
234
+ .instance_size = sizeof(ChipideaState),
235
+ .instance_init = chipidea_init,
236
+ .class_init = chipidea_class_init,
237
+};
238
+
239
+static void chipidea_register_type(void)
240
+{
241
+ type_register_static(&chipidea_info);
242
+}
243
+type_init(chipidea_register_type)
244
--
31
--
245
2.16.1
32
2.34.1
246
33
247
34
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add minimal code needed to allow upstream Linux guest to boot.
3
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
4
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Cc: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Cc: Jason Wang <jasowang@redhat.com>
6
Message-id: 20230206223502.25122-3-philmd@linaro.org
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
8
---
18
include/hw/timer/imx_gpt.h | 1 +
9
target/arm/m_helper.c | 11 ++++++++---
19
hw/timer/imx_gpt.c | 25 +++++++++++++++++++++++++
10
1 file changed, 8 insertions(+), 3 deletions(-)
20
2 files changed, 26 insertions(+)
21
11
22
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
12
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
23
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/timer/imx_gpt.h
14
--- a/target/arm/m_helper.c
25
+++ b/include/hw/timer/imx_gpt.h
15
+++ b/target/arm/m_helper.c
26
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
27
#define TYPE_IMX25_GPT "imx25.gpt"
17
return 0;
28
#define TYPE_IMX31_GPT "imx31.gpt"
29
#define TYPE_IMX6_GPT "imx6.gpt"
30
+#define TYPE_IMX7_GPT "imx7.gpt"
31
32
#define TYPE_IMX_GPT TYPE_IMX25_GPT
33
34
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/timer/imx_gpt.c
37
+++ b/hw/timer/imx_gpt.c
38
@@ -XXX,XX +XXX,XX @@ static const IMXClk imx6_gpt_clocks[] = {
39
CLK_HIGH, /* 111 reference clock */
40
};
41
42
+static const IMXClk imx7_gpt_clocks[] = {
43
+ CLK_NONE, /* 000 No clock source */
44
+ CLK_IPG, /* 001 ipg_clk, 532MHz*/
45
+ CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */
46
+ CLK_EXT, /* 011 External clock */
47
+ CLK_32k, /* 100 ipg_clk_32k */
48
+ CLK_HIGH, /* 101 reference clock */
49
+ CLK_NONE, /* 110 not defined */
50
+ CLK_NONE, /* 111 not defined */
51
+};
52
+
53
static void imx_gpt_set_freq(IMXGPTState *s)
54
{
55
uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
56
@@ -XXX,XX +XXX,XX @@ static void imx6_gpt_init(Object *obj)
57
s->clocks = imx6_gpt_clocks;
58
}
18
}
59
19
60
+static void imx7_gpt_init(Object *obj)
20
-#else
21
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
61
+{
22
+{
62
+ IMXGPTState *s = IMX_GPT(obj);
23
+ return ARMMMUIdx_MUser;
63
+
64
+ s->clocks = imx7_gpt_clocks;
65
+}
24
+}
66
+
25
+
67
static const TypeInfo imx25_gpt_info = {
26
+#else /* !CONFIG_USER_ONLY */
68
.name = TYPE_IMX25_GPT,
27
69
.parent = TYPE_SYS_BUS_DEVICE,
28
/*
70
@@ -XXX,XX +XXX,XX @@ static const TypeInfo imx6_gpt_info = {
29
* What kind of stack write are we doing? This affects how exceptions
71
.instance_init = imx6_gpt_init,
30
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
72
};
31
return tt_resp;
73
32
}
74
+static const TypeInfo imx7_gpt_info = {
33
75
+ .name = TYPE_IMX7_GPT,
34
-#endif /* !CONFIG_USER_ONLY */
76
+ .parent = TYPE_IMX25_GPT,
35
-
77
+ .instance_init = imx7_gpt_init,
36
ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
78
+};
37
bool secstate, bool priv, bool negpri)
38
{
39
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
40
41
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
42
}
79
+
43
+
80
static void imx_gpt_register_types(void)
44
+#endif /* !CONFIG_USER_ONLY */
81
{
82
type_register_static(&imx25_gpt_info);
83
type_register_static(&imx31_gpt_info);
84
type_register_static(&imx6_gpt_info);
85
+ type_register_static(&imx7_gpt_info);
86
}
87
88
type_init(imx_gpt_register_types)
89
--
45
--
90
2.16.1
46
2.34.1
91
47
92
48
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Define ZCR_EL[1-3].
3
arm_v7m_mmu_idx_all() and arm_v7m_mmu_idx_for_secstate_and_priv()
4
are only used for system emulation in m_helper.c.
5
Move the definitions to avoid prototype forward declarations.
4
6
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180123035349.24538-5-richard.henderson@linaro.org
9
Message-id: 20230206223502.25122-4-philmd@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/cpu.h | 5 ++
12
target/arm/internals.h | 14 --------
11
target/arm/helper.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++
13
target/arm/m_helper.c | 74 +++++++++++++++++++++---------------------
12
2 files changed, 136 insertions(+)
14
2 files changed, 37 insertions(+), 51 deletions(-)
13
15
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
18
--- a/target/arm/internals.h
17
+++ b/target/arm/cpu.h
19
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
20
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx core_to_aa64_mmu_idx(int mmu_idx)
19
*/
21
20
float_status fp_status;
22
int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
21
float_status standard_fp_status;
23
24
-/*
25
- * Return the MMU index for a v7M CPU with all relevant information
26
- * manually specified.
27
- */
28
-ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
29
- bool secstate, bool priv, bool negpri);
30
-
31
-/*
32
- * Return the MMU index for a v7M CPU in the specified security and
33
- * privilege state.
34
- */
35
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
36
- bool secstate, bool priv);
37
-
38
/* Return the MMU index for a v7M CPU in the specified security state */
39
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
40
41
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/m_helper.c
44
+++ b/target/arm/m_helper.c
45
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
46
47
#else /* !CONFIG_USER_ONLY */
48
49
+static ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
50
+ bool secstate, bool priv, bool negpri)
51
+{
52
+ ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
22
+
53
+
23
+ /* ZCR_EL[1-3] */
54
+ if (priv) {
24
+ uint64_t zcr_el[4];
55
+ mmu_idx |= ARM_MMU_IDX_M_PRIV;
25
} vfp;
26
uint64_t exclusive_addr;
27
uint64_t exclusive_val;
28
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
29
#define CPTR_TCPAC (1U << 31)
30
#define CPTR_TTA (1U << 20)
31
#define CPTR_TFP (1U << 10)
32
+#define CPTR_TZ (1U << 8) /* CPTR_EL2 */
33
+#define CPTR_EZ (1U << 8) /* CPTR_EL3 */
34
35
#define MDCR_EPMAD (1U << 21)
36
#define MDCR_EDAD (1U << 20)
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
42
REGINFO_SENTINEL
43
};
44
45
+/* Return the exception level to which SVE-disabled exceptions should
46
+ * be taken, or 0 if SVE is enabled.
47
+ */
48
+static int sve_exception_el(CPUARMState *env)
49
+{
50
+#ifndef CONFIG_USER_ONLY
51
+ unsigned current_el = arm_current_el(env);
52
+
53
+ /* The CPACR.ZEN controls traps to EL1:
54
+ * 0, 2 : trap EL0 and EL1 accesses
55
+ * 1 : trap only EL0 accesses
56
+ * 3 : trap no accesses
57
+ */
58
+ switch (extract32(env->cp15.cpacr_el1, 16, 2)) {
59
+ default:
60
+ if (current_el <= 1) {
61
+ /* Trap to PL1, which might be EL1 or EL3 */
62
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
63
+ return 3;
64
+ }
65
+ return 1;
66
+ }
67
+ break;
68
+ case 1:
69
+ if (current_el == 0) {
70
+ return 1;
71
+ }
72
+ break;
73
+ case 3:
74
+ break;
75
+ }
56
+ }
76
+
57
+
77
+ /* Similarly for CPACR.FPEN, after having checked ZEN. */
58
+ if (negpri) {
78
+ switch (extract32(env->cp15.cpacr_el1, 20, 2)) {
59
+ mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
79
+ default:
80
+ if (current_el <= 1) {
81
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
82
+ return 3;
83
+ }
84
+ return 1;
85
+ }
86
+ break;
87
+ case 1:
88
+ if (current_el == 0) {
89
+ return 1;
90
+ }
91
+ break;
92
+ case 3:
93
+ break;
94
+ }
60
+ }
95
+
61
+
96
+ /* CPTR_EL2. Check both TZ and TFP. */
62
+ if (secstate) {
97
+ if (current_el <= 2
63
+ mmu_idx |= ARM_MMU_IDX_M_S;
98
+ && (env->cp15.cptr_el[2] & (CPTR_TFP | CPTR_TZ))
99
+ && !arm_is_secure_below_el3(env)) {
100
+ return 2;
101
+ }
64
+ }
102
+
65
+
103
+ /* CPTR_EL3. Check both EZ and TFP. */
66
+ return mmu_idx;
104
+ if (!(env->cp15.cptr_el[3] & CPTR_EZ)
105
+ || (env->cp15.cptr_el[3] & CPTR_TFP)) {
106
+ return 3;
107
+ }
108
+#endif
109
+ return 0;
110
+}
67
+}
111
+
68
+
112
+static CPAccessResult zcr_access(CPUARMState *env, const ARMCPRegInfo *ri,
69
+static ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
113
+ bool isread)
70
+ bool secstate, bool priv)
114
+{
71
+{
115
+ switch (sve_exception_el(env)) {
72
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
116
+ case 3:
73
+
117
+ return CP_ACCESS_TRAP_EL3;
74
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
118
+ case 2:
119
+ return CP_ACCESS_TRAP_EL2;
120
+ case 1:
121
+ return CP_ACCESS_TRAP;
122
+ }
123
+ return CP_ACCESS_OK;
124
+}
75
+}
125
+
76
+
126
+static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
77
+/* Return the MMU index for a v7M CPU in the specified security state */
127
+ uint64_t value)
78
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
128
+{
79
+{
129
+ /* Bits other than [3:0] are RAZ/WI. */
80
+ bool priv = arm_v7m_is_handler_mode(env) ||
130
+ raw_write(env, ri, value & 0xf);
81
+ !(env->v7m.control[secstate] & 1);
82
+
83
+ return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
131
+}
84
+}
132
+
85
+
133
+static const ARMCPRegInfo zcr_el1_reginfo = {
86
/*
134
+ .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
87
* What kind of stack write are we doing? This affects how exceptions
135
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
88
* generated during the stacking are treated.
136
+ .access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
89
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
137
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
90
return tt_resp;
138
+ .writefn = zcr_write, .raw_writefn = raw_write
139
+};
140
+
141
+static const ARMCPRegInfo zcr_el2_reginfo = {
142
+ .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
143
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
144
+ .access = PL2_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
145
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
146
+ .writefn = zcr_write, .raw_writefn = raw_write
147
+};
148
+
149
+static const ARMCPRegInfo zcr_no_el2_reginfo = {
150
+ .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
151
+ .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
152
+ .access = PL2_RW, .type = ARM_CP_64BIT,
153
+ .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
154
+};
155
+
156
+static const ARMCPRegInfo zcr_el3_reginfo = {
157
+ .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
158
+ .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
159
+ .access = PL3_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
160
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
161
+ .writefn = zcr_write, .raw_writefn = raw_write
162
+};
163
+
164
void hw_watchpoint_update(ARMCPU *cpu, int n)
165
{
166
CPUARMState *env = &cpu->env;
167
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
168
}
169
define_one_arm_cp_reg(cpu, &sctlr);
170
}
171
+
172
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
173
+ define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
174
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
175
+ define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
176
+ } else {
177
+ define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
178
+ }
179
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
180
+ define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
181
+ }
182
+ }
183
}
91
}
184
92
185
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
93
-ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
94
- bool secstate, bool priv, bool negpri)
95
-{
96
- ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
97
-
98
- if (priv) {
99
- mmu_idx |= ARM_MMU_IDX_M_PRIV;
100
- }
101
-
102
- if (negpri) {
103
- mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
104
- }
105
-
106
- if (secstate) {
107
- mmu_idx |= ARM_MMU_IDX_M_S;
108
- }
109
-
110
- return mmu_idx;
111
-}
112
-
113
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
114
- bool secstate, bool priv)
115
-{
116
- bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
117
-
118
- return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
119
-}
120
-
121
-/* Return the MMU index for a v7M CPU in the specified security state */
122
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
123
-{
124
- bool priv = arm_v7m_is_handler_mode(env) ||
125
- !(env->v7m.control[secstate] & 1);
126
-
127
- return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
128
-}
129
-
130
#endif /* !CONFIG_USER_ONLY */
186
--
131
--
187
2.16.1
132
2.34.1
188
133
189
134
diff view generated by jsdifflib
1
Make the load of the exception vector from the vector table honour
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
the SAU and any bus error on the load (possibly provoking a derived
3
exception), rather than simply aborting if the load fails.
4
2
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20230206223502.25122-5-philmd@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 1517324542-6607-7-git-send-email-peter.maydell@linaro.org
8
---
7
---
9
target/arm/helper.c | 71 +++++++++++++++++++++++++++++++++++++++++------------
8
target/arm/helper.c | 12 ++++++++++--
10
1 file changed, 55 insertions(+), 16 deletions(-)
9
1 file changed, 10 insertions(+), 2 deletions(-)
11
10
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
13
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
14
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
15
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
17
}
16
}
18
}
17
}
19
18
20
-static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
19
+#ifndef CONFIG_USER_ONLY
21
+static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
20
/*
22
+ uint32_t *pvec)
21
* We don't know until after realize whether there's a GICv3
22
* attached, and that is what registers the gicv3 sysregs.
23
@@ -XXX,XX +XXX,XX @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
24
return pfr1;
25
}
26
27
-#ifndef CONFIG_USER_ONLY
28
static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
23
{
29
{
24
CPUState *cs = CPU(cpu);
30
ARMCPU *cpu = env_archcpu(env);
25
CPUARMState *env = &cpu->env;
31
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
26
MemTxResult result;
32
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1,
27
- hwaddr vec = env->v7m.vecbase[targets_secure] + exc * 4;
33
.access = PL1_R, .type = ARM_CP_NO_RAW,
28
- uint32_t addr;
34
.accessfn = access_aa32_tid3,
29
+ uint32_t addr = env->v7m.vecbase[targets_secure] + exc * 4;
35
+#ifdef CONFIG_USER_ONLY
30
+ uint32_t vector_entry;
36
+ .type = ARM_CP_CONST,
31
+ MemTxAttrs attrs = {};
37
+ .resetvalue = cpu->isar.id_pfr1,
32
+ ARMMMUIdx mmu_idx;
38
+#else
33
+ bool exc_secure;
39
+ .type = ARM_CP_NO_RAW,
34
+
40
+ .accessfn = access_aa32_tid3,
35
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targets_secure, true);
41
.readfn = id_pfr1_read,
36
42
- .writefn = arm_cp_write_ignore },
37
- addr = address_space_ldl(cs->as, vec,
43
+ .writefn = arm_cp_write_ignore
38
- MEMTXATTRS_UNSPECIFIED, &result);
44
+#endif
39
+ /* We don't do a get_phys_addr() here because the rules for vector
45
+ },
40
+ * loads are special: they always use the default memory map, and
46
{ .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH,
41
+ * the default memory map permits reads from all addresses.
47
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
42
+ * Since there's no easy way to pass through to pmsav8_mpu_lookup()
48
.access = PL1_R, .type = ARM_CP_CONST,
43
+ * that we want this special case which would always say "yes",
44
+ * we just do the SAU lookup here followed by a direct physical load.
45
+ */
46
+ attrs.secure = targets_secure;
47
+ attrs.user = false;
48
+
49
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
50
+ V8M_SAttributes sattrs = {};
51
+
52
+ v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx, &sattrs);
53
+ if (sattrs.ns) {
54
+ attrs.secure = false;
55
+ } else if (!targets_secure) {
56
+ /* NS access to S memory */
57
+ goto load_fail;
58
+ }
59
+ }
60
+
61
+ vector_entry = address_space_ldl(arm_addressspace(cs, attrs), addr,
62
+ attrs, &result);
63
if (result != MEMTX_OK) {
64
- /* Architecturally this should cause a HardFault setting HSFR.VECTTBL,
65
- * which would then be immediately followed by our failing to load
66
- * the entry vector for that HardFault, which is a Lockup case.
67
- * Since we don't model Lockup, we just report this guest error
68
- * via cpu_abort().
69
- */
70
- cpu_abort(cs, "Failed to read from %s exception vector table "
71
- "entry %08x\n", targets_secure ? "secure" : "nonsecure",
72
- (unsigned)vec);
73
+ goto load_fail;
74
}
75
- return addr;
76
+ *pvec = vector_entry;
77
+ return true;
78
+
79
+load_fail:
80
+ /* All vector table fetch fails are reported as HardFault, with
81
+ * HFSR.VECTTBL and .FORCED set. (FORCED is set because
82
+ * technically the underlying exception is a MemManage or BusFault
83
+ * that is escalated to HardFault.) This is a terminal exception,
84
+ * so we will either take the HardFault immediately or else enter
85
+ * lockup (the latter case is handled in armv7m_nvic_set_pending_derived()).
86
+ */
87
+ exc_secure = targets_secure ||
88
+ !(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK);
89
+ env->v7m.hfsr |= R_V7M_HFSR_VECTTBL_MASK | R_V7M_HFSR_FORCED_MASK;
90
+ armv7m_nvic_set_pending_derived(env->nvic, ARMV7M_EXCP_HARD, exc_secure);
91
+ return false;
92
}
93
94
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
95
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
96
return;
97
}
98
99
- addr = arm_v7m_load_vector(cpu, exc, targets_secure);
100
+ if (!arm_v7m_load_vector(cpu, exc, targets_secure, &addr)) {
101
+ /* Vector load failed: derived exception */
102
+ v7m_exception_taken(cpu, lr, true, true);
103
+ return;
104
+ }
105
106
/* Now we've done everything that might cause a derived exception
107
* we can go ahead and activate whichever exception we're going to
108
--
49
--
109
2.16.1
50
2.34.1
110
51
111
52
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This implements emulation of the new SHA-3 instructions that have
3
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
4
been added as an optional extensions to the ARMv8 Crypto Extensions
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
in ARM v8.2.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
6
Message-id: 20230206223502.25122-6-philmd@linaro.org
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
8
Message-id: 20180207111729.15737-3-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/cpu.h | 1 +
9
linux-user/user-internals.h | 2 +-
13
target/arm/translate-a64.c | 148 +++++++++++++++++++++++++++++++++++++++++++--
10
target/arm/cpu.h | 2 +-
14
2 files changed, 145 insertions(+), 4 deletions(-)
11
linux-user/arm/cpu_loop.c | 4 ++--
12
3 files changed, 4 insertions(+), 4 deletions(-)
15
13
14
diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/user-internals.h
17
+++ b/linux-user/user-internals.h
18
@@ -XXX,XX +XXX,XX @@ void print_termios(void *arg);
19
#ifdef TARGET_ARM
20
static inline int regpairs_aligned(CPUArchState *cpu_env, int num)
21
{
22
- return cpu_env->eabi == 1;
23
+ return cpu_env->eabi;
24
}
25
#elif defined(TARGET_MIPS) && defined(TARGET_ABI_MIPSO32)
26
static inline int regpairs_aligned(CPUArchState *cpu_env, int num) { return 1; }
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
29
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ enum arm_features {
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
21
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
32
22
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
33
#if defined(CONFIG_USER_ONLY)
23
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
34
/* For usermode syscall translation. */
24
+ ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
35
- int eabi;
25
};
36
+ bool eabi;
26
37
#endif
27
static inline int arm_feature(CPUARMState *env, int feature)
38
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
39
struct CPUBreakpoint *cpu_breakpoint[16];
40
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
29
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
42
--- a/linux-user/arm/cpu_loop.c
31
+++ b/target/arm/translate-a64.c
43
+++ b/linux-user/arm/cpu_loop.c
32
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
44
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
33
feature = ARM_FEATURE_V8_SHA512;
34
genfn = gen_helper_crypto_sha512su1;
35
break;
45
break;
36
- default:
46
case EXCP_SWI:
37
- unallocated_encoding(s);
47
{
38
- return;
48
- env->eabi = 1;
39
+ case 3: /* RAX1 */
49
+ env->eabi = true;
40
+ feature = ARM_FEATURE_V8_SHA3;
50
/* system call */
41
+ genfn = NULL;
51
if (env->thumb) {
42
+ break;
52
/* Thumb is always EABI style with syscall number in r7 */
43
}
53
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
44
} else {
54
* > 0xfffff and are handled below as out-of-range.
45
unallocated_encoding(s);
55
*/
46
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
56
n ^= ARM_SYSCALL_BASE;
47
tcg_temp_free_ptr(tcg_rn_ptr);
57
- env->eabi = 0;
48
tcg_temp_free_ptr(tcg_rm_ptr);
58
+ env->eabi = false;
49
} else {
59
}
50
- g_assert_not_reached();
60
}
51
+ TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
52
+ int pass;
53
+
54
+ tcg_op1 = tcg_temp_new_i64();
55
+ tcg_op2 = tcg_temp_new_i64();
56
+ tcg_res[0] = tcg_temp_new_i64();
57
+ tcg_res[1] = tcg_temp_new_i64();
58
+
59
+ for (pass = 0; pass < 2; pass++) {
60
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
61
+ read_vec_element(s, tcg_op2, rm, pass, MO_64);
62
+
63
+ tcg_gen_rotli_i64(tcg_res[pass], tcg_op2, 1);
64
+ tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
65
+ }
66
+ write_vec_element(s, tcg_res[0], rd, 0, MO_64);
67
+ write_vec_element(s, tcg_res[1], rd, 1, MO_64);
68
+
69
+ tcg_temp_free_i64(tcg_op1);
70
+ tcg_temp_free_i64(tcg_op2);
71
+ tcg_temp_free_i64(tcg_res[0]);
72
+ tcg_temp_free_i64(tcg_res[1]);
73
}
74
}
75
76
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
77
tcg_temp_free_ptr(tcg_rn_ptr);
78
}
79
80
+/* Crypto four-register
81
+ * 31 23 22 21 20 16 15 14 10 9 5 4 0
82
+ * +-------------------+-----+------+---+------+------+------+
83
+ * | 1 1 0 0 1 1 1 0 0 | Op0 | Rm | 0 | Ra | Rn | Rd |
84
+ * +-------------------+-----+------+---+------+------+------+
85
+ */
86
+static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
87
+{
88
+ int op0 = extract32(insn, 21, 2);
89
+ int rm = extract32(insn, 16, 5);
90
+ int ra = extract32(insn, 10, 5);
91
+ int rn = extract32(insn, 5, 5);
92
+ int rd = extract32(insn, 0, 5);
93
+ int feature;
94
+
95
+ switch (op0) {
96
+ case 0: /* EOR3 */
97
+ case 1: /* BCAX */
98
+ feature = ARM_FEATURE_V8_SHA3;
99
+ break;
100
+ default:
101
+ unallocated_encoding(s);
102
+ return;
103
+ }
104
+
105
+ if (!arm_dc_feature(s, feature)) {
106
+ unallocated_encoding(s);
107
+ return;
108
+ }
109
+
110
+ if (!fp_access_check(s)) {
111
+ return;
112
+ }
113
+
114
+ if (op0 < 2) {
115
+ TCGv_i64 tcg_op1, tcg_op2, tcg_op3, tcg_res[2];
116
+ int pass;
117
+
118
+ tcg_op1 = tcg_temp_new_i64();
119
+ tcg_op2 = tcg_temp_new_i64();
120
+ tcg_op3 = tcg_temp_new_i64();
121
+ tcg_res[0] = tcg_temp_new_i64();
122
+ tcg_res[1] = tcg_temp_new_i64();
123
+
124
+ for (pass = 0; pass < 2; pass++) {
125
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
126
+ read_vec_element(s, tcg_op2, rm, pass, MO_64);
127
+ read_vec_element(s, tcg_op3, ra, pass, MO_64);
128
+
129
+ if (op0 == 0) {
130
+ /* EOR3 */
131
+ tcg_gen_xor_i64(tcg_res[pass], tcg_op2, tcg_op3);
132
+ } else {
133
+ /* BCAX */
134
+ tcg_gen_andc_i64(tcg_res[pass], tcg_op2, tcg_op3);
135
+ }
136
+ tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1);
137
+ }
138
+ write_vec_element(s, tcg_res[0], rd, 0, MO_64);
139
+ write_vec_element(s, tcg_res[1], rd, 1, MO_64);
140
+
141
+ tcg_temp_free_i64(tcg_op1);
142
+ tcg_temp_free_i64(tcg_op2);
143
+ tcg_temp_free_i64(tcg_op3);
144
+ tcg_temp_free_i64(tcg_res[0]);
145
+ tcg_temp_free_i64(tcg_res[1]);
146
+ } else {
147
+ g_assert_not_reached();
148
+ }
149
+}
150
+
151
+/* Crypto XAR
152
+ * 31 21 20 16 15 10 9 5 4 0
153
+ * +-----------------------+------+--------+------+------+
154
+ * | 1 1 0 0 1 1 1 0 1 0 0 | Rm | imm6 | Rn | Rd |
155
+ * +-----------------------+------+--------+------+------+
156
+ */
157
+static void disas_crypto_xar(DisasContext *s, uint32_t insn)
158
+{
159
+ int rm = extract32(insn, 16, 5);
160
+ int imm6 = extract32(insn, 10, 6);
161
+ int rn = extract32(insn, 5, 5);
162
+ int rd = extract32(insn, 0, 5);
163
+ TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
164
+ int pass;
165
+
166
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA3)) {
167
+ unallocated_encoding(s);
168
+ return;
169
+ }
170
+
171
+ if (!fp_access_check(s)) {
172
+ return;
173
+ }
174
+
175
+ tcg_op1 = tcg_temp_new_i64();
176
+ tcg_op2 = tcg_temp_new_i64();
177
+ tcg_res[0] = tcg_temp_new_i64();
178
+ tcg_res[1] = tcg_temp_new_i64();
179
+
180
+ for (pass = 0; pass < 2; pass++) {
181
+ read_vec_element(s, tcg_op1, rn, pass, MO_64);
182
+ read_vec_element(s, tcg_op2, rm, pass, MO_64);
183
+
184
+ tcg_gen_xor_i64(tcg_res[pass], tcg_op1, tcg_op2);
185
+ tcg_gen_rotri_i64(tcg_res[pass], tcg_res[pass], imm6);
186
+ }
187
+ write_vec_element(s, tcg_res[0], rd, 0, MO_64);
188
+ write_vec_element(s, tcg_res[1], rd, 1, MO_64);
189
+
190
+ tcg_temp_free_i64(tcg_op1);
191
+ tcg_temp_free_i64(tcg_op2);
192
+ tcg_temp_free_i64(tcg_res[0]);
193
+ tcg_temp_free_i64(tcg_res[1]);
194
+}
195
+
196
/* C3.6 Data processing - SIMD, inc Crypto
197
*
198
* As the decode gets a little complex we are using a table based
199
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
200
{ 0x5e280800, 0xff3e0c00, disas_crypto_two_reg_sha },
201
{ 0xce608000, 0xffe0b000, disas_crypto_three_reg_sha512 },
202
{ 0xcec08000, 0xfffff000, disas_crypto_two_reg_sha512 },
203
+ { 0xce000000, 0xff808000, disas_crypto_four_reg },
204
+ { 0xce800000, 0xffe00000, disas_crypto_xar },
205
{ 0x00000000, 0x00000000, NULL }
206
};
207
61
208
--
62
--
209
2.16.1
63
2.34.1
210
64
211
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add both SVE exception state and vector length.
3
Although the 'eabi' field is only used in user emulation where
4
CPU reset doesn't occur, it doesn't belong to the area to reset.
5
Move it after the 'end_reset_fields' for consistency.
4
6
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20180123035349.24538-6-richard.henderson@linaro.org
9
Message-id: 20230206223502.25122-7-philmd@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/cpu.h | 8 ++++++++
12
target/arm/cpu.h | 9 ++++-----
11
target/arm/translate.h | 2 ++
13
1 file changed, 4 insertions(+), 5 deletions(-)
12
target/arm/helper.c | 25 ++++++++++++++++++++++++-
13
target/arm/translate-a64.c | 2 ++
14
4 files changed, 36 insertions(+), 1 deletion(-)
15
14
16
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
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
17
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
21
#define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT)
20
ARMVectorReg zarray[ARM_MAX_VQ * 16];
22
#define ARM_TBFLAG_TBI1_SHIFT 1 /* TBI1 for EL0/1 */
23
#define ARM_TBFLAG_TBI1_MASK (0x1ull << ARM_TBFLAG_TBI1_SHIFT)
24
+#define ARM_TBFLAG_SVEEXC_EL_SHIFT 2
25
+#define ARM_TBFLAG_SVEEXC_EL_MASK (0x3 << ARM_TBFLAG_SVEEXC_EL_SHIFT)
26
+#define ARM_TBFLAG_ZCR_LEN_SHIFT 4
27
+#define ARM_TBFLAG_ZCR_LEN_MASK (0xf << ARM_TBFLAG_ZCR_LEN_SHIFT)
28
29
/* some convenience accessor macros */
30
#define ARM_TBFLAG_AARCH64_STATE(F) \
31
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
32
(((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT)
33
#define ARM_TBFLAG_TBI1(F) \
34
(((F) & ARM_TBFLAG_TBI1_MASK) >> ARM_TBFLAG_TBI1_SHIFT)
35
+#define ARM_TBFLAG_SVEEXC_EL(F) \
36
+ (((F) & ARM_TBFLAG_SVEEXC_EL_MASK) >> ARM_TBFLAG_SVEEXC_EL_SHIFT)
37
+#define ARM_TBFLAG_ZCR_LEN(F) \
38
+ (((F) & ARM_TBFLAG_ZCR_LEN_MASK) >> ARM_TBFLAG_ZCR_LEN_SHIFT)
39
40
static inline bool bswap_code(bool sctlr_b)
41
{
42
diff --git a/target/arm/translate.h b/target/arm/translate.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/translate.h
45
+++ b/target/arm/translate.h
46
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
47
bool tbi1; /* TBI1 for EL0/1, not used for EL2/3 */
48
bool ns; /* Use non-secure CPREG bank on access */
49
int fp_excp_el; /* FP exception EL or 0 if enabled */
50
+ int sve_excp_el; /* SVE exception EL or 0 if enabled */
51
+ int sve_len; /* SVE vector length in bytes */
52
/* Flag indicating that exceptions from secure mode are routed to EL3. */
53
bool secure_routed_to_el3;
54
bool vfp_enabled; /* FP enabled via FPSCR.EN */
55
diff --git a/target/arm/helper.c b/target/arm/helper.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/helper.c
58
+++ b/target/arm/helper.c
59
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
60
target_ulong *cs_base, uint32_t *pflags)
61
{
62
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
63
+ int fp_el = fp_exception_el(env);
64
uint32_t flags;
65
66
if (is_a64(env)) {
67
+ int sve_el = sve_exception_el(env);
68
+ uint32_t zcr_len;
69
+
70
*pc = env->pc;
71
flags = ARM_TBFLAG_AARCH64_STATE_MASK;
72
/* Get control bits for tagged addresses */
73
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
74
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
75
+ flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
76
+
77
+ /* If SVE is disabled, but FP is enabled,
78
+ then the effective len is 0. */
79
+ if (sve_el != 0 && fp_el == 0) {
80
+ zcr_len = 0;
81
+ } else {
82
+ int current_el = arm_current_el(env);
83
+
84
+ zcr_len = env->vfp.zcr_el[current_el <= 1 ? 1 : current_el];
85
+ zcr_len &= 0xf;
86
+ if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
87
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
88
+ }
89
+ if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
90
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
91
+ }
92
+ }
93
+ flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
94
} else {
95
*pc = env->regs[15];
96
flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
97
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
98
if (arm_cpu_data_is_big_endian(env)) {
99
flags |= ARM_TBFLAG_BE_DATA_MASK;
100
}
101
- flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
102
+ flags |= fp_el << ARM_TBFLAG_FPEXC_EL_SHIFT;
103
104
if (arm_v7m_is_handler_mode(env)) {
105
flags |= ARM_TBFLAG_HANDLER_MASK;
106
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-a64.c
109
+++ b/target/arm/translate-a64.c
110
@@ -XXX,XX +XXX,XX @@ static int aarch64_tr_init_disas_context(DisasContextBase *dcbase,
111
dc->user = (dc->current_el == 0);
112
#endif
21
#endif
113
dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
22
114
+ dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
23
-#if defined(CONFIG_USER_ONLY)
115
+ dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;
24
- /* For usermode syscall translation. */
116
dc->vec_len = 0;
25
- bool eabi;
117
dc->vec_stride = 0;
26
-#endif
118
dc->cp_regs = arm_cpu->cp_regs;
27
-
28
struct CPUBreakpoint *cpu_breakpoint[16];
29
struct CPUWatchpoint *cpu_watchpoint[16];
30
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
32
const struct arm_boot_info *boot_info;
33
/* Store GICv3CPUState to access from this struct */
34
void *gicv3state;
35
+#if defined(CONFIG_USER_ONLY)
36
+ /* For usermode syscall translation. */
37
+ bool eabi;
38
+#endif /* CONFIG_USER_ONLY */
39
40
#ifdef TARGET_TAGGED_ADDRESSES
41
/* Linux syscall tagged address support */
119
--
42
--
120
2.16.1
43
2.34.1
121
44
122
45
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20230206223502.25122-8-philmd@linaro.org
6
Message-id: 20180123035349.24538-3-richard.henderson@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/cpu.h | 12 ++++++++++++
8
target/arm/cpu.h | 3 ++-
10
1 file changed, 12 insertions(+)
9
1 file changed, 2 insertions(+), 1 deletion(-)
11
10
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
13
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
14
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVectorReg {
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
17
uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
16
18
} ARMVectorReg;
17
void *nvic;
19
18
const struct arm_boot_info *boot_info;
20
+/* In AArch32 mode, predicate registers do not exist at all. */
19
+#if !defined(CONFIG_USER_ONLY)
21
+#ifdef TARGET_AARCH64
20
/* Store GICv3CPUState to access from this struct */
22
+typedef struct ARMPredicateReg {
21
void *gicv3state;
23
+ uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
22
-#if defined(CONFIG_USER_ONLY)
24
+} ARMPredicateReg;
23
+#else /* CONFIG_USER_ONLY */
25
+#endif
24
/* For usermode syscall translation. */
26
+
25
bool eabi;
27
26
#endif /* CONFIG_USER_ONLY */
28
typedef struct CPUARMState {
29
/* Regs for current mode. */
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
31
struct {
32
ARMVectorReg zregs[32];
33
34
+#ifdef TARGET_AARCH64
35
+ /* Store FFR as pregs[16] to make it easier to treat as any other. */
36
+ ARMPredicateReg pregs[17];
37
+#endif
38
+
39
uint32_t xregs[16];
40
/* We store these fpcsr fields separately for convenience. */
41
int vec_len;
42
--
27
--
43
2.16.1
28
2.34.1
44
29
45
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Change vfp.regs as a uint64_t to vfp.zregs as an ARMVectorReg.
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
The previous patches have made the change in representation
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
relatively painless.
5
Message-id: 20230206223502.25122-9-philmd@linaro.org
6
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20180123035349.24538-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/cpu.h | 59 +++++++++++++++++++++++++++++++---------------
8
target/arm/cpu.h | 2 +-
14
target/arm/machine.c | 35 ++++++++++++++++++++++++++-
9
1 file changed, 1 insertion(+), 1 deletion(-)
15
target/arm/translate-a64.c | 8 +++----
16
target/arm/translate.c | 7 +++---
17
4 files changed, 81 insertions(+), 28 deletions(-)
18
10
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
13
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
14
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
24
uint32_t base_mask;
16
} sau;
25
} TCR;
17
26
18
void *nvic;
27
+/* Define a maximum sized vector register.
19
- const struct arm_boot_info *boot_info;
28
+ * For 32-bit, this is a 128-bit NEON/AdvSIMD register.
20
#if !defined(CONFIG_USER_ONLY)
29
+ * For 64-bit, this is a 2048-bit SVE register.
21
+ const struct arm_boot_info *boot_info;
30
+ *
22
/* Store GICv3CPUState to access from this struct */
31
+ * Note that the mapping between S, D, and Q views of the register bank
23
void *gicv3state;
32
+ * differs between AArch64 and AArch32.
24
#else /* CONFIG_USER_ONLY */
33
+ * In AArch32:
34
+ * Qn = regs[n].d[1]:regs[n].d[0]
35
+ * Dn = regs[n / 2].d[n & 1]
36
+ * Sn = regs[n / 4].d[n % 4 / 2],
37
+ * bits 31..0 for even n, and bits 63..32 for odd n
38
+ * (and regs[16] to regs[31] are inaccessible)
39
+ * In AArch64:
40
+ * Zn = regs[n].d[*]
41
+ * Qn = regs[n].d[1]:regs[n].d[0]
42
+ * Dn = regs[n].d[0]
43
+ * Sn = regs[n].d[0] bits 31..0
44
+ *
45
+ * This corresponds to the architecturally defined mapping between
46
+ * the two execution states, and means we do not need to explicitly
47
+ * map these registers when changing states.
48
+ *
49
+ * Align the data for use with TCG host vector operations.
50
+ */
51
+
52
+#ifdef TARGET_AARCH64
53
+# define ARM_MAX_VQ 16
54
+#else
55
+# define ARM_MAX_VQ 1
56
+#endif
57
+
58
+typedef struct ARMVectorReg {
59
+ uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
60
+} ARMVectorReg;
61
+
62
+
63
typedef struct CPUARMState {
64
/* Regs for current mode. */
65
uint32_t regs[16];
66
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
67
68
/* VFP coprocessor state. */
69
struct {
70
- /* VFP/Neon register state. Note that the mapping between S, D and Q
71
- * views of the register bank differs between AArch64 and AArch32:
72
- * In AArch32:
73
- * Qn = regs[2n+1]:regs[2n]
74
- * Dn = regs[n]
75
- * Sn = regs[n/2] bits 31..0 for even n, and bits 63..32 for odd n
76
- * (and regs[32] to regs[63] are inaccessible)
77
- * In AArch64:
78
- * Qn = regs[2n+1]:regs[2n]
79
- * Dn = regs[2n]
80
- * Sn = regs[2n] bits 31..0
81
- * This corresponds to the architecturally defined mapping between
82
- * the two execution states, and means we do not need to explicitly
83
- * map these registers when changing states.
84
- */
85
- uint64_t regs[64] QEMU_ALIGNED(16);
86
+ ARMVectorReg zregs[32];
87
88
uint32_t xregs[16];
89
/* We store these fpcsr fields separately for convenience. */
90
@@ -XXX,XX +XXX,XX @@ static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
91
*/
92
static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
93
{
94
- return &env->vfp.regs[regno];
95
+ return &env->vfp.zregs[regno >> 1].d[regno & 1];
96
}
97
98
/**
99
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
100
*/
101
static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
102
{
103
- return &env->vfp.regs[2 * regno];
104
+ return &env->vfp.zregs[regno].d[0];
105
}
106
107
/**
108
@@ -XXX,XX +XXX,XX @@ static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
109
*/
110
static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
111
{
112
- return &env->vfp.regs[2 * regno];
113
+ return &env->vfp.zregs[regno].d[0];
114
}
115
116
#endif
117
diff --git a/target/arm/machine.c b/target/arm/machine.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/machine.c
120
+++ b/target/arm/machine.c
121
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_vfp = {
122
.minimum_version_id = 3,
123
.needed = vfp_needed,
124
.fields = (VMStateField[]) {
125
- VMSTATE_UINT64_ARRAY(env.vfp.regs, ARMCPU, 64),
126
+ /* For compatibility, store Qn out of Zn here. */
127
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[0].d, ARMCPU, 0, 2),
128
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[1].d, ARMCPU, 0, 2),
129
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[2].d, ARMCPU, 0, 2),
130
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[3].d, ARMCPU, 0, 2),
131
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[4].d, ARMCPU, 0, 2),
132
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[5].d, ARMCPU, 0, 2),
133
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[6].d, ARMCPU, 0, 2),
134
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[7].d, ARMCPU, 0, 2),
135
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[8].d, ARMCPU, 0, 2),
136
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[9].d, ARMCPU, 0, 2),
137
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[10].d, ARMCPU, 0, 2),
138
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[11].d, ARMCPU, 0, 2),
139
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[12].d, ARMCPU, 0, 2),
140
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[13].d, ARMCPU, 0, 2),
141
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[14].d, ARMCPU, 0, 2),
142
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[15].d, ARMCPU, 0, 2),
143
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[16].d, ARMCPU, 0, 2),
144
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[17].d, ARMCPU, 0, 2),
145
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[18].d, ARMCPU, 0, 2),
146
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[19].d, ARMCPU, 0, 2),
147
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[20].d, ARMCPU, 0, 2),
148
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[21].d, ARMCPU, 0, 2),
149
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[22].d, ARMCPU, 0, 2),
150
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[23].d, ARMCPU, 0, 2),
151
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[24].d, ARMCPU, 0, 2),
152
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[25].d, ARMCPU, 0, 2),
153
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[26].d, ARMCPU, 0, 2),
154
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[27].d, ARMCPU, 0, 2),
155
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[28].d, ARMCPU, 0, 2),
156
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[29].d, ARMCPU, 0, 2),
157
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[30].d, ARMCPU, 0, 2),
158
+ VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[31].d, ARMCPU, 0, 2),
159
+
160
/* The xregs array is a little awkward because element 1 (FPSCR)
161
* requires a specific accessor, so we have to split it up in
162
* the vmstate:
163
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/translate-a64.c
166
+++ b/target/arm/translate-a64.c
167
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
168
{
169
int offs = 0;
170
#ifdef HOST_WORDS_BIGENDIAN
171
- /* This is complicated slightly because vfp.regs[2n] is
172
- * still the low half and vfp.regs[2n+1] the high half
173
+ /* This is complicated slightly because vfp.zregs[n].d[0] is
174
+ * still the low half and vfp.zregs[n].d[1] the high half
175
* of the 128 bit vector, even on big endian systems.
176
* Calculate the offset assuming a fully bigendian 128 bits,
177
* then XOR to account for the order of the two 64 bit halves.
178
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
179
#else
180
offs += element * (1 << size);
181
#endif
182
- offs += offsetof(CPUARMState, vfp.regs[regno * 2]);
183
+ offs += offsetof(CPUARMState, vfp.zregs[regno]);
184
assert_fp_access_checked(s);
185
return offs;
186
}
187
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
188
static inline int vec_full_reg_offset(DisasContext *s, int regno)
189
{
190
assert_fp_access_checked(s);
191
- return offsetof(CPUARMState, vfp.regs[regno * 2]);
192
+ return offsetof(CPUARMState, vfp.zregs[regno]);
193
}
194
195
/* Return a newly allocated pointer to the vector register. */
196
diff --git a/target/arm/translate.c b/target/arm/translate.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/target/arm/translate.c
199
+++ b/target/arm/translate.c
200
@@ -XXX,XX +XXX,XX @@ static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
201
}
202
}
203
204
-static inline long
205
-vfp_reg_offset (int dp, int reg)
206
+static inline long vfp_reg_offset(bool dp, unsigned reg)
207
{
208
if (dp) {
209
- return offsetof(CPUARMState, vfp.regs[reg]);
210
+ return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
211
} else {
212
- long ofs = offsetof(CPUARMState, vfp.regs[reg >> 1]);
213
+ long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
214
if (reg & 1) {
215
ofs += offsetof(CPU_DoubleU, l.upper);
216
} else {
217
--
25
--
218
2.16.1
26
2.34.1
219
27
220
28
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This implements emulation of the new SHA-512 instructions that have
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
been added as an optional extensions to the ARMv8 Crypto Extensions
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
in ARM v8.2.
5
Message-id: 20230206223502.25122-10-philmd@linaro.org
6
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
8
Message-id: 20180207111729.15737-2-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
target/arm/cpu.h | 1 +
8
target/arm/cpu.h | 2 +-
13
target/arm/helper.h | 5 +++
9
1 file changed, 1 insertion(+), 1 deletion(-)
14
target/arm/crypto_helper.c | 90 ++++++++++++++++++++++++++++++++++++-
15
target/arm/translate-a64.c | 110 +++++++++++++++++++++++++++++++++++++++++++++
16
4 files changed, 205 insertions(+), 1 deletion(-)
17
10
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
13
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
14
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
23
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
16
uint32_t ctrl;
24
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
17
} sau;
25
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
18
26
+ ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
19
- void *nvic;
27
};
20
#if !defined(CONFIG_USER_ONLY)
28
21
+ void *nvic;
29
static inline int arm_feature(CPUARMState *env, int feature)
22
const struct arm_boot_info *boot_info;
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
23
/* Store GICv3CPUState to access from this struct */
31
index XXXXXXX..XXXXXXX 100644
24
void *gicv3state;
32
--- a/target/arm/helper.h
33
+++ b/target/arm/helper.h
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
35
DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr)
36
DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
37
38
+DEF_HELPER_FLAGS_3(crypto_sha512h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
39
+DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
40
+DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr)
41
+DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
42
+
43
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
44
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
45
DEF_HELPER_2(dc_zva, void, env, i64)
46
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/crypto_helper.c
49
+++ b/target/arm/crypto_helper.c
50
@@ -XXX,XX +XXX,XX @@
51
/*
52
* crypto_helper.c - emulate v8 Crypto Extensions instructions
53
*
54
- * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
55
+ * Copyright (C) 2013 - 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
56
*
57
* This library is free software; you can redistribute it and/or
58
* modify it under the terms of the GNU Lesser General Public
59
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
60
rd[0] = d.l[0];
61
rd[1] = d.l[1];
62
}
63
+
64
+/*
65
+ * The SHA-512 logical functions (same as above but using 64-bit operands)
66
+ */
67
+
68
+static uint64_t cho512(uint64_t x, uint64_t y, uint64_t z)
69
+{
70
+ return (x & (y ^ z)) ^ z;
71
+}
72
+
73
+static uint64_t maj512(uint64_t x, uint64_t y, uint64_t z)
74
+{
75
+ return (x & y) | ((x | y) & z);
76
+}
77
+
78
+static uint64_t S0_512(uint64_t x)
79
+{
80
+ return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
81
+}
82
+
83
+static uint64_t S1_512(uint64_t x)
84
+{
85
+ return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
86
+}
87
+
88
+static uint64_t s0_512(uint64_t x)
89
+{
90
+ return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
91
+}
92
+
93
+static uint64_t s1_512(uint64_t x)
94
+{
95
+ return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
96
+}
97
+
98
+void HELPER(crypto_sha512h)(void *vd, void *vn, void *vm)
99
+{
100
+ uint64_t *rd = vd;
101
+ uint64_t *rn = vn;
102
+ uint64_t *rm = vm;
103
+ uint64_t d0 = rd[0];
104
+ uint64_t d1 = rd[1];
105
+
106
+ d1 += S1_512(rm[1]) + cho512(rm[1], rn[0], rn[1]);
107
+ d0 += S1_512(d1 + rm[0]) + cho512(d1 + rm[0], rm[1], rn[0]);
108
+
109
+ rd[0] = d0;
110
+ rd[1] = d1;
111
+}
112
+
113
+void HELPER(crypto_sha512h2)(void *vd, void *vn, void *vm)
114
+{
115
+ uint64_t *rd = vd;
116
+ uint64_t *rn = vn;
117
+ uint64_t *rm = vm;
118
+ uint64_t d0 = rd[0];
119
+ uint64_t d1 = rd[1];
120
+
121
+ d1 += S0_512(rm[0]) + maj512(rn[0], rm[1], rm[0]);
122
+ d0 += S0_512(d1) + maj512(d1, rm[0], rm[1]);
123
+
124
+ rd[0] = d0;
125
+ rd[1] = d1;
126
+}
127
+
128
+void HELPER(crypto_sha512su0)(void *vd, void *vn)
129
+{
130
+ uint64_t *rd = vd;
131
+ uint64_t *rn = vn;
132
+ uint64_t d0 = rd[0];
133
+ uint64_t d1 = rd[1];
134
+
135
+ d0 += s0_512(rd[1]);
136
+ d1 += s0_512(rn[0]);
137
+
138
+ rd[0] = d0;
139
+ rd[1] = d1;
140
+}
141
+
142
+void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
143
+{
144
+ uint64_t *rd = vd;
145
+ uint64_t *rn = vn;
146
+ uint64_t *rm = vm;
147
+
148
+ rd[0] += s1_512(rn[0]) + rm[0];
149
+ rd[1] += s1_512(rn[1]) + rm[1];
150
+}
151
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/target/arm/translate-a64.c
154
+++ b/target/arm/translate-a64.c
155
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
156
tcg_temp_free_ptr(tcg_rn_ptr);
157
}
158
159
+/* Crypto three-reg SHA512
160
+ * 31 21 20 16 15 14 13 12 11 10 9 5 4 0
161
+ * +-----------------------+------+---+---+-----+--------+------+------+
162
+ * | 1 1 0 0 1 1 1 0 0 1 1 | Rm | 1 | O | 0 0 | opcode | Rn | Rd |
163
+ * +-----------------------+------+---+---+-----+--------+------+------+
164
+ */
165
+static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
166
+{
167
+ int opcode = extract32(insn, 10, 2);
168
+ int o = extract32(insn, 14, 1);
169
+ int rm = extract32(insn, 16, 5);
170
+ int rn = extract32(insn, 5, 5);
171
+ int rd = extract32(insn, 0, 5);
172
+ int feature;
173
+ CryptoThreeOpFn *genfn;
174
+
175
+ if (o == 0) {
176
+ switch (opcode) {
177
+ case 0: /* SHA512H */
178
+ feature = ARM_FEATURE_V8_SHA512;
179
+ genfn = gen_helper_crypto_sha512h;
180
+ break;
181
+ case 1: /* SHA512H2 */
182
+ feature = ARM_FEATURE_V8_SHA512;
183
+ genfn = gen_helper_crypto_sha512h2;
184
+ break;
185
+ case 2: /* SHA512SU1 */
186
+ feature = ARM_FEATURE_V8_SHA512;
187
+ genfn = gen_helper_crypto_sha512su1;
188
+ break;
189
+ default:
190
+ unallocated_encoding(s);
191
+ return;
192
+ }
193
+ } else {
194
+ unallocated_encoding(s);
195
+ return;
196
+ }
197
+
198
+ if (!arm_dc_feature(s, feature)) {
199
+ unallocated_encoding(s);
200
+ return;
201
+ }
202
+
203
+ if (!fp_access_check(s)) {
204
+ return;
205
+ }
206
+
207
+ if (genfn) {
208
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
209
+
210
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
211
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
212
+ tcg_rm_ptr = vec_full_reg_ptr(s, rm);
213
+
214
+ genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr);
215
+
216
+ tcg_temp_free_ptr(tcg_rd_ptr);
217
+ tcg_temp_free_ptr(tcg_rn_ptr);
218
+ tcg_temp_free_ptr(tcg_rm_ptr);
219
+ } else {
220
+ g_assert_not_reached();
221
+ }
222
+}
223
+
224
+/* Crypto two-reg SHA512
225
+ * 31 12 11 10 9 5 4 0
226
+ * +-----------------------------------------+--------+------+------+
227
+ * | 1 1 0 0 1 1 1 0 1 1 0 0 0 0 0 0 1 0 0 0 | opcode | Rn | Rd |
228
+ * +-----------------------------------------+--------+------+------+
229
+ */
230
+static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
231
+{
232
+ int opcode = extract32(insn, 10, 2);
233
+ int rn = extract32(insn, 5, 5);
234
+ int rd = extract32(insn, 0, 5);
235
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
236
+ int feature;
237
+ CryptoTwoOpFn *genfn;
238
+
239
+ switch (opcode) {
240
+ case 0: /* SHA512SU0 */
241
+ feature = ARM_FEATURE_V8_SHA512;
242
+ genfn = gen_helper_crypto_sha512su0;
243
+ break;
244
+ default:
245
+ unallocated_encoding(s);
246
+ return;
247
+ }
248
+
249
+ if (!arm_dc_feature(s, feature)) {
250
+ unallocated_encoding(s);
251
+ return;
252
+ }
253
+
254
+ if (!fp_access_check(s)) {
255
+ return;
256
+ }
257
+
258
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
259
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
260
+
261
+ genfn(tcg_rd_ptr, tcg_rn_ptr);
262
+
263
+ tcg_temp_free_ptr(tcg_rd_ptr);
264
+ tcg_temp_free_ptr(tcg_rn_ptr);
265
+}
266
+
267
/* C3.6 Data processing - SIMD, inc Crypto
268
*
269
* As the decode gets a little complex we are using a table based
270
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
271
{ 0x4e280800, 0xff3e0c00, disas_crypto_aes },
272
{ 0x5e000000, 0xff208c00, disas_crypto_three_reg_sha },
273
{ 0x5e280800, 0xff3e0c00, disas_crypto_two_reg_sha },
274
+ { 0xce608000, 0xffe0b000, disas_crypto_three_reg_sha512 },
275
+ { 0xcec08000, 0xfffff000, disas_crypto_two_reg_sha512 },
276
{ 0x00000000, 0x00000000, NULL }
277
};
278
279
--
25
--
280
2.16.1
26
2.34.1
281
27
282
28
diff view generated by jsdifflib
1
Currently armv7m_nvic_acknowledge_irq() does three things:
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
* make the current highest priority pending interrupt active
2
3
* return a bool indicating whether that interrupt is targeting
3
There is no point in using a void pointer to access the NVIC.
4
Secure or NonSecure state
4
Use the real type to avoid casting it while debugging.
5
* implicitly tell the caller which is the highest priority
5
6
pending interrupt by setting env->v7m.exception
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
We need to split these jobs, because v7m_exception_taken()
8
Message-id: 20230206223502.25122-11-philmd@linaro.org
9
needs to know whether the pending interrupt targets Secure so
10
it can choose to stack callee-saves registers or not, but it
11
must not make the interrupt active until after it has done
12
that stacking, in case the stacking causes a derived exception.
13
Similarly, it needs to know the number of the pending interrupt
14
so it can read the correct vector table entry before the
15
interrupt is made active, because vector table reads might
16
also cause a derived exception.
17
18
Create a new armv7m_nvic_get_pending_irq_info() function which simply
19
returns information about the highest priority pending interrupt, and
20
use it to rearrange the v7m_exception_taken() code so we don't
21
acknowledge the exception until we've done all the things which could
22
possibly cause a derived exception.
23
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
27
Message-id: 1517324542-6607-3-git-send-email-peter.maydell@linaro.org
28
---
10
---
29
target/arm/cpu.h | 19 ++++++++++++++++---
11
target/arm/cpu.h | 46 ++++++++++++++++++++++---------------------
30
hw/intc/armv7m_nvic.c | 30 +++++++++++++++++++++++-------
12
hw/intc/armv7m_nvic.c | 38 ++++++++++++-----------------------
31
target/arm/helper.c | 16 ++++++++++++----
13
target/arm/cpu.c | 1 +
32
hw/intc/trace-events | 3 ++-
14
target/arm/m_helper.c | 2 +-
33
4 files changed, 53 insertions(+), 15 deletions(-)
15
4 files changed, 39 insertions(+), 48 deletions(-)
34
16
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
38
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMTBFlags {
22
23
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
24
25
+typedef struct NVICState NVICState;
26
+
27
typedef struct CPUArchState {
28
/* Regs for current mode. */
29
uint32_t regs[16];
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
31
} sau;
32
33
#if !defined(CONFIG_USER_ONLY)
34
- void *nvic;
35
+ NVICState *nvic;
36
const struct arm_boot_info *boot_info;
37
/* Store GICv3CPUState to access from this struct */
38
void *gicv3state;
39
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
40
41
/* Interface between CPU and Interrupt controller. */
42
#ifndef CONFIG_USER_ONLY
43
-bool armv7m_nvic_can_take_pending_exception(void *opaque);
44
+bool armv7m_nvic_can_take_pending_exception(NVICState *s);
45
#else
46
-static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
47
+static inline bool armv7m_nvic_can_take_pending_exception(NVICState *s)
48
{
49
return true;
50
}
51
#endif
52
/**
53
* armv7m_nvic_set_pending: mark the specified exception as pending
54
- * @opaque: the NVIC
55
+ * @s: the NVIC
56
* @irq: the exception number to mark pending
57
* @secure: false for non-banked exceptions or for the nonsecure
58
* version of a banked exception, true for the secure version of a banked
59
@@ -XXX,XX +XXX,XX @@ static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
60
* if @secure is true and @irq does not specify one of the fixed set
61
* of architecturally banked exceptions.
62
*/
63
-void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
64
+void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure);
65
/**
66
* armv7m_nvic_set_pending_derived: mark this derived exception as pending
67
- * @opaque: the NVIC
68
+ * @s: the NVIC
69
* @irq: the exception number to mark pending
70
* @secure: false for non-banked exceptions or for the nonsecure
71
* version of a banked exception, true for the secure version of a banked
39
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
72
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
73
* exceptions (exceptions generated in the course of trying to take
40
* a different exception).
74
* a different exception).
41
*/
75
*/
42
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
76
-void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
43
+/**
77
+void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure);
44
+ * armv7m_nvic_get_pending_irq_info: return highest priority pending
78
/**
45
+ * exception, and whether it targets Secure state
79
* armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
46
+ * @opaque: the NVIC
80
- * @opaque: the NVIC
47
+ * @pirq: set to pending exception number
81
+ * @s: the NVIC
48
+ * @ptargets_secure: set to whether pending exception targets Secure
82
* @irq: the exception number to mark pending
49
+ *
83
* @secure: false for non-banked exceptions or for the nonsecure
50
+ * This function writes the number of the highest priority pending
84
* version of a banked exception, true for the secure version of a banked
51
+ * exception (the one which would be made active by
85
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
52
+ * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
86
* Similar to armv7m_nvic_set_pending(), but specifically for exceptions
53
+ * to true if the current highest priority pending exception should
87
* generated in the course of lazy stacking of FP registers.
54
+ * be taken to Secure state, false for NS.
88
*/
55
+ */
89
-void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
56
+void armv7m_nvic_get_pending_irq_info(void *opaque, int *pirq,
90
+void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure);
57
+ bool *ptargets_secure);
91
/**
92
* armv7m_nvic_get_pending_irq_info: return highest priority pending
93
* exception, and whether it targets Secure state
94
- * @opaque: the NVIC
95
+ * @s: the NVIC
96
* @pirq: set to pending exception number
97
* @ptargets_secure: set to whether pending exception targets Secure
98
*
99
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
100
* to true if the current highest priority pending exception should
101
* be taken to Secure state, false for NS.
102
*/
103
-void armv7m_nvic_get_pending_irq_info(void *opaque, int *pirq,
104
+void armv7m_nvic_get_pending_irq_info(NVICState *s, int *pirq,
105
bool *ptargets_secure);
58
/**
106
/**
59
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
107
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
60
* @opaque: the NVIC
108
- * @opaque: the NVIC
61
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
109
+ * @s: the NVIC
110
*
62
* Move the current highest priority pending exception from the pending
111
* Move the current highest priority pending exception from the pending
63
* state to the active state, and update v7m.exception to indicate that
112
* state to the active state, and update v7m.exception to indicate that
64
* it is the exception currently being handled.
113
* it is the exception currently being handled.
65
- *
114
*/
66
- * Returns: true if exception should be taken to Secure state, false for NS
115
-void armv7m_nvic_acknowledge_irq(void *opaque);
67
*/
116
+void armv7m_nvic_acknowledge_irq(NVICState *s);
68
-bool armv7m_nvic_acknowledge_irq(void *opaque);
69
+void armv7m_nvic_acknowledge_irq(void *opaque);
70
/**
117
/**
71
* armv7m_nvic_complete_irq: complete specified interrupt or exception
118
* armv7m_nvic_complete_irq: complete specified interrupt or exception
72
* @opaque: the NVIC
119
- * @opaque: the NVIC
120
+ * @s: the NVIC
121
* @irq: the exception number to complete
122
* @secure: true if this exception was secure
123
*
124
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
125
* 0 if there is still an irq active after this one was completed
126
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
127
*/
128
-int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
129
+int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure);
130
/**
131
* armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
132
- * @opaque: the NVIC
133
+ * @s: the NVIC
134
* @irq: the exception number to mark pending
135
* @secure: false for non-banked exceptions or for the nonsecure
136
* version of a banked exception, true for the secure version of a banked
137
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
138
* interrupt the current execution priority. This controls whether the
139
* RDY bit for it in the FPCCR is set.
140
*/
141
-bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
142
+bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure);
143
/**
144
* armv7m_nvic_raw_execution_priority: return the raw execution priority
145
- * @opaque: the NVIC
146
+ * @s: the NVIC
147
*
148
* Returns: the raw execution priority as defined by the v8M architecture.
149
* This is the execution priority minus the effects of AIRCR.PRIS,
150
* and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
151
* (v8M ARM ARM I_PKLD.)
152
*/
153
-int armv7m_nvic_raw_execution_priority(void *opaque);
154
+int armv7m_nvic_raw_execution_priority(NVICState *s);
155
/**
156
* armv7m_nvic_neg_prio_requested: return true if the requested execution
157
* priority is negative for the specified security state.
158
- * @opaque: the NVIC
159
+ * @s: the NVIC
160
* @secure: the security state to test
161
* This corresponds to the pseudocode IsReqExecPriNeg().
162
*/
163
#ifndef CONFIG_USER_ONLY
164
-bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure);
165
+bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure);
166
#else
167
-static inline bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
168
+static inline bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
169
{
170
return false;
171
}
73
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
172
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
74
index XXXXXXX..XXXXXXX 100644
173
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/intc/armv7m_nvic.c
174
--- a/hw/intc/armv7m_nvic.c
76
+++ b/hw/intc/armv7m_nvic.c
175
+++ b/hw/intc/armv7m_nvic.c
77
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
176
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
78
}
177
return MIN(running, s->exception_prio);
178
}
179
180
-bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
181
+bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
182
{
183
/* Return true if the requested execution priority is negative
184
* for the specified security state, ie that security state
185
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
186
* mean we don't allow FAULTMASK_NS to actually make the execution
187
* priority negative). Compare pseudocode IsReqExcPriNeg().
188
*/
189
- NVICState *s = opaque;
190
-
191
if (s->cpu->env.v7m.faultmask[secure]) {
192
return true;
193
}
194
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
195
return false;
196
}
197
198
-bool armv7m_nvic_can_take_pending_exception(void *opaque)
199
+bool armv7m_nvic_can_take_pending_exception(NVICState *s)
200
{
201
- NVICState *s = opaque;
202
-
203
return nvic_exec_prio(s) > nvic_pending_prio(s);
204
}
205
206
-int armv7m_nvic_raw_execution_priority(void *opaque)
207
+int armv7m_nvic_raw_execution_priority(NVICState *s)
208
{
209
- NVICState *s = opaque;
210
-
211
return s->exception_prio;
212
}
213
214
@@ -XXX,XX +XXX,XX @@ static void nvic_irq_update(NVICState *s)
215
* if @secure is true and @irq does not specify one of the fixed set
216
* of architecturally banked exceptions.
217
*/
218
-static void armv7m_nvic_clear_pending(void *opaque, int irq, bool secure)
219
+static void armv7m_nvic_clear_pending(NVICState *s, int irq, bool secure)
220
{
221
- NVICState *s = (NVICState *)opaque;
222
VecInfo *vec;
223
224
assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
225
@@ -XXX,XX +XXX,XX @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
226
}
227
}
228
229
-void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
230
+void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure)
231
{
232
- do_armv7m_nvic_set_pending(opaque, irq, secure, false);
233
+ do_armv7m_nvic_set_pending(s, irq, secure, false);
234
}
235
236
-void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
237
+void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure)
238
{
239
- do_armv7m_nvic_set_pending(opaque, irq, secure, true);
240
+ do_armv7m_nvic_set_pending(s, irq, secure, true);
241
}
242
243
-void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
244
+void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure)
245
{
246
/*
247
* Pend an exception during lazy FP stacking. This differs
248
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
249
* whether we should escalate depends on the saved context
250
* in the FPCCR register, not on the current state of the CPU/NVIC.
251
*/
252
- NVICState *s = (NVICState *)opaque;
253
bool banked = exc_is_banked(irq);
254
VecInfo *vec;
255
bool targets_secure;
256
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
257
}
79
258
80
/* Make pending IRQ active. */
259
/* Make pending IRQ active. */
81
-bool armv7m_nvic_acknowledge_irq(void *opaque)
260
-void armv7m_nvic_acknowledge_irq(void *opaque)
82
+void armv7m_nvic_acknowledge_irq(void *opaque)
261
+void armv7m_nvic_acknowledge_irq(NVICState *s)
83
{
262
{
84
NVICState *s = (NVICState *)opaque;
263
- NVICState *s = (NVICState *)opaque;
85
CPUARMState *env = &s->cpu->env;
264
CPUARMState *env = &s->cpu->env;
86
const int pending = s->vectpending;
265
const int pending = s->vectpending;
87
const int running = nvic_exec_prio(s);
266
const int running = nvic_exec_prio(s);
267
@@ -XXX,XX +XXX,XX @@ static bool vectpending_targets_secure(NVICState *s)
268
exc_targets_secure(s, s->vectpending);
269
}
270
271
-void armv7m_nvic_get_pending_irq_info(void *opaque,
272
+void armv7m_nvic_get_pending_irq_info(NVICState *s,
273
int *pirq, bool *ptargets_secure)
274
{
275
- NVICState *s = (NVICState *)opaque;
276
const int pending = s->vectpending;
277
bool targets_secure;
278
279
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_get_pending_irq_info(void *opaque,
280
*pirq = pending;
281
}
282
283
-int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
284
+int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure)
285
{
286
- NVICState *s = (NVICState *)opaque;
287
VecInfo *vec = NULL;
288
int ret = 0;
289
290
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
291
return ret;
292
}
293
294
-bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
295
+bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure)
296
{
297
/*
298
* Return whether an exception is "ready", i.e. it is enabled and is
299
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
300
* for non-banked exceptions secure is always false; for banked exceptions
301
* it indicates which of the exceptions is required.
302
*/
303
- NVICState *s = (NVICState *)opaque;
304
bool banked = exc_is_banked(irq);
88
VecInfo *vec;
305
VecInfo *vec;
89
- bool targets_secure;
306
int running = nvic_exec_prio(s);
90
307
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
91
assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
92
93
if (s->vectpending_is_s_banked) {
94
vec = &s->sec_vectors[pending];
95
- targets_secure = true;
96
} else {
97
vec = &s->vectors[pending];
98
- targets_secure = !exc_is_banked(s->vectpending) &&
99
- exc_targets_secure(s, s->vectpending);
100
}
101
102
assert(vec->enabled);
103
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_acknowledge_irq(void *opaque)
104
105
assert(s->vectpending_prio < running);
106
107
- trace_nvic_acknowledge_irq(pending, s->vectpending_prio, targets_secure);
108
+ trace_nvic_acknowledge_irq(pending, s->vectpending_prio);
109
110
vec->active = 1;
111
vec->pending = 0;
112
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_acknowledge_irq(void *opaque)
113
write_v7m_exception(env, s->vectpending);
114
115
nvic_irq_update(s);
116
+}
117
+
118
+void armv7m_nvic_get_pending_irq_info(void *opaque,
119
+ int *pirq, bool *ptargets_secure)
120
+{
121
+ NVICState *s = (NVICState *)opaque;
122
+ const int pending = s->vectpending;
123
+ bool targets_secure;
124
+
125
+ assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
126
+
127
+ if (s->vectpending_is_s_banked) {
128
+ targets_secure = true;
129
+ } else {
130
+ targets_secure = !exc_is_banked(pending) &&
131
+ exc_targets_secure(s, pending);
132
+ }
133
+
134
+ trace_nvic_get_pending_irq_info(pending, targets_secure);
135
136
- return targets_secure;
137
+ *ptargets_secure = targets_secure;
138
+ *pirq = pending;
139
}
140
141
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
142
diff --git a/target/arm/helper.c b/target/arm/helper.c
143
index XXXXXXX..XXXXXXX 100644
308
index XXXXXXX..XXXXXXX 100644
144
--- a/target/arm/helper.c
309
--- a/target/arm/cpu.c
145
+++ b/target/arm/helper.c
310
+++ b/target/arm/cpu.c
146
@@ -XXX,XX +XXX,XX @@ static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
311
@@ -XXX,XX +XXX,XX @@
147
}
312
#if !defined(CONFIG_USER_ONLY)
148
}
313
#include "hw/loader.h"
149
314
#include "hw/boards.h"
150
-static uint32_t arm_v7m_load_vector(ARMCPU *cpu, bool targets_secure)
315
+#include "hw/intc/armv7m_nvic.h"
151
+static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
316
#endif
152
{
317
#include "sysemu/tcg.h"
153
CPUState *cs = CPU(cpu);
318
#include "sysemu/qtest.h"
154
CPUARMState *env = &cpu->env;
319
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
155
MemTxResult result;
156
- hwaddr vec = env->v7m.vecbase[targets_secure] + env->v7m.exception * 4;
157
+ hwaddr vec = env->v7m.vecbase[targets_secure] + exc * 4;
158
uint32_t addr;
159
160
addr = address_space_ldl(cs->as, vec,
161
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
162
CPUARMState *env = &cpu->env;
163
uint32_t addr;
164
bool targets_secure;
165
+ int exc;
166
167
- targets_secure = armv7m_nvic_acknowledge_irq(env->nvic);
168
+ armv7m_nvic_get_pending_irq_info(env->nvic, &exc, &targets_secure);
169
170
if (arm_feature(env, ARM_FEATURE_V8)) {
171
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
172
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
173
}
174
}
175
176
+ addr = arm_v7m_load_vector(cpu, exc, targets_secure);
177
+
178
+ /* Now we've done everything that might cause a derived exception
179
+ * we can go ahead and activate whichever exception we're going to
180
+ * take (which might now be the derived exception).
181
+ */
182
+ armv7m_nvic_acknowledge_irq(env->nvic);
183
+
184
/* Switch to target security state -- must do this before writing SPSEL */
185
switch_v7m_security_state(env, targets_secure);
186
write_v7m_control_spsel(env, 0);
187
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
188
/* Clear IT bits */
189
env->condexec_bits = 0;
190
env->regs[14] = lr;
191
- addr = arm_v7m_load_vector(cpu, targets_secure);
192
env->regs[15] = addr & 0xfffffffe;
193
env->thumb = addr & 1;
194
}
195
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
196
index XXXXXXX..XXXXXXX 100644
320
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/intc/trace-events
321
--- a/target/arm/m_helper.c
198
+++ b/hw/intc/trace-events
322
+++ b/target/arm/m_helper.c
199
@@ -XXX,XX +XXX,XX @@ nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
323
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
200
nvic_set_pending(int irq, bool secure, bool derived, int en, int prio) "NVIC set pending irq %d secure-bank %d derived %d (enabled: %d priority %d)"
324
* that we will need later in order to do lazy FP reg stacking.
201
nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
325
*/
202
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
326
bool is_secure = env->v7m.secure;
203
-nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)"
327
- void *nvic = env->nvic;
204
+nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (prio %d)"
328
+ NVICState *nvic = env->nvic;
205
+nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d"
329
/*
206
nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)"
330
* Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
207
nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d"
331
* are banked and we want to update the bit in the bank for the
208
nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
209
--
332
--
210
2.16.1
333
2.34.1
211
334
212
335
diff view generated by jsdifflib
1
In order to support derived exceptions (exceptions generated in
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
the course of trying to take an exception), we need to be able
2
3
to handle prioritizing whether to take the original exception
3
While dozens of files include "cpu.h", only 3 files require
4
or the derived exception.
4
these NVIC helper declarations.
5
5
6
We do this by introducing a new function
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
armv7m_nvic_set_pending_derived() which the exception-taking code in
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
helper.c will call when a derived exception occurs. Derived
8
Message-id: 20230206223502.25122-12-philmd@linaro.org
9
exceptions are dealt with mostly like normal pending exceptions, so
10
we share the implementation with the armv7m_nvic_set_pending()
11
function.
12
13
Note that the way we structure this is significantly different
14
from the v8M Arm ARM pseudocode: that does all the prioritization
15
logic in the DerivedLateArrival() function, whereas we choose to
16
let the existing "identify highest priority exception" logic
17
do the prioritization for us. The effect is the same, though.
18
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 1517324542-6607-2-git-send-email-peter.maydell@linaro.org
22
---
10
---
23
target/arm/cpu.h | 13 ++++++++++
11
include/hw/intc/armv7m_nvic.h | 123 ++++++++++++++++++++++++++++++++++
24
hw/intc/armv7m_nvic.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++--
12
target/arm/cpu.h | 123 ----------------------------------
25
hw/intc/trace-events | 2 +-
13
target/arm/cpu.c | 4 +-
26
3 files changed, 80 insertions(+), 3 deletions(-)
14
target/arm/cpu_tcg.c | 3 +
27
15
target/arm/m_helper.c | 3 +
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
5 files changed, 132 insertions(+), 124 deletions(-)
29
index XXXXXXX..XXXXXXX 100644
17
30
--- a/target/arm/cpu.h
18
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
31
+++ b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
32
@@ -XXX,XX +XXX,XX @@ static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
20
--- a/include/hw/intc/armv7m_nvic.h
33
* of architecturally banked exceptions.
21
+++ b/include/hw/intc/armv7m_nvic.h
34
*/
22
@@ -XXX,XX +XXX,XX @@ struct NVICState {
35
void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
23
qemu_irq sysresetreq;
36
+/**
24
};
37
+ * armv7m_nvic_set_pending_derived: mark this derived exception as pending
25
38
+ * @opaque: the NVIC
26
+/* Interface between CPU and Interrupt controller. */
27
+/**
28
+ * armv7m_nvic_set_pending: mark the specified exception as pending
29
+ * @s: the NVIC
39
+ * @irq: the exception number to mark pending
30
+ * @irq: the exception number to mark pending
40
+ * @secure: false for non-banked exceptions or for the nonsecure
31
+ * @secure: false for non-banked exceptions or for the nonsecure
41
+ * version of a banked exception, true for the secure version of a banked
32
+ * version of a banked exception, true for the secure version of a banked
42
+ * exception.
33
+ * exception.
43
+ *
34
+ *
35
+ * Marks the specified exception as pending. Note that we will assert()
36
+ * if @secure is true and @irq does not specify one of the fixed set
37
+ * of architecturally banked exceptions.
38
+ */
39
+void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure);
40
+/**
41
+ * armv7m_nvic_set_pending_derived: mark this derived exception as pending
42
+ * @s: the NVIC
43
+ * @irq: the exception number to mark pending
44
+ * @secure: false for non-banked exceptions or for the nonsecure
45
+ * version of a banked exception, true for the secure version of a banked
46
+ * exception.
47
+ *
44
+ * Similar to armv7m_nvic_set_pending(), but specifically for derived
48
+ * Similar to armv7m_nvic_set_pending(), but specifically for derived
45
+ * exceptions (exceptions generated in the course of trying to take
49
+ * exceptions (exceptions generated in the course of trying to take
46
+ * a different exception).
50
+ * a different exception).
47
+ */
51
+ */
48
+void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
52
+void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure);
49
/**
53
+/**
50
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
54
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
51
* @opaque: the NVIC
55
+ * @s: the NVIC
52
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
56
+ * @irq: the exception number to mark pending
53
index XXXXXXX..XXXXXXX 100644
57
+ * @secure: false for non-banked exceptions or for the nonsecure
54
--- a/hw/intc/armv7m_nvic.c
58
+ * version of a banked exception, true for the secure version of a banked
55
+++ b/hw/intc/armv7m_nvic.c
59
+ * exception.
56
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_clear_pending(void *opaque, int irq, bool secure)
60
+ *
57
}
61
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
58
}
62
+ * generated in the course of lazy stacking of FP registers.
59
63
+ */
60
-void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
64
+void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure);
61
+static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
65
+/**
62
+ bool derived)
66
+ * armv7m_nvic_get_pending_irq_info: return highest priority pending
63
{
67
+ * exception, and whether it targets Secure state
64
+ /* Pend an exception, including possibly escalating it to HardFault.
68
+ * @s: the NVIC
65
+ *
69
+ * @pirq: set to pending exception number
66
+ * This function handles both "normal" pending of interrupts and
70
+ * @ptargets_secure: set to whether pending exception targets Secure
67
+ * exceptions, and also derived exceptions (ones which occur as
71
+ *
68
+ * a result of trying to take some other exception).
72
+ * This function writes the number of the highest priority pending
69
+ *
73
+ * exception (the one which would be made active by
70
+ * If derived == true, the caller guarantees that we are part way through
74
+ * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
71
+ * trying to take an exception (but have not yet called
75
+ * to true if the current highest priority pending exception should
72
+ * armv7m_nvic_acknowledge_irq() to make it active), and so:
76
+ * be taken to Secure state, false for NS.
73
+ * - s->vectpending is the "original exception" we were trying to take
77
+ */
74
+ * - irq is the "derived exception"
78
+void armv7m_nvic_get_pending_irq_info(NVICState *s, int *pirq,
75
+ * - nvic_exec_prio(s) gives the priority before exception entry
79
+ bool *ptargets_secure);
76
+ * Here we handle the prioritization logic which the pseudocode puts
80
+/**
77
+ * in the DerivedLateArrival() function.
81
+ * armv7m_nvic_acknowledge_irq: make highest priority pending exception active
78
+ */
82
+ * @s: the NVIC
83
+ *
84
+ * Move the current highest priority pending exception from the pending
85
+ * state to the active state, and update v7m.exception to indicate that
86
+ * it is the exception currently being handled.
87
+ */
88
+void armv7m_nvic_acknowledge_irq(NVICState *s);
89
+/**
90
+ * armv7m_nvic_complete_irq: complete specified interrupt or exception
91
+ * @s: the NVIC
92
+ * @irq: the exception number to complete
93
+ * @secure: true if this exception was secure
94
+ *
95
+ * Returns: -1 if the irq was not active
96
+ * 1 if completing this irq brought us back to base (no active irqs)
97
+ * 0 if there is still an irq active after this one was completed
98
+ * (Ignoring -1, this is the same as the RETTOBASE value before completion.)
99
+ */
100
+int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure);
101
+/**
102
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
103
+ * @s: the NVIC
104
+ * @irq: the exception number to mark pending
105
+ * @secure: false for non-banked exceptions or for the nonsecure
106
+ * version of a banked exception, true for the secure version of a banked
107
+ * exception.
108
+ *
109
+ * Return whether an exception is "ready", i.e. whether the exception is
110
+ * enabled and is configured at a priority which would allow it to
111
+ * interrupt the current execution priority. This controls whether the
112
+ * RDY bit for it in the FPCCR is set.
113
+ */
114
+bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure);
115
+/**
116
+ * armv7m_nvic_raw_execution_priority: return the raw execution priority
117
+ * @s: the NVIC
118
+ *
119
+ * Returns: the raw execution priority as defined by the v8M architecture.
120
+ * This is the execution priority minus the effects of AIRCR.PRIS,
121
+ * and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
122
+ * (v8M ARM ARM I_PKLD.)
123
+ */
124
+int armv7m_nvic_raw_execution_priority(NVICState *s);
125
+/**
126
+ * armv7m_nvic_neg_prio_requested: return true if the requested execution
127
+ * priority is negative for the specified security state.
128
+ * @s: the NVIC
129
+ * @secure: the security state to test
130
+ * This corresponds to the pseudocode IsReqExecPriNeg().
131
+ */
132
+#ifndef CONFIG_USER_ONLY
133
+bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure);
134
+#else
135
+static inline bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
136
+{
137
+ return false;
138
+}
139
+#endif
140
+#ifndef CONFIG_USER_ONLY
141
+bool armv7m_nvic_can_take_pending_exception(NVICState *s);
142
+#else
143
+static inline bool armv7m_nvic_can_take_pending_exception(NVICState *s)
144
+{
145
+ return true;
146
+}
147
+#endif
79
+
148
+
80
NVICState *s = (NVICState *)opaque;
149
#endif
81
bool banked = exc_is_banked(irq);
150
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
82
VecInfo *vec;
151
index XXXXXXX..XXXXXXX 100644
83
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
152
--- a/target/arm/cpu.h
84
153
+++ b/target/arm/cpu.h
85
vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
154
@@ -XXX,XX +XXX,XX @@ void arm_cpu_list(void);
86
155
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
87
- trace_nvic_set_pending(irq, secure, vec->enabled, vec->prio);
156
uint32_t cur_el, bool secure);
88
+ trace_nvic_set_pending(irq, secure, derived, vec->enabled, vec->prio);
157
89
+
158
-/* Interface between CPU and Interrupt controller. */
90
+ if (derived) {
159
-#ifndef CONFIG_USER_ONLY
91
+ /* Derived exceptions are always synchronous. */
160
-bool armv7m_nvic_can_take_pending_exception(NVICState *s);
92
+ assert(irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV);
161
-#else
93
+
162
-static inline bool armv7m_nvic_can_take_pending_exception(NVICState *s)
94
+ if (irq == ARMV7M_EXCP_DEBUG &&
163
-{
95
+ exc_group_prio(s, vec->prio, secure) >= nvic_exec_prio(s)) {
164
- return true;
96
+ /* DebugMonitorFault, but its priority is lower than the
165
-}
97
+ * preempted exception priority: just ignore it.
166
-#endif
98
+ */
167
-/**
99
+ return;
168
- * armv7m_nvic_set_pending: mark the specified exception as pending
100
+ }
169
- * @s: the NVIC
101
+
170
- * @irq: the exception number to mark pending
102
+ if (irq == ARMV7M_EXCP_HARD && vec->prio >= s->vectpending_prio) {
171
- * @secure: false for non-banked exceptions or for the nonsecure
103
+ /* If this is a terminal exception (one which means we cannot
172
- * version of a banked exception, true for the secure version of a banked
104
+ * take the original exception, like a failure to read its
173
- * exception.
105
+ * vector table entry), then we must take the derived exception.
174
- *
106
+ * If the derived exception can't take priority over the
175
- * Marks the specified exception as pending. Note that we will assert()
107
+ * original exception, then we go into Lockup.
176
- * if @secure is true and @irq does not specify one of the fixed set
108
+ *
177
- * of architecturally banked exceptions.
109
+ * For QEMU, we rely on the fact that a derived exception is
178
- */
110
+ * terminal if and only if it's reported to us as HardFault,
179
-void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure);
111
+ * which saves having to have an extra argument is_terminal
180
-/**
112
+ * that we'd only use in one place.
181
- * armv7m_nvic_set_pending_derived: mark this derived exception as pending
113
+ */
182
- * @s: the NVIC
114
+ cpu_abort(&s->cpu->parent_obj,
183
- * @irq: the exception number to mark pending
115
+ "Lockup: can't take terminal derived exception "
184
- * @secure: false for non-banked exceptions or for the nonsecure
116
+ "(original exception priority %d)\n",
185
- * version of a banked exception, true for the secure version of a banked
117
+ s->vectpending_prio);
186
- * exception.
118
+ }
187
- *
119
+ /* We now continue with the same code as for a normal pending
188
- * Similar to armv7m_nvic_set_pending(), but specifically for derived
120
+ * exception, which will cause us to pend the derived exception.
189
- * exceptions (exceptions generated in the course of trying to take
121
+ * We'll then take either the original or the derived exception
190
- * a different exception).
122
+ * based on which is higher priority by the usual mechanism
191
- */
123
+ * for selecting the highest priority pending interrupt.
192
-void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure);
124
+ */
193
-/**
125
+ }
194
- * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
126
195
- * @s: the NVIC
127
if (irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV) {
196
- * @irq: the exception number to mark pending
128
/* If a synchronous exception is pending then it may be
197
- * @secure: false for non-banked exceptions or for the nonsecure
129
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
198
- * version of a banked exception, true for the secure version of a banked
130
}
199
- * exception.
131
}
200
- *
132
201
- * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
133
+void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
202
- * generated in the course of lazy stacking of FP registers.
134
+{
203
- */
135
+ do_armv7m_nvic_set_pending(opaque, irq, secure, false);
204
-void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure);
136
+}
205
-/**
137
+
206
- * armv7m_nvic_get_pending_irq_info: return highest priority pending
138
+void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
207
- * exception, and whether it targets Secure state
139
+{
208
- * @s: the NVIC
140
+ do_armv7m_nvic_set_pending(opaque, irq, secure, true);
209
- * @pirq: set to pending exception number
141
+}
210
- * @ptargets_secure: set to whether pending exception targets Secure
142
+
211
- *
143
/* Make pending IRQ active. */
212
- * This function writes the number of the highest priority pending
144
bool armv7m_nvic_acknowledge_irq(void *opaque)
213
- * exception (the one which would be made active by
145
{
214
- * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
146
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
215
- * to true if the current highest priority pending exception should
147
index XXXXXXX..XXXXXXX 100644
216
- * be taken to Secure state, false for NS.
148
--- a/hw/intc/trace-events
217
- */
149
+++ b/hw/intc/trace-events
218
-void armv7m_nvic_get_pending_irq_info(NVICState *s, int *pirq,
150
@@ -XXX,XX +XXX,XX @@ nvic_set_prio(int irq, bool secure, uint8_t prio) "NVIC set irq %d secure-bank %
219
- bool *ptargets_secure);
151
nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d"
220
-/**
152
nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d"
221
- * armv7m_nvic_acknowledge_irq: make highest priority pending exception active
153
nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
222
- * @s: the NVIC
154
-nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending irq %d secure-bank %d (enabled: %d priority %d)"
223
- *
155
+nvic_set_pending(int irq, bool secure, bool derived, int en, int prio) "NVIC set pending irq %d secure-bank %d derived %d (enabled: %d priority %d)"
224
- * Move the current highest priority pending exception from the pending
156
nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
225
- * state to the active state, and update v7m.exception to indicate that
157
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
226
- * it is the exception currently being handled.
158
nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)"
227
- */
228
-void armv7m_nvic_acknowledge_irq(NVICState *s);
229
-/**
230
- * armv7m_nvic_complete_irq: complete specified interrupt or exception
231
- * @s: the NVIC
232
- * @irq: the exception number to complete
233
- * @secure: true if this exception was secure
234
- *
235
- * Returns: -1 if the irq was not active
236
- * 1 if completing this irq brought us back to base (no active irqs)
237
- * 0 if there is still an irq active after this one was completed
238
- * (Ignoring -1, this is the same as the RETTOBASE value before completion.)
239
- */
240
-int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure);
241
-/**
242
- * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
243
- * @s: the NVIC
244
- * @irq: the exception number to mark pending
245
- * @secure: false for non-banked exceptions or for the nonsecure
246
- * version of a banked exception, true for the secure version of a banked
247
- * exception.
248
- *
249
- * Return whether an exception is "ready", i.e. whether the exception is
250
- * enabled and is configured at a priority which would allow it to
251
- * interrupt the current execution priority. This controls whether the
252
- * RDY bit for it in the FPCCR is set.
253
- */
254
-bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure);
255
-/**
256
- * armv7m_nvic_raw_execution_priority: return the raw execution priority
257
- * @s: the NVIC
258
- *
259
- * Returns: the raw execution priority as defined by the v8M architecture.
260
- * This is the execution priority minus the effects of AIRCR.PRIS,
261
- * and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
262
- * (v8M ARM ARM I_PKLD.)
263
- */
264
-int armv7m_nvic_raw_execution_priority(NVICState *s);
265
-/**
266
- * armv7m_nvic_neg_prio_requested: return true if the requested execution
267
- * priority is negative for the specified security state.
268
- * @s: the NVIC
269
- * @secure: the security state to test
270
- * This corresponds to the pseudocode IsReqExecPriNeg().
271
- */
272
-#ifndef CONFIG_USER_ONLY
273
-bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure);
274
-#else
275
-static inline bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
276
-{
277
- return false;
278
-}
279
-#endif
280
-
281
/* Interface for defining coprocessor registers.
282
* Registers are defined in tables of arm_cp_reginfo structs
283
* which are passed to define_arm_cp_regs().
284
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
285
index XXXXXXX..XXXXXXX 100644
286
--- a/target/arm/cpu.c
287
+++ b/target/arm/cpu.c
288
@@ -XXX,XX +XXX,XX @@
289
#if !defined(CONFIG_USER_ONLY)
290
#include "hw/loader.h"
291
#include "hw/boards.h"
292
+#ifdef CONFIG_TCG
293
#include "hw/intc/armv7m_nvic.h"
294
-#endif
295
+#endif /* CONFIG_TCG */
296
+#endif /* !CONFIG_USER_ONLY */
297
#include "sysemu/tcg.h"
298
#include "sysemu/qtest.h"
299
#include "sysemu/hw_accel.h"
300
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
301
index XXXXXXX..XXXXXXX 100644
302
--- a/target/arm/cpu_tcg.c
303
+++ b/target/arm/cpu_tcg.c
304
@@ -XXX,XX +XXX,XX @@
305
#include "hw/boards.h"
306
#endif
307
#include "cpregs.h"
308
+#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
309
+#include "hw/intc/armv7m_nvic.h"
310
+#endif
311
312
313
/* Share AArch32 -cpu max features with AArch64. */
314
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
315
index XXXXXXX..XXXXXXX 100644
316
--- a/target/arm/m_helper.c
317
+++ b/target/arm/m_helper.c
318
@@ -XXX,XX +XXX,XX @@
319
#include "exec/cpu_ldst.h"
320
#include "semihosting/common-semi.h"
321
#endif
322
+#if !defined(CONFIG_USER_ONLY)
323
+#include "hw/intc/armv7m_nvic.h"
324
+#endif
325
326
static void v7m_msr_xpsr(CPUARMState *env, uint32_t mask,
327
uint32_t reg, uint32_t val)
159
--
328
--
160
2.16.1
329
2.34.1
161
330
162
331
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Add minimal code needed to allow upstream Linux guest to boot.
3
The two TCG tests for GICv2 and GICv3 are very heavy weight distros
4
4
that take a long time to boot up, especially for an --enable-debug
5
build. The total code coverage they give is:
6
7
Overall coverage rate:
8
lines......: 11.2% (59584 of 530123 lines)
9
functions..: 15.0% (7436 of 49443 functions)
10
branches...: 6.3% (19273 of 303933 branches)
11
12
We already get pretty close to that with the machine_aarch64_virt
13
tests which only does one full boot (~120s vs ~600s) of alpine. We
14
expand the kernel+initrd boot (~8s) to test both GICs and also add an
15
RNG device and a block device to generate a few IRQs and exercise the
16
storage layer. With that we get to a coverage of:
17
18
Overall coverage rate:
19
lines......: 11.0% (58121 of 530123 lines)
20
functions..: 14.9% (7343 of 49443 functions)
21
branches...: 6.0% (18269 of 303933 branches)
22
23
which I feel is close enough given the massive time saving. If we want
24
to target any more sub-systems we can use lighter weight more directed
25
tests.
26
27
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
28
Reviewed-by: Fabiano Rosas <farosas@suse.de>
29
Acked-by: Richard Henderson <richard.henderson@linaro.org>
30
Message-id: 20230203181632.2919715-1-alex.bennee@linaro.org
5
Cc: Peter Maydell <peter.maydell@linaro.org>
31
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Cc: Jason Wang <jasowang@redhat.com>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
33
---
17
hw/intc/Makefile.objs | 2 +-
34
tests/avocado/boot_linux.py | 48 ++++----------------
18
include/hw/intc/imx_gpcv2.h | 22 ++++++++
35
tests/avocado/machine_aarch64_virt.py | 63 ++++++++++++++++++++++++---
19
hw/intc/imx_gpcv2.c | 125 ++++++++++++++++++++++++++++++++++++++++++++
36
2 files changed, 65 insertions(+), 46 deletions(-)
20
3 files changed, 148 insertions(+), 1 deletion(-)
37
21
create mode 100644 include/hw/intc/imx_gpcv2.h
38
diff --git a/tests/avocado/boot_linux.py b/tests/avocado/boot_linux.py
22
create mode 100644 hw/intc/imx_gpcv2.c
23
24
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
25
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/intc/Makefile.objs
40
--- a/tests/avocado/boot_linux.py
27
+++ b/hw/intc/Makefile.objs
41
+++ b/tests/avocado/boot_linux.py
28
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XILINX) += xilinx_intc.o
42
@@ -XXX,XX +XXX,XX @@ def test_pc_q35_kvm(self):
29
common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-pmu-iomod-intc.o
43
self.launch_and_wait(set_up_ssh_connection=False)
30
common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-ipi.o
44
31
common-obj-$(CONFIG_ETRAXFS) += etraxfs_pic.o
45
32
-common-obj-$(CONFIG_IMX) += imx_avic.o
46
-# For Aarch64 we only boot KVM tests in CI as the TCG tests are very
33
+common-obj-$(CONFIG_IMX) += imx_avic.o imx_gpcv2.o
47
-# heavyweight. There are lighter weight distros which we use in the
34
common-obj-$(CONFIG_LM32) += lm32_pic.o
48
-# machine_aarch64_virt.py tests.
35
common-obj-$(CONFIG_REALVIEW) += realview_gic.o
49
+# For Aarch64 we only boot KVM tests in CI as booting the current
36
common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
50
+# Fedora OS in TCG tests is very heavyweight. There are lighter weight
37
diff --git a/include/hw/intc/imx_gpcv2.h b/include/hw/intc/imx_gpcv2.h
51
+# distros which we use in the machine_aarch64_virt.py tests.
38
new file mode 100644
52
class BootLinuxAarch64(LinuxTest):
39
index XXXXXXX..XXXXXXX
53
"""
40
--- /dev/null
54
:avocado: tags=arch:aarch64
41
+++ b/include/hw/intc/imx_gpcv2.h
55
:avocado: tags=machine:virt
56
- :avocado: tags=machine:gic-version=2
57
"""
58
timeout = 720
59
60
- def add_common_args(self):
61
- self.vm.add_args('-bios',
62
- os.path.join(BUILD_DIR, 'pc-bios',
63
- 'edk2-aarch64-code.fd'))
64
- self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
65
- self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom')
66
-
67
- @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
68
- def test_fedora_cloud_tcg_gicv2(self):
69
- """
70
- :avocado: tags=accel:tcg
71
- :avocado: tags=cpu:max
72
- :avocado: tags=device:gicv2
73
- """
74
- self.require_accelerator("tcg")
75
- self.vm.add_args("-accel", "tcg")
76
- self.vm.add_args("-cpu", "max,lpa2=off")
77
- self.vm.add_args("-machine", "virt,gic-version=2")
78
- self.add_common_args()
79
- self.launch_and_wait(set_up_ssh_connection=False)
80
-
81
- @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
82
- def test_fedora_cloud_tcg_gicv3(self):
83
- """
84
- :avocado: tags=accel:tcg
85
- :avocado: tags=cpu:max
86
- :avocado: tags=device:gicv3
87
- """
88
- self.require_accelerator("tcg")
89
- self.vm.add_args("-accel", "tcg")
90
- self.vm.add_args("-cpu", "max,lpa2=off")
91
- self.vm.add_args("-machine", "virt,gic-version=3")
92
- self.add_common_args()
93
- self.launch_and_wait(set_up_ssh_connection=False)
94
-
95
def test_virt_kvm(self):
96
"""
97
:avocado: tags=accel:kvm
98
@@ -XXX,XX +XXX,XX @@ def test_virt_kvm(self):
99
self.require_accelerator("kvm")
100
self.vm.add_args("-accel", "kvm")
101
self.vm.add_args("-machine", "virt,gic-version=host")
102
- self.add_common_args()
103
+ self.vm.add_args('-bios',
104
+ os.path.join(BUILD_DIR, 'pc-bios',
105
+ 'edk2-aarch64-code.fd'))
106
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
107
+ self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom')
108
self.launch_and_wait(set_up_ssh_connection=False)
109
110
111
diff --git a/tests/avocado/machine_aarch64_virt.py b/tests/avocado/machine_aarch64_virt.py
112
index XXXXXXX..XXXXXXX 100644
113
--- a/tests/avocado/machine_aarch64_virt.py
114
+++ b/tests/avocado/machine_aarch64_virt.py
42
@@ -XXX,XX +XXX,XX @@
115
@@ -XXX,XX +XXX,XX @@
43
+#ifndef IMX_GPCV2_H
116
44
+#define IMX_GPCV2_H
117
import time
45
+
118
import os
46
+#include "hw/sysbus.h"
119
+import logging
47
+
120
48
+enum IMXGPCv2Registers {
121
from avocado_qemu import QemuSystemTest
49
+ GPC_NUM = 0xE00 / sizeof(uint32_t),
122
from avocado_qemu import wait_for_console_pattern
50
+};
123
from avocado_qemu import exec_command
51
+
124
from avocado_qemu import BUILD_DIR
52
+typedef struct IMXGPCv2State {
125
+from avocado.utils import process
53
+ /*< private >*/
126
+from avocado.utils.path import find_command
54
+ SysBusDevice parent_obj;
127
55
+
128
class Aarch64VirtMachine(QemuSystemTest):
56
+ /*< public >*/
129
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
57
+ MemoryRegion iomem;
130
@@ -XXX,XX +XXX,XX @@ def test_alpine_virt_tcg_gic_max(self):
58
+ uint32_t regs[GPC_NUM];
131
self.wait_for_console_pattern('Welcome to Alpine Linux 3.16')
59
+} IMXGPCv2State;
132
60
+
133
61
+#define TYPE_IMX_GPCV2 "imx-gpcv2"
134
- def test_aarch64_virt(self):
62
+#define IMX_GPCV2(obj) OBJECT_CHECK(IMXGPCv2State, (obj), TYPE_IMX_GPCV2)
135
+ def common_aarch64_virt(self, machine):
63
+
136
"""
64
+#endif /* IMX_GPCV2_H */
137
- :avocado: tags=arch:aarch64
65
diff --git a/hw/intc/imx_gpcv2.c b/hw/intc/imx_gpcv2.c
138
- :avocado: tags=machine:virt
66
new file mode 100644
139
- :avocado: tags=accel:tcg
67
index XXXXXXX..XXXXXXX
140
- :avocado: tags=cpu:max
68
--- /dev/null
141
+ Common code to launch basic virt machine with kernel+initrd
69
+++ b/hw/intc/imx_gpcv2.c
142
+ and a scratch disk.
70
@@ -XXX,XX +XXX,XX @@
143
"""
71
+/*
144
+ logger = logging.getLogger('aarch64_virt')
72
+ * Copyright (c) 2018, Impinj, Inc.
145
+
73
+ *
146
kernel_url = ('https://fileserver.linaro.org/s/'
74
+ * i.MX7 GPCv2 block emulation code
147
'z6B2ARM7DQT3HWN/download')
75
+ *
148
-
76
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
149
kernel_hash = 'ed11daab50c151dde0e1e9c9cb8b2d9bd3215347'
77
+ *
150
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
78
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
151
79
+ * See the COPYING file in the top-level directory.
152
@@ -XXX,XX +XXX,XX @@ def test_aarch64_virt(self):
80
+ */
153
'console=ttyAMA0')
81
+
154
self.require_accelerator("tcg")
82
+#include "qemu/osdep.h"
155
self.vm.add_args('-cpu', 'max,pauth-impdef=on',
83
+#include "hw/intc/imx_gpcv2.h"
156
+ '-machine', machine,
84
+#include "qemu/log.h"
157
'-accel', 'tcg',
85
+
158
'-kernel', kernel_path,
86
+#define GPC_PU_PGC_SW_PUP_REQ 0x0f8
159
'-append', kernel_command_line)
87
+#define GPC_PU_PGC_SW_PDN_REQ 0x104
160
+
88
+
161
+ # A RNG offers an easy way to generate a few IRQs
89
+#define USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
162
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
90
+#define USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
163
+ self.vm.add_args('-object',
91
+#define USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
164
+ 'rng-random,id=rng0,filename=/dev/urandom')
92
+#define PCIE_PHY_SW_Pxx_REQ BIT(1)
165
+
93
+#define MIPI_PHY_SW_Pxx_REQ BIT(0)
166
+ # Also add a scratch block device
94
+
167
+ logger.info('creating scratch qcow2 image')
95
+
168
+ image_path = os.path.join(self.workdir, 'scratch.qcow2')
96
+static void imx_gpcv2_reset(DeviceState *dev)
169
+ qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
97
+{
170
+ if not os.path.exists(qemu_img):
98
+ IMXGPCv2State *s = IMX_GPCV2(dev);
171
+ qemu_img = find_command('qemu-img', False)
99
+
172
+ if qemu_img is False:
100
+ memset(s->regs, 0, sizeof(s->regs));
173
+ self.cancel('Could not find "qemu-img", which is required to '
101
+}
174
+ 'create the temporary qcow2 image')
102
+
175
+ cmd = '%s create -f qcow2 %s 8M' % (qemu_img, image_path)
103
+static uint64_t imx_gpcv2_read(void *opaque, hwaddr offset,
176
+ process.run(cmd)
104
+ unsigned size)
177
+
105
+{
178
+ # Add the device
106
+ IMXGPCv2State *s = opaque;
179
+ self.vm.add_args('-blockdev',
107
+
180
+ f"driver=qcow2,file.driver=file,file.filename={image_path},node-name=scratch")
108
+ return s->regs[offset / sizeof(uint32_t)];
181
+ self.vm.add_args('-device',
109
+}
182
+ 'virtio-blk-device,drive=scratch')
110
+
183
+
111
+static void imx_gpcv2_write(void *opaque, hwaddr offset,
184
self.vm.launch()
112
+ uint64_t value, unsigned size)
185
self.wait_for_console_pattern('Welcome to Buildroot')
113
+{
186
time.sleep(0.1)
114
+ IMXGPCv2State *s = opaque;
187
exec_command(self, 'root')
115
+ const size_t idx = offset / sizeof(uint32_t);
188
time.sleep(0.1)
116
+
189
+ exec_command(self, 'dd if=/dev/hwrng of=/dev/vda bs=512 count=4')
117
+ s->regs[idx] = value;
190
+ time.sleep(0.1)
118
+
191
+ exec_command(self, 'md5sum /dev/vda')
119
+ /*
192
+ time.sleep(0.1)
120
+ * Real HW will clear those bits once as a way to indicate that
193
+ exec_command(self, 'cat /proc/interrupts')
121
+ * power up request is complete
194
+ time.sleep(0.1)
122
+ */
195
exec_command(self, 'cat /proc/self/maps')
123
+ if (offset == GPC_PU_PGC_SW_PUP_REQ ||
196
time.sleep(0.1)
124
+ offset == GPC_PU_PGC_SW_PDN_REQ) {
197
+
125
+ s->regs[idx] &= ~(USB_HSIC_PHY_SW_Pxx_REQ |
198
+ def test_aarch64_virt_gicv3(self):
126
+ USB_OTG2_PHY_SW_Pxx_REQ |
199
+ """
127
+ USB_OTG1_PHY_SW_Pxx_REQ |
200
+ :avocado: tags=arch:aarch64
128
+ PCIE_PHY_SW_Pxx_REQ |
201
+ :avocado: tags=machine:virt
129
+ MIPI_PHY_SW_Pxx_REQ);
202
+ :avocado: tags=accel:tcg
130
+ }
203
+ :avocado: tags=cpu:max
131
+}
204
+ """
132
+
205
+ self.common_aarch64_virt("virt,gic_version=3")
133
+static const struct MemoryRegionOps imx_gpcv2_ops = {
206
+
134
+ .read = imx_gpcv2_read,
207
+ def test_aarch64_virt_gicv2(self):
135
+ .write = imx_gpcv2_write,
208
+ """
136
+ .endianness = DEVICE_NATIVE_ENDIAN,
209
+ :avocado: tags=arch:aarch64
137
+ .impl = {
210
+ :avocado: tags=machine:virt
138
+ /*
211
+ :avocado: tags=accel:tcg
139
+ * Our device would not work correctly if the guest was doing
212
+ :avocado: tags=cpu:max
140
+ * unaligned access. This might not be a limitation on the real
213
+ """
141
+ * device but in practice there is no reason for a guest to access
214
+ self.common_aarch64_virt("virt,gic-version=2")
142
+ * this device unaligned.
143
+ */
144
+ .min_access_size = 4,
145
+ .max_access_size = 4,
146
+ .unaligned = false,
147
+ },
148
+};
149
+
150
+static void imx_gpcv2_init(Object *obj)
151
+{
152
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
153
+ IMXGPCv2State *s = IMX_GPCV2(obj);
154
+
155
+ memory_region_init_io(&s->iomem,
156
+ obj,
157
+ &imx_gpcv2_ops,
158
+ s,
159
+ TYPE_IMX_GPCV2 ".iomem",
160
+ sizeof(s->regs));
161
+ sysbus_init_mmio(sd, &s->iomem);
162
+}
163
+
164
+static const VMStateDescription vmstate_imx_gpcv2 = {
165
+ .name = TYPE_IMX_GPCV2,
166
+ .version_id = 1,
167
+ .minimum_version_id = 1,
168
+ .fields = (VMStateField[]) {
169
+ VMSTATE_UINT32_ARRAY(regs, IMXGPCv2State, GPC_NUM),
170
+ VMSTATE_END_OF_LIST()
171
+ },
172
+};
173
+
174
+static void imx_gpcv2_class_init(ObjectClass *klass, void *data)
175
+{
176
+ DeviceClass *dc = DEVICE_CLASS(klass);
177
+
178
+ dc->reset = imx_gpcv2_reset;
179
+ dc->vmsd = &vmstate_imx_gpcv2;
180
+ dc->desc = "i.MX GPCv2 Module";
181
+}
182
+
183
+static const TypeInfo imx_gpcv2_info = {
184
+ .name = TYPE_IMX_GPCV2,
185
+ .parent = TYPE_SYS_BUS_DEVICE,
186
+ .instance_size = sizeof(IMXGPCv2State),
187
+ .instance_init = imx_gpcv2_init,
188
+ .class_init = imx_gpcv2_class_init,
189
+};
190
+
191
+static void imx_gpcv2_register_type(void)
192
+{
193
+ type_register_static(&imx_gpcv2_info);
194
+}
195
+type_init(imx_gpcv2_register_type)
196
--
215
--
197
2.16.1
216
2.34.1
198
217
199
218
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Mostafa Saleh <smostafa@google.com>
2
2
3
Save the high parts of the Zregs and all of the Pregs.
3
GBPA register can be used to globally abort all
4
The ZCR_ELx registers are migrated via the CP mechanism.
4
transactions.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
It is described in the SMMU manual in "6.3.14 SMMU_GBPA".
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
ABORT reset value is IMPLEMENTATION DEFINED, it is chosen to
8
be zero(Do not abort incoming transactions).
9
10
Other fields have default values of Use Incoming.
11
12
If UPDATE is not set, the write is ignored. This is the only permitted
13
behavior in SMMUv3.2 and later.(6.3.14.1 Update procedure)
14
15
As this patch adds a new state to the SMMU (GBPA), it is added
16
in a new subsection for forward migration compatibility.
17
GBPA is only migrated if its value is different from the reset value.
18
It does this to be backward migration compatible if SW didn't write
19
the register.
20
21
Signed-off-by: Mostafa Saleh <smostafa@google.com>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Reviewed-by: Eric Auger <eric.auger@redhat.com>
24
Message-id: 20230214094009.2445653-1-smostafa@google.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20180123035349.24538-4-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
27
---
12
target/arm/machine.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
28
hw/arm/smmuv3-internal.h | 7 +++++++
13
1 file changed, 53 insertions(+)
29
include/hw/arm/smmuv3.h | 1 +
30
hw/arm/smmuv3.c | 43 +++++++++++++++++++++++++++++++++++++++-
31
3 files changed, 50 insertions(+), 1 deletion(-)
14
32
15
diff --git a/target/arm/machine.c b/target/arm/machine.c
33
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
16
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/machine.c
35
--- a/hw/arm/smmuv3-internal.h
18
+++ b/target/arm/machine.c
36
+++ b/hw/arm/smmuv3-internal.h
19
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_iwmmxt = {
37
@@ -XXX,XX +XXX,XX @@ REG32(CR0ACK, 0x24)
38
REG32(CR1, 0x28)
39
REG32(CR2, 0x2c)
40
REG32(STATUSR, 0x40)
41
+REG32(GBPA, 0x44)
42
+ FIELD(GBPA, ABORT, 20, 1)
43
+ FIELD(GBPA, UPDATE, 31, 1)
44
+
45
+/* Use incoming. */
46
+#define SMMU_GBPA_RESET_VAL 0x1000
47
+
48
REG32(IRQ_CTRL, 0x50)
49
FIELD(IRQ_CTRL, GERROR_IRQEN, 0, 1)
50
FIELD(IRQ_CTRL, PRI_IRQEN, 1, 1)
51
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/include/hw/arm/smmuv3.h
54
+++ b/include/hw/arm/smmuv3.h
55
@@ -XXX,XX +XXX,XX @@ struct SMMUv3State {
56
uint32_t cr[3];
57
uint32_t cr0ack;
58
uint32_t statusr;
59
+ uint32_t gbpa;
60
uint32_t irq_ctrl;
61
uint32_t gerror;
62
uint32_t gerrorn;
63
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/smmuv3.c
66
+++ b/hw/arm/smmuv3.c
67
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
68
s->gerror = 0;
69
s->gerrorn = 0;
70
s->statusr = 0;
71
+ s->gbpa = SMMU_GBPA_RESET_VAL;
72
}
73
74
static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf,
75
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
76
qemu_mutex_lock(&s->mutex);
77
78
if (!smmu_enabled(s)) {
79
- status = SMMU_TRANS_DISABLE;
80
+ if (FIELD_EX32(s->gbpa, GBPA, ABORT)) {
81
+ status = SMMU_TRANS_ABORT;
82
+ } else {
83
+ status = SMMU_TRANS_DISABLE;
84
+ }
85
goto epilogue;
20
}
86
}
87
88
@@ -XXX,XX +XXX,XX @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
89
case A_GERROR_IRQ_CFG2:
90
s->gerror_irq_cfg2 = data;
91
return MEMTX_OK;
92
+ case A_GBPA:
93
+ /*
94
+ * If UPDATE is not set, the write is ignored. This is the only
95
+ * permitted behavior in SMMUv3.2 and later.
96
+ */
97
+ if (data & R_GBPA_UPDATE_MASK) {
98
+ /* Ignore update bit as write is synchronous. */
99
+ s->gbpa = data & ~R_GBPA_UPDATE_MASK;
100
+ }
101
+ return MEMTX_OK;
102
case A_STRTAB_BASE: /* 64b */
103
s->strtab_base = deposit64(s->strtab_base, 0, 32, data);
104
return MEMTX_OK;
105
@@ -XXX,XX +XXX,XX @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset,
106
case A_STATUSR:
107
*data = s->statusr;
108
return MEMTX_OK;
109
+ case A_GBPA:
110
+ *data = s->gbpa;
111
+ return MEMTX_OK;
112
case A_IRQ_CTRL:
113
case A_IRQ_CTRL_ACK:
114
*data = s->irq_ctrl;
115
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_smmuv3_queue = {
116
},
21
};
117
};
22
118
23
+#ifdef TARGET_AARCH64
119
+static bool smmuv3_gbpa_needed(void *opaque)
24
+/* The expression ARM_MAX_VQ - 2 is 0 for pure AArch32 build,
120
+{
25
+ * and ARMPredicateReg is actively empty. This triggers errors
121
+ SMMUv3State *s = opaque;
26
+ * in the expansion of the VMSTATE macros.
27
+ */
28
+
122
+
29
+static bool sve_needed(void *opaque)
123
+ /* Only migrate GBPA if it has different reset value. */
30
+{
124
+ return s->gbpa != SMMU_GBPA_RESET_VAL;
31
+ ARMCPU *cpu = opaque;
32
+ CPUARMState *env = &cpu->env;
33
+
34
+ return arm_feature(env, ARM_FEATURE_SVE);
35
+}
125
+}
36
+
126
+
37
+/* The first two words of each Zreg is stored in VFP state. */
127
+static const VMStateDescription vmstate_gbpa = {
38
+static const VMStateDescription vmstate_zreg_hi_reg = {
128
+ .name = "smmuv3/gbpa",
39
+ .name = "cpu/sve/zreg_hi",
40
+ .version_id = 1,
129
+ .version_id = 1,
41
+ .minimum_version_id = 1,
130
+ .minimum_version_id = 1,
131
+ .needed = smmuv3_gbpa_needed,
42
+ .fields = (VMStateField[]) {
132
+ .fields = (VMStateField[]) {
43
+ VMSTATE_UINT64_SUB_ARRAY(d, ARMVectorReg, 2, ARM_MAX_VQ - 2),
133
+ VMSTATE_UINT32(gbpa, SMMUv3State),
44
+ VMSTATE_END_OF_LIST()
134
+ VMSTATE_END_OF_LIST()
45
+ }
135
+ }
46
+};
136
+};
47
+
137
+
48
+static const VMStateDescription vmstate_preg_reg = {
138
static const VMStateDescription vmstate_smmuv3 = {
49
+ .name = "cpu/sve/preg",
139
.name = "smmuv3",
50
+ .version_id = 1,
140
.version_id = 1,
51
+ .minimum_version_id = 1,
141
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_smmuv3 = {
52
+ .fields = (VMStateField[]) {
142
53
+ VMSTATE_UINT64_ARRAY(p, ARMPredicateReg, 2 * ARM_MAX_VQ / 8),
143
VMSTATE_END_OF_LIST(),
54
+ VMSTATE_END_OF_LIST()
144
},
145
+ .subsections = (const VMStateDescription * []) {
146
+ &vmstate_gbpa,
147
+ NULL
55
+ }
148
+ }
56
+};
57
+
58
+static const VMStateDescription vmstate_sve = {
59
+ .name = "cpu/sve",
60
+ .version_id = 1,
61
+ .minimum_version_id = 1,
62
+ .needed = sve_needed,
63
+ .fields = (VMStateField[]) {
64
+ VMSTATE_STRUCT_ARRAY(env.vfp.zregs, ARMCPU, 32, 0,
65
+ vmstate_zreg_hi_reg, ARMVectorReg),
66
+ VMSTATE_STRUCT_ARRAY(env.vfp.pregs, ARMCPU, 17, 0,
67
+ vmstate_preg_reg, ARMPredicateReg),
68
+ VMSTATE_END_OF_LIST()
69
+ }
70
+};
71
+#endif /* AARCH64 */
72
+
73
static bool m_needed(void *opaque)
74
{
75
ARMCPU *cpu = opaque;
76
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
77
&vmstate_pmsav7,
78
&vmstate_pmsav8,
79
&vmstate_m_security,
80
+#ifdef TARGET_AARCH64
81
+ &vmstate_sve,
82
+#endif
83
NULL
84
}
85
};
149
};
150
151
static void smmuv3_instance_init(Object *obj)
86
--
152
--
87
2.16.1
153
2.34.1
88
89
diff view generated by jsdifflib
1
The code where we added the TT instruction was accidentally
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
missing a 'break', which meant that after generating the code
3
to execute the TT we would fall through to 'goto illegal_op'
4
and generate code to take an UNDEF insn.
5
2
3
Since commit acc0b8b05a when running the ZynqMP ZCU102 board with
4
a QEMU configured using --without-default-devices, we get:
5
6
$ qemu-system-aarch64 -M xlnx-zcu102
7
qemu-system-aarch64: missing object type 'usb_dwc3'
8
Abort trap: 6
9
10
Fix by adding the missing Kconfig dependency.
11
12
Fixes: acc0b8b05a ("hw/arm/xlnx-zynqmp: Connect ZynqMP's USB controllers")
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-id: 20230216092327.2203-1-philmd@linaro.org
15
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180206103941.13985-1-peter.maydell@linaro.org
9
---
17
---
10
target/arm/translate.c | 1 +
18
hw/arm/Kconfig | 1 +
11
1 file changed, 1 insertion(+)
19
1 file changed, 1 insertion(+)
12
20
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
21
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
23
--- a/hw/arm/Kconfig
16
+++ b/target/arm/translate.c
24
+++ b/hw/arm/Kconfig
17
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
25
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP_ARM
18
tcg_temp_free_i32(addr);
26
select XLNX_CSU_DMA
19
tcg_temp_free_i32(op);
27
select XLNX_ZYNQMP
20
store_reg(s, rd, ttresp);
28
select XLNX_ZDMA
21
+ break;
29
+ select USB_DWC3
22
}
30
23
goto illegal_op;
31
config XLNX_VERSAL
24
}
32
bool
25
--
33
--
26
2.16.1
34
2.34.1
27
35
28
36
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Cornelia Huck <cohuck@redhat.com>
2
2
3
This implements emulation of the new SM3 instructions that have
3
Just use current_accel_name() directly.
4
been added as an optional extension to the ARMv8 Crypto Extensions
5
in ARM v8.2.
6
4
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
5
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
8
Message-id: 20180207111729.15737-4-ard.biesheuvel@linaro.org
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/cpu.h | 1 +
10
hw/arm/virt.c | 6 +++---
13
target/arm/helper.h | 4 ++
11
1 file changed, 3 insertions(+), 3 deletions(-)
14
target/arm/crypto_helper.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++
15
target/arm/translate-a64.c | 88 ++++++++++++++++++++++++++++++++++++++++--
16
4 files changed, 186 insertions(+), 3 deletions(-)
17
12
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
15
--- a/hw/arm/virt.c
21
+++ b/target/arm/cpu.h
16
+++ b/hw/arm/virt.c
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
17
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
23
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
18
if (vms->secure && (kvm_enabled() || hvf_enabled())) {
24
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
19
error_report("mach-virt: %s does not support providing "
25
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
20
"Security extensions (TrustZone) to the guest CPU",
26
+ ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
21
- kvm_enabled() ? "KVM" : "HVF");
27
};
22
+ current_accel_name());
28
23
exit(1);
29
static inline int arm_feature(CPUARMState *env, int feature)
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.h
33
+++ b/target/arm/helper.h
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
35
DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr)
36
DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
37
38
+DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
39
+DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
40
+DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
41
+
42
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
43
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
44
DEF_HELPER_2(dc_zva, void, env, i64)
45
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/crypto_helper.c
48
+++ b/target/arm/crypto_helper.c
49
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha512su1)(void *vd, void *vn, void *vm)
50
rd[0] += s1_512(rn[0]) + rm[0];
51
rd[1] += s1_512(rn[1]) + rm[1];
52
}
53
+
54
+void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
55
+{
56
+ uint64_t *rd = vd;
57
+ uint64_t *rn = vn;
58
+ uint64_t *rm = vm;
59
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
60
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
61
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
62
+ uint32_t t;
63
+
64
+ t = CR_ST_WORD(d, 0) ^ CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 1), 17);
65
+ CR_ST_WORD(d, 0) = t ^ ror32(t, 17) ^ ror32(t, 9);
66
+
67
+ t = CR_ST_WORD(d, 1) ^ CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 2), 17);
68
+ CR_ST_WORD(d, 1) = t ^ ror32(t, 17) ^ ror32(t, 9);
69
+
70
+ t = CR_ST_WORD(d, 2) ^ CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 3), 17);
71
+ CR_ST_WORD(d, 2) = t ^ ror32(t, 17) ^ ror32(t, 9);
72
+
73
+ t = CR_ST_WORD(d, 3) ^ CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 0), 17);
74
+ CR_ST_WORD(d, 3) = t ^ ror32(t, 17) ^ ror32(t, 9);
75
+
76
+ rd[0] = d.l[0];
77
+ rd[1] = d.l[1];
78
+}
79
+
80
+void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
81
+{
82
+ uint64_t *rd = vd;
83
+ uint64_t *rn = vn;
84
+ uint64_t *rm = vm;
85
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
86
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
87
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
88
+ uint32_t t = CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 0), 25);
89
+
90
+ CR_ST_WORD(d, 0) ^= t;
91
+ CR_ST_WORD(d, 1) ^= CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 1), 25);
92
+ CR_ST_WORD(d, 2) ^= CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 2), 25);
93
+ CR_ST_WORD(d, 3) ^= CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(m, 3), 25) ^
94
+ ror32(t, 17) ^ ror32(t, 2) ^ ror32(t, 26);
95
+
96
+ rd[0] = d.l[0];
97
+ rd[1] = d.l[1];
98
+}
99
+
100
+void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
101
+ uint32_t opcode)
102
+{
103
+ uint64_t *rd = vd;
104
+ uint64_t *rn = vn;
105
+ uint64_t *rm = vm;
106
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
107
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
108
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
109
+ uint32_t t;
110
+
111
+ assert(imm2 < 4);
112
+
113
+ if (opcode == 0 || opcode == 2) {
114
+ /* SM3TT1A, SM3TT2A */
115
+ t = par(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
116
+ } else if (opcode == 1) {
117
+ /* SM3TT1B */
118
+ t = maj(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
119
+ } else if (opcode == 3) {
120
+ /* SM3TT2B */
121
+ t = cho(CR_ST_WORD(d, 3), CR_ST_WORD(d, 2), CR_ST_WORD(d, 1));
122
+ } else {
123
+ g_assert_not_reached();
124
+ }
125
+
126
+ t += CR_ST_WORD(d, 0) + CR_ST_WORD(m, imm2);
127
+
128
+ CR_ST_WORD(d, 0) = CR_ST_WORD(d, 1);
129
+
130
+ if (opcode < 2) {
131
+ /* SM3TT1A, SM3TT1B */
132
+ t += CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(d, 3), 20);
133
+
134
+ CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 23);
135
+ } else {
136
+ /* SM3TT2A, SM3TT2B */
137
+ t += CR_ST_WORD(n, 3);
138
+ t ^= rol32(t, 9) ^ rol32(t, 17);
139
+
140
+ CR_ST_WORD(d, 1) = ror32(CR_ST_WORD(d, 2), 13);
141
+ }
142
+
143
+ CR_ST_WORD(d, 2) = CR_ST_WORD(d, 3);
144
+ CR_ST_WORD(d, 3) = t;
145
+
146
+ rd[0] = d.l[0];
147
+ rd[1] = d.l[1];
148
+}
149
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-a64.c
152
+++ b/target/arm/translate-a64.c
153
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
154
break;
155
}
156
} else {
157
- unallocated_encoding(s);
158
- return;
159
+ switch (opcode) {
160
+ case 0: /* SM3PARTW1 */
161
+ feature = ARM_FEATURE_V8_SM3;
162
+ genfn = gen_helper_crypto_sm3partw1;
163
+ break;
164
+ case 1: /* SM3PARTW2 */
165
+ feature = ARM_FEATURE_V8_SM3;
166
+ genfn = gen_helper_crypto_sm3partw2;
167
+ break;
168
+ default:
169
+ unallocated_encoding(s);
170
+ return;
171
+ }
172
}
24
}
173
25
174
if (!arm_dc_feature(s, feature)) {
26
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
175
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
27
error_report("mach-virt: %s does not support providing "
176
case 1: /* BCAX */
28
"Virtualization extensions to the guest CPU",
177
feature = ARM_FEATURE_V8_SHA3;
29
- kvm_enabled() ? "KVM" : "HVF");
178
break;
30
+ current_accel_name());
179
+ case 2: /* SM3SS1 */
31
exit(1);
180
+ feature = ARM_FEATURE_V8_SM3;
181
+ break;
182
default:
183
unallocated_encoding(s);
184
return;
185
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
186
tcg_temp_free_i64(tcg_res[0]);
187
tcg_temp_free_i64(tcg_res[1]);
188
} else {
189
- g_assert_not_reached();
190
+ TCGv_i32 tcg_op1, tcg_op2, tcg_op3, tcg_res, tcg_zero;
191
+
192
+ tcg_op1 = tcg_temp_new_i32();
193
+ tcg_op2 = tcg_temp_new_i32();
194
+ tcg_op3 = tcg_temp_new_i32();
195
+ tcg_res = tcg_temp_new_i32();
196
+ tcg_zero = tcg_const_i32(0);
197
+
198
+ read_vec_element_i32(s, tcg_op1, rn, 3, MO_32);
199
+ read_vec_element_i32(s, tcg_op2, rm, 3, MO_32);
200
+ read_vec_element_i32(s, tcg_op3, ra, 3, MO_32);
201
+
202
+ tcg_gen_rotri_i32(tcg_res, tcg_op1, 20);
203
+ tcg_gen_add_i32(tcg_res, tcg_res, tcg_op2);
204
+ tcg_gen_add_i32(tcg_res, tcg_res, tcg_op3);
205
+ tcg_gen_rotri_i32(tcg_res, tcg_res, 25);
206
+
207
+ write_vec_element_i32(s, tcg_zero, rd, 0, MO_32);
208
+ write_vec_element_i32(s, tcg_zero, rd, 1, MO_32);
209
+ write_vec_element_i32(s, tcg_zero, rd, 2, MO_32);
210
+ write_vec_element_i32(s, tcg_res, rd, 3, MO_32);
211
+
212
+ tcg_temp_free_i32(tcg_op1);
213
+ tcg_temp_free_i32(tcg_op2);
214
+ tcg_temp_free_i32(tcg_op3);
215
+ tcg_temp_free_i32(tcg_res);
216
+ tcg_temp_free_i32(tcg_zero);
217
}
32
}
218
}
33
219
34
if (vms->mte && (kvm_enabled() || hvf_enabled())) {
220
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_xar(DisasContext *s, uint32_t insn)
35
error_report("mach-virt: %s does not support providing "
221
tcg_temp_free_i64(tcg_res[1]);
36
"MTE to the guest CPU",
222
}
37
- kvm_enabled() ? "KVM" : "HVF");
223
38
+ current_accel_name());
224
+/* Crypto three-reg imm2
39
exit(1);
225
+ * 31 21 20 16 15 14 13 12 11 10 9 5 4 0
40
}
226
+ * +-----------------------+------+-----+------+--------+------+------+
227
+ * | 1 1 0 0 1 1 1 0 0 1 0 | Rm | 1 0 | imm2 | opcode | Rn | Rd |
228
+ * +-----------------------+------+-----+------+--------+------+------+
229
+ */
230
+static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn)
231
+{
232
+ int opcode = extract32(insn, 10, 2);
233
+ int imm2 = extract32(insn, 12, 2);
234
+ int rm = extract32(insn, 16, 5);
235
+ int rn = extract32(insn, 5, 5);
236
+ int rd = extract32(insn, 0, 5);
237
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
238
+ TCGv_i32 tcg_imm2, tcg_opcode;
239
+
240
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_SM3)) {
241
+ unallocated_encoding(s);
242
+ return;
243
+ }
244
+
245
+ if (!fp_access_check(s)) {
246
+ return;
247
+ }
248
+
249
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
250
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
251
+ tcg_rm_ptr = vec_full_reg_ptr(s, rm);
252
+ tcg_imm2 = tcg_const_i32(imm2);
253
+ tcg_opcode = tcg_const_i32(opcode);
254
+
255
+ gen_helper_crypto_sm3tt(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr, tcg_imm2,
256
+ tcg_opcode);
257
+
258
+ tcg_temp_free_ptr(tcg_rd_ptr);
259
+ tcg_temp_free_ptr(tcg_rn_ptr);
260
+ tcg_temp_free_ptr(tcg_rm_ptr);
261
+ tcg_temp_free_i32(tcg_imm2);
262
+ tcg_temp_free_i32(tcg_opcode);
263
+}
264
+
265
/* C3.6 Data processing - SIMD, inc Crypto
266
*
267
* As the decode gets a little complex we are using a table based
268
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
269
{ 0xcec08000, 0xfffff000, disas_crypto_two_reg_sha512 },
270
{ 0xce000000, 0xff808000, disas_crypto_four_reg },
271
{ 0xce800000, 0xffe00000, disas_crypto_xar },
272
+ { 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
273
{ 0x00000000, 0x00000000, NULL }
274
};
275
41
276
--
42
--
277
2.16.1
43
2.34.1
278
279
diff view generated by jsdifflib
1
The documentation for the generic loader claims that you can
1
From: Hao Wu <wuhaotsh@google.com>
2
set the PC for a CPU with an option of the form
3
-device loader,cpu-num=0,addr=0x10000004
4
2
5
However if you try this QEMU complains:
3
Havard is no longer working on the Nuvoton systems for a while
6
cpu_num must be specified when setting a program counter
4
and won't be able to do any work on it in the future. So I'll
5
take over maintaining the Nuvoton system from him.
7
6
8
This is because we were testing against 0 rather than CPU_NONE.
7
Signed-off-by: Hao Wu <wuhaotsh@google.com>
9
8
Acked-by: Havard Skinnemoen <hskinnemoen@google.com>
9
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
10
Message-id: 20230208235433.3989937-2-wuhaotsh@google.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180205150426.20542-1-peter.maydell@linaro.org
14
---
12
---
15
hw/core/generic-loader.c | 2 +-
13
MAINTAINERS | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
17
15
18
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
16
diff --git a/MAINTAINERS b/MAINTAINERS
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/core/generic-loader.c
18
--- a/MAINTAINERS
21
+++ b/hw/core/generic-loader.c
19
+++ b/MAINTAINERS
22
@@ -XXX,XX +XXX,XX @@ static void generic_loader_realize(DeviceState *dev, Error **errp)
20
@@ -XXX,XX +XXX,XX @@ F: include/hw/net/mv88w8618_eth.h
23
error_setg(errp, "data can not be specified when setting a "
21
F: docs/system/arm/musicpal.rst
24
"program counter");
22
25
return;
23
Nuvoton NPCM7xx
26
- } else if (!s->cpu_num) {
24
-M: Havard Skinnemoen <hskinnemoen@google.com>
27
+ } else if (s->cpu_num == CPU_NONE) {
25
M: Tyrone Ting <kfting@nuvoton.com>
28
error_setg(errp, "cpu_num must be specified when setting a "
26
+M: Hao Wu <wuhaotsh@google.com>
29
"program counter");
27
L: qemu-arm@nongnu.org
30
return;
28
S: Supported
29
F: hw/*/npcm7xx*
31
--
30
--
32
2.16.1
31
2.34.1
33
34
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
Add minimal code needed to allow upstream Linux guest to boot.
3
Nuvoton's PSPI is a general purpose SPI module which enables
4
connections to SPI-based peripheral devices.
4
5
5
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
6
Cc: Jason Wang <jasowang@redhat.com>
7
Reviewed-by: Chris Rauer <crauer@google.com>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Message-id: 20230208235433.3989937-3-wuhaotsh@google.com
9
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
11
---
18
hw/misc/Makefile.objs | 1 +
12
MAINTAINERS | 6 +-
19
include/hw/misc/imx7_gpr.h | 28 ++++++++++
13
include/hw/ssi/npcm_pspi.h | 53 +++++++++
20
hw/misc/imx7_gpr.c | 124 +++++++++++++++++++++++++++++++++++++++++++++
14
hw/ssi/npcm_pspi.c | 221 +++++++++++++++++++++++++++++++++++++
21
hw/misc/trace-events | 4 ++
15
hw/ssi/meson.build | 2 +-
22
4 files changed, 157 insertions(+)
16
hw/ssi/trace-events | 5 +
23
create mode 100644 include/hw/misc/imx7_gpr.h
17
5 files changed, 283 insertions(+), 4 deletions(-)
24
create mode 100644 hw/misc/imx7_gpr.c
18
create mode 100644 include/hw/ssi/npcm_pspi.h
19
create mode 100644 hw/ssi/npcm_pspi.c
25
20
26
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
21
diff --git a/MAINTAINERS b/MAINTAINERS
27
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/misc/Makefile.objs
23
--- a/MAINTAINERS
29
+++ b/hw/misc/Makefile.objs
24
+++ b/MAINTAINERS
30
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx6_src.o
25
@@ -XXX,XX +XXX,XX @@ M: Tyrone Ting <kfting@nuvoton.com>
31
obj-$(CONFIG_IMX) += imx7_ccm.o
26
M: Hao Wu <wuhaotsh@google.com>
32
obj-$(CONFIG_IMX) += imx2_wdt.o
27
L: qemu-arm@nongnu.org
33
obj-$(CONFIG_IMX) += imx7_snvs.o
28
S: Supported
34
+obj-$(CONFIG_IMX) += imx7_gpr.o
29
-F: hw/*/npcm7xx*
35
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
30
-F: include/hw/*/npcm7xx*
36
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
31
-F: tests/qtest/npcm7xx*
37
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
32
+F: hw/*/npcm*
38
diff --git a/include/hw/misc/imx7_gpr.h b/include/hw/misc/imx7_gpr.h
33
+F: include/hw/*/npcm*
34
+F: tests/qtest/npcm*
35
F: pc-bios/npcm7xx_bootrom.bin
36
F: roms/vbootrom
37
F: docs/system/arm/nuvoton.rst
38
diff --git a/include/hw/ssi/npcm_pspi.h b/include/hw/ssi/npcm_pspi.h
39
new file mode 100644
39
new file mode 100644
40
index XXXXXXX..XXXXXXX
40
index XXXXXXX..XXXXXXX
41
--- /dev/null
41
--- /dev/null
42
+++ b/include/hw/misc/imx7_gpr.h
42
+++ b/include/hw/ssi/npcm_pspi.h
43
@@ -XXX,XX +XXX,XX @@
43
@@ -XXX,XX +XXX,XX @@
44
+/*
44
+/*
45
+ * Copyright (c) 2017, Impinj, Inc.
45
+ * Nuvoton Peripheral SPI Module
46
+ *
46
+ *
47
+ * i.MX7 GPR IP block emulation code
47
+ * Copyright 2023 Google LLC
48
+ *
48
+ *
49
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
49
+ * This program is free software; you can redistribute it and/or modify it
50
+ *
50
+ * under the terms of the GNU General Public License as published by the
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
51
+ * Free Software Foundation; either version 2 of the License, or
52
+ * See the COPYING file in the top-level directory.
52
+ * (at your option) any later version.
53
+ *
54
+ * This program is distributed in the hope that it will be useful, but WITHOUT
55
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
56
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
57
+ * for more details.
53
+ */
58
+ */
54
+
59
+#ifndef NPCM_PSPI_H
55
+#ifndef IMX7_GPR_H
60
+#define NPCM_PSPI_H
56
+#define IMX7_GPR_H
61
+
57
+
62
+#include "hw/ssi/ssi.h"
58
+#include "qemu/bitops.h"
59
+#include "hw/sysbus.h"
63
+#include "hw/sysbus.h"
60
+
64
+
61
+#define TYPE_IMX7_GPR "imx7.gpr"
65
+/*
62
+#define IMX7_GPR(obj) OBJECT_CHECK(IMX7GPRState, (obj), TYPE_IMX7_GPR)
66
+ * Number of registers in our device state structure. Don't change this without
63
+
67
+ * incrementing the version_id in the vmstate.
64
+typedef struct IMX7GPRState {
68
+ */
65
+ /* <private> */
69
+#define NPCM_PSPI_NR_REGS 3
66
+ SysBusDevice parent_obj;
70
+
71
+/**
72
+ * NPCMPSPIState - Device state for one Flash Interface Unit.
73
+ * @parent: System bus device.
74
+ * @mmio: Memory region for register access.
75
+ * @spi: The SPI bus mastered by this controller.
76
+ * @regs: Register contents.
77
+ * @irq: The interrupt request queue for this module.
78
+ *
79
+ * Each PSPI has a shared bank of registers, and controls up to four chip
80
+ * selects. Each chip select has a dedicated memory region which may be used to
81
+ * read and write the flash connected to that chip select as if it were memory.
82
+ */
83
+typedef struct NPCMPSPIState {
84
+ SysBusDevice parent;
67
+
85
+
68
+ MemoryRegion mmio;
86
+ MemoryRegion mmio;
69
+} IMX7GPRState;
87
+
70
+
88
+ SSIBus *spi;
71
+#endif /* IMX7_GPR_H */
89
+ uint16_t regs[NPCM_PSPI_NR_REGS];
72
diff --git a/hw/misc/imx7_gpr.c b/hw/misc/imx7_gpr.c
90
+ qemu_irq irq;
91
+} NPCMPSPIState;
92
+
93
+#define TYPE_NPCM_PSPI "npcm-pspi"
94
+OBJECT_DECLARE_SIMPLE_TYPE(NPCMPSPIState, NPCM_PSPI)
95
+
96
+#endif /* NPCM_PSPI_H */
97
diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c
73
new file mode 100644
98
new file mode 100644
74
index XXXXXXX..XXXXXXX
99
index XXXXXXX..XXXXXXX
75
--- /dev/null
100
--- /dev/null
76
+++ b/hw/misc/imx7_gpr.c
101
+++ b/hw/ssi/npcm_pspi.c
77
@@ -XXX,XX +XXX,XX @@
102
@@ -XXX,XX +XXX,XX @@
78
+/*
103
+/*
79
+ * Copyright (c) 2018, Impinj, Inc.
104
+ * Nuvoton NPCM Peripheral SPI Module (PSPI)
80
+ *
105
+ *
81
+ * i.MX7 GPR IP block emulation code
106
+ * Copyright 2023 Google LLC
82
+ *
107
+ *
83
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
108
+ * This program is free software; you can redistribute it and/or modify it
84
+ *
109
+ * under the terms of the GNU General Public License as published by the
85
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
110
+ * Free Software Foundation; either version 2 of the License, or
86
+ * See the COPYING file in the top-level directory.
111
+ * (at your option) any later version.
87
+ *
112
+ *
88
+ * Bare minimum emulation code needed to support being able to shut
113
+ * This program is distributed in the hope that it will be useful, but WITHOUT
89
+ * down linux guest gracefully.
114
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
115
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
116
+ * for more details.
90
+ */
117
+ */
91
+
118
+
92
+#include "qemu/osdep.h"
119
+#include "qemu/osdep.h"
93
+#include "hw/misc/imx7_gpr.h"
120
+
121
+#include "hw/irq.h"
122
+#include "hw/registerfields.h"
123
+#include "hw/ssi/npcm_pspi.h"
124
+#include "migration/vmstate.h"
125
+#include "qapi/error.h"
126
+#include "qemu/error-report.h"
94
+#include "qemu/log.h"
127
+#include "qemu/log.h"
95
+#include "sysemu/sysemu.h"
128
+#include "qemu/module.h"
129
+#include "qemu/units.h"
96
+
130
+
97
+#include "trace.h"
131
+#include "trace.h"
98
+
132
+
99
+enum IMX7GPRRegisters {
133
+REG16(PSPI_DATA, 0x0)
100
+ IOMUXC_GPR0 = 0x00,
134
+REG16(PSPI_CTL1, 0x2)
101
+ IOMUXC_GPR1 = 0x04,
135
+ FIELD(PSPI_CTL1, SPIEN, 0, 1)
102
+ IOMUXC_GPR2 = 0x08,
136
+ FIELD(PSPI_CTL1, MOD, 2, 1)
103
+ IOMUXC_GPR3 = 0x0c,
137
+ FIELD(PSPI_CTL1, EIR, 5, 1)
104
+ IOMUXC_GPR4 = 0x10,
138
+ FIELD(PSPI_CTL1, EIW, 6, 1)
105
+ IOMUXC_GPR5 = 0x14,
139
+ FIELD(PSPI_CTL1, SCM, 7, 1)
106
+ IOMUXC_GPR6 = 0x18,
140
+ FIELD(PSPI_CTL1, SCIDL, 8, 1)
107
+ IOMUXC_GPR7 = 0x1c,
141
+ FIELD(PSPI_CTL1, SCDV, 9, 7)
108
+ IOMUXC_GPR8 = 0x20,
142
+REG16(PSPI_STAT, 0x4)
109
+ IOMUXC_GPR9 = 0x24,
143
+ FIELD(PSPI_STAT, BSY, 0, 1)
110
+ IOMUXC_GPR10 = 0x28,
144
+ FIELD(PSPI_STAT, RBF, 1, 1)
111
+ IOMUXC_GPR11 = 0x2c,
145
+
112
+ IOMUXC_GPR12 = 0x30,
146
+static void npcm_pspi_update_irq(NPCMPSPIState *s)
113
+ IOMUXC_GPR13 = 0x34,
147
+{
114
+ IOMUXC_GPR14 = 0x38,
148
+ int level = 0;
115
+ IOMUXC_GPR15 = 0x3c,
149
+
116
+ IOMUXC_GPR16 = 0x40,
150
+ /* Only fire IRQ when the module is enabled. */
117
+ IOMUXC_GPR17 = 0x44,
151
+ if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, SPIEN)) {
118
+ IOMUXC_GPR18 = 0x48,
152
+ /* Update interrupt as BSY is cleared. */
119
+ IOMUXC_GPR19 = 0x4c,
153
+ if ((!FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, BSY)) &&
120
+ IOMUXC_GPR20 = 0x50,
154
+ FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIW)) {
121
+ IOMUXC_GPR21 = 0x54,
155
+ level = 1;
122
+ IOMUXC_GPR22 = 0x58,
156
+ }
123
+};
157
+
124
+
158
+ /* Update interrupt as RBF is set. */
125
+#define IMX7D_GPR1_IRQ_MASK BIT(12)
159
+ if (FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, RBF) &&
126
+#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK BIT(13)
160
+ FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIR)) {
127
+#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK BIT(14)
161
+ level = 1;
128
+#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK (0x3 << 13)
162
+ }
129
+#define IMX7D_GPR1_ENET1_CLK_DIR_MASK BIT(17)
130
+#define IMX7D_GPR1_ENET2_CLK_DIR_MASK BIT(18)
131
+#define IMX7D_GPR1_ENET_CLK_DIR_MASK (0x3 << 17)
132
+
133
+#define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI BIT(4)
134
+#define IMX7D_GPR12_PCIE_PHY_REFCLK_SEL BIT(5)
135
+#define IMX7D_GPR22_PCIE_PHY_PLL_LOCKED BIT(31)
136
+
137
+
138
+static uint64_t imx7_gpr_read(void *opaque, hwaddr offset, unsigned size)
139
+{
140
+ trace_imx7_gpr_read(offset);
141
+
142
+ if (offset == IOMUXC_GPR22) {
143
+ return IMX7D_GPR22_PCIE_PHY_PLL_LOCKED;
144
+ }
163
+ }
145
+
164
+ qemu_set_irq(s->irq, level);
146
+ return 0;
165
+}
147
+}
166
+
148
+
167
+static uint16_t npcm_pspi_read_data(NPCMPSPIState *s)
149
+static void imx7_gpr_write(void *opaque, hwaddr offset,
168
+{
150
+ uint64_t v, unsigned size)
169
+ uint16_t value = s->regs[R_PSPI_DATA];
151
+{
170
+
152
+ trace_imx7_gpr_write(offset, v);
171
+ /* Clear stat bits as the value are read out. */
153
+}
172
+ s->regs[R_PSPI_STAT] = 0;
154
+
173
+
155
+static const struct MemoryRegionOps imx7_gpr_ops = {
174
+ return value;
156
+ .read = imx7_gpr_read,
175
+}
157
+ .write = imx7_gpr_write,
176
+
158
+ .endianness = DEVICE_NATIVE_ENDIAN,
177
+static void npcm_pspi_write_data(NPCMPSPIState *s, uint16_t data)
178
+{
179
+ uint16_t value = 0;
180
+
181
+ if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, MOD)) {
182
+ value = ssi_transfer(s->spi, extract16(data, 8, 8)) << 8;
183
+ }
184
+ value |= ssi_transfer(s->spi, extract16(data, 0, 8));
185
+ s->regs[R_PSPI_DATA] = value;
186
+
187
+ /* Mark data as available */
188
+ s->regs[R_PSPI_STAT] = R_PSPI_STAT_BSY_MASK | R_PSPI_STAT_RBF_MASK;
189
+}
190
+
191
+/* Control register read handler. */
192
+static uint64_t npcm_pspi_ctrl_read(void *opaque, hwaddr addr,
193
+ unsigned int size)
194
+{
195
+ NPCMPSPIState *s = opaque;
196
+ uint16_t value;
197
+
198
+ switch (addr) {
199
+ case A_PSPI_DATA:
200
+ value = npcm_pspi_read_data(s);
201
+ break;
202
+
203
+ case A_PSPI_CTL1:
204
+ value = s->regs[R_PSPI_CTL1];
205
+ break;
206
+
207
+ case A_PSPI_STAT:
208
+ value = s->regs[R_PSPI_STAT];
209
+ break;
210
+
211
+ default:
212
+ qemu_log_mask(LOG_GUEST_ERROR,
213
+ "%s: write to invalid offset 0x%" PRIx64 "\n",
214
+ DEVICE(s)->canonical_path, addr);
215
+ return 0;
216
+ }
217
+ trace_npcm_pspi_ctrl_read(DEVICE(s)->canonical_path, addr, value);
218
+ npcm_pspi_update_irq(s);
219
+
220
+ return value;
221
+}
222
+
223
+/* Control register write handler. */
224
+static void npcm_pspi_ctrl_write(void *opaque, hwaddr addr, uint64_t v,
225
+ unsigned int size)
226
+{
227
+ NPCMPSPIState *s = opaque;
228
+ uint16_t value = v;
229
+
230
+ trace_npcm_pspi_ctrl_write(DEVICE(s)->canonical_path, addr, value);
231
+
232
+ switch (addr) {
233
+ case A_PSPI_DATA:
234
+ npcm_pspi_write_data(s, value);
235
+ break;
236
+
237
+ case A_PSPI_CTL1:
238
+ s->regs[R_PSPI_CTL1] = value;
239
+ break;
240
+
241
+ case A_PSPI_STAT:
242
+ qemu_log_mask(LOG_GUEST_ERROR,
243
+ "%s: write to read-only register PSPI_STAT: 0x%08"
244
+ PRIx64 "\n", DEVICE(s)->canonical_path, v);
245
+ break;
246
+
247
+ default:
248
+ qemu_log_mask(LOG_GUEST_ERROR,
249
+ "%s: write to invalid offset 0x%" PRIx64 "\n",
250
+ DEVICE(s)->canonical_path, addr);
251
+ return;
252
+ }
253
+ npcm_pspi_update_irq(s);
254
+}
255
+
256
+static const MemoryRegionOps npcm_pspi_ctrl_ops = {
257
+ .read = npcm_pspi_ctrl_read,
258
+ .write = npcm_pspi_ctrl_write,
259
+ .endianness = DEVICE_LITTLE_ENDIAN,
260
+ .valid = {
261
+ .min_access_size = 1,
262
+ .max_access_size = 2,
263
+ .unaligned = false,
264
+ },
159
+ .impl = {
265
+ .impl = {
160
+ /*
266
+ .min_access_size = 2,
161
+ * Our device would not work correctly if the guest was doing
267
+ .max_access_size = 2,
162
+ * unaligned access. This might not be a limitation on the
163
+ * real device but in practice there is no reason for a guest
164
+ * to access this device unaligned.
165
+ */
166
+ .min_access_size = 4,
167
+ .max_access_size = 4,
168
+ .unaligned = false,
268
+ .unaligned = false,
169
+ },
269
+ },
170
+};
270
+};
171
+
271
+
172
+static void imx7_gpr_init(Object *obj)
272
+static void npcm_pspi_enter_reset(Object *obj, ResetType type)
173
+{
273
+{
174
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
274
+ NPCMPSPIState *s = NPCM_PSPI(obj);
175
+ IMX7GPRState *s = IMX7_GPR(obj);
275
+
176
+
276
+ trace_npcm_pspi_enter_reset(DEVICE(obj)->canonical_path, type);
177
+ memory_region_init_io(&s->mmio, obj, &imx7_gpr_ops, s,
277
+ memset(s->regs, 0, sizeof(s->regs));
178
+ TYPE_IMX7_GPR, 64 * 1024);
278
+}
179
+ sysbus_init_mmio(sd, &s->mmio);
279
+
180
+}
280
+static void npcm_pspi_realize(DeviceState *dev, Error **errp)
181
+
281
+{
182
+static void imx7_gpr_class_init(ObjectClass *klass, void *data)
282
+ NPCMPSPIState *s = NPCM_PSPI(dev);
183
+{
283
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
284
+ Object *obj = OBJECT(dev);
285
+
286
+ s->spi = ssi_create_bus(dev, "pspi");
287
+ memory_region_init_io(&s->mmio, obj, &npcm_pspi_ctrl_ops, s,
288
+ "mmio", 4 * KiB);
289
+ sysbus_init_mmio(sbd, &s->mmio);
290
+ sysbus_init_irq(sbd, &s->irq);
291
+}
292
+
293
+static const VMStateDescription vmstate_npcm_pspi = {
294
+ .name = "npcm-pspi",
295
+ .version_id = 0,
296
+ .minimum_version_id = 0,
297
+ .fields = (VMStateField[]) {
298
+ VMSTATE_UINT16_ARRAY(regs, NPCMPSPIState, NPCM_PSPI_NR_REGS),
299
+ VMSTATE_END_OF_LIST(),
300
+ },
301
+};
302
+
303
+
304
+static void npcm_pspi_class_init(ObjectClass *klass, void *data)
305
+{
306
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
184
+ DeviceClass *dc = DEVICE_CLASS(klass);
307
+ DeviceClass *dc = DEVICE_CLASS(klass);
185
+
308
+
186
+ dc->desc = "i.MX7 General Purpose Registers Module";
309
+ dc->desc = "NPCM Peripheral SPI Module";
187
+}
310
+ dc->realize = npcm_pspi_realize;
188
+
311
+ dc->vmsd = &vmstate_npcm_pspi;
189
+static const TypeInfo imx7_gpr_info = {
312
+ rc->phases.enter = npcm_pspi_enter_reset;
190
+ .name = TYPE_IMX7_GPR,
313
+}
191
+ .parent = TYPE_SYS_BUS_DEVICE,
314
+
192
+ .instance_size = sizeof(IMX7GPRState),
315
+static const TypeInfo npcm_pspi_types[] = {
193
+ .instance_init = imx7_gpr_init,
316
+ {
194
+ .class_init = imx7_gpr_class_init,
317
+ .name = TYPE_NPCM_PSPI,
318
+ .parent = TYPE_SYS_BUS_DEVICE,
319
+ .instance_size = sizeof(NPCMPSPIState),
320
+ .class_init = npcm_pspi_class_init,
321
+ },
195
+};
322
+};
196
+
323
+DEFINE_TYPES(npcm_pspi_types);
197
+static void imx7_gpr_register_type(void)
324
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
198
+{
199
+ type_register_static(&imx7_gpr_info);
200
+}
201
+type_init(imx7_gpr_register_type)
202
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
203
index XXXXXXX..XXXXXXX 100644
325
index XXXXXXX..XXXXXXX 100644
204
--- a/hw/misc/trace-events
326
--- a/hw/ssi/meson.build
205
+++ b/hw/misc/trace-events
327
+++ b/hw/ssi/meson.build
206
@@ -XXX,XX +XXX,XX @@ mps2_scc_cfg_read(unsigned function, unsigned device, uint32_t value) "MPS2 SCC
328
@@ -XXX,XX +XXX,XX @@
207
msf2_sysreg_write(uint64_t offset, uint32_t val, uint32_t prev) "msf2-sysreg write: addr 0x%08" HWADDR_PRIx " data 0x%" PRIx32 " prev 0x%" PRIx32
329
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_smc.c'))
208
msf2_sysreg_read(uint64_t offset, uint32_t val) "msf2-sysreg read: addr 0x%08" HWADDR_PRIx " data 0x%08" PRIx32
330
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-spi.c'))
209
msf2_sysreg_write_pll_status(void) "Invalid write to read only PLL status register"
331
-softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c'))
210
+
332
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c', 'npcm_pspi.c'))
211
+#hw/misc/imx7_gpr.c
333
softmmu_ss.add(when: 'CONFIG_PL022', if_true: files('pl022.c'))
212
+imx7_gpr_read(uint64_t offset) "addr 0x%08" HWADDR_PRIx
334
softmmu_ss.add(when: 'CONFIG_SIFIVE_SPI', if_true: files('sifive_spi.c'))
213
+imx7_gpr_write(uint64_t offset, uint64_t value) "addr 0x%08" HWADDR_PRIx "value 0x%08" HWADDR_PRIx
335
softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
336
diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events
337
index XXXXXXX..XXXXXXX 100644
338
--- a/hw/ssi/trace-events
339
+++ b/hw/ssi/trace-events
340
@@ -XXX,XX +XXX,XX @@ npcm7xx_fiu_ctrl_write(const char *id, uint64_t addr, uint32_t data) "%s offset:
341
npcm7xx_fiu_flash_read(const char *id, int cs, uint64_t addr, unsigned int size, uint64_t value) "%s[%d] offset: 0x%08" PRIx64 " size: %u value: 0x%" PRIx64
342
npcm7xx_fiu_flash_write(const char *id, unsigned cs, uint64_t addr, unsigned int size, uint64_t value) "%s[%d] offset: 0x%08" PRIx64 " size: %u value: 0x%" PRIx64
343
344
+# npcm_pspi.c
345
+npcm_pspi_enter_reset(const char *id, int reset_type) "%s reset type: %d"
346
+npcm_pspi_ctrl_read(const char *id, uint64_t addr, uint16_t data) "%s offset: 0x%03" PRIx64 " value: 0x%04" PRIx16
347
+npcm_pspi_ctrl_write(const char *id, uint64_t addr, uint16_t data) "%s offset: 0x%03" PRIx64 " value: 0x%04" PRIx16
348
+
349
# ibex_spi_host.c
350
351
ibex_spi_host_reset(const char *msg) "%s"
214
--
352
--
215
2.16.1
353
2.34.1
216
217
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
This implements emulation of the new SM4 instructions that have
3
Signed-off-by: Hao Wu <wuhaotsh@google.com>
4
been added as an optional extension to the ARMv8 Crypto Extensions
4
Reviewed-by: Titus Rwantare <titusr@google.com>
5
in ARM v8.2.
5
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
6
6
Message-id: 20230208235433.3989937-4-wuhaotsh@google.com
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
8
Message-id: 20180207111729.15737-5-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/cpu.h | 1 +
9
docs/system/arm/nuvoton.rst | 2 +-
13
target/arm/helper.h | 3 ++
10
include/hw/arm/npcm7xx.h | 2 ++
14
target/arm/crypto_helper.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++
11
hw/arm/npcm7xx.c | 25 +++++++++++++++++++++++--
15
target/arm/translate-a64.c | 8 ++++
12
3 files changed, 26 insertions(+), 3 deletions(-)
16
4 files changed, 103 insertions(+)
17
13
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
16
--- a/docs/system/arm/nuvoton.rst
21
+++ b/target/arm/cpu.h
17
+++ b/docs/system/arm/nuvoton.rst
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
18
@@ -XXX,XX +XXX,XX @@ Supported devices
23
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
19
* SMBus controller (SMBF)
24
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
20
* Ethernet controller (EMC)
25
ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
21
* Tachometer
26
+ ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
22
+ * Peripheral SPI controller (PSPI)
23
24
Missing devices
25
---------------
26
@@ -XXX,XX +XXX,XX @@ Missing devices
27
28
* Ethernet controller (GMAC)
29
* USB device (USBD)
30
- * Peripheral SPI controller (PSPI)
31
* SD/MMC host
32
* PECI interface
33
* PCI and PCIe root complex and bridges
34
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/npcm7xx.h
37
+++ b/include/hw/arm/npcm7xx.h
38
@@ -XXX,XX +XXX,XX @@
39
#include "hw/nvram/npcm7xx_otp.h"
40
#include "hw/timer/npcm7xx_timer.h"
41
#include "hw/ssi/npcm7xx_fiu.h"
42
+#include "hw/ssi/npcm_pspi.h"
43
#include "hw/usb/hcd-ehci.h"
44
#include "hw/usb/hcd-ohci.h"
45
#include "target/arm/cpu.h"
46
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxState {
47
NPCM7xxFIUState fiu[2];
48
NPCM7xxEMCState emc[2];
49
NPCM7xxSDHCIState mmc;
50
+ NPCMPSPIState pspi[2];
27
};
51
};
28
52
29
static inline int arm_feature(CPUARMState *env, int feature)
53
#define TYPE_NPCM7XX "npcm7xx"
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
54
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
31
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.h
56
--- a/hw/arm/npcm7xx.c
33
+++ b/target/arm/helper.h
57
+++ b/hw/arm/npcm7xx.c
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
58
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
35
DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
59
NPCM7XX_EMC1RX_IRQ = 15,
36
DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
60
NPCM7XX_EMC1TX_IRQ,
37
61
NPCM7XX_MMC_IRQ = 26,
38
+DEF_HELPER_FLAGS_2(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr)
62
+ NPCM7XX_PSPI2_IRQ = 28,
39
+DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
63
+ NPCM7XX_PSPI1_IRQ = 31,
40
+
64
NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
41
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
65
NPCM7XX_TIMER1_IRQ,
42
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
66
NPCM7XX_TIMER2_IRQ,
43
DEF_HELPER_2(dc_zva, void, env, i64)
67
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_emc_addr[] = {
44
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
68
0xf0826000,
45
index XXXXXXX..XXXXXXX 100644
69
};
46
--- a/target/arm/crypto_helper.c
70
47
+++ b/target/arm/crypto_helper.c
71
+/* Register base address for each PSPI Module */
48
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
72
+static const hwaddr npcm7xx_pspi_addr[] = {
49
rd[0] = d.l[0];
73
+ 0xf0200000,
50
rd[1] = d.l[1];
74
+ 0xf0201000,
51
}
52
+
53
+static uint8_t const sm4_sbox[] = {
54
+ 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
55
+ 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
56
+ 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
57
+ 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
58
+ 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
59
+ 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
60
+ 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
61
+ 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
62
+ 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
63
+ 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
64
+ 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
65
+ 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
66
+ 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
67
+ 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
68
+ 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
69
+ 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
70
+ 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
71
+ 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
72
+ 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
73
+ 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
74
+ 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
75
+ 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
76
+ 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
77
+ 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
78
+ 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
79
+ 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
80
+ 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
81
+ 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
82
+ 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
83
+ 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
84
+ 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
85
+ 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
86
+};
75
+};
87
+
76
+
88
+void HELPER(crypto_sm4e)(void *vd, void *vn)
77
static const struct {
89
+{
78
hwaddr regs_addr;
90
+ uint64_t *rd = vd;
79
uint32_t unconnected_pins;
91
+ uint64_t *rn = vn;
80
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
92
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
81
object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
93
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
82
}
94
+ uint32_t t, i;
83
95
+
84
+ for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
96
+ for (i = 0; i < 4; i++) {
85
+ object_initialize_child(obj, "pspi[*]", &s->pspi[i], TYPE_NPCM_PSPI);
97
+ t = CR_ST_WORD(d, (i + 1) % 4) ^
98
+ CR_ST_WORD(d, (i + 2) % 4) ^
99
+ CR_ST_WORD(d, (i + 3) % 4) ^
100
+ CR_ST_WORD(n, i);
101
+
102
+ t = sm4_sbox[t & 0xff] |
103
+ sm4_sbox[(t >> 8) & 0xff] << 8 |
104
+ sm4_sbox[(t >> 16) & 0xff] << 16 |
105
+ sm4_sbox[(t >> 24) & 0xff] << 24;
106
+
107
+ CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
108
+ rol32(t, 24);
109
+ }
86
+ }
110
+
87
+
111
+ rd[0] = d.l[0];
88
object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI);
112
+ rd[1] = d.l[1];
89
}
113
+}
90
91
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
92
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc), 0,
93
npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
94
95
+ /* PSPI */
96
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pspi_addr) != ARRAY_SIZE(s->pspi));
97
+ for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
98
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->pspi[i]);
99
+ int irq = (i == 0) ? NPCM7XX_PSPI1_IRQ : NPCM7XX_PSPI2_IRQ;
114
+
100
+
115
+void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm)
101
+ sysbus_realize(sbd, &error_abort);
116
+{
102
+ sysbus_mmio_map(sbd, 0, npcm7xx_pspi_addr[i]);
117
+ uint64_t *rd = vd;
103
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, irq));
118
+ uint64_t *rn = vn;
119
+ uint64_t *rm = vm;
120
+ union CRYPTO_STATE d;
121
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
122
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
123
+ uint32_t t, i;
124
+
125
+ d = n;
126
+ for (i = 0; i < 4; i++) {
127
+ t = CR_ST_WORD(d, (i + 1) % 4) ^
128
+ CR_ST_WORD(d, (i + 2) % 4) ^
129
+ CR_ST_WORD(d, (i + 3) % 4) ^
130
+ CR_ST_WORD(m, i);
131
+
132
+ t = sm4_sbox[t & 0xff] |
133
+ sm4_sbox[(t >> 8) & 0xff] << 8 |
134
+ sm4_sbox[(t >> 16) & 0xff] << 16 |
135
+ sm4_sbox[(t >> 24) & 0xff] << 24;
136
+
137
+ CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
138
+ }
104
+ }
139
+
105
+
140
+ rd[0] = d.l[0];
106
create_unimplemented_device("npcm7xx.shm", 0xc0001000, 4 * KiB);
141
+ rd[1] = d.l[1];
107
create_unimplemented_device("npcm7xx.vdmx", 0xe0800000, 4 * KiB);
142
+}
108
create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB);
143
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
109
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
144
index XXXXXXX..XXXXXXX 100644
110
create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
145
--- a/target/arm/translate-a64.c
111
create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
146
+++ b/target/arm/translate-a64.c
112
create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
147
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
113
- create_unimplemented_device("npcm7xx.pspi1", 0xf0200000, 4 * KiB);
148
feature = ARM_FEATURE_V8_SM3;
114
- create_unimplemented_device("npcm7xx.pspi2", 0xf0201000, 4 * KiB);
149
genfn = gen_helper_crypto_sm3partw2;
115
create_unimplemented_device("npcm7xx.ahbpci", 0xf0400000, 1 * MiB);
150
break;
116
create_unimplemented_device("npcm7xx.mcphy", 0xf05f0000, 64 * KiB);
151
+ case 2: /* SM4EKEY */
117
create_unimplemented_device("npcm7xx.gmac1", 0xf0802000, 8 * KiB);
152
+ feature = ARM_FEATURE_V8_SM4;
153
+ genfn = gen_helper_crypto_sm4ekey;
154
+ break;
155
default:
156
unallocated_encoding(s);
157
return;
158
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
159
feature = ARM_FEATURE_V8_SHA512;
160
genfn = gen_helper_crypto_sha512su0;
161
break;
162
+ case 1: /* SM4E */
163
+ feature = ARM_FEATURE_V8_SM4;
164
+ genfn = gen_helper_crypto_sm4e;
165
+ break;
166
default:
167
unallocated_encoding(s);
168
return;
169
--
118
--
170
2.16.1
119
2.34.1
171
172
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Add code to emulate SNVS IP-block. Currently only the bits needed to
3
Addresses targeting the second translation table (TTB1) in the SMMU have
4
be able to emulate machine shutdown are implemented.
4
all upper bits set. Ensure the IOMMU region covers all 64 bits.
5
5
6
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Cc: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Message-id: 20230214171921.1917916-2-jean-philippe@linaro.org
10
Cc: Michael S. Tsirkin <mst@redhat.com>
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
11
---
18
hw/misc/Makefile.objs | 1 +
12
include/hw/arm/smmu-common.h | 2 --
19
include/hw/misc/imx7_snvs.h | 35 +++++++++++++++++++
13
hw/arm/smmu-common.c | 2 +-
20
hw/misc/imx7_snvs.c | 83 +++++++++++++++++++++++++++++++++++++++++++++
14
2 files changed, 1 insertion(+), 3 deletions(-)
21
3 files changed, 119 insertions(+)
22
create mode 100644 include/hw/misc/imx7_snvs.h
23
create mode 100644 hw/misc/imx7_snvs.c
24
15
25
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
16
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/misc/Makefile.objs
18
--- a/include/hw/arm/smmu-common.h
28
+++ b/hw/misc/Makefile.objs
19
+++ b/include/hw/arm/smmu-common.h
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx6_ccm.o
30
obj-$(CONFIG_IMX) += imx6_src.o
31
obj-$(CONFIG_IMX) += imx7_ccm.o
32
obj-$(CONFIG_IMX) += imx2_wdt.o
33
+obj-$(CONFIG_IMX) += imx7_snvs.o
34
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
35
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
36
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
37
diff --git a/include/hw/misc/imx7_snvs.h b/include/hw/misc/imx7_snvs.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/misc/imx7_snvs.h
42
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
43
+/*
21
#define SMMU_PCI_DEVFN_MAX 256
44
+ * Copyright (c) 2017, Impinj, Inc.
22
#define SMMU_PCI_DEVFN(sid) (sid & 0xFF)
45
+ *
23
46
+ * i.MX7 SNVS block emulation code
24
-#define SMMU_MAX_VA_BITS 48
47
+ *
25
-
48
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
26
/*
49
+ *
27
* Page table walk error types
50
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
28
*/
51
+ * See the COPYING file in the top-level directory.
29
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
52
+ */
30
index XXXXXXX..XXXXXXX 100644
53
+
31
--- a/hw/arm/smmu-common.c
54
+#ifndef IMX7_SNVS_H
32
+++ b/hw/arm/smmu-common.c
55
+#define IMX7_SNVS_H
33
@@ -XXX,XX +XXX,XX @@ static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
56
+
34
57
+#include "qemu/bitops.h"
35
memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu),
58
+#include "hw/sysbus.h"
36
s->mrtypename,
59
+
37
- OBJECT(s), name, 1ULL << SMMU_MAX_VA_BITS);
60
+
38
+ OBJECT(s), name, UINT64_MAX);
61
+enum IMX7SNVSRegisters {
39
address_space_init(&sdev->as,
62
+ SNVS_LPCR = 0x38,
40
MEMORY_REGION(&sdev->iommu), name);
63
+ SNVS_LPCR_TOP = BIT(6),
41
trace_smmu_add_mr(name);
64
+ SNVS_LPCR_DP_EN = BIT(5)
65
+};
66
+
67
+#define TYPE_IMX7_SNVS "imx7.snvs"
68
+#define IMX7_SNVS(obj) OBJECT_CHECK(IMX7SNVSState, (obj), TYPE_IMX7_SNVS)
69
+
70
+typedef struct IMX7SNVSState {
71
+ /* <private> */
72
+ SysBusDevice parent_obj;
73
+
74
+ MemoryRegion mmio;
75
+} IMX7SNVSState;
76
+
77
+#endif /* IMX7_SNVS_H */
78
diff --git a/hw/misc/imx7_snvs.c b/hw/misc/imx7_snvs.c
79
new file mode 100644
80
index XXXXXXX..XXXXXXX
81
--- /dev/null
82
+++ b/hw/misc/imx7_snvs.c
83
@@ -XXX,XX +XXX,XX @@
84
+/*
85
+ * IMX7 Secure Non-Volatile Storage
86
+ *
87
+ * Copyright (c) 2018, Impinj, Inc.
88
+ *
89
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
90
+ *
91
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
92
+ * See the COPYING file in the top-level directory.
93
+ *
94
+ * Bare minimum emulation code needed to support being able to shut
95
+ * down linux guest gracefully.
96
+ */
97
+
98
+#include "qemu/osdep.h"
99
+#include "hw/misc/imx7_snvs.h"
100
+#include "qemu/log.h"
101
+#include "sysemu/sysemu.h"
102
+
103
+static uint64_t imx7_snvs_read(void *opaque, hwaddr offset, unsigned size)
104
+{
105
+ return 0;
106
+}
107
+
108
+static void imx7_snvs_write(void *opaque, hwaddr offset,
109
+ uint64_t v, unsigned size)
110
+{
111
+ const uint32_t value = v;
112
+ const uint32_t mask = SNVS_LPCR_TOP | SNVS_LPCR_DP_EN;
113
+
114
+ if (offset == SNVS_LPCR && ((value & mask) == mask)) {
115
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
116
+ }
117
+}
118
+
119
+static const struct MemoryRegionOps imx7_snvs_ops = {
120
+ .read = imx7_snvs_read,
121
+ .write = imx7_snvs_write,
122
+ .endianness = DEVICE_NATIVE_ENDIAN,
123
+ .impl = {
124
+ /*
125
+ * Our device would not work correctly if the guest was doing
126
+ * unaligned access. This might not be a limitation on the real
127
+ * device but in practice there is no reason for a guest to access
128
+ * this device unaligned.
129
+ */
130
+ .min_access_size = 4,
131
+ .max_access_size = 4,
132
+ .unaligned = false,
133
+ },
134
+};
135
+
136
+static void imx7_snvs_init(Object *obj)
137
+{
138
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
139
+ IMX7SNVSState *s = IMX7_SNVS(obj);
140
+
141
+ memory_region_init_io(&s->mmio, obj, &imx7_snvs_ops, s,
142
+ TYPE_IMX7_SNVS, 0x1000);
143
+
144
+ sysbus_init_mmio(sd, &s->mmio);
145
+}
146
+
147
+static void imx7_snvs_class_init(ObjectClass *klass, void *data)
148
+{
149
+ DeviceClass *dc = DEVICE_CLASS(klass);
150
+
151
+ dc->desc = "i.MX7 Secure Non-Volatile Storage Module";
152
+}
153
+
154
+static const TypeInfo imx7_snvs_info = {
155
+ .name = TYPE_IMX7_SNVS,
156
+ .parent = TYPE_SYS_BUS_DEVICE,
157
+ .instance_size = sizeof(IMX7SNVSState),
158
+ .instance_init = imx7_snvs_init,
159
+ .class_init = imx7_snvs_class_init,
160
+};
161
+
162
+static void imx7_snvs_register_type(void)
163
+{
164
+ type_register_static(&imx7_snvs_info);
165
+}
166
+type_init(imx7_snvs_register_type)
167
--
42
--
168
2.16.1
43
2.34.1
169
170
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Convert i.MX6 to use TYPE_IMX_USDHC since that's what real HW comes
3
Addresses targeting the second translation table (TTB1) in the SMMU have
4
with.
4
all upper bits set (except for the top byte when TBI is enabled). Fix
5
the TTB1 check.
5
6
6
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Reported-by: Ola Hugosson <ola.hugosson@arm.com>
7
Cc: Jason Wang <jasowang@redhat.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Cc: Michael S. Tsirkin <mst@redhat.com>
11
Message-id: 20230214171921.1917916-3-jean-philippe@linaro.org
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
13
---
18
hw/arm/fsl-imx6.c | 2 +-
14
hw/arm/smmu-common.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
20
16
21
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
17
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/fsl-imx6.c
19
--- a/hw/arm/smmu-common.c
24
+++ b/hw/arm/fsl-imx6.c
20
+++ b/hw/arm/smmu-common.c
25
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_init(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
26
}
22
/* there is a ttbr0 region and we are in it (high bits all zero) */
27
23
return &cfg->tt[0];
28
for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
24
} else if (cfg->tt[1].tsz &&
29
- object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), TYPE_SYSBUS_SDHCI);
25
- !extract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte)) {
30
+ object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), TYPE_IMX_USDHC);
26
+ sextract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte) == -1) {
31
qdev_set_parent_bus(DEVICE(&s->esdhc[i]), sysbus_get_default());
27
/* there is a ttbr1 region and we are in it (high bits all one) */
32
snprintf(name, NAME_SIZE, "sdhc%d", i + 1);
28
return &cfg->tt[1];
33
object_property_add_child(obj, name, OBJECT(&s->esdhc[i]), NULL);
29
} else if (!cfg->tt[0].tsz) {
34
--
30
--
35
2.16.1
31
2.34.1
36
37
diff view generated by jsdifflib
1
In the v8M architecture, if the process of taking an exception
1
From: Claudio Fontana <cfontana@suse.de>
2
results in a further exception this is called a derived exception
3
(for example, an MPU exception when writing the exception frame to
4
memory). If the derived exception happens while pushing the initial
5
stack frame, we must ignore any subsequent possible exception
6
pushing the callee-saves registers.
7
2
8
In preparation for making the stack writes check for exceptions,
3
make it clearer from the name that this is a tcg-only function.
9
add a return value from v7m_push_stack() and a new parameter to
10
v7m_exception_taken(), so that the former can tell the latter that
11
it needs to ignore failures to write to the stack. We also plumb
12
the argument through to v7m_push_callee_stack(), which is where
13
the code to ignore the failures will be.
14
4
15
(Note that the v8M ARM pseudocode structures this slightly differently:
5
Signed-off-by: Claudio Fontana <cfontana@suse.de>
16
derived exceptions cause the attempt to process the original
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
17
exception to be abandoned; then at the top level it calls
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
DerivedLateArrival to prioritize the derived exception and call
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
19
TakeException from there. We choose to let the NVIC do the prioritization
9
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
20
and continue forward with a call to TakeException which will then
21
take either the original or the derived exception. The effect is
22
the same, but this structure works better for QEMU because we don't
23
have a convenient top level place to do the abandon-and-retry logic.)
24
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 1517324542-6607-4-git-send-email-peter.maydell@linaro.org
28
---
11
---
29
target/arm/helper.c | 35 +++++++++++++++++++++++------------
12
target/arm/helper.c | 4 ++--
30
1 file changed, 23 insertions(+), 12 deletions(-)
13
1 file changed, 2 insertions(+), 2 deletions(-)
31
14
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
37
return addr;
20
* trapped to the hypervisor in KVM.
38
}
21
*/
39
22
#ifdef CONFIG_TCG
40
-static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain)
23
-static void handle_semihosting(CPUState *cs)
41
+static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
24
+static void tcg_handle_semihosting(CPUState *cs)
42
+ bool ignore_faults)
43
{
25
{
44
/* For v8M, push the callee-saves register part of the stack frame.
45
* Compare the v8M pseudocode PushCalleeStack().
46
@@ -XXX,XX +XXX,XX @@ static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain)
47
*frame_sp_p = frameptr;
48
}
49
50
-static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
51
+static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
52
+ bool ignore_stackfaults)
53
{
54
/* Do the "take the exception" parts of exception entry,
55
* but not the pushing of state to the stack. This is
56
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
57
*/
58
if (lr & R_V7M_EXCRET_DCRS_MASK &&
59
!(dotailchain && (lr & R_V7M_EXCRET_ES_MASK))) {
60
- v7m_push_callee_stack(cpu, lr, dotailchain);
61
+ v7m_push_callee_stack(cpu, lr, dotailchain,
62
+ ignore_stackfaults);
63
}
64
lr |= R_V7M_EXCRET_DCRS_MASK;
65
}
66
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
67
env->thumb = addr & 1;
68
}
69
70
-static void v7m_push_stack(ARMCPU *cpu)
71
+static bool v7m_push_stack(ARMCPU *cpu)
72
{
73
/* Do the "set up stack frame" part of exception entry,
74
* similar to pseudocode PushStack().
75
+ * Return true if we generate a derived exception (and so
76
+ * should ignore further stack faults trying to process
77
+ * that derived exception.)
78
*/
79
CPUARMState *env = &cpu->env;
80
uint32_t xpsr = xpsr_read(env);
81
@@ -XXX,XX +XXX,XX @@ static void v7m_push_stack(ARMCPU *cpu)
82
v7m_push(env, env->regs[2]);
83
v7m_push(env, env->regs[1]);
84
v7m_push(env, env->regs[0]);
85
+
86
+ return false;
87
}
88
89
static void do_v7m_exception_exit(ARMCPU *cpu)
90
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
91
if (sfault) {
92
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
93
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
94
- v7m_exception_taken(cpu, excret, true);
95
+ v7m_exception_taken(cpu, excret, true, false);
96
qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
97
"stackframe: failed EXC_RETURN.ES validity check\n");
98
return;
99
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
100
*/
101
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
102
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
103
- v7m_exception_taken(cpu, excret, true);
104
+ v7m_exception_taken(cpu, excret, true, false);
105
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
106
"stackframe: failed exception return integrity check\n");
107
return;
108
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
109
/* Take a SecureFault on the current stack */
110
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
111
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
112
- v7m_exception_taken(cpu, excret, true);
113
+ v7m_exception_taken(cpu, excret, true, false);
114
qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
115
"stackframe: failed exception return integrity "
116
"signature check\n");
117
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
118
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
119
env->v7m.secure);
120
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
121
- v7m_exception_taken(cpu, excret, true);
122
+ v7m_exception_taken(cpu, excret, true, false);
123
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
124
"stackframe: failed exception return integrity "
125
"check\n");
126
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
127
/* Take an INVPC UsageFault by pushing the stack again;
128
* we know we're v7M so this is never a Secure UsageFault.
129
*/
130
+ bool ignore_stackfaults;
131
+
132
assert(!arm_feature(env, ARM_FEATURE_V8));
133
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, false);
134
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
135
- v7m_push_stack(cpu);
136
- v7m_exception_taken(cpu, excret, false);
137
+ ignore_stackfaults = v7m_push_stack(cpu);
138
+ v7m_exception_taken(cpu, excret, false, ignore_stackfaults);
139
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on new stackframe: "
140
"failed exception return integrity check\n");
141
return;
142
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
143
ARMCPU *cpu = ARM_CPU(cs);
26
ARMCPU *cpu = ARM_CPU(cs);
144
CPUARMState *env = &cpu->env;
27
CPUARMState *env = &cpu->env;
145
uint32_t lr;
28
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
146
+ bool ignore_stackfaults;
29
*/
147
30
#ifdef CONFIG_TCG
148
arm_log_exception(cs->exception_index);
31
if (cs->exception_index == EXCP_SEMIHOST) {
149
32
- handle_semihosting(cs);
150
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
33
+ tcg_handle_semihosting(cs);
151
lr |= R_V7M_EXCRET_MODE_MASK;
34
return;
152
}
35
}
153
36
#endif
154
- v7m_push_stack(cpu);
155
- v7m_exception_taken(cpu, lr, false);
156
+ ignore_stackfaults = v7m_push_stack(cpu);
157
+ v7m_exception_taken(cpu, lr, false, ignore_stackfaults);
158
qemu_log_mask(CPU_LOG_INT, "... as %d\n", env->v7m.exception);
159
}
160
161
--
37
--
162
2.16.1
38
2.34.1
163
39
164
40
diff view generated by jsdifflib
1
Make v7m_push_callee_stack() honour the MPU by using the
1
From: Claudio Fontana <cfontana@suse.de>
2
new v7m_stack_write() function. We return a flag to indicate
3
whether the pushes failed, which we can then use in
4
v7m_exception_taken() to cause us to handle the derived
5
exception correctly.
6
2
3
for "all" builds (tcg + kvm), we want to avoid doing
4
the psci check if tcg is built-in, but not enabled.
5
6
Signed-off-by: Claudio Fontana <cfontana@suse.de>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Fabiano Rosas <farosas@suse.de>
9
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 1517324542-6607-6-git-send-email-peter.maydell@linaro.org
11
---
11
---
12
target/arm/helper.c | 64 ++++++++++++++++++++++++++++++++++++++++-------------
12
target/arm/helper.c | 3 ++-
13
1 file changed, 49 insertions(+), 15 deletions(-)
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
19
@@ -XXX,XX +XXX,XX @@
20
return addr;
20
#include "hw/irq.h"
21
}
21
#include "sysemu/cpu-timers.h"
22
22
#include "sysemu/kvm.h"
23
-static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
23
+#include "sysemu/tcg.h"
24
+static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
24
#include "qapi/qapi-commands-machine-target.h"
25
bool ignore_faults)
25
#include "qapi/error.h"
26
{
26
#include "qemu/guest-random.h"
27
/* For v8M, push the callee-saves register part of the stack frame.
27
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
28
@@ -XXX,XX +XXX,XX @@ static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
28
env->exception.syndrome);
29
* In the tailchaining case this may not be the current stack.
30
*/
31
CPUARMState *env = &cpu->env;
32
- CPUState *cs = CPU(cpu);
33
uint32_t *frame_sp_p;
34
uint32_t frameptr;
35
+ ARMMMUIdx mmu_idx;
36
+ bool stacked_ok;
37
38
if (dotailchain) {
39
- frame_sp_p = get_v7m_sp_ptr(env, true,
40
- lr & R_V7M_EXCRET_MODE_MASK,
41
+ bool mode = lr & R_V7M_EXCRET_MODE_MASK;
42
+ bool priv = !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_NPRIV_MASK) ||
43
+ !mode;
44
+
45
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, M_REG_S, priv);
46
+ frame_sp_p = get_v7m_sp_ptr(env, M_REG_S, mode,
47
lr & R_V7M_EXCRET_SPSEL_MASK);
48
} else {
49
+ mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
50
frame_sp_p = &env->regs[13];
51
}
29
}
52
30
53
frameptr = *frame_sp_p - 0x28;
31
- if (arm_is_psci_call(cpu, cs->exception_index)) {
54
32
+ if (tcg_enabled() && arm_is_psci_call(cpu, cs->exception_index)) {
55
- stl_phys(cs->as, frameptr, 0xfefa125b);
33
arm_handle_psci_call(cpu);
56
- stl_phys(cs->as, frameptr + 0x8, env->regs[4]);
34
qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
57
- stl_phys(cs->as, frameptr + 0xc, env->regs[5]);
35
return;
58
- stl_phys(cs->as, frameptr + 0x10, env->regs[6]);
59
- stl_phys(cs->as, frameptr + 0x14, env->regs[7]);
60
- stl_phys(cs->as, frameptr + 0x18, env->regs[8]);
61
- stl_phys(cs->as, frameptr + 0x1c, env->regs[9]);
62
- stl_phys(cs->as, frameptr + 0x20, env->regs[10]);
63
- stl_phys(cs->as, frameptr + 0x24, env->regs[11]);
64
+ /* Write as much of the stack frame as we can. A write failure may
65
+ * cause us to pend a derived exception.
66
+ */
67
+ stacked_ok =
68
+ v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
69
+ v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
70
+ ignore_faults) &&
71
+ v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
72
+ ignore_faults) &&
73
+ v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx,
74
+ ignore_faults) &&
75
+ v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx,
76
+ ignore_faults) &&
77
+ v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx,
78
+ ignore_faults) &&
79
+ v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx,
80
+ ignore_faults) &&
81
+ v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx,
82
+ ignore_faults) &&
83
+ v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx,
84
+ ignore_faults);
85
86
+ /* Update SP regardless of whether any of the stack accesses failed.
87
+ * When we implement v8M stack limit checking then this attempt to
88
+ * update SP might also fail and result in a derived exception.
89
+ */
90
*frame_sp_p = frameptr;
91
+
92
+ return !stacked_ok;
93
}
94
95
static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
96
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
97
uint32_t addr;
98
bool targets_secure;
99
int exc;
100
+ bool push_failed = false;
101
102
armv7m_nvic_get_pending_irq_info(env->nvic, &exc, &targets_secure);
103
104
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
105
*/
106
if (lr & R_V7M_EXCRET_DCRS_MASK &&
107
!(dotailchain && (lr & R_V7M_EXCRET_ES_MASK))) {
108
- v7m_push_callee_stack(cpu, lr, dotailchain,
109
- ignore_stackfaults);
110
+ push_failed = v7m_push_callee_stack(cpu, lr, dotailchain,
111
+ ignore_stackfaults);
112
}
113
lr |= R_V7M_EXCRET_DCRS_MASK;
114
}
115
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
116
}
117
}
118
119
+ if (push_failed && !ignore_stackfaults) {
120
+ /* Derived exception on callee-saves register stacking:
121
+ * we might now want to take a different exception which
122
+ * targets a different security state, so try again from the top.
123
+ */
124
+ v7m_exception_taken(cpu, lr, true, true);
125
+ return;
126
+ }
127
+
128
addr = arm_v7m_load_vector(cpu, exc, targets_secure);
129
130
/* Now we've done everything that might cause a derived exception
131
--
36
--
132
2.16.1
37
2.34.1
133
38
134
39
diff view generated by jsdifflib
1
The memory writes done to push registers on the stack
1
From: Claudio Fontana <cfontana@suse.de>
2
on exception entry in M profile CPUs are supposed to
3
go via MPU permissions checks, which may cause us to
4
take a derived exception instead of the original one of
5
the MPU lookup fails. We were implementing these as
6
always-succeeds direct writes to physical memory.
7
Rewrite v7m_push_stack() to do the necessary checks.
8
2
3
Signed-off-by: Claudio Fontana <cfontana@suse.de>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Fabiano Rosas <farosas@suse.de>
6
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 1517324542-6607-5-git-send-email-peter.maydell@linaro.org
12
---
8
---
13
target/arm/helper.c | 103 ++++++++++++++++++++++++++++++++++++++++++++--------
9
target/arm/helper.c | 12 +++++++-----
14
1 file changed, 87 insertions(+), 16 deletions(-)
10
1 file changed, 7 insertions(+), 5 deletions(-)
15
11
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
14
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
15
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
16
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
21
return target_el;
17
unsigned int cur_el = arm_current_el(env);
22
}
18
int rt;
23
19
24
-static void v7m_push(CPUARMState *env, uint32_t val)
20
- /*
25
+static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
21
- * Note that new_el can never be 0. If cur_el is 0, then
26
+ ARMMMUIdx mmu_idx, bool ignfault)
22
- * el0_a64 is is_a64(), else el0_a64 is ignored.
27
{
23
- */
28
- CPUState *cs = CPU(arm_env_get_cpu(env));
24
- aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
29
+ CPUState *cs = CPU(cpu);
25
+ if (tcg_enabled()) {
30
+ CPUARMState *env = &cpu->env;
26
+ /*
31
+ MemTxAttrs attrs = {};
27
+ * Note that new_el can never be 0. If cur_el is 0, then
32
+ MemTxResult txres;
28
+ * el0_a64 is is_a64(), else el0_a64 is ignored.
33
+ target_ulong page_size;
29
+ */
34
+ hwaddr physaddr;
30
+ aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
35
+ int prot;
36
+ ARMMMUFaultInfo fi;
37
+ bool secure = mmu_idx & ARM_MMU_IDX_M_S;
38
+ int exc;
39
+ bool exc_secure;
40
41
- env->regs[13] -= 4;
42
- stl_phys(cs->as, env->regs[13], val);
43
+ if (get_phys_addr(env, addr, MMU_DATA_STORE, mmu_idx, &physaddr,
44
+ &attrs, &prot, &page_size, &fi, NULL)) {
45
+ /* MPU/SAU lookup failed */
46
+ if (fi.type == ARMFault_QEMU_SFault) {
47
+ qemu_log_mask(CPU_LOG_INT,
48
+ "...SecureFault with SFSR.AUVIOL during stacking\n");
49
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
50
+ env->v7m.sfar = addr;
51
+ exc = ARMV7M_EXCP_SECURE;
52
+ exc_secure = false;
53
+ } else {
54
+ qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
55
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
56
+ exc = ARMV7M_EXCP_MEM;
57
+ exc_secure = secure;
58
+ }
59
+ goto pend_fault;
60
+ }
31
+ }
61
+ address_space_stl_le(arm_addressspace(cs, attrs), physaddr, value,
32
62
+ attrs, &txres);
33
if (cur_el < new_el) {
63
+ if (txres != MEMTX_OK) {
34
/*
64
+ /* BusFault trying to write the data */
65
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
66
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
67
+ exc = ARMV7M_EXCP_BUS;
68
+ exc_secure = false;
69
+ goto pend_fault;
70
+ }
71
+ return true;
72
+
73
+pend_fault:
74
+ /* By pending the exception at this point we are making
75
+ * the IMPDEF choice "overridden exceptions pended" (see the
76
+ * MergeExcInfo() pseudocode). The other choice would be to not
77
+ * pend them now and then make a choice about which to throw away
78
+ * later if we have two derived exceptions.
79
+ * The only case when we must not pend the exception but instead
80
+ * throw it away is if we are doing the push of the callee registers
81
+ * and we've already generated a derived exception. Even in this
82
+ * case we will still update the fault status registers.
83
+ */
84
+ if (!ignfault) {
85
+ armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
86
+ }
87
+ return false;
88
}
89
90
/* Return true if we're using the process stack pointer (not the MSP) */
91
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
92
* should ignore further stack faults trying to process
93
* that derived exception.)
94
*/
95
+ bool stacked_ok;
96
CPUARMState *env = &cpu->env;
97
uint32_t xpsr = xpsr_read(env);
98
+ uint32_t frameptr = env->regs[13];
99
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
100
101
/* Align stack pointer if the guest wants that */
102
- if ((env->regs[13] & 4) &&
103
+ if ((frameptr & 4) &&
104
(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKALIGN_MASK)) {
105
- env->regs[13] -= 4;
106
+ frameptr -= 4;
107
xpsr |= XPSR_SPREALIGN;
108
}
109
- /* Switch to the handler mode. */
110
- v7m_push(env, xpsr);
111
- v7m_push(env, env->regs[15]);
112
- v7m_push(env, env->regs[14]);
113
- v7m_push(env, env->regs[12]);
114
- v7m_push(env, env->regs[3]);
115
- v7m_push(env, env->regs[2]);
116
- v7m_push(env, env->regs[1]);
117
- v7m_push(env, env->regs[0]);
118
119
- return false;
120
+ frameptr -= 0x20;
121
+
122
+ /* Write as much of the stack frame as we can. If we fail a stack
123
+ * write this will result in a derived exception being pended
124
+ * (which may be taken in preference to the one we started with
125
+ * if it has higher priority).
126
+ */
127
+ stacked_ok =
128
+ v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
129
+ v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
130
+ v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
131
+ v7m_stack_write(cpu, frameptr + 12, env->regs[3], mmu_idx, false) &&
132
+ v7m_stack_write(cpu, frameptr + 16, env->regs[12], mmu_idx, false) &&
133
+ v7m_stack_write(cpu, frameptr + 20, env->regs[14], mmu_idx, false) &&
134
+ v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
135
+ v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
136
+
137
+ /* Update SP regardless of whether any of the stack accesses failed.
138
+ * When we implement v8M stack limit checking then this attempt to
139
+ * update SP might also fail and result in a derived exception.
140
+ */
141
+ env->regs[13] = frameptr;
142
+
143
+ return !stacked_ok;
144
}
145
146
static void do_v7m_exception_exit(ARMCPU *cpu)
147
--
35
--
148
2.16.1
36
2.34.1
149
37
150
38
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
IP block found on several generations of i.MX family does not use
3
Move this earlier to make the next patch diff cleaner. While here
4
vanilla SDHCI implementation and it comes with a number of quirks.
4
update the comment slightly to not give the impression that the
5
misalignment affects only TCG.
5
6
6
Introduce i.MX SDHCI subtype of SDHCI block to add code necessary to
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
support unmodified Linux guest driver.
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
9
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Cc: Jason Wang <jasowang@redhat.com>
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
13
Cc: Michael S. Tsirkin <mst@redhat.com>
14
Cc: qemu-devel@nongnu.org
15
Cc: qemu-arm@nongnu.org
16
Cc: yurovsky@gmail.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
19
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
[PMM: define and use ESDHC_UNDOCUMENTED_REG27]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
12
---
23
hw/sd/sdhci-internal.h | 23 +++++
13
target/arm/machine.c | 18 +++++++++---------
24
include/hw/sd/sdhci.h | 13 +++
14
1 file changed, 9 insertions(+), 9 deletions(-)
25
hw/sd/sdhci.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++-
26
3 files changed, 265 insertions(+), 1 deletion(-)
27
15
28
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
16
diff --git a/target/arm/machine.c b/target/arm/machine.c
29
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/sd/sdhci-internal.h
18
--- a/target/arm/machine.c
31
+++ b/hw/sd/sdhci-internal.h
19
+++ b/target/arm/machine.c
32
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
33
34
/* R/W Host control Register 0x0 */
35
#define SDHC_HOSTCTL 0x28
36
+#define SDHC_CTRL_LED 0x01
37
#define SDHC_CTRL_DMA_CHECK_MASK 0x18
38
#define SDHC_CTRL_SDMA 0x00
39
#define SDHC_CTRL_ADMA1_32 0x08
40
#define SDHC_CTRL_ADMA2_32 0x10
41
#define SDHC_CTRL_ADMA2_64 0x18
42
#define SDHC_DMA_TYPE(x) ((x) & SDHC_CTRL_DMA_CHECK_MASK)
43
+#define SDHC_CTRL_4BITBUS 0x02
44
+#define SDHC_CTRL_8BITBUS 0x20
45
+#define SDHC_CTRL_CDTEST_INS 0x40
46
+#define SDHC_CTRL_CDTEST_EN 0x80
47
+
48
49
/* R/W Power Control Register 0x0 */
50
#define SDHC_PWRCON 0x29
51
@@ -XXX,XX +XXX,XX @@ enum {
52
sdhc_gap_write = 2 /* SDHC stopped at block gap during write operation */
53
};
54
55
+extern const VMStateDescription sdhci_vmstate;
56
+
57
+
58
+#define ESDHC_MIX_CTRL 0x48
59
+#define ESDHC_VENDOR_SPEC 0xc0
60
+#define ESDHC_DLL_CTRL 0x60
61
+
62
+#define ESDHC_TUNING_CTRL 0xcc
63
+#define ESDHC_TUNE_CTRL_STATUS 0x68
64
+#define ESDHC_WTMK_LVL 0x44
65
+
66
+/* Undocumented register used by guests working around erratum ERR004536 */
67
+#define ESDHC_UNDOCUMENTED_REG27 0x6c
68
+
69
+#define ESDHC_CTRL_4BITBUS (0x1 << 1)
70
+#define ESDHC_CTRL_8BITBUS (0x2 << 1)
71
+
72
#endif
73
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
74
index XXXXXXX..XXXXXXX 100644
75
--- a/include/hw/sd/sdhci.h
76
+++ b/include/hw/sd/sdhci.h
77
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
78
AddressSpace sysbus_dma_as;
79
AddressSpace *dma_as;
80
MemoryRegion *dma_mr;
81
+ const MemoryRegionOps *io_ops;
82
83
QEMUTimer *insert_timer; /* timer for 'changing' sd card. */
84
QEMUTimer *transfer_timer;
85
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
86
87
/* Configurable properties */
88
bool pending_insert_quirk; /* Quirk for Raspberry Pi card insert int */
89
+ uint32_t quirks;
90
} SDHCIState;
91
92
+/*
93
+ * Controller does not provide transfer-complete interrupt when not
94
+ * busy.
95
+ *
96
+ * NOTE: This definition is taken out of Linux kernel and so the
97
+ * original bit number is preserved
98
+ */
99
+#define SDHCI_QUIRK_NO_BUSY_IRQ BIT(14)
100
+
101
#define TYPE_PCI_SDHCI "sdhci-pci"
102
#define PCI_SDHCI(obj) OBJECT_CHECK(SDHCIState, (obj), TYPE_PCI_SDHCI)
103
104
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
105
#define SYSBUS_SDHCI(obj) \
106
OBJECT_CHECK(SDHCIState, (obj), TYPE_SYSBUS_SDHCI)
107
108
+#define TYPE_IMX_USDHC "imx-usdhc"
109
+
110
#endif /* SDHCI_H */
111
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/hw/sd/sdhci.c
114
+++ b/hw/sd/sdhci.c
115
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
116
}
117
}
21
}
118
119
- if ((s->norintstsen & SDHC_NISEN_TRSCMP) &&
120
+ if (!(s->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) &&
121
+ (s->norintstsen & SDHC_NISEN_TRSCMP) &&
122
(s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) {
123
s->norintsts |= SDHC_NIS_TRSCMP;
124
}
125
@@ -XXX,XX +XXX,XX @@ static void sdhci_initfn(SDHCIState *s)
126
127
s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
128
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
129
+
130
+ s->io_ops = &sdhci_mmio_ops;
131
}
132
133
static void sdhci_uninitfn(SDHCIState *s)
134
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
135
}
22
}
136
23
137
sysbus_init_irq(sbd, &s->irq);
24
+ /*
138
+
25
+ * Misaligned thumb pc is architecturally impossible. Fail the
139
+ memory_region_init_io(&s->iomem, OBJECT(s), s->io_ops, s, "sdhci",
26
+ * incoming migration. For TCG it would trigger the assert in
140
+ SDHC_REGISTERS_MAP_SIZE);
27
+ * thumb_tr_translate_insn().
141
+
28
+ */
142
sysbus_init_mmio(sbd, &s->iomem);
29
+ if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
143
}
30
+ return -1;
144
145
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sdhci_bus_info = {
146
.class_init = sdhci_bus_class_init,
147
};
148
149
+static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
150
+{
151
+ SDHCIState *s = SYSBUS_SDHCI(opaque);
152
+ uint32_t ret;
153
+ uint16_t hostctl;
154
+
155
+ switch (offset) {
156
+ default:
157
+ return sdhci_read(opaque, offset, size);
158
+
159
+ case SDHC_HOSTCTL:
160
+ /*
161
+ * For a detailed explanation on the following bit
162
+ * manipulation code see comments in a similar part of
163
+ * usdhc_write()
164
+ */
165
+ hostctl = SDHC_DMA_TYPE(s->hostctl) << (8 - 3);
166
+
167
+ if (s->hostctl & SDHC_CTRL_8BITBUS) {
168
+ hostctl |= ESDHC_CTRL_8BITBUS;
169
+ }
170
+
171
+ if (s->hostctl & SDHC_CTRL_4BITBUS) {
172
+ hostctl |= ESDHC_CTRL_4BITBUS;
173
+ }
174
+
175
+ ret = hostctl;
176
+ ret |= (uint32_t)s->blkgap << 16;
177
+ ret |= (uint32_t)s->wakcon << 24;
178
+
179
+ break;
180
+
181
+ case ESDHC_DLL_CTRL:
182
+ case ESDHC_TUNE_CTRL_STATUS:
183
+ case ESDHC_UNDOCUMENTED_REG27:
184
+ case ESDHC_TUNING_CTRL:
185
+ case ESDHC_VENDOR_SPEC:
186
+ case ESDHC_MIX_CTRL:
187
+ case ESDHC_WTMK_LVL:
188
+ ret = 0;
189
+ break;
190
+ }
31
+ }
191
+
32
+
192
+ return ret;
33
hw_breakpoint_update_all(cpu);
193
+}
34
hw_watchpoint_update_all(cpu);
194
+
35
195
+static void
36
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
196
+usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
37
}
197
+{
38
}
198
+ SDHCIState *s = SYSBUS_SDHCI(opaque);
39
199
+ uint8_t hostctl;
40
- /*
200
+ uint32_t value = (uint32_t)val;
41
- * Misaligned thumb pc is architecturally impossible.
201
+
42
- * We have an assert in thumb_tr_translate_insn to verify this.
202
+ switch (offset) {
43
- * Fail an incoming migrate to avoid this assert.
203
+ case ESDHC_DLL_CTRL:
44
- */
204
+ case ESDHC_TUNE_CTRL_STATUS:
45
- if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
205
+ case ESDHC_UNDOCUMENTED_REG27:
46
- return -1;
206
+ case ESDHC_TUNING_CTRL:
47
- }
207
+ case ESDHC_WTMK_LVL:
48
-
208
+ case ESDHC_VENDOR_SPEC:
49
if (!kvm_enabled()) {
209
+ break;
50
pmu_op_finish(&cpu->env);
210
+
51
}
211
+ case SDHC_HOSTCTL:
212
+ /*
213
+ * Here's What ESDHCI has at offset 0x28 (SDHC_HOSTCTL)
214
+ *
215
+ * 7 6 5 4 3 2 1 0
216
+ * |-----------+--------+--------+-----------+----------+---------|
217
+ * | Card | Card | Endian | DATA3 | Data | Led |
218
+ * | Detect | Detect | Mode | as Card | Transfer | Control |
219
+ * | Signal | Test | | Detection | Width | |
220
+ * | Selection | Level | | Pin | | |
221
+ * |-----------+--------+--------+-----------+----------+---------|
222
+ *
223
+ * and 0x29
224
+ *
225
+ * 15 10 9 8
226
+ * |----------+------|
227
+ * | Reserved | DMA |
228
+ * | | Sel. |
229
+ * | | |
230
+ * |----------+------|
231
+ *
232
+ * and here's what SDCHI spec expects those offsets to be:
233
+ *
234
+ * 0x28 (Host Control Register)
235
+ *
236
+ * 7 6 5 4 3 2 1 0
237
+ * |--------+--------+----------+------+--------+----------+---------|
238
+ * | Card | Card | Extended | DMA | High | Data | LED |
239
+ * | Detect | Detect | Data | Sel. | Speed | Transfer | Control |
240
+ * | Signal | Test | Transfer | | Enable | Width | |
241
+ * | Sel. | Level | Width | | | | |
242
+ * |--------+--------+----------+------+--------+----------+---------|
243
+ *
244
+ * and 0x29 (Power Control Register)
245
+ *
246
+ * |----------------------------------|
247
+ * | Power Control Register |
248
+ * | |
249
+ * | Description omitted, |
250
+ * | since it has no analog in ESDHCI |
251
+ * | |
252
+ * |----------------------------------|
253
+ *
254
+ * Since offsets 0x2A and 0x2B should be compatible between
255
+ * both IP specs we only need to reconcile least 16-bit of the
256
+ * word we've been given.
257
+ */
258
+
259
+ /*
260
+ * First, save bits 7 6 and 0 since they are identical
261
+ */
262
+ hostctl = value & (SDHC_CTRL_LED |
263
+ SDHC_CTRL_CDTEST_INS |
264
+ SDHC_CTRL_CDTEST_EN);
265
+ /*
266
+ * Second, split "Data Transfer Width" from bits 2 and 1 in to
267
+ * bits 5 and 1
268
+ */
269
+ if (value & ESDHC_CTRL_8BITBUS) {
270
+ hostctl |= SDHC_CTRL_8BITBUS;
271
+ }
272
+
273
+ if (value & ESDHC_CTRL_4BITBUS) {
274
+ hostctl |= ESDHC_CTRL_4BITBUS;
275
+ }
276
+
277
+ /*
278
+ * Third, move DMA select from bits 9 and 8 to bits 4 and 3
279
+ */
280
+ hostctl |= SDHC_DMA_TYPE(value >> (8 - 3));
281
+
282
+ /*
283
+ * Now place the corrected value into low 16-bit of the value
284
+ * we are going to give standard SDHCI write function
285
+ *
286
+ * NOTE: This transformation should be the inverse of what can
287
+ * be found in drivers/mmc/host/sdhci-esdhc-imx.c in Linux
288
+ * kernel
289
+ */
290
+ value &= ~UINT16_MAX;
291
+ value |= hostctl;
292
+ value |= (uint16_t)s->pwrcon << 8;
293
+
294
+ sdhci_write(opaque, offset, value, size);
295
+ break;
296
+
297
+ case ESDHC_MIX_CTRL:
298
+ /*
299
+ * So, when SD/MMC stack in Linux tries to write to "Transfer
300
+ * Mode Register", ESDHC i.MX quirk code will translate it
301
+ * into a write to ESDHC_MIX_CTRL, so we do the opposite in
302
+ * order to get where we started
303
+ *
304
+ * Note that Auto CMD23 Enable bit is located in a wrong place
305
+ * on i.MX, but since it is not used by QEMU we do not care.
306
+ *
307
+ * We don't want to call sdhci_write(.., SDHC_TRNMOD, ...)
308
+ * here becuase it will result in a call to
309
+ * sdhci_send_command(s) which we don't want.
310
+ *
311
+ */
312
+ s->trnmod = value & UINT16_MAX;
313
+ break;
314
+ case SDHC_TRNMOD:
315
+ /*
316
+ * Similar to above, but this time a write to "Command
317
+ * Register" will be translated into a 4-byte write to
318
+ * "Transfer Mode register" where lower 16-bit of value would
319
+ * be set to zero. So what we do is fill those bits with
320
+ * cached value from s->trnmod and let the SDHCI
321
+ * infrastructure handle the rest
322
+ */
323
+ sdhci_write(opaque, offset, val | s->trnmod, size);
324
+ break;
325
+ case SDHC_BLKSIZE:
326
+ /*
327
+ * ESDHCI does not implement "Host SDMA Buffer Boundary", and
328
+ * Linux driver will try to zero this field out which will
329
+ * break the rest of SDHCI emulation.
330
+ *
331
+ * Linux defaults to maximum possible setting (512K boundary)
332
+ * and it seems to be the only option that i.MX IP implements,
333
+ * so we artificially set it to that value.
334
+ */
335
+ val |= 0x7 << 12;
336
+ /* FALLTHROUGH */
337
+ default:
338
+ sdhci_write(opaque, offset, val, size);
339
+ break;
340
+ }
341
+}
342
+
343
+
344
+static const MemoryRegionOps usdhc_mmio_ops = {
345
+ .read = usdhc_read,
346
+ .write = usdhc_write,
347
+ .valid = {
348
+ .min_access_size = 1,
349
+ .max_access_size = 4,
350
+ .unaligned = false
351
+ },
352
+ .endianness = DEVICE_LITTLE_ENDIAN,
353
+};
354
+
355
+static void imx_usdhc_init(Object *obj)
356
+{
357
+ SDHCIState *s = SYSBUS_SDHCI(obj);
358
+
359
+ s->io_ops = &usdhc_mmio_ops;
360
+ s->quirks = SDHCI_QUIRK_NO_BUSY_IRQ;
361
+}
362
+
363
+static const TypeInfo imx_usdhc_info = {
364
+ .name = TYPE_IMX_USDHC,
365
+ .parent = TYPE_SYSBUS_SDHCI,
366
+ .instance_init = imx_usdhc_init,
367
+};
368
+
369
static void sdhci_register_types(void)
370
{
371
type_register_static(&sdhci_pci_info);
372
type_register_static(&sdhci_sysbus_info);
373
type_register_static(&sdhci_bus_info);
374
+ type_register_static(&imx_usdhc_info);
375
}
376
377
type_init(sdhci_register_types)
378
--
52
--
379
2.16.1
53
2.34.1
380
54
381
55
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Add enough code to emulate i.MX2 watchdog IP block so it would be
3
Since commit cf7c6d1004 ("target/arm: Split out cpregs.h") we now have
4
possible to reboot the machine running Linux Guest.
4
a cpregs.h header which is more suitable for this code.
5
5
6
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Code moved verbatim.
7
Cc: Jason Wang <jasowang@redhat.com>
7
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Fabiano Rosas <farosas@suse.de>
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Cc: qemu-devel@nongnu.org
11
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
13
---
19
hw/misc/Makefile.objs | 1 +
14
target/arm/cpregs.h | 98 +++++++++++++++++++++++++++++++++++++++++++++
20
include/hw/misc/imx2_wdt.h | 33 +++++++++++++++++
15
target/arm/cpu.h | 91 -----------------------------------------
21
hw/misc/imx2_wdt.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++
16
2 files changed, 98 insertions(+), 91 deletions(-)
22
3 files changed, 123 insertions(+)
17
23
create mode 100644 include/hw/misc/imx2_wdt.h
18
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
24
create mode 100644 hw/misc/imx2_wdt.c
25
26
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
27
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/misc/Makefile.objs
20
--- a/target/arm/cpregs.h
29
+++ b/hw/misc/Makefile.objs
21
+++ b/target/arm/cpregs.h
30
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx25_ccm.o
22
@@ -XXX,XX +XXX,XX @@ enum {
31
obj-$(CONFIG_IMX) += imx6_ccm.o
23
ARM_CP_SME = 1 << 19,
32
obj-$(CONFIG_IMX) += imx6_src.o
24
};
33
obj-$(CONFIG_IMX) += imx7_ccm.o
25
34
+obj-$(CONFIG_IMX) += imx2_wdt.o
26
+/*
35
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
27
+ * Interface for defining coprocessor registers.
36
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
28
+ * Registers are defined in tables of arm_cp_reginfo structs
37
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
29
+ * which are passed to define_arm_cp_regs().
38
diff --git a/include/hw/misc/imx2_wdt.h b/include/hw/misc/imx2_wdt.h
30
+ */
39
new file mode 100644
31
+
40
index XXXXXXX..XXXXXXX
32
+/*
41
--- /dev/null
33
+ * When looking up a coprocessor register we look for it
42
+++ b/include/hw/misc/imx2_wdt.h
34
+ * via an integer which encodes all of:
43
@@ -XXX,XX +XXX,XX @@
35
+ * coprocessor number
44
+/*
36
+ * Crn, Crm, opc1, opc2 fields
45
+ * Copyright (c) 2017, Impinj, Inc.
37
+ * 32 or 64 bit register (ie is it accessed via MRC/MCR
46
+ *
38
+ * or via MRRC/MCRR?)
47
+ * i.MX2 Watchdog IP block
39
+ * non-secure/secure bank (AArch32 only)
48
+ *
40
+ * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
49
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
41
+ * (In this case crn and opc2 should be zero.)
50
+ *
42
+ * For AArch64, there is no 32/64 bit size distinction;
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
43
+ * instead all registers have a 2 bit op0, 3 bit op1 and op2,
52
+ * See the COPYING file in the top-level directory.
44
+ * and 4 bit CRn and CRm. The encoding patterns are chosen
53
+ */
45
+ * to be easy to convert to and from the KVM encodings, and also
54
+
46
+ * so that the hashtable can contain both AArch32 and AArch64
55
+#ifndef IMX2_WDT_H
47
+ * registers (to allow for interprocessing where we might run
56
+#define IMX2_WDT_H
48
+ * 32 bit code on a 64 bit core).
57
+
49
+ */
58
+#include "hw/sysbus.h"
50
+/*
59
+
51
+ * This bit is private to our hashtable cpreg; in KVM register
60
+#define TYPE_IMX2_WDT "imx2.wdt"
52
+ * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64
61
+#define IMX2_WDT(obj) OBJECT_CHECK(IMX2WdtState, (obj), TYPE_IMX2_WDT)
53
+ * in the upper bits of the 64 bit ID.
62
+
54
+ */
63
+enum IMX2WdtRegisters {
55
+#define CP_REG_AA64_SHIFT 28
64
+ IMX2_WDT_WCR = 0x0000,
56
+#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
65
+ IMX2_WDT_REG_NUM = 0x0008 / sizeof(uint16_t) + 1,
57
+
66
+};
58
+/*
67
+
59
+ * To enable banking of coprocessor registers depending on ns-bit we
68
+
60
+ * add a bit to distinguish between secure and non-secure cpregs in the
69
+typedef struct IMX2WdtState {
61
+ * hashtable.
70
+ /* <private> */
62
+ */
71
+ SysBusDevice parent_obj;
63
+#define CP_REG_NS_SHIFT 29
72
+
64
+#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
73
+ MemoryRegion mmio;
65
+
74
+} IMX2WdtState;
66
+#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
75
+
67
+ ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
76
+#endif /* IMX7_SNVS_H */
68
+ ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
77
diff --git a/hw/misc/imx2_wdt.c b/hw/misc/imx2_wdt.c
69
+
78
new file mode 100644
70
+#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
79
index XXXXXXX..XXXXXXX
71
+ (CP_REG_AA64_MASK | \
80
--- /dev/null
72
+ ((cp) << CP_REG_ARM_COPROC_SHIFT) | \
81
+++ b/hw/misc/imx2_wdt.c
73
+ ((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
82
@@ -XXX,XX +XXX,XX @@
74
+ ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
83
+/*
75
+ ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
84
+ * Copyright (c) 2018, Impinj, Inc.
76
+ ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
85
+ *
77
+ ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
86
+ * i.MX2 Watchdog IP block
78
+
87
+ *
79
+/*
88
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
80
+ * Convert a full 64 bit KVM register ID to the truncated 32 bit
89
+ *
81
+ * version used as a key for the coprocessor register hashtable
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
82
+ */
91
+ * See the COPYING file in the top-level directory.
83
+static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
92
+ */
93
+
94
+#include "qemu/osdep.h"
95
+#include "qemu/bitops.h"
96
+#include "sysemu/watchdog.h"
97
+
98
+#include "hw/misc/imx2_wdt.h"
99
+
100
+#define IMX2_WDT_WCR_WDA BIT(5) /* -> External Reset WDOG_B */
101
+#define IMX2_WDT_WCR_SRS BIT(4) /* -> Software Reset Signal */
102
+
103
+static uint64_t imx2_wdt_read(void *opaque, hwaddr addr,
104
+ unsigned int size)
105
+{
84
+{
106
+ return 0;
85
+ uint32_t cpregid = kvmid;
86
+ if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
87
+ cpregid |= CP_REG_AA64_MASK;
88
+ } else {
89
+ if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
90
+ cpregid |= (1 << 15);
91
+ }
92
+
93
+ /*
94
+ * KVM is always non-secure so add the NS flag on AArch32 register
95
+ * entries.
96
+ */
97
+ cpregid |= 1 << CP_REG_NS_SHIFT;
98
+ }
99
+ return cpregid;
107
+}
100
+}
108
+
101
+
109
+static void imx2_wdt_write(void *opaque, hwaddr addr,
102
+/*
110
+ uint64_t value, unsigned int size)
103
+ * Convert a truncated 32 bit hashtable key into the full
104
+ * 64 bit KVM register ID.
105
+ */
106
+static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
111
+{
107
+{
112
+ if (addr == IMX2_WDT_WCR &&
108
+ uint64_t kvmid;
113
+ (value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) {
109
+
114
+ watchdog_perform_action();
110
+ if (cpregid & CP_REG_AA64_MASK) {
111
+ kvmid = cpregid & ~CP_REG_AA64_MASK;
112
+ kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64;
113
+ } else {
114
+ kvmid = cpregid & ~(1 << 15);
115
+ if (cpregid & (1 << 15)) {
116
+ kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
117
+ } else {
118
+ kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
119
+ }
115
+ }
120
+ }
121
+ return kvmid;
116
+}
122
+}
117
+
123
+
118
+static const MemoryRegionOps imx2_wdt_ops = {
124
/*
119
+ .read = imx2_wdt_read,
125
* Valid values for ARMCPRegInfo state field, indicating which of
120
+ .write = imx2_wdt_write,
126
* the AArch32 and AArch64 execution states this register is visible in.
121
+ .endianness = DEVICE_NATIVE_ENDIAN,
127
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
122
+ .impl = {
128
index XXXXXXX..XXXXXXX 100644
123
+ /*
129
--- a/target/arm/cpu.h
124
+ * Our device would not work correctly if the guest was doing
130
+++ b/target/arm/cpu.h
125
+ * unaligned access. This might not be a limitation on the
131
@@ -XXX,XX +XXX,XX @@ void arm_cpu_list(void);
126
+ * real device but in practice there is no reason for a guest
132
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
127
+ * to access this device unaligned.
133
uint32_t cur_el, bool secure);
128
+ */
134
129
+ .min_access_size = 4,
135
-/* Interface for defining coprocessor registers.
130
+ .max_access_size = 4,
136
- * Registers are defined in tables of arm_cp_reginfo structs
131
+ .unaligned = false,
137
- * which are passed to define_arm_cp_regs().
132
+ },
138
- */
133
+};
139
-
134
+
140
-/* When looking up a coprocessor register we look for it
135
+static void imx2_wdt_realize(DeviceState *dev, Error **errp)
141
- * via an integer which encodes all of:
136
+{
142
- * coprocessor number
137
+ IMX2WdtState *s = IMX2_WDT(dev);
143
- * Crn, Crm, opc1, opc2 fields
138
+
144
- * 32 or 64 bit register (ie is it accessed via MRC/MCR
139
+ memory_region_init_io(&s->mmio, OBJECT(dev),
145
- * or via MRRC/MCRR?)
140
+ &imx2_wdt_ops, s,
146
- * non-secure/secure bank (AArch32 only)
141
+ TYPE_IMX2_WDT".mmio",
147
- * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
142
+ IMX2_WDT_REG_NUM * sizeof(uint16_t));
148
- * (In this case crn and opc2 should be zero.)
143
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
149
- * For AArch64, there is no 32/64 bit size distinction;
144
+}
150
- * instead all registers have a 2 bit op0, 3 bit op1 and op2,
145
+
151
- * and 4 bit CRn and CRm. The encoding patterns are chosen
146
+static void imx2_wdt_class_init(ObjectClass *klass, void *data)
152
- * to be easy to convert to and from the KVM encodings, and also
147
+{
153
- * so that the hashtable can contain both AArch32 and AArch64
148
+ DeviceClass *dc = DEVICE_CLASS(klass);
154
- * registers (to allow for interprocessing where we might run
149
+
155
- * 32 bit code on a 64 bit core).
150
+ dc->realize = imx2_wdt_realize;
156
- */
151
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
157
-/* This bit is private to our hashtable cpreg; in KVM register
152
+}
158
- * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64
153
+
159
- * in the upper bits of the 64 bit ID.
154
+static const TypeInfo imx2_wdt_info = {
160
- */
155
+ .name = TYPE_IMX2_WDT,
161
-#define CP_REG_AA64_SHIFT 28
156
+ .parent = TYPE_SYS_BUS_DEVICE,
162
-#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
157
+ .instance_size = sizeof(IMX2WdtState),
163
-
158
+ .class_init = imx2_wdt_class_init,
164
-/* To enable banking of coprocessor registers depending on ns-bit we
159
+};
165
- * add a bit to distinguish between secure and non-secure cpregs in the
160
+
166
- * hashtable.
161
+static WatchdogTimerModel model = {
167
- */
162
+ .wdt_name = "imx2-watchdog",
168
-#define CP_REG_NS_SHIFT 29
163
+ .wdt_description = "i.MX2 Watchdog",
169
-#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
164
+};
170
-
165
+
171
-#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
166
+static void imx2_wdt_register_type(void)
172
- ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
167
+{
173
- ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
168
+ watchdog_add_model(&model);
174
-
169
+ type_register_static(&imx2_wdt_info);
175
-#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
170
+}
176
- (CP_REG_AA64_MASK | \
171
+type_init(imx2_wdt_register_type)
177
- ((cp) << CP_REG_ARM_COPROC_SHIFT) | \
178
- ((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
179
- ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
180
- ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
181
- ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
182
- ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
183
-
184
-/* Convert a full 64 bit KVM register ID to the truncated 32 bit
185
- * version used as a key for the coprocessor register hashtable
186
- */
187
-static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
188
-{
189
- uint32_t cpregid = kvmid;
190
- if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
191
- cpregid |= CP_REG_AA64_MASK;
192
- } else {
193
- if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
194
- cpregid |= (1 << 15);
195
- }
196
-
197
- /* KVM is always non-secure so add the NS flag on AArch32 register
198
- * entries.
199
- */
200
- cpregid |= 1 << CP_REG_NS_SHIFT;
201
- }
202
- return cpregid;
203
-}
204
-
205
-/* Convert a truncated 32 bit hashtable key into the full
206
- * 64 bit KVM register ID.
207
- */
208
-static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
209
-{
210
- uint64_t kvmid;
211
-
212
- if (cpregid & CP_REG_AA64_MASK) {
213
- kvmid = cpregid & ~CP_REG_AA64_MASK;
214
- kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64;
215
- } else {
216
- kvmid = cpregid & ~(1 << 15);
217
- if (cpregid & (1 << 15)) {
218
- kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
219
- } else {
220
- kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
221
- }
222
- }
223
- return kvmid;
224
-}
225
-
226
/* Return the highest implemented Exception Level */
227
static inline int arm_highest_el(CPUARMState *env)
228
{
172
--
229
--
173
2.16.1
230
2.34.1
174
231
175
232
diff view generated by jsdifflib
1
From: Christoffer Dall <christoffer.dall@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
KVM doesn't support emulating a GICv3 in userspace, only GICv2. We
3
If a test was tagged with the "accel" tag and the specified
4
currently attempt this anyway, and as a result a KVM guest doesn't
4
accelerator it not present in the qemu binary, cancel the test.
5
receive interrupts and the user is left wondering why. Report an error
6
to the user if this particular combination is requested.
7
5
8
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
6
We can now write tests without explicit calls to require_accelerator,
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
just the tag is enough.
10
Message-id: 20180201205307.30343-1-christoffer.dall@linaro.org
8
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
target/arm/kvm_arm.h | 4 ++++
14
tests/avocado/avocado_qemu/__init__.py | 4 ++++
14
1 file changed, 4 insertions(+)
15
1 file changed, 4 insertions(+)
15
16
16
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
17
diff --git a/tests/avocado/avocado_qemu/__init__.py b/tests/avocado/avocado_qemu/__init__.py
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/kvm_arm.h
19
--- a/tests/avocado/avocado_qemu/__init__.py
19
+++ b/target/arm/kvm_arm.h
20
+++ b/tests/avocado/avocado_qemu/__init__.py
20
@@ -XXX,XX +XXX,XX @@ static inline const char *gicv3_class_name(void)
21
@@ -XXX,XX +XXX,XX @@ def setUp(self):
21
exit(1);
22
22
#endif
23
super().setUp('qemu-system-')
23
} else {
24
24
+ if (kvm_enabled()) {
25
+ accel_required = self._get_unique_tag_val('accel')
25
+ error_report("Userspace GICv3 is not supported with KVM");
26
+ if accel_required:
26
+ exit(1);
27
+ self.require_accelerator(accel_required)
27
+ }
28
+
28
return "arm-gicv3";
29
self.machine = self.params.get('machine',
29
}
30
default=self._get_unique_tag_val('machine'))
30
}
31
31
--
32
--
32
2.16.1
33
2.34.1
33
34
34
35
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Add minimal code needed to allow upstream Linux guest to boot.
3
This allows the test to be skipped when TCG is not present in the QEMU
4
binary.
4
5
5
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
6
Cc: Jason Wang <jasowang@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
hw/misc/Makefile.objs | 1 +
11
tests/avocado/boot_linux_console.py | 1 +
18
include/hw/misc/imx7_ccm.h | 139 +++++++++++++++++++++++
12
tests/avocado/reverse_debugging.py | 8 ++++++++
19
hw/misc/imx7_ccm.c | 277 +++++++++++++++++++++++++++++++++++++++++++++
13
2 files changed, 9 insertions(+)
20
3 files changed, 417 insertions(+)
21
create mode 100644 include/hw/misc/imx7_ccm.h
22
create mode 100644 hw/misc/imx7_ccm.c
23
14
24
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
15
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/misc/Makefile.objs
17
--- a/tests/avocado/boot_linux_console.py
27
+++ b/hw/misc/Makefile.objs
18
+++ b/tests/avocado/boot_linux_console.py
28
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx31_ccm.o
19
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_uboot_netbsd9(self):
29
obj-$(CONFIG_IMX) += imx25_ccm.o
20
30
obj-$(CONFIG_IMX) += imx6_ccm.o
21
def test_aarch64_raspi3_atf(self):
31
obj-$(CONFIG_IMX) += imx6_src.o
22
"""
32
+obj-$(CONFIG_IMX) += imx7_ccm.o
23
+ :avocado: tags=accel:tcg
33
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
24
:avocado: tags=arch:aarch64
34
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
25
:avocado: tags=machine:raspi3b
35
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
26
:avocado: tags=cpu:cortex-a53
36
diff --git a/include/hw/misc/imx7_ccm.h b/include/hw/misc/imx7_ccm.h
27
diff --git a/tests/avocado/reverse_debugging.py b/tests/avocado/reverse_debugging.py
37
new file mode 100644
28
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX
29
--- a/tests/avocado/reverse_debugging.py
39
--- /dev/null
30
+++ b/tests/avocado/reverse_debugging.py
40
+++ b/include/hw/misc/imx7_ccm.h
31
@@ -XXX,XX +XXX,XX @@ def reverse_debugging(self, shift=7, args=None):
41
@@ -XXX,XX +XXX,XX @@
32
vm.shutdown()
42
+/*
33
43
+ * Copyright (c) 2017, Impinj, Inc.
34
class ReverseDebugging_X86_64(ReverseDebugging):
44
+ *
35
+ """
45
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
36
+ :avocado: tags=accel:tcg
46
+ *
37
+ """
47
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
48
+ *
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
50
+ * See the COPYING file in the top-level directory.
51
+ */
52
+
38
+
53
+#ifndef IMX7_CCM_H
39
REG_PC = 0x10
54
+#define IMX7_CCM_H
40
REG_CS = 0x12
41
def get_pc(self, g):
42
@@ -XXX,XX +XXX,XX @@ def test_x86_64_pc(self):
43
self.reverse_debugging()
44
45
class ReverseDebugging_AArch64(ReverseDebugging):
46
+ """
47
+ :avocado: tags=accel:tcg
48
+ """
55
+
49
+
56
+#include "hw/misc/imx_ccm.h"
50
REG_PC = 32
57
+#include "qemu/bitops.h"
51
58
+
52
# unidentified gitlab timeout problem
59
+enum IMX7AnalogRegisters {
60
+ ANALOG_PLL_ARM,
61
+ ANALOG_PLL_ARM_SET,
62
+ ANALOG_PLL_ARM_CLR,
63
+ ANALOG_PLL_ARM_TOG,
64
+ ANALOG_PLL_DDR,
65
+ ANALOG_PLL_DDR_SET,
66
+ ANALOG_PLL_DDR_CLR,
67
+ ANALOG_PLL_DDR_TOG,
68
+ ANALOG_PLL_DDR_SS,
69
+ ANALOG_PLL_DDR_SS_SET,
70
+ ANALOG_PLL_DDR_SS_CLR,
71
+ ANALOG_PLL_DDR_SS_TOG,
72
+ ANALOG_PLL_DDR_NUM,
73
+ ANALOG_PLL_DDR_NUM_SET,
74
+ ANALOG_PLL_DDR_NUM_CLR,
75
+ ANALOG_PLL_DDR_NUM_TOG,
76
+ ANALOG_PLL_DDR_DENOM,
77
+ ANALOG_PLL_DDR_DENOM_SET,
78
+ ANALOG_PLL_DDR_DENOM_CLR,
79
+ ANALOG_PLL_DDR_DENOM_TOG,
80
+ ANALOG_PLL_480,
81
+ ANALOG_PLL_480_SET,
82
+ ANALOG_PLL_480_CLR,
83
+ ANALOG_PLL_480_TOG,
84
+ ANALOG_PLL_480A,
85
+ ANALOG_PLL_480A_SET,
86
+ ANALOG_PLL_480A_CLR,
87
+ ANALOG_PLL_480A_TOG,
88
+ ANALOG_PLL_480B,
89
+ ANALOG_PLL_480B_SET,
90
+ ANALOG_PLL_480B_CLR,
91
+ ANALOG_PLL_480B_TOG,
92
+ ANALOG_PLL_ENET,
93
+ ANALOG_PLL_ENET_SET,
94
+ ANALOG_PLL_ENET_CLR,
95
+ ANALOG_PLL_ENET_TOG,
96
+ ANALOG_PLL_AUDIO,
97
+ ANALOG_PLL_AUDIO_SET,
98
+ ANALOG_PLL_AUDIO_CLR,
99
+ ANALOG_PLL_AUDIO_TOG,
100
+ ANALOG_PLL_AUDIO_SS,
101
+ ANALOG_PLL_AUDIO_SS_SET,
102
+ ANALOG_PLL_AUDIO_SS_CLR,
103
+ ANALOG_PLL_AUDIO_SS_TOG,
104
+ ANALOG_PLL_AUDIO_NUM,
105
+ ANALOG_PLL_AUDIO_NUM_SET,
106
+ ANALOG_PLL_AUDIO_NUM_CLR,
107
+ ANALOG_PLL_AUDIO_NUM_TOG,
108
+ ANALOG_PLL_AUDIO_DENOM,
109
+ ANALOG_PLL_AUDIO_DENOM_SET,
110
+ ANALOG_PLL_AUDIO_DENOM_CLR,
111
+ ANALOG_PLL_AUDIO_DENOM_TOG,
112
+ ANALOG_PLL_VIDEO,
113
+ ANALOG_PLL_VIDEO_SET,
114
+ ANALOG_PLL_VIDEO_CLR,
115
+ ANALOG_PLL_VIDEO_TOG,
116
+ ANALOG_PLL_VIDEO_SS,
117
+ ANALOG_PLL_VIDEO_SS_SET,
118
+ ANALOG_PLL_VIDEO_SS_CLR,
119
+ ANALOG_PLL_VIDEO_SS_TOG,
120
+ ANALOG_PLL_VIDEO_NUM,
121
+ ANALOG_PLL_VIDEO_NUM_SET,
122
+ ANALOG_PLL_VIDEO_NUM_CLR,
123
+ ANALOG_PLL_VIDEO_NUM_TOG,
124
+ ANALOG_PLL_VIDEO_DENOM,
125
+ ANALOG_PLL_VIDEO_DENOM_SET,
126
+ ANALOG_PLL_VIDEO_DENOM_CLR,
127
+ ANALOG_PLL_VIDEO_DENOM_TOG,
128
+ ANALOG_PLL_MISC0,
129
+ ANALOG_PLL_MISC0_SET,
130
+ ANALOG_PLL_MISC0_CLR,
131
+ ANALOG_PLL_MISC0_TOG,
132
+
133
+ ANALOG_DIGPROG = 0x800 / sizeof(uint32_t),
134
+ ANALOG_MAX,
135
+
136
+ ANALOG_PLL_LOCK = BIT(31)
137
+};
138
+
139
+enum IMX7CCMRegisters {
140
+ CCM_MAX = 0xBE00 / sizeof(uint32_t) + 1,
141
+};
142
+
143
+enum IMX7PMURegisters {
144
+ PMU_MAX = 0x140 / sizeof(uint32_t),
145
+};
146
+
147
+#define TYPE_IMX7_CCM "imx7.ccm"
148
+#define IMX7_CCM(obj) OBJECT_CHECK(IMX7CCMState, (obj), TYPE_IMX7_CCM)
149
+
150
+typedef struct IMX7CCMState {
151
+ /* <private> */
152
+ IMXCCMState parent_obj;
153
+
154
+ /* <public> */
155
+ MemoryRegion iomem;
156
+
157
+ uint32_t ccm[CCM_MAX];
158
+} IMX7CCMState;
159
+
160
+
161
+#define TYPE_IMX7_ANALOG "imx7.analog"
162
+#define IMX7_ANALOG(obj) OBJECT_CHECK(IMX7AnalogState, (obj), TYPE_IMX7_ANALOG)
163
+
164
+typedef struct IMX7AnalogState {
165
+ /* <private> */
166
+ IMXCCMState parent_obj;
167
+
168
+ /* <public> */
169
+ struct {
170
+ MemoryRegion container;
171
+ MemoryRegion analog;
172
+ MemoryRegion digprog;
173
+ MemoryRegion pmu;
174
+ } mmio;
175
+
176
+ uint32_t analog[ANALOG_MAX];
177
+ uint32_t pmu[PMU_MAX];
178
+} IMX7AnalogState;
179
+
180
+#endif /* IMX7_CCM_H */
181
diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c
182
new file mode 100644
183
index XXXXXXX..XXXXXXX
184
--- /dev/null
185
+++ b/hw/misc/imx7_ccm.c
186
@@ -XXX,XX +XXX,XX @@
187
+/*
188
+ * Copyright (c) 2018, Impinj, Inc.
189
+ *
190
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
191
+ *
192
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
193
+ *
194
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
195
+ * See the COPYING file in the top-level directory.
196
+ */
197
+
198
+#include "qemu/osdep.h"
199
+#include "qemu/log.h"
200
+
201
+#include "hw/misc/imx7_ccm.h"
202
+
203
+static void imx7_analog_reset(DeviceState *dev)
204
+{
205
+ IMX7AnalogState *s = IMX7_ANALOG(dev);
206
+
207
+ memset(s->pmu, 0, sizeof(s->pmu));
208
+ memset(s->analog, 0, sizeof(s->analog));
209
+
210
+ s->analog[ANALOG_PLL_ARM] = 0x00002042;
211
+ s->analog[ANALOG_PLL_DDR] = 0x0060302c;
212
+ s->analog[ANALOG_PLL_DDR_SS] = 0x00000000;
213
+ s->analog[ANALOG_PLL_DDR_NUM] = 0x06aaac4d;
214
+ s->analog[ANALOG_PLL_DDR_DENOM] = 0x100003ec;
215
+ s->analog[ANALOG_PLL_480] = 0x00002000;
216
+ s->analog[ANALOG_PLL_480A] = 0x52605a56;
217
+ s->analog[ANALOG_PLL_480B] = 0x52525216;
218
+ s->analog[ANALOG_PLL_ENET] = 0x00001fc0;
219
+ s->analog[ANALOG_PLL_AUDIO] = 0x0001301b;
220
+ s->analog[ANALOG_PLL_AUDIO_SS] = 0x00000000;
221
+ s->analog[ANALOG_PLL_AUDIO_NUM] = 0x05f5e100;
222
+ s->analog[ANALOG_PLL_AUDIO_DENOM] = 0x2964619c;
223
+ s->analog[ANALOG_PLL_VIDEO] = 0x0008201b;
224
+ s->analog[ANALOG_PLL_VIDEO_SS] = 0x00000000;
225
+ s->analog[ANALOG_PLL_VIDEO_NUM] = 0x0000f699;
226
+ s->analog[ANALOG_PLL_VIDEO_DENOM] = 0x000f4240;
227
+ s->analog[ANALOG_PLL_MISC0] = 0x00000000;
228
+
229
+ /* all PLLs need to be locked */
230
+ s->analog[ANALOG_PLL_ARM] |= ANALOG_PLL_LOCK;
231
+ s->analog[ANALOG_PLL_DDR] |= ANALOG_PLL_LOCK;
232
+ s->analog[ANALOG_PLL_480] |= ANALOG_PLL_LOCK;
233
+ s->analog[ANALOG_PLL_480A] |= ANALOG_PLL_LOCK;
234
+ s->analog[ANALOG_PLL_480B] |= ANALOG_PLL_LOCK;
235
+ s->analog[ANALOG_PLL_ENET] |= ANALOG_PLL_LOCK;
236
+ s->analog[ANALOG_PLL_AUDIO] |= ANALOG_PLL_LOCK;
237
+ s->analog[ANALOG_PLL_VIDEO] |= ANALOG_PLL_LOCK;
238
+ s->analog[ANALOG_PLL_MISC0] |= ANALOG_PLL_LOCK;
239
+
240
+ /*
241
+ * Since I couldn't find any info about this in the reference
242
+ * manual the value of this register is based strictly on matching
243
+ * what Linux kernel expects it to be.
244
+ */
245
+ s->analog[ANALOG_DIGPROG] = 0x720000;
246
+ /*
247
+ * Set revision to be 1.0 (Arbitrary choice, no particular
248
+ * reason).
249
+ */
250
+ s->analog[ANALOG_DIGPROG] |= 0x000010;
251
+}
252
+
253
+static void imx7_ccm_reset(DeviceState *dev)
254
+{
255
+ IMX7CCMState *s = IMX7_CCM(dev);
256
+
257
+ memset(s->ccm, 0, sizeof(s->ccm));
258
+}
259
+
260
+#define CCM_INDEX(offset) (((offset) & ~(hwaddr)0xF) / sizeof(uint32_t))
261
+#define CCM_BITOP(offset) ((offset) & (hwaddr)0xF)
262
+
263
+enum {
264
+ CCM_BITOP_NONE = 0x00,
265
+ CCM_BITOP_SET = 0x04,
266
+ CCM_BITOP_CLR = 0x08,
267
+ CCM_BITOP_TOG = 0x0C,
268
+};
269
+
270
+static uint64_t imx7_set_clr_tog_read(void *opaque, hwaddr offset,
271
+ unsigned size)
272
+{
273
+ const uint32_t *mmio = opaque;
274
+
275
+ return mmio[CCM_INDEX(offset)];
276
+}
277
+
278
+static void imx7_set_clr_tog_write(void *opaque, hwaddr offset,
279
+ uint64_t value, unsigned size)
280
+{
281
+ const uint8_t bitop = CCM_BITOP(offset);
282
+ const uint32_t index = CCM_INDEX(offset);
283
+ uint32_t *mmio = opaque;
284
+
285
+ switch (bitop) {
286
+ case CCM_BITOP_NONE:
287
+ mmio[index] = value;
288
+ break;
289
+ case CCM_BITOP_SET:
290
+ mmio[index] |= value;
291
+ break;
292
+ case CCM_BITOP_CLR:
293
+ mmio[index] &= ~value;
294
+ break;
295
+ case CCM_BITOP_TOG:
296
+ mmio[index] ^= value;
297
+ break;
298
+ };
299
+}
300
+
301
+static const struct MemoryRegionOps imx7_set_clr_tog_ops = {
302
+ .read = imx7_set_clr_tog_read,
303
+ .write = imx7_set_clr_tog_write,
304
+ .endianness = DEVICE_NATIVE_ENDIAN,
305
+ .impl = {
306
+ /*
307
+ * Our device would not work correctly if the guest was doing
308
+ * unaligned access. This might not be a limitation on the real
309
+ * device but in practice there is no reason for a guest to access
310
+ * this device unaligned.
311
+ */
312
+ .min_access_size = 4,
313
+ .max_access_size = 4,
314
+ .unaligned = false,
315
+ },
316
+};
317
+
318
+static const struct MemoryRegionOps imx7_digprog_ops = {
319
+ .read = imx7_set_clr_tog_read,
320
+ .endianness = DEVICE_NATIVE_ENDIAN,
321
+ .impl = {
322
+ .min_access_size = 4,
323
+ .max_access_size = 4,
324
+ .unaligned = false,
325
+ },
326
+};
327
+
328
+static void imx7_ccm_init(Object *obj)
329
+{
330
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
331
+ IMX7CCMState *s = IMX7_CCM(obj);
332
+
333
+ memory_region_init_io(&s->iomem,
334
+ obj,
335
+ &imx7_set_clr_tog_ops,
336
+ s->ccm,
337
+ TYPE_IMX7_CCM ".ccm",
338
+ sizeof(s->ccm));
339
+
340
+ sysbus_init_mmio(sd, &s->iomem);
341
+}
342
+
343
+static void imx7_analog_init(Object *obj)
344
+{
345
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
346
+ IMX7AnalogState *s = IMX7_ANALOG(obj);
347
+
348
+ memory_region_init(&s->mmio.container, obj, TYPE_IMX7_ANALOG,
349
+ 0x10000);
350
+
351
+ memory_region_init_io(&s->mmio.analog,
352
+ obj,
353
+ &imx7_set_clr_tog_ops,
354
+ s->analog,
355
+ TYPE_IMX7_ANALOG,
356
+ sizeof(s->analog));
357
+
358
+ memory_region_add_subregion(&s->mmio.container,
359
+ 0x60, &s->mmio.analog);
360
+
361
+ memory_region_init_io(&s->mmio.pmu,
362
+ obj,
363
+ &imx7_set_clr_tog_ops,
364
+ s->pmu,
365
+ TYPE_IMX7_ANALOG ".pmu",
366
+ sizeof(s->pmu));
367
+
368
+ memory_region_add_subregion(&s->mmio.container,
369
+ 0x200, &s->mmio.pmu);
370
+
371
+ memory_region_init_io(&s->mmio.digprog,
372
+ obj,
373
+ &imx7_digprog_ops,
374
+ &s->analog[ANALOG_DIGPROG],
375
+ TYPE_IMX7_ANALOG ".digprog",
376
+ sizeof(uint32_t));
377
+
378
+ memory_region_add_subregion_overlap(&s->mmio.container,
379
+ 0x800, &s->mmio.digprog, 10);
380
+
381
+
382
+ sysbus_init_mmio(sd, &s->mmio.container);
383
+}
384
+
385
+static const VMStateDescription vmstate_imx7_ccm = {
386
+ .name = TYPE_IMX7_CCM,
387
+ .version_id = 1,
388
+ .minimum_version_id = 1,
389
+ .fields = (VMStateField[]) {
390
+ VMSTATE_UINT32_ARRAY(ccm, IMX7CCMState, CCM_MAX),
391
+ VMSTATE_END_OF_LIST()
392
+ },
393
+};
394
+
395
+static uint32_t imx7_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
396
+{
397
+ /*
398
+ * This function is "consumed" by GPT emulation code, however on
399
+ * i.MX7 each GPT block can have their own clock root. This means
400
+ * that this functions needs somehow to know requester's identity
401
+ * and the way to pass it: be it via additional IMXClk constants
402
+ * or by adding another argument to this method needs to be
403
+ * figured out
404
+ */
405
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Not implemented\n",
406
+ TYPE_IMX7_CCM, __func__);
407
+ return 0;
408
+}
409
+
410
+static void imx7_ccm_class_init(ObjectClass *klass, void *data)
411
+{
412
+ DeviceClass *dc = DEVICE_CLASS(klass);
413
+ IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
414
+
415
+ dc->reset = imx7_ccm_reset;
416
+ dc->vmsd = &vmstate_imx7_ccm;
417
+ dc->desc = "i.MX7 Clock Control Module";
418
+
419
+ ccm->get_clock_frequency = imx7_ccm_get_clock_frequency;
420
+}
421
+
422
+static const TypeInfo imx7_ccm_info = {
423
+ .name = TYPE_IMX7_CCM,
424
+ .parent = TYPE_IMX_CCM,
425
+ .instance_size = sizeof(IMX7CCMState),
426
+ .instance_init = imx7_ccm_init,
427
+ .class_init = imx7_ccm_class_init,
428
+};
429
+
430
+static const VMStateDescription vmstate_imx7_analog = {
431
+ .name = TYPE_IMX7_ANALOG,
432
+ .version_id = 1,
433
+ .minimum_version_id = 1,
434
+ .fields = (VMStateField[]) {
435
+ VMSTATE_UINT32_ARRAY(analog, IMX7AnalogState, ANALOG_MAX),
436
+ VMSTATE_UINT32_ARRAY(pmu, IMX7AnalogState, PMU_MAX),
437
+ VMSTATE_END_OF_LIST()
438
+ },
439
+};
440
+
441
+static void imx7_analog_class_init(ObjectClass *klass, void *data)
442
+{
443
+ DeviceClass *dc = DEVICE_CLASS(klass);
444
+
445
+ dc->reset = imx7_analog_reset;
446
+ dc->vmsd = &vmstate_imx7_analog;
447
+ dc->desc = "i.MX7 Analog Module";
448
+}
449
+
450
+static const TypeInfo imx7_analog_info = {
451
+ .name = TYPE_IMX7_ANALOG,
452
+ .parent = TYPE_SYS_BUS_DEVICE,
453
+ .instance_size = sizeof(IMX7AnalogState),
454
+ .instance_init = imx7_analog_init,
455
+ .class_init = imx7_analog_class_init,
456
+};
457
+
458
+static void imx7_ccm_register_type(void)
459
+{
460
+ type_register_static(&imx7_ccm_info);
461
+ type_register_static(&imx7_analog_info);
462
+}
463
+type_init(imx7_ccm_register_type)
464
--
53
--
465
2.16.1
54
2.34.1
466
55
467
56
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Move virt's PSCI DT fixup code to arm/boot.c and set this fixup to
3
Now that the cortex-a15 is under CONFIG_TCG, use as default CPU for a
4
happen automatically for every board that doesn't mark "psci-conduit"
4
KVM-only build the 'max' cpu.
5
as disabled. This way emulated boards other than "virt" that rely on
6
PSIC for SMP could benefit from that code.
7
5
8
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Note that we cannot use 'host' here because the qtests can run without
9
Cc: Jason Wang <jasowang@redhat.com>
7
any other accelerator (than qtest) and 'host' depends on KVM being
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
enabled.
11
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
12
Cc: Michael S. Tsirkin <mst@redhat.com>
10
Signed-off-by: Fabiano Rosas <farosas@suse.de>
13
Cc: qemu-devel@nongnu.org
11
Acked-by: Richard Henderson <richard.henderson@linaro.org>
14
Cc: qemu-arm@nongnu.org
12
Reviewed-by: Thomas Huth <thuth@redhat.com>
15
Cc: yurovsky@gmail.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
14
---
21
hw/arm/boot.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15
hw/arm/virt.c | 4 ++++
22
hw/arm/virt.c | 61 -------------------------------------------------------
16
1 file changed, 4 insertions(+)
23
2 files changed, 65 insertions(+), 61 deletions(-)
24
17
25
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/boot.c
28
+++ b/hw/arm/boot.c
29
@@ -XXX,XX +XXX,XX @@ static void set_kernel_args_old(const struct arm_boot_info *info)
30
}
31
}
32
33
+static void fdt_add_psci_node(void *fdt)
34
+{
35
+ uint32_t cpu_suspend_fn;
36
+ uint32_t cpu_off_fn;
37
+ uint32_t cpu_on_fn;
38
+ uint32_t migrate_fn;
39
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
40
+ const char *psci_method;
41
+ int64_t psci_conduit;
42
+
43
+ psci_conduit = object_property_get_int(OBJECT(armcpu),
44
+ "psci-conduit",
45
+ &error_abort);
46
+ switch (psci_conduit) {
47
+ case QEMU_PSCI_CONDUIT_DISABLED:
48
+ return;
49
+ case QEMU_PSCI_CONDUIT_HVC:
50
+ psci_method = "hvc";
51
+ break;
52
+ case QEMU_PSCI_CONDUIT_SMC:
53
+ psci_method = "smc";
54
+ break;
55
+ default:
56
+ g_assert_not_reached();
57
+ }
58
+
59
+ qemu_fdt_add_subnode(fdt, "/psci");
60
+ if (armcpu->psci_version == 2) {
61
+ const char comp[] = "arm,psci-0.2\0arm,psci";
62
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
63
+
64
+ cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
65
+ if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
66
+ cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
67
+ cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
68
+ migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
69
+ } else {
70
+ cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
71
+ cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
72
+ migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
73
+ }
74
+ } else {
75
+ qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
76
+
77
+ cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
78
+ cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
79
+ cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
80
+ migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
81
+ }
82
+
83
+ /* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
84
+ * to the instruction that should be used to invoke PSCI functions.
85
+ * However, the device tree binding uses 'method' instead, so that is
86
+ * what we should use here.
87
+ */
88
+ qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
89
+
90
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
91
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
92
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
93
+ qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
94
+}
95
+
96
/**
97
* load_dtb() - load a device tree binary image into memory
98
* @addr: the address to load the image at
99
@@ -XXX,XX +XXX,XX @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
100
}
101
}
102
103
+ fdt_add_psci_node(fdt);
104
+
105
if (binfo->modify_dtb) {
106
binfo->modify_dtb(binfo, fdt);
107
}
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
109
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/virt.c
20
--- a/hw/arm/virt.c
111
+++ b/hw/arm/virt.c
21
+++ b/hw/arm/virt.c
112
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
22
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
113
}
23
mc->minimum_page_bits = 12;
114
}
24
mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
115
25
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
116
-static void fdt_add_psci_node(const VirtMachineState *vms)
26
+#ifdef CONFIG_TCG
117
-{
27
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
118
- uint32_t cpu_suspend_fn;
28
+#else
119
- uint32_t cpu_off_fn;
29
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("max");
120
- uint32_t cpu_on_fn;
30
+#endif
121
- uint32_t migrate_fn;
31
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
122
- void *fdt = vms->fdt;
32
mc->kvm_type = virt_kvm_type;
123
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
33
assert(!mc->get_hotplug_handler);
124
- const char *psci_method;
125
-
126
- switch (vms->psci_conduit) {
127
- case QEMU_PSCI_CONDUIT_DISABLED:
128
- return;
129
- case QEMU_PSCI_CONDUIT_HVC:
130
- psci_method = "hvc";
131
- break;
132
- case QEMU_PSCI_CONDUIT_SMC:
133
- psci_method = "smc";
134
- break;
135
- default:
136
- g_assert_not_reached();
137
- }
138
-
139
- qemu_fdt_add_subnode(fdt, "/psci");
140
- if (armcpu->psci_version == 2) {
141
- const char comp[] = "arm,psci-0.2\0arm,psci";
142
- qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
143
-
144
- cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
145
- if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
146
- cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
147
- cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
148
- migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
149
- } else {
150
- cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
151
- cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
152
- migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
153
- }
154
- } else {
155
- qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
156
-
157
- cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
158
- cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
159
- cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
160
- migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
161
- }
162
-
163
- /* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
164
- * to the instruction that should be used to invoke PSCI functions.
165
- * However, the device tree binding uses 'method' instead, so that is
166
- * what we should use here.
167
- */
168
- qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
169
-
170
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
171
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
172
- qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
173
- qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
174
-}
175
-
176
static void fdt_add_timer_nodes(const VirtMachineState *vms)
177
{
178
/* On real hardware these interrupts are level-triggered.
179
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
180
}
181
fdt_add_timer_nodes(vms);
182
fdt_add_cpu_nodes(vms);
183
- fdt_add_psci_node(vms);
184
185
memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
186
machine->ram_size);
187
--
34
--
188
2.16.1
35
2.34.1
189
190
diff view generated by jsdifflib
1
Handle possible MPU faults, SAU faults or bus errors when
1
From: Fabiano Rosas <farosas@suse.de>
2
popping register state off the stack during exception return.
3
2
3
Signed-off-by: Fabiano Rosas <farosas@suse.de>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Acked-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 1517324542-6607-8-git-send-email-peter.maydell@linaro.org
7
---
7
---
8
target/arm/helper.c | 115 ++++++++++++++++++++++++++++++++++++++++++----------
8
tests/qtest/arm-cpu-features.c | 28 ++++++++++++++++++----------
9
1 file changed, 94 insertions(+), 21 deletions(-)
9
1 file changed, 18 insertions(+), 10 deletions(-)
10
10
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
13
--- a/tests/qtest/arm-cpu-features.c
14
+++ b/target/arm/helper.c
14
+++ b/tests/qtest/arm-cpu-features.c
15
@@ -XXX,XX +XXX,XX @@ pend_fault:
15
@@ -XXX,XX +XXX,XX @@
16
return false;
16
#define SVE_MAX_VQ 16
17
}
17
18
18
#define MACHINE "-machine virt,gic-version=max -accel tcg "
19
+static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
19
-#define MACHINE_KVM "-machine virt,gic-version=max -accel kvm -accel tcg "
20
+ ARMMMUIdx mmu_idx)
20
+#define MACHINE_KVM "-machine virt,gic-version=max -accel kvm "
21
+{
21
#define QUERY_HEAD "{ 'execute': 'query-cpu-model-expansion', " \
22
+ CPUState *cs = CPU(cpu);
22
" 'arguments': { 'type': 'full', "
23
+ CPUARMState *env = &cpu->env;
23
#define QUERY_TAIL "}}"
24
+ MemTxAttrs attrs = {};
24
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
25
+ MemTxResult txres;
25
{
26
+ target_ulong page_size;
26
g_test_init(&argc, &argv, NULL);
27
+ hwaddr physaddr;
27
28
+ int prot;
28
- qtest_add_data_func("/arm/query-cpu-model-expansion",
29
+ ARMMMUFaultInfo fi;
29
- NULL, test_query_cpu_model_expansion);
30
+ bool secure = mmu_idx & ARM_MMU_IDX_M_S;
30
+ if (qtest_has_accel("tcg")) {
31
+ int exc;
31
+ qtest_add_data_func("/arm/query-cpu-model-expansion",
32
+ bool exc_secure;
32
+ NULL, test_query_cpu_model_expansion);
33
+ uint32_t value;
34
+
35
+ if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &physaddr,
36
+ &attrs, &prot, &page_size, &fi, NULL)) {
37
+ /* MPU/SAU lookup failed */
38
+ if (fi.type == ARMFault_QEMU_SFault) {
39
+ qemu_log_mask(CPU_LOG_INT,
40
+ "...SecureFault with SFSR.AUVIOL during unstack\n");
41
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
42
+ env->v7m.sfar = addr;
43
+ exc = ARMV7M_EXCP_SECURE;
44
+ exc_secure = false;
45
+ } else {
46
+ qemu_log_mask(CPU_LOG_INT,
47
+ "...MemManageFault with CFSR.MUNSTKERR\n");
48
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MUNSTKERR_MASK;
49
+ exc = ARMV7M_EXCP_MEM;
50
+ exc_secure = secure;
51
+ }
52
+ goto pend_fault;
53
+ }
33
+ }
54
+
34
+
55
+ value = address_space_ldl(arm_addressspace(cs, attrs), physaddr,
35
+ if (!g_str_equal(qtest_get_arch(), "aarch64")) {
56
+ attrs, &txres);
36
+ goto out;
57
+ if (txres != MEMTX_OK) {
37
+ }
58
+ /* BusFault trying to read the data */
38
59
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
39
/*
60
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_UNSTKERR_MASK;
40
* For now we only run KVM specific tests with AArch64 QEMU in
61
+ exc = ARMV7M_EXCP_BUS;
41
* order avoid attempting to run an AArch32 QEMU with KVM on
62
+ exc_secure = false;
42
* AArch64 hosts. That won't work and isn't easy to detect.
63
+ goto pend_fault;
43
*/
44
- if (g_str_equal(qtest_get_arch(), "aarch64") && qtest_has_accel("kvm")) {
45
+ if (qtest_has_accel("kvm")) {
46
/*
47
* This tests target the 'host' CPU type, so register it only if
48
* KVM is available.
49
*/
50
qtest_add_data_func("/arm/kvm/query-cpu-model-expansion",
51
NULL, test_query_cpu_model_expansion_kvm);
52
- }
53
54
- if (g_str_equal(qtest_get_arch(), "aarch64")) {
55
- qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-max-vq-8",
56
- NULL, sve_tests_sve_max_vq_8);
57
- qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off",
58
- NULL, sve_tests_sve_off);
59
qtest_add_data_func("/arm/kvm/query-cpu-model-expansion/sve-off",
60
NULL, sve_tests_sve_off_kvm);
61
}
62
63
+ if (qtest_has_accel("tcg")) {
64
+ qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-max-vq-8",
65
+ NULL, sve_tests_sve_max_vq_8);
66
+ qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off",
67
+ NULL, sve_tests_sve_off);
64
+ }
68
+ }
65
+
69
+
66
+ *dest = value;
70
+out:
67
+ return true;
71
return g_test_run();
68
+
72
}
69
+pend_fault:
70
+ /* By pending the exception at this point we are making
71
+ * the IMPDEF choice "overridden exceptions pended" (see the
72
+ * MergeExcInfo() pseudocode). The other choice would be to not
73
+ * pend them now and then make a choice about which to throw away
74
+ * later if we have two derived exceptions.
75
+ */
76
+ armv7m_nvic_set_pending(env->nvic, exc, exc_secure);
77
+ return false;
78
+}
79
+
80
/* Return true if we're using the process stack pointer (not the MSP) */
81
static bool v7m_using_psp(CPUARMState *env)
82
{
83
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
84
!return_to_handler,
85
return_to_sp_process);
86
uint32_t frameptr = *frame_sp_p;
87
+ bool pop_ok = true;
88
+ ARMMMUIdx mmu_idx;
89
+
90
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, return_to_secure,
91
+ !return_to_handler);
92
93
if (!QEMU_IS_ALIGNED(frameptr, 8) &&
94
arm_feature(env, ARM_FEATURE_V8)) {
95
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
96
return;
97
}
98
99
- env->regs[4] = ldl_phys(cs->as, frameptr + 0x8);
100
- env->regs[5] = ldl_phys(cs->as, frameptr + 0xc);
101
- env->regs[6] = ldl_phys(cs->as, frameptr + 0x10);
102
- env->regs[7] = ldl_phys(cs->as, frameptr + 0x14);
103
- env->regs[8] = ldl_phys(cs->as, frameptr + 0x18);
104
- env->regs[9] = ldl_phys(cs->as, frameptr + 0x1c);
105
- env->regs[10] = ldl_phys(cs->as, frameptr + 0x20);
106
- env->regs[11] = ldl_phys(cs->as, frameptr + 0x24);
107
+ pop_ok =
108
+ v7m_stack_read(cpu, &env->regs[4], frameptr + 0x8, mmu_idx) &&
109
+ v7m_stack_read(cpu, &env->regs[4], frameptr + 0x8, mmu_idx) &&
110
+ v7m_stack_read(cpu, &env->regs[5], frameptr + 0xc, mmu_idx) &&
111
+ v7m_stack_read(cpu, &env->regs[6], frameptr + 0x10, mmu_idx) &&
112
+ v7m_stack_read(cpu, &env->regs[7], frameptr + 0x14, mmu_idx) &&
113
+ v7m_stack_read(cpu, &env->regs[8], frameptr + 0x18, mmu_idx) &&
114
+ v7m_stack_read(cpu, &env->regs[9], frameptr + 0x1c, mmu_idx) &&
115
+ v7m_stack_read(cpu, &env->regs[10], frameptr + 0x20, mmu_idx) &&
116
+ v7m_stack_read(cpu, &env->regs[11], frameptr + 0x24, mmu_idx);
117
118
frameptr += 0x28;
119
}
120
121
- /* Pop registers. TODO: make these accesses use the correct
122
- * attributes and address space (S/NS, priv/unpriv) and handle
123
- * memory transaction failures.
124
- */
125
- env->regs[0] = ldl_phys(cs->as, frameptr);
126
- env->regs[1] = ldl_phys(cs->as, frameptr + 0x4);
127
- env->regs[2] = ldl_phys(cs->as, frameptr + 0x8);
128
- env->regs[3] = ldl_phys(cs->as, frameptr + 0xc);
129
- env->regs[12] = ldl_phys(cs->as, frameptr + 0x10);
130
- env->regs[14] = ldl_phys(cs->as, frameptr + 0x14);
131
- env->regs[15] = ldl_phys(cs->as, frameptr + 0x18);
132
+ /* Pop registers */
133
+ pop_ok = pop_ok &&
134
+ v7m_stack_read(cpu, &env->regs[0], frameptr, mmu_idx) &&
135
+ v7m_stack_read(cpu, &env->regs[1], frameptr + 0x4, mmu_idx) &&
136
+ v7m_stack_read(cpu, &env->regs[2], frameptr + 0x8, mmu_idx) &&
137
+ v7m_stack_read(cpu, &env->regs[3], frameptr + 0xc, mmu_idx) &&
138
+ v7m_stack_read(cpu, &env->regs[12], frameptr + 0x10, mmu_idx) &&
139
+ v7m_stack_read(cpu, &env->regs[14], frameptr + 0x14, mmu_idx) &&
140
+ v7m_stack_read(cpu, &env->regs[15], frameptr + 0x18, mmu_idx) &&
141
+ v7m_stack_read(cpu, &xpsr, frameptr + 0x1c, mmu_idx);
142
+
143
+ if (!pop_ok) {
144
+ /* v7m_stack_read() pended a fault, so take it (as a tail
145
+ * chained exception on the same stack frame)
146
+ */
147
+ v7m_exception_taken(cpu, excret, true, false);
148
+ return;
149
+ }
150
151
/* Returning from an exception with a PC with bit 0 set is defined
152
* behaviour on v8M (bit 0 is ignored), but for v7M it was specified
153
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
154
}
155
}
156
157
- xpsr = ldl_phys(cs->as, frameptr + 0x1c);
158
-
159
if (arm_feature(env, ARM_FEATURE_V8)) {
160
/* For v8M we have to check whether the xPSR exception field
161
* matches the EXCRET value for return to handler/thread
162
--
73
--
163
2.16.1
74
2.34.1
164
165
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Add support for the new ARMv8.2 SHA-3, SM3, SM4 and SHA-512 instructions to
3
These tests set -accel tcg, so restrict them to when TCG is present.
4
AArch64 user mode emulation.
5
4
6
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
5
Signed-off-by: Fabiano Rosas <farosas@suse.de>
7
Message-id: 20180207111729.15737-6-ard.biesheuvel@linaro.org
6
Acked-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
linux-user/elfload.c | 19 +++++++++++++++++++
10
tests/qtest/meson.build | 4 ++--
12
target/arm/cpu64.c | 4 ++++
11
1 file changed, 2 insertions(+), 2 deletions(-)
13
2 files changed, 23 insertions(+)
14
12
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
13
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
15
--- a/tests/qtest/meson.build
18
+++ b/linux-user/elfload.c
16
+++ b/tests/qtest/meson.build
19
@@ -XXX,XX +XXX,XX @@ enum {
17
@@ -XXX,XX +XXX,XX @@ qtests_arm = \
20
ARM_HWCAP_A64_SHA1 = 1 << 5,
18
# TODO: once aarch64 TCG is fixed on ARM 32 bit host, make bios-tables-test unconditional
21
ARM_HWCAP_A64_SHA2 = 1 << 6,
19
qtests_aarch64 = \
22
ARM_HWCAP_A64_CRC32 = 1 << 7,
20
(cpu != 'arm' and unpack_edk2_blobs ? ['bios-tables-test'] : []) + \
23
+ ARM_HWCAP_A64_ATOMICS = 1 << 8,
21
- (config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? ['tpm-tis-device-test'] : []) + \
24
+ ARM_HWCAP_A64_FPHP = 1 << 9,
22
- (config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? ['tpm-tis-device-swtpm-test'] : []) + \
25
+ ARM_HWCAP_A64_ASIMDHP = 1 << 10,
23
+ (config_all.has_key('CONFIG_TCG') and config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? \
26
+ ARM_HWCAP_A64_CPUID = 1 << 11,
24
+ ['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) + \
27
+ ARM_HWCAP_A64_ASIMDRDM = 1 << 12,
25
(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
28
+ ARM_HWCAP_A64_JSCVT = 1 << 13,
26
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
29
+ ARM_HWCAP_A64_FCMA = 1 << 14,
27
['arm-cpu-features',
30
+ ARM_HWCAP_A64_LRCPC = 1 << 15,
31
+ ARM_HWCAP_A64_DCPOP = 1 << 16,
32
+ ARM_HWCAP_A64_SHA3 = 1 << 17,
33
+ ARM_HWCAP_A64_SM3 = 1 << 18,
34
+ ARM_HWCAP_A64_SM4 = 1 << 19,
35
+ ARM_HWCAP_A64_ASIMDDP = 1 << 20,
36
+ ARM_HWCAP_A64_SHA512 = 1 << 21,
37
+ ARM_HWCAP_A64_SVE = 1 << 22,
38
};
39
40
#define ELF_HWCAP get_elf_hwcap()
41
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
42
GET_FEATURE(ARM_FEATURE_V8_SHA1, ARM_HWCAP_A64_SHA1);
43
GET_FEATURE(ARM_FEATURE_V8_SHA256, ARM_HWCAP_A64_SHA2);
44
GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP_A64_CRC32);
45
+ GET_FEATURE(ARM_FEATURE_V8_SHA3, ARM_HWCAP_A64_SHA3);
46
+ GET_FEATURE(ARM_FEATURE_V8_SM3, ARM_HWCAP_A64_SM3);
47
+ GET_FEATURE(ARM_FEATURE_V8_SM4, ARM_HWCAP_A64_SM4);
48
+ GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512);
49
#undef GET_FEATURE
50
51
return hwcaps;
52
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu64.c
55
+++ b/target/arm/cpu64.c
56
@@ -XXX,XX +XXX,XX @@ static void aarch64_any_initfn(Object *obj)
57
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
58
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
59
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
60
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
61
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
62
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
63
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
64
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
65
set_feature(&cpu->env, ARM_FEATURE_CRC);
66
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
67
--
28
--
68
2.16.1
29
2.34.1
69
70
diff view generated by jsdifflib