1
Another lump of target-arm patches. I still have some patches in
1
Hi; here's the first target-arm pullreq for the 7.0 cycle.
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
thanks
6
-- PMM
4
-- PMM
7
5
8
The following changes since commit 04bb7fe2bf55bdf66d5b7a5a719b40bbb4048178:
6
The following changes since commit 76b56fdfc9fa43ec6e5986aee33f108c6c6a511e:
9
7
10
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20180208' into staging (2018-02-08 17:41:15 +0000)
8
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2021-12-14 12:46:18 -0800)
11
9
12
are available in the Git repository at:
10
are available in the Git repository at:
13
11
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180209
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211215
15
13
16
for you to fetch changes up to bbba7757bacc9f890a3f028d328b4b429dbe78ec:
14
for you to fetch changes up to aed176558806674d030a8305d989d4e6a5073359:
17
15
18
hw/core/generic-loader: Allow PC to be set on command line (2018-02-09 10:55:40 +0000)
16
tests/acpi: add expected blob for VIOT test on virt machine (2021-12-15 10:35:26 +0000)
19
17
20
----------------------------------------------------------------
18
----------------------------------------------------------------
21
target-arm queue:
19
target-arm queue:
22
* Support M profile derived exceptions on exception entry and exit
20
* ITS: error reporting cleanup
23
* Implement AArch64 v8.2 crypto insns (SHA-512, SHA-3, SM3, SM4)
21
* aspeed: improve documentation
24
* Implement working i.MX6 SD controller
22
* Fix STM32F2XX USART data register readout
25
* Various devices preparatory to i.MX7 support
23
* allow emulated GICv3 to be disabled in non-TCG builds
26
* Preparatory patches for SVE emulation
24
* fix exception priority for singlestep, misaligned PC, bp, etc
27
* v8M: Fix bug in implementation of 'TT' insn
25
* Correct calculation of tlb range invalidate length
28
* Give useful error if user tries to use userspace GICv3 with KVM
26
* npcm7xx_emc: fix missing queue_flush
27
* virt: Add VIOT ACPI table for virtio-iommu
28
* target/i386: Use assert() to sanity-check b1 in SSE decode
29
* Don't include qemu-common unnecessarily
29
30
30
----------------------------------------------------------------
31
----------------------------------------------------------------
31
Andrey Smirnov (10):
32
Alex Bennée (1):
32
sdhci: Add i.MX specific subtype of SDHCI
33
hw/intc: clean-up error reporting for failed ITS cmd
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
34
43
Ard Biesheuvel (5):
35
Jean-Philippe Brucker (8):
44
target/arm: implement SHA-512 instructions
36
hw/arm/virt-acpi-build: Add VIOT table for virtio-iommu
45
target/arm: implement SHA-3 instructions
37
hw/arm/virt: Remove device tree restriction for virtio-iommu
46
target/arm: implement SM3 instructions
38
hw/arm/virt: Reject instantiation of multiple IOMMUs
47
target/arm: implement SM4 instructions
39
hw/arm/virt: Use object_property_set instead of qdev_prop_set
48
target/arm: enable user-mode SHA-3, SM3, SM4 and SHA-512 instruction support
40
tests/acpi: allow updates of VIOT expected data files
41
tests/acpi: add test case for VIOT
42
tests/acpi: add expected blobs for VIOT test on q35 machine
43
tests/acpi: add expected blob for VIOT test on virt machine
49
44
50
Christoffer Dall (1):
45
Joel Stanley (4):
51
target/arm/kvm: gic: Prevent creating userspace GICv3 with KVM
46
docs: aspeed: Add new boards
47
docs: aspeed: Update OpenBMC image URL
48
docs: aspeed: Give an example of booting a kernel
49
docs: aspeed: ADC is now modelled
52
50
53
Peter Maydell (9):
51
Olivier Hériveaux (1):
54
target/arm: Add armv7m_nvic_set_pending_derived()
52
Fix STM32F2XX USART data register readout
55
target/arm: Split "get pending exception info" from "acknowledge it"
56
target/arm: Add ignore_stackfaults argument to v7m_exception_taken()
57
target/arm: Make v7M exception entry stack push check MPU
58
target/arm: Make v7m_push_callee_stack() honour MPU
59
target/arm: Make exception vector loads honour the SAU
60
target/arm: Handle exceptions during exception stack pop
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
53
64
Richard Henderson (5):
54
Patrick Venture (1):
65
target/arm: Expand vector registers for SVE
55
hw/net: npcm7xx_emc fix missing queue_flush
66
target/arm: Add predicate registers for SVE
67
target/arm: Add SVE to migration state
68
target/arm: Add ZCR_ELx
69
target/arm: Add SVE state to TB->FLAGS
70
56
71
hw/intc/Makefile.objs | 2 +-
57
Peter Maydell (6):
72
hw/misc/Makefile.objs | 4 +
58
target/i386: Use assert() to sanity-check b1 in SSE decode
73
hw/usb/Makefile.objs | 1 +
59
include/hw/i386: Don't include qemu-common.h in .h files
74
hw/sd/sdhci-internal.h | 23 ++
60
target/hexagon/cpu.h: don't include qemu-common.h
75
include/hw/intc/imx_gpcv2.h | 22 ++
61
target/rx/cpu.h: Don't include qemu-common.h
76
include/hw/misc/imx2_wdt.h | 33 +++
62
hw/arm: Don't include qemu-common.h unnecessarily
77
include/hw/misc/imx7_ccm.h | 139 +++++++++++
63
target/arm: Correct calculation of tlb range invalidate length
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
64
65
Philippe Mathieu-Daudé (2):
66
hw/intc/arm_gicv3: Extract gicv3_set_gicv3state from arm_gicv3_cpuif.c
67
hw/intc/arm_gicv3: Introduce CONFIG_ARM_GIC_TCG Kconfig selector
68
69
Richard Henderson (10):
70
target/arm: Hoist pc_next to a local variable in aarch64_tr_translate_insn
71
target/arm: Hoist pc_next to a local variable in arm_tr_translate_insn
72
target/arm: Hoist pc_next to a local variable in thumb_tr_translate_insn
73
target/arm: Split arm_pre_translate_insn
74
target/arm: Advance pc for arch single-step exception
75
target/arm: Split compute_fsr_fsc out of arm_deliver_fault
76
target/arm: Take an exception if PC is misaligned
77
target/arm: Assert thumb pc is aligned
78
target/arm: Suppress bp for exceptions with more priority
79
tests/tcg: Add arm and aarch64 pc alignment tests
80
81
docs/system/arm/aspeed.rst | 26 ++++++++++++----
82
include/hw/i386/microvm.h | 1 -
83
include/hw/i386/x86.h | 1 -
84
target/arm/helper.h | 1 +
85
target/arm/syndrome.h | 5 +++
86
target/hexagon/cpu.h | 1 -
87
target/rx/cpu.h | 1 -
88
hw/arm/boot.c | 1 -
89
hw/arm/digic_boards.c | 1 -
90
hw/arm/highbank.c | 1 -
91
hw/arm/npcm7xx_boards.c | 1 -
92
hw/arm/sbsa-ref.c | 1 -
93
hw/arm/stm32f405_soc.c | 1 -
94
hw/arm/vexpress.c | 1 -
95
hw/arm/virt-acpi-build.c | 7 +++++
96
hw/arm/virt.c | 21 ++++++-------
97
hw/char/stm32f2xx_usart.c | 3 +-
98
hw/intc/arm_gicv3.c | 2 +-
99
hw/intc/arm_gicv3_cpuif.c | 10 +-----
100
hw/intc/arm_gicv3_cpuif_common.c | 22 +++++++++++++
101
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++--------
102
hw/net/npcm7xx_emc.c | 18 +++++------
103
hw/virtio/virtio-iommu-pci.c | 12 ++------
104
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++------------
105
linux-user/hexagon/cpu_loop.c | 1 +
106
target/arm/debug_helper.c | 23 ++++++++++++++
107
target/arm/gdbstub.c | 9 ++++--
108
target/arm/helper.c | 6 ++--
109
target/arm/machine.c | 10 ++++++
110
target/arm/tlb_helper.c | 63 ++++++++++++++++++++++++++++----------
111
target/arm/translate-a64.c | 23 ++++++++++++--
112
target/arm/translate.c | 58 ++++++++++++++++++++++++++---------
113
target/i386/tcg/translate.c | 12 ++------
114
tests/qtest/bios-tables-test.c | 38 +++++++++++++++++++++++
115
tests/tcg/aarch64/pcalign-a64.c | 37 ++++++++++++++++++++++
116
tests/tcg/arm/pcalign-a32.c | 46 ++++++++++++++++++++++++++++
117
hw/arm/Kconfig | 1 +
118
hw/intc/Kconfig | 5 +++
119
hw/intc/meson.build | 11 ++++---
120
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
121
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
122
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
123
tests/tcg/aarch64/Makefile.target | 4 +--
124
tests/tcg/arm/Makefile.target | 4 +++
125
44 files changed, 429 insertions(+), 145 deletions(-)
126
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
127
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
128
create mode 100644 tests/tcg/arm/pcalign-a32.c
129
create mode 100644 tests/data/acpi/q35/DSDT.viot
130
create mode 100644 tests/data/acpi/q35/VIOT.viot
131
create mode 100644 tests/data/acpi/virt/VIOT
132
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
While trying to debug a GIC ITS failure I saw some guest errors that
4
had poor formatting as well as leaving me confused as to what failed.
5
As most of the checks aren't possible without a valid dte split that
6
check apart and then check the other conditions in steps. This avoids
7
us relying on undefined data.
4
8
9
I still get a failure with the current kvm-unit-tests but at least I
10
know (partially) why now:
11
12
Exception return from AArch64 EL1 to AArch64 EL1 PC 0x40080588
13
PASS: gicv3: its-trigger: inv/invall: dev2/eventid=20 now triggers an LPI
14
ITS: MAPD devid=2 size = 0x8 itt=0x40430000 valid=0
15
INT dev_id=2 event_id=20
16
process_its_cmd: invalid command attributes: invalid dte: 0 for 2 (MEM_TX: 0)
17
PASS: gicv3: its-trigger: mapd valid=false: no LPI after device unmap
18
SUMMARY: 6 tests, 1 unexpected failures
19
20
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20211112170454.3158925-1-alex.bennee@linaro.org
23
Cc: Shashi Mallela <shashi.mallela@linaro.org>
5
Cc: Peter Maydell <peter.maydell@linaro.org>
24
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>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
26
---
17
hw/intc/Makefile.objs | 2 +-
27
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++++++++++++++------------
18
include/hw/intc/imx_gpcv2.h | 22 ++++++++
28
1 file changed, 27 insertions(+), 12 deletions(-)
19
hw/intc/imx_gpcv2.c | 125 ++++++++++++++++++++++++++++++++++++++++++++
20
3 files changed, 148 insertions(+), 1 deletion(-)
21
create mode 100644 include/hw/intc/imx_gpcv2.h
22
create mode 100644 hw/intc/imx_gpcv2.c
23
29
24
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
30
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
25
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/intc/Makefile.objs
32
--- a/hw/intc/arm_gicv3_its.c
27
+++ b/hw/intc/Makefile.objs
33
+++ b/hw/intc/arm_gicv3_its.c
28
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XILINX) += xilinx_intc.o
34
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
29
common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-pmu-iomod-intc.o
35
if (res != MEMTX_OK) {
30
common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-ipi.o
36
return result;
31
common-obj-$(CONFIG_ETRAXFS) += etraxfs_pic.o
37
}
32
-common-obj-$(CONFIG_IMX) += imx_avic.o
38
+ } else {
33
+common-obj-$(CONFIG_IMX) += imx_avic.o imx_gpcv2.o
39
+ qemu_log_mask(LOG_GUEST_ERROR,
34
common-obj-$(CONFIG_LM32) += lm32_pic.o
40
+ "%s: invalid command attributes: "
35
common-obj-$(CONFIG_REALVIEW) += realview_gic.o
41
+ "invalid dte: %"PRIx64" for %d (MEM_TX: %d)\n",
36
common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
42
+ __func__, dte, devid, res);
37
diff --git a/include/hw/intc/imx_gpcv2.h b/include/hw/intc/imx_gpcv2.h
43
+ return result;
38
new file mode 100644
44
}
39
index XXXXXXX..XXXXXXX
45
40
--- /dev/null
46
- if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid ||
41
+++ b/include/hw/intc/imx_gpcv2.h
47
- !cte_valid || (eventid > max_eventid)) {
42
@@ -XXX,XX +XXX,XX @@
43
+#ifndef IMX_GPCV2_H
44
+#define IMX_GPCV2_H
45
+
46
+#include "hw/sysbus.h"
47
+
48
+enum IMXGPCv2Registers {
49
+ GPC_NUM = 0xE00 / sizeof(uint32_t),
50
+};
51
+
52
+typedef struct IMXGPCv2State {
53
+ /*< private >*/
54
+ SysBusDevice parent_obj;
55
+
56
+ /*< public >*/
57
+ MemoryRegion iomem;
58
+ uint32_t regs[GPC_NUM];
59
+} IMXGPCv2State;
60
+
61
+#define TYPE_IMX_GPCV2 "imx-gpcv2"
62
+#define IMX_GPCV2(obj) OBJECT_CHECK(IMXGPCv2State, (obj), TYPE_IMX_GPCV2)
63
+
64
+#endif /* IMX_GPCV2_H */
65
diff --git a/hw/intc/imx_gpcv2.c b/hw/intc/imx_gpcv2.c
66
new file mode 100644
67
index XXXXXXX..XXXXXXX
68
--- /dev/null
69
+++ b/hw/intc/imx_gpcv2.c
70
@@ -XXX,XX +XXX,XX @@
71
+/*
72
+ * Copyright (c) 2018, Impinj, Inc.
73
+ *
74
+ * i.MX7 GPCv2 block emulation code
75
+ *
76
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
77
+ *
78
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
79
+ * See the COPYING file in the top-level directory.
80
+ */
81
+
82
+#include "qemu/osdep.h"
83
+#include "hw/intc/imx_gpcv2.h"
84
+#include "qemu/log.h"
85
+
86
+#define GPC_PU_PGC_SW_PUP_REQ 0x0f8
87
+#define GPC_PU_PGC_SW_PDN_REQ 0x104
88
+
89
+#define USB_HSIC_PHY_SW_Pxx_REQ BIT(4)
90
+#define USB_OTG2_PHY_SW_Pxx_REQ BIT(3)
91
+#define USB_OTG1_PHY_SW_Pxx_REQ BIT(2)
92
+#define PCIE_PHY_SW_Pxx_REQ BIT(1)
93
+#define MIPI_PHY_SW_Pxx_REQ BIT(0)
94
+
95
+
96
+static void imx_gpcv2_reset(DeviceState *dev)
97
+{
98
+ IMXGPCv2State *s = IMX_GPCV2(dev);
99
+
100
+ memset(s->regs, 0, sizeof(s->regs));
101
+}
102
+
103
+static uint64_t imx_gpcv2_read(void *opaque, hwaddr offset,
104
+ unsigned size)
105
+{
106
+ IMXGPCv2State *s = opaque;
107
+
108
+ return s->regs[offset / sizeof(uint32_t)];
109
+}
110
+
111
+static void imx_gpcv2_write(void *opaque, hwaddr offset,
112
+ uint64_t value, unsigned size)
113
+{
114
+ IMXGPCv2State *s = opaque;
115
+ const size_t idx = offset / sizeof(uint32_t);
116
+
117
+ s->regs[idx] = value;
118
+
48
+
119
+ /*
49
+ /*
120
+ * Real HW will clear those bits once as a way to indicate that
50
+ * In this implementation, in case of guest errors we ignore the
121
+ * power up request is complete
51
+ * command and move onto the next command in the queue.
122
+ */
52
+ */
123
+ if (offset == GPC_PU_PGC_SW_PUP_REQ ||
53
+ if (devid > s->dt.maxids.max_devids) {
124
+ offset == GPC_PU_PGC_SW_PDN_REQ) {
54
qemu_log_mask(LOG_GUEST_ERROR,
125
+ s->regs[idx] &= ~(USB_HSIC_PHY_SW_Pxx_REQ |
55
- "%s: invalid command attributes "
126
+ USB_OTG2_PHY_SW_Pxx_REQ |
56
- "devid %d or eventid %d or invalid dte %d or"
127
+ USB_OTG1_PHY_SW_Pxx_REQ |
57
- "invalid cte %d or invalid ite %d\n",
128
+ PCIE_PHY_SW_Pxx_REQ |
58
- __func__, devid, eventid, dte_valid, cte_valid,
129
+ MIPI_PHY_SW_Pxx_REQ);
59
- ite_valid);
130
+ }
60
- /*
131
+}
61
- * in this implementation, in case of error
62
- * we ignore this command and move onto the next
63
- * command in the queue
64
- */
65
+ "%s: invalid command attributes: devid %d>%d",
66
+ __func__, devid, s->dt.maxids.max_devids);
132
+
67
+
133
+static const struct MemoryRegionOps imx_gpcv2_ops = {
68
+ } else if (!dte_valid || !ite_valid || !cte_valid) {
134
+ .read = imx_gpcv2_read,
69
+ qemu_log_mask(LOG_GUEST_ERROR,
135
+ .write = imx_gpcv2_write,
70
+ "%s: invalid command attributes: "
136
+ .endianness = DEVICE_NATIVE_ENDIAN,
71
+ "dte: %s, ite: %s, cte: %s\n",
137
+ .impl = {
72
+ __func__,
138
+ /*
73
+ dte_valid ? "valid" : "invalid",
139
+ * Our device would not work correctly if the guest was doing
74
+ ite_valid ? "valid" : "invalid",
140
+ * unaligned access. This might not be a limitation on the real
75
+ cte_valid ? "valid" : "invalid");
141
+ * device but in practice there is no reason for a guest to access
76
+ } else if (eventid > max_eventid) {
142
+ * this device unaligned.
77
+ qemu_log_mask(LOG_GUEST_ERROR,
143
+ */
78
+ "%s: invalid command attributes: eventid %d > %d\n",
144
+ .min_access_size = 4,
79
+ __func__, eventid, max_eventid);
145
+ .max_access_size = 4,
80
} else {
146
+ .unaligned = false,
81
/*
147
+ },
82
* Current implementation only supports rdbase == procnum
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
--
83
--
197
2.16.1
84
2.25.1
198
85
199
86
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
Add X11, FP5280G2, G220A, Rainier and Fuji. Mention that Swift will be
4
removed in v7.0.
5
6
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20211117065752.330632-2-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 7 ++++++-
12
1 file changed, 6 insertions(+), 1 deletion(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ AST2400 SoC based machines :
19
20
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
21
- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
22
+- ``supermicrox11-bmc`` Supermicro X11 BMC
23
24
AST2500 SoC based machines :
25
26
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
27
- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
28
- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
29
- ``sonorapass-bmc`` OCP SonoraPass BMC
30
-- ``swift-bmc`` OpenPOWER Swift BMC POWER9
31
+- ``swift-bmc`` OpenPOWER Swift BMC POWER9 (to be removed in v7.0)
32
+- ``fp5280g2-bmc`` Inspur FP5280G2 BMC
33
+- ``g220a-bmc`` Bytedance G220A BMC
34
35
AST2600 SoC based machines :
36
37
- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
38
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
39
+- ``rainier-bmc`` IBM Rainier POWER10 BMC
40
+- ``fuji-bmc`` Facebook Fuji BMC
41
42
Supported devices
43
-----------------
44
--
45
2.25.1
46
47
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
Convert i.MX6 to use TYPE_IMX_USDHC since that's what real HW comes
3
This is the latest URL for the OpenBMC CI. The old URL still works, but
4
with.
4
redirects.
5
5
6
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Cc: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20211117065752.330632-3-joel@jms.id.au
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
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: 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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
hw/arm/fsl-imx6.c | 2 +-
11
docs/system/arm/aspeed.rst | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
20
13
21
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
22
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/fsl-imx6.c
16
--- a/docs/system/arm/aspeed.rst
24
+++ b/hw/arm/fsl-imx6.c
17
+++ b/docs/system/arm/aspeed.rst
25
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_init(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ The Aspeed machines can be started using the ``-kernel`` option to
26
}
19
load a Linux kernel or from a firmware. Images can be downloaded from
27
20
the OpenBMC jenkins :
28
for (i = 0; i < FSL_IMX6_NUM_ESDHCS; i++) {
21
29
- object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), TYPE_SYSBUS_SDHCI);
22
- https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/distro=ubuntu,label=docker-builder
30
+ object_initialize(&s->esdhc[i], sizeof(s->esdhc[i]), TYPE_IMX_USDHC);
23
+ https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
31
qdev_set_parent_bus(DEVICE(&s->esdhc[i]), sysbus_get_default());
24
32
snprintf(name, NAME_SIZE, "sdhc%d", i + 1);
25
or directly from the OpenBMC GitHub release repository :
33
object_property_add_child(obj, name, OBJECT(&s->esdhc[i]), NULL);
26
34
--
27
--
35
2.16.1
28
2.25.1
36
29
37
30
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
A common use case for the ASPEED machine is to boot a Linux kernel.
4
Provide a full example command line.
5
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20211117065752.330632-4-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 15 ++++++++++++---
12
1 file changed, 12 insertions(+), 3 deletions(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ Missing devices
19
Boot options
20
------------
21
22
-The Aspeed machines can be started using the ``-kernel`` option to
23
-load a Linux kernel or from a firmware. Images can be downloaded from
24
-the OpenBMC jenkins :
25
+The Aspeed machines can be started using the ``-kernel`` and ``-dtb`` options
26
+to load a Linux kernel or from a firmware. Images can be downloaded from the
27
+OpenBMC jenkins :
28
29
https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
30
31
@@ -XXX,XX +XXX,XX @@ or directly from the OpenBMC GitHub release repository :
32
33
https://github.com/openbmc/openbmc/releases
34
35
+To boot a kernel directly from a Linux build tree:
36
+
37
+.. code-block:: bash
38
+
39
+ $ qemu-system-arm -M ast2600-evb -nographic \
40
+ -kernel arch/arm/boot/zImage \
41
+ -dtb arch/arm/boot/dts/aspeed-ast2600-evb.dtb \
42
+ -initrd rootfs.cpio
43
+
44
The image should be attached as an MTD drive. Run :
45
46
.. code-block:: bash
47
--
48
2.25.1
49
50
diff view generated by jsdifflib
1
The documentation for the generic loader claims that you can
1
From: Joel Stanley <joel@jms.id.au>
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
Move it to the supported list.
6
cpu_num must be specified when setting a program counter
7
4
8
This is because we were testing against 0 rather than CPU_NONE.
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
9
6
Message-id: 20211117065752.330632-5-joel@jms.id.au
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
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
---
8
---
15
hw/core/generic-loader.c | 2 +-
9
docs/system/arm/aspeed.rst | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
17
11
18
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
12
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/core/generic-loader.c
14
--- a/docs/system/arm/aspeed.rst
21
+++ b/hw/core/generic-loader.c
15
+++ b/docs/system/arm/aspeed.rst
22
@@ -XXX,XX +XXX,XX @@ static void generic_loader_realize(DeviceState *dev, Error **errp)
16
@@ -XXX,XX +XXX,XX @@ Supported devices
23
error_setg(errp, "data can not be specified when setting a "
17
* Front LEDs (PCA9552 on I2C bus)
24
"program counter");
18
* LPC Peripheral Controller (a subset of subdevices are supported)
25
return;
19
* Hash/Crypto Engine (HACE) - Hash support only. TODO: HMAC and RSA
26
- } else if (!s->cpu_num) {
20
+ * ADC
27
+ } else if (s->cpu_num == CPU_NONE) {
21
28
error_setg(errp, "cpu_num must be specified when setting a "
22
29
"program counter");
23
Missing devices
30
return;
24
---------------
25
26
* Coprocessor support
27
- * ADC (out of tree implementation)
28
* PWM and Fan Controller
29
* Slave GPIO Controller
30
* Super I/O Controller
31
--
31
--
32
2.16.1
32
2.25.1
33
33
34
34
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
2
2
3
This implements emulation of the new SM4 instructions that have
3
Fix issue where the data register may be overwritten by next character
4
been added as an optional extension to the ARMv8 Crypto Extensions
4
reception before being read and returned.
5
in ARM v8.2.
6
5
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
6
Signed-off-by: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
8
Message-id: 20180207111729.15737-5-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20211128120723.4053-1-olivier.heriveaux@ledger.fr
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
target/arm/cpu.h | 1 +
12
hw/char/stm32f2xx_usart.c | 3 ++-
13
target/arm/helper.h | 3 ++
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
target/arm/crypto_helper.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++
15
target/arm/translate-a64.c | 8 ++++
16
4 files changed, 103 insertions(+)
17
14
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
17
--- a/hw/char/stm32f2xx_usart.c
21
+++ b/target/arm/cpu.h
18
+++ b/hw/char/stm32f2xx_usart.c
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
19
@@ -XXX,XX +XXX,XX @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
23
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
20
return retvalue;
24
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
21
case USART_DR:
25
ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
22
DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
26
+ ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
23
+ retvalue = s->usart_dr & 0x3FF;
27
};
24
s->usart_sr &= ~USART_SR_RXNE;
28
25
qemu_chr_fe_accept_input(&s->chr);
29
static inline int arm_feature(CPUARMState *env, int feature)
26
qemu_set_irq(s->irq, 0);
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
27
- return s->usart_dr & 0x3FF;
31
index XXXXXXX..XXXXXXX 100644
28
+ return retvalue;
32
--- a/target/arm/helper.h
29
case USART_BRR:
33
+++ b/target/arm/helper.h
30
return s->usart_brr;
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
31
case USART_CR1:
35
DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
36
DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
37
38
+DEF_HELPER_FLAGS_2(crypto_sm4e, TCG_CALL_NO_RWG, void, ptr, ptr)
39
+DEF_HELPER_FLAGS_3(crypto_sm4ekey, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
40
+
41
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
42
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
43
DEF_HELPER_2(dc_zva, void, env, i64)
44
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/crypto_helper.c
47
+++ b/target/arm/crypto_helper.c
48
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
49
rd[0] = d.l[0];
50
rd[1] = d.l[1];
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
+};
87
+
88
+void HELPER(crypto_sm4e)(void *vd, void *vn)
89
+{
90
+ uint64_t *rd = vd;
91
+ uint64_t *rn = vn;
92
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
93
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
94
+ uint32_t t, i;
95
+
96
+ for (i = 0; i < 4; i++) {
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
+ }
110
+
111
+ rd[0] = d.l[0];
112
+ rd[1] = d.l[1];
113
+}
114
+
115
+void HELPER(crypto_sm4ekey)(void *vd, void *vn, void* vm)
116
+{
117
+ uint64_t *rd = vd;
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
+ }
139
+
140
+ rd[0] = d.l[0];
141
+ rd[1] = d.l[1];
142
+}
143
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/target/arm/translate-a64.c
146
+++ b/target/arm/translate-a64.c
147
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
148
feature = ARM_FEATURE_V8_SM3;
149
genfn = gen_helper_crypto_sm3partw2;
150
break;
151
+ case 2: /* SM4EKEY */
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
--
32
--
170
2.16.1
33
2.25.1
171
34
172
35
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Add enough code to emulate i.MX2 watchdog IP block so it would be
3
gicv3_set_gicv3state() is used by arm_gicv3_common.c in
4
possible to reboot the machine running Linux Guest.
4
arm_gicv3_common_realize(). Since we want to restrict
5
arm_gicv3_cpuif.c to TCG, extract gicv3_set_gicv3state()
6
to a new file. Add this file to the meson 'specific'
7
source set, since it needs access to "cpu.h".
5
8
6
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Cc: Jason Wang <jasowang@redhat.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
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>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
11
Message-id: 20211115223619.2599282-2-philmd@redhat.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
hw/intc/arm_gicv3_cpuif.c | 10 +---------
20
include/hw/misc/imx2_wdt.h | 33 +++++++++++++++++
15
hw/intc/arm_gicv3_cpuif_common.c | 22 ++++++++++++++++++++++
21
hw/misc/imx2_wdt.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++
16
hw/intc/meson.build | 1 +
22
3 files changed, 123 insertions(+)
17
3 files changed, 24 insertions(+), 9 deletions(-)
23
create mode 100644 include/hw/misc/imx2_wdt.h
18
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
24
create mode 100644 hw/misc/imx2_wdt.c
25
19
26
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
20
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
27
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/misc/Makefile.objs
22
--- a/hw/intc/arm_gicv3_cpuif.c
29
+++ b/hw/misc/Makefile.objs
23
+++ b/hw/intc/arm_gicv3_cpuif.c
30
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx25_ccm.o
24
@@ -XXX,XX +XXX,XX @@
31
obj-$(CONFIG_IMX) += imx6_ccm.o
25
/*
32
obj-$(CONFIG_IMX) += imx6_src.o
26
- * ARM Generic Interrupt Controller v3
33
obj-$(CONFIG_IMX) += imx7_ccm.o
27
+ * ARM Generic Interrupt Controller v3 (emulation)
34
+obj-$(CONFIG_IMX) += imx2_wdt.o
28
*
35
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
29
* Copyright (c) 2016 Linaro Limited
36
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
30
* Written by Peter Maydell
37
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
31
@@ -XXX,XX +XXX,XX @@
38
diff --git a/include/hw/misc/imx2_wdt.h b/include/hw/misc/imx2_wdt.h
32
#include "hw/irq.h"
33
#include "cpu.h"
34
35
-void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
36
-{
37
- ARMCPU *arm_cpu = ARM_CPU(cpu);
38
- CPUARMState *env = &arm_cpu->env;
39
-
40
- env->gicv3state = (void *)s;
41
-};
42
-
43
static GICv3CPUState *icc_cs_from_env(CPUARMState *env)
44
{
45
return env->gicv3state;
46
diff --git a/hw/intc/arm_gicv3_cpuif_common.c b/hw/intc/arm_gicv3_cpuif_common.c
39
new file mode 100644
47
new file mode 100644
40
index XXXXXXX..XXXXXXX
48
index XXXXXXX..XXXXXXX
41
--- /dev/null
49
--- /dev/null
42
+++ b/include/hw/misc/imx2_wdt.h
50
+++ b/hw/intc/arm_gicv3_cpuif_common.c
43
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@
52
+/* SPDX-License-Identifier: GPL-2.0-or-later */
44
+/*
53
+/*
45
+ * Copyright (c) 2017, Impinj, Inc.
54
+ * ARM Generic Interrupt Controller v3
46
+ *
55
+ *
47
+ * i.MX2 Watchdog IP block
56
+ * Copyright (c) 2016 Linaro Limited
57
+ * Written by Peter Maydell
48
+ *
58
+ *
49
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
59
+ * This code is licensed under the GPL, version 2 or (at your option)
50
+ *
60
+ * any later version.
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
53
+ */
54
+
55
+#ifndef IMX2_WDT_H
56
+#define IMX2_WDT_H
57
+
58
+#include "hw/sysbus.h"
59
+
60
+#define TYPE_IMX2_WDT "imx2.wdt"
61
+#define IMX2_WDT(obj) OBJECT_CHECK(IMX2WdtState, (obj), TYPE_IMX2_WDT)
62
+
63
+enum IMX2WdtRegisters {
64
+ IMX2_WDT_WCR = 0x0000,
65
+ IMX2_WDT_REG_NUM = 0x0008 / sizeof(uint16_t) + 1,
66
+};
67
+
68
+
69
+typedef struct IMX2WdtState {
70
+ /* <private> */
71
+ SysBusDevice parent_obj;
72
+
73
+ MemoryRegion mmio;
74
+} IMX2WdtState;
75
+
76
+#endif /* IMX7_SNVS_H */
77
diff --git a/hw/misc/imx2_wdt.c b/hw/misc/imx2_wdt.c
78
new file mode 100644
79
index XXXXXXX..XXXXXXX
80
--- /dev/null
81
+++ b/hw/misc/imx2_wdt.c
82
@@ -XXX,XX +XXX,XX @@
83
+/*
84
+ * Copyright (c) 2018, Impinj, Inc.
85
+ *
86
+ * i.MX2 Watchdog IP block
87
+ *
88
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
89
+ *
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
91
+ * See the COPYING file in the top-level directory.
92
+ */
61
+ */
93
+
62
+
94
+#include "qemu/osdep.h"
63
+#include "qemu/osdep.h"
95
+#include "qemu/bitops.h"
64
+#include "gicv3_internal.h"
96
+#include "sysemu/watchdog.h"
65
+#include "cpu.h"
97
+
66
+
98
+#include "hw/misc/imx2_wdt.h"
67
+void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
68
+{
69
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
70
+ CPUARMState *env = &arm_cpu->env;
99
+
71
+
100
+#define IMX2_WDT_WCR_WDA BIT(5) /* -> External Reset WDOG_B */
72
+ env->gicv3state = (void *)s;
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
+{
106
+ return 0;
107
+}
108
+
109
+static void imx2_wdt_write(void *opaque, hwaddr addr,
110
+ uint64_t value, unsigned int size)
111
+{
112
+ if (addr == IMX2_WDT_WCR &&
113
+ (value & (IMX2_WDT_WCR_WDA | IMX2_WDT_WCR_SRS))) {
114
+ watchdog_perform_action();
115
+ }
116
+}
117
+
118
+static const MemoryRegionOps imx2_wdt_ops = {
119
+ .read = imx2_wdt_read,
120
+ .write = imx2_wdt_write,
121
+ .endianness = DEVICE_NATIVE_ENDIAN,
122
+ .impl = {
123
+ /*
124
+ * Our device would not work correctly if the guest was doing
125
+ * unaligned access. This might not be a limitation on the
126
+ * real device but in practice there is no reason for a guest
127
+ * to access this device unaligned.
128
+ */
129
+ .min_access_size = 4,
130
+ .max_access_size = 4,
131
+ .unaligned = false,
132
+ },
133
+};
73
+};
134
+
74
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
135
+static void imx2_wdt_realize(DeviceState *dev, Error **errp)
75
index XXXXXXX..XXXXXXX 100644
136
+{
76
--- a/hw/intc/meson.build
137
+ IMX2WdtState *s = IMX2_WDT(dev);
77
+++ b/hw/intc/meson.build
138
+
78
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
139
+ memory_region_init_io(&s->mmio, OBJECT(dev),
79
140
+ &imx2_wdt_ops, s,
80
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
141
+ TYPE_IMX2_WDT".mmio",
81
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
142
+ IMX2_WDT_REG_NUM * sizeof(uint16_t));
82
+specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
143
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
83
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
144
+}
84
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
145
+
85
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
146
+static void imx2_wdt_class_init(ObjectClass *klass, void *data)
147
+{
148
+ DeviceClass *dc = DEVICE_CLASS(klass);
149
+
150
+ dc->realize = imx2_wdt_realize;
151
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
152
+}
153
+
154
+static const TypeInfo imx2_wdt_info = {
155
+ .name = TYPE_IMX2_WDT,
156
+ .parent = TYPE_SYS_BUS_DEVICE,
157
+ .instance_size = sizeof(IMX2WdtState),
158
+ .class_init = imx2_wdt_class_init,
159
+};
160
+
161
+static WatchdogTimerModel model = {
162
+ .wdt_name = "imx2-watchdog",
163
+ .wdt_description = "i.MX2 Watchdog",
164
+};
165
+
166
+static void imx2_wdt_register_type(void)
167
+{
168
+ watchdog_add_model(&model);
169
+ type_register_static(&imx2_wdt_info);
170
+}
171
+type_init(imx2_wdt_register_type)
172
--
86
--
173
2.16.1
87
2.25.1
174
88
175
89
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This implements emulation of the new SHA-512 instructions that have
3
The TYPE_ARM_GICV3 device is an emulated one. When using
4
been added as an optional extensions to the ARMv8 Crypto Extensions
4
KVM, it is recommended to use the TYPE_KVM_ARM_GICV3 device
5
in ARM v8.2.
5
(which uses in-kernel support).
6
6
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
7
When using --with-devices-FOO, it is possible to build a
8
Message-id: 20180207111729.15737-2-ard.biesheuvel@linaro.org
8
binary with a specific set of devices. When this binary is
9
restricted to KVM accelerator, the TYPE_ARM_GICV3 device is
10
irrelevant, and it is desirable to remove it from the binary.
11
12
Therefore introduce the CONFIG_ARM_GIC_TCG Kconfig selector
13
which select the files required to have the TYPE_ARM_GICV3
14
device, but also allowing to de-select this device.
15
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Message-id: 20211115223619.2599282-3-philmd@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
20
---
12
target/arm/cpu.h | 1 +
21
hw/intc/arm_gicv3.c | 2 +-
13
target/arm/helper.h | 5 +++
22
hw/intc/Kconfig | 5 +++++
14
target/arm/crypto_helper.c | 90 ++++++++++++++++++++++++++++++++++++-
23
hw/intc/meson.build | 10 ++++++----
15
target/arm/translate-a64.c | 110 +++++++++++++++++++++++++++++++++++++++++++++
24
3 files changed, 12 insertions(+), 5 deletions(-)
16
4 files changed, 205 insertions(+), 1 deletion(-)
17
25
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
19
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
28
--- a/hw/intc/arm_gicv3.c
21
+++ b/target/arm/cpu.h
29
+++ b/hw/intc/arm_gicv3.c
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
23
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
24
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
25
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
26
+ ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
27
};
28
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_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 @@
30
@@ -XXX,XX +XXX,XX @@
51
/*
31
/*
52
* crypto_helper.c - emulate v8 Crypto Extensions instructions
32
- * ARM Generic Interrupt Controller v3
33
+ * ARM Generic Interrupt Controller v3 (emulation)
53
*
34
*
54
- * Copyright (C) 2013 - 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
35
* Copyright (c) 2015 Huawei.
55
+ * Copyright (C) 2013 - 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
36
* Copyright (c) 2016 Linaro Limited
56
*
37
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
57
* This library is free software; you can redistribute it and/or
38
index XXXXXXX..XXXXXXX 100644
58
* modify it under the terms of the GNU Lesser General Public
39
--- a/hw/intc/Kconfig
59
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
40
+++ b/hw/intc/Kconfig
60
rd[0] = d.l[0];
41
@@ -XXX,XX +XXX,XX @@ config APIC
61
rd[1] = d.l[1];
42
select MSI_NONBROKEN
62
}
43
select I8259
44
45
+config ARM_GIC_TCG
46
+ bool
47
+ default y
48
+ depends on ARM_GIC && TCG
63
+
49
+
64
+/*
50
config ARM_GIC_KVM
65
+ * The SHA-512 logical functions (same as above but using 64-bit operands)
51
bool
66
+ */
52
default y
67
+
53
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
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
54
index XXXXXXX..XXXXXXX 100644
153
--- a/target/arm/translate-a64.c
55
--- a/hw/intc/meson.build
154
+++ b/target/arm/translate-a64.c
56
+++ b/hw/intc/meson.build
155
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
57
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARM_GIC', if_true: files(
156
tcg_temp_free_ptr(tcg_rn_ptr);
58
'arm_gic.c',
157
}
59
'arm_gic_common.c',
158
60
'arm_gicv2m.c',
159
+/* Crypto three-reg SHA512
61
- 'arm_gicv3.c',
160
+ * 31 21 20 16 15 14 13 12 11 10 9 5 4 0
62
'arm_gicv3_common.c',
161
+ * +-----------------------+------+---+---+-----+--------+------+------+
63
- 'arm_gicv3_dist.c',
162
+ * | 1 1 0 0 1 1 1 0 0 1 1 | Rm | 1 | O | 0 0 | opcode | Rn | Rd |
64
'arm_gicv3_its_common.c',
163
+ * +-----------------------+------+---+---+-----+--------+------+------+
65
- 'arm_gicv3_redist.c',
164
+ */
66
+))
165
+static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
67
+softmmu_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files(
166
+{
68
+ 'arm_gicv3.c',
167
+ int opcode = extract32(insn, 10, 2);
69
+ 'arm_gicv3_dist.c',
168
+ int o = extract32(insn, 14, 1);
70
'arm_gicv3_its.c',
169
+ int rm = extract32(insn, 16, 5);
71
+ 'arm_gicv3_redist.c',
170
+ int rn = extract32(insn, 5, 5);
72
))
171
+ int rd = extract32(insn, 0, 5);
73
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
172
+ int feature;
74
softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))
173
+ CryptoThreeOpFn *genfn;
75
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
174
+
76
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
175
+ if (o == 0) {
77
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
176
+ switch (opcode) {
78
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
177
+ case 0: /* SHA512H */
79
-specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
178
+ feature = ARM_FEATURE_V8_SHA512;
80
+specific_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files('arm_gicv3_cpuif.c'))
179
+ genfn = gen_helper_crypto_sha512h;
81
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
180
+ break;
82
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
181
+ case 1: /* SHA512H2 */
83
specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
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
--
84
--
280
2.16.1
85
2.25.1
281
86
282
87
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Add both SVE exception state and vector length.
4
2
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180123035349.24538-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
6
---
10
target/arm/cpu.h | 8 ++++++++
7
target/arm/translate-a64.c | 7 ++++---
11
target/arm/translate.h | 2 ++
8
1 file changed, 4 insertions(+), 3 deletions(-)
12
target/arm/helper.c | 25 ++++++++++++++++++++++++-
13
target/arm/translate-a64.c | 2 ++
14
4 files changed, 36 insertions(+), 1 deletion(-)
15
9
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
21
#define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT)
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
10
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
107
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-a64.c
12
--- a/target/arm/translate-a64.c
109
+++ b/target/arm/translate-a64.c
13
+++ b/target/arm/translate-a64.c
110
@@ -XXX,XX +XXX,XX @@ static int aarch64_tr_init_disas_context(DisasContextBase *dcbase,
14
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
111
dc->user = (dc->current_el == 0);
15
{
112
#endif
16
DisasContext *s = container_of(dcbase, DisasContext, base);
113
dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
17
CPUARMState *env = cpu->env_ptr;
114
+ dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
18
+ uint64_t pc = s->base.pc_next;
115
+ dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;
19
uint32_t insn;
116
dc->vec_len = 0;
20
117
dc->vec_stride = 0;
21
if (s->ss_active && !s->pstate_ss) {
118
dc->cp_regs = arm_cpu->cp_regs;
22
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
23
return;
24
}
25
26
- s->pc_curr = s->base.pc_next;
27
- insn = arm_ldl_code(env, &s->base, s->base.pc_next, s->sctlr_b);
28
+ s->pc_curr = pc;
29
+ insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
30
s->insn = insn;
31
- s->base.pc_next += 4;
32
+ s->base.pc_next = pc + 4;
33
34
s->fp_access_checked = false;
35
s->sve_access_checked = false;
119
--
36
--
120
2.16.1
37
2.25.1
121
38
122
39
diff view generated by jsdifflib
1
The code where we added the TT instruction was accidentally
1
From: Richard Henderson <richard.henderson@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
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
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
---
6
---
10
target/arm/translate.c | 1 +
7
target/arm/translate.c | 9 +++++----
11
1 file changed, 1 insertion(+)
8
1 file changed, 5 insertions(+), 4 deletions(-)
12
9
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
12
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
13
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
14
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
18
tcg_temp_free_i32(addr);
15
{
19
tcg_temp_free_i32(op);
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
20
store_reg(s, rd, ttresp);
17
CPUARMState *env = cpu->env_ptr;
21
+ break;
18
+ uint32_t pc = dc->base.pc_next;
22
}
19
unsigned int insn;
23
goto illegal_op;
20
24
}
21
if (arm_pre_translate_insn(dc)) {
22
- dc->base.pc_next += 4;
23
+ dc->base.pc_next = pc + 4;
24
return;
25
}
26
27
- dc->pc_curr = dc->base.pc_next;
28
- insn = arm_ldl_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
29
+ dc->pc_curr = pc;
30
+ insn = arm_ldl_code(env, &dc->base, pc, dc->sctlr_b);
31
dc->insn = insn;
32
- dc->base.pc_next += 4;
33
+ dc->base.pc_next = pc + 4;
34
disas_arm_insn(dc, insn);
35
36
arm_post_translate_insn(dc);
25
--
37
--
26
2.16.1
38
2.25.1
27
39
28
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20180123035349.24538-3-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
6
---
9
target/arm/cpu.h | 12 ++++++++++++
7
target/arm/translate.c | 16 ++++++++--------
10
1 file changed, 12 insertions(+)
8
1 file changed, 8 insertions(+), 8 deletions(-)
11
9
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
12
--- a/target/arm/translate.c
15
+++ b/target/arm/cpu.h
13
+++ b/target/arm/translate.c
16
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVectorReg {
14
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
17
uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
15
{
18
} ARMVectorReg;
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
19
17
CPUARMState *env = cpu->env_ptr;
20
+/* In AArch32 mode, predicate registers do not exist at all. */
18
+ uint32_t pc = dc->base.pc_next;
21
+#ifdef TARGET_AARCH64
19
uint32_t insn;
22
+typedef struct ARMPredicateReg {
20
bool is_16bit;
23
+ uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
21
24
+} ARMPredicateReg;
22
if (arm_pre_translate_insn(dc)) {
25
+#endif
23
- dc->base.pc_next += 2;
26
+
24
+ dc->base.pc_next = pc + 2;
27
25
return;
28
typedef struct CPUARMState {
26
}
29
/* Regs for current mode. */
27
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
28
- dc->pc_curr = dc->base.pc_next;
31
struct {
29
- insn = arm_lduw_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
32
ARMVectorReg zregs[32];
30
+ dc->pc_curr = pc;
33
31
+ insn = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
34
+#ifdef TARGET_AARCH64
32
is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
35
+ /* Store FFR as pregs[16] to make it easier to treat as any other. */
33
- dc->base.pc_next += 2;
36
+ ARMPredicateReg pregs[17];
34
+ pc += 2;
37
+#endif
35
if (!is_16bit) {
38
+
36
- uint32_t insn2 = arm_lduw_code(env, &dc->base, dc->base.pc_next,
39
uint32_t xregs[16];
37
- dc->sctlr_b);
40
/* We store these fpcsr fields separately for convenience. */
38
-
41
int vec_len;
39
+ uint32_t insn2 = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
40
insn = insn << 16 | insn2;
41
- dc->base.pc_next += 2;
42
+ pc += 2;
43
}
44
+ dc->base.pc_next = pc;
45
dc->insn = insn;
46
47
if (dc->pstate_il) {
42
--
48
--
43
2.16.1
49
2.25.1
44
50
45
51
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Save the high parts of the Zregs and all of the Pregs.
3
Create arm_check_ss_active and arm_check_kernelpage.
4
The ZCR_ELx registers are migrated via the CP mechanism.
4
5
Reverse the order of the tests. While it doesn't matter in practice,
6
because only user-only has a kernel page and user-only never sets
7
ss_active, ss_active has priority over execution exceptions and it
8
is best to keep them in the proper order.
5
9
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
target/arm/machine.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
14
target/arm/translate.c | 10 +++++++---
13
1 file changed, 53 insertions(+)
15
1 file changed, 7 insertions(+), 3 deletions(-)
14
16
15
diff --git a/target/arm/machine.c b/target/arm/machine.c
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/machine.c
19
--- a/target/arm/translate.c
18
+++ b/target/arm/machine.c
20
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_iwmmxt = {
21
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
22
dc->insn_start = tcg_last_op();
23
}
24
25
-static bool arm_pre_translate_insn(DisasContext *dc)
26
+static bool arm_check_kernelpage(DisasContext *dc)
27
{
28
#ifdef CONFIG_USER_ONLY
29
/* Intercept jump to the magic kernel page. */
30
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
31
return true;
20
}
32
}
21
};
33
#endif
22
34
+ return false;
23
+#ifdef TARGET_AARCH64
35
+}
24
+/* The expression ARM_MAX_VQ - 2 is 0 for pure AArch32 build,
36
25
+ * and ARMPredicateReg is actively empty. This triggers errors
37
+static bool arm_check_ss_active(DisasContext *dc)
26
+ * in the expansion of the VMSTATE macros.
27
+ */
28
+
29
+static bool sve_needed(void *opaque)
30
+{
38
+{
31
+ ARMCPU *cpu = opaque;
39
if (dc->ss_active && !dc->pstate_ss) {
32
+ CPUARMState *env = &cpu->env;
40
/* Singlestep state is Active-pending.
33
+
41
* If we're in this state at the start of a TB then either
34
+ return arm_feature(env, ARM_FEATURE_SVE);
42
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
35
+}
43
uint32_t pc = dc->base.pc_next;
36
+
44
unsigned int insn;
37
+/* The first two words of each Zreg is stored in VFP state. */
45
38
+static const VMStateDescription vmstate_zreg_hi_reg = {
46
- if (arm_pre_translate_insn(dc)) {
39
+ .name = "cpu/sve/zreg_hi",
47
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
40
+ .version_id = 1,
48
dc->base.pc_next = pc + 4;
41
+ .minimum_version_id = 1,
49
return;
42
+ .fields = (VMStateField[]) {
43
+ VMSTATE_UINT64_SUB_ARRAY(d, ARMVectorReg, 2, ARM_MAX_VQ - 2),
44
+ VMSTATE_END_OF_LIST()
45
+ }
46
+};
47
+
48
+static const VMStateDescription vmstate_preg_reg = {
49
+ .name = "cpu/sve/preg",
50
+ .version_id = 1,
51
+ .minimum_version_id = 1,
52
+ .fields = (VMStateField[]) {
53
+ VMSTATE_UINT64_ARRAY(p, ARMPredicateReg, 2 * ARM_MAX_VQ / 8),
54
+ VMSTATE_END_OF_LIST()
55
+ }
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
}
50
}
85
};
51
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
52
uint32_t insn;
53
bool is_16bit;
54
55
- if (arm_pre_translate_insn(dc)) {
56
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
57
dc->base.pc_next = pc + 2;
58
return;
59
}
86
--
60
--
87
2.16.1
61
2.25.1
88
62
89
63
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This implements emulation of the new SHA-3 instructions that have
3
The size of the code covered by a TranslationBlock cannot be 0;
4
been added as an optional extensions to the ARMv8 Crypto Extensions
4
this is checked via assert in tb_gen_code.
5
in ARM v8.2.
6
5
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180207111729.15737-3-ard.biesheuvel@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@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
target/arm/translate-a64.c | 1 +
13
target/arm/translate-a64.c | 148 +++++++++++++++++++++++++++++++++++++++++++--
11
1 file changed, 1 insertion(+)
14
2 files changed, 145 insertions(+), 4 deletions(-)
15
12
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ enum arm_features {
21
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
22
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
23
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
24
+ ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
25
};
26
27
static inline int arm_feature(CPUARMState *env, int feature)
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
15
--- a/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
33
feature = ARM_FEATURE_V8_SHA512;
18
assert(s->base.num_insns == 1);
34
genfn = gen_helper_crypto_sha512su1;
19
gen_swstep_exception(s, 0, 0);
35
break;
20
s->base.is_jmp = DISAS_NORETURN;
36
- default:
21
+ s->base.pc_next = pc + 4;
37
- unallocated_encoding(s);
22
return;
38
- return;
39
+ case 3: /* RAX1 */
40
+ feature = ARM_FEATURE_V8_SHA3;
41
+ genfn = NULL;
42
+ break;
43
}
44
} else {
45
unallocated_encoding(s);
46
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
47
tcg_temp_free_ptr(tcg_rn_ptr);
48
tcg_temp_free_ptr(tcg_rm_ptr);
49
} else {
50
- g_assert_not_reached();
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
}
23
}
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
24
208
--
25
--
209
2.16.1
26
2.25.1
210
27
211
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Define ZCR_EL[1-3].
3
We will reuse this section of arm_deliver_fault for
4
raising pc alignment faults.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180123035349.24538-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
target/arm/cpu.h | 5 ++
10
target/arm/tlb_helper.c | 45 +++++++++++++++++++++++++----------------
11
target/arm/helper.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 28 insertions(+), 17 deletions(-)
12
2 files changed, 136 insertions(+)
13
12
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
15
--- a/target/arm/tlb_helper.c
17
+++ b/target/arm/cpu.h
16
+++ b/target/arm/tlb_helper.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
17
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
19
*/
18
return syn;
20
float_status fp_status;
19
}
21
float_status standard_fp_status;
20
22
+
21
-static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
23
+ /* ZCR_EL[1-3] */
22
- MMUAccessType access_type,
24
+ uint64_t zcr_el[4];
23
- int mmu_idx, ARMMMUFaultInfo *fi)
25
} vfp;
24
+static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
26
uint64_t exclusive_addr;
25
+ int target_el, int mmu_idx, uint32_t *ret_fsc)
27
uint64_t exclusive_val;
26
{
28
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
27
- CPUARMState *env = &cpu->env;
29
#define CPTR_TCPAC (1U << 31)
28
- int target_el;
30
#define CPTR_TTA (1U << 20)
29
- bool same_el;
31
#define CPTR_TFP (1U << 10)
30
- uint32_t syn, exc, fsr, fsc;
32
+#define CPTR_TZ (1U << 8) /* CPTR_EL2 */
31
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
33
+#define CPTR_EZ (1U << 8) /* CPTR_EL3 */
32
-
34
33
- target_el = exception_target_el(env);
35
#define MDCR_EPMAD (1U << 21)
34
- if (fi->stage2) {
36
#define MDCR_EDAD (1U << 20)
35
- target_el = 2;
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
- env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
38
index XXXXXXX..XXXXXXX 100644
37
- if (arm_is_secure_below_el3(env) && fi->s1ns) {
39
--- a/target/arm/helper.c
38
- env->cp15.hpfar_el2 |= HPFAR_NS;
40
+++ b/target/arm/helper.c
39
- }
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
40
- }
42
REGINFO_SENTINEL
41
- same_el = (arm_current_el(env) == target_el);
43
};
42
+ uint32_t fsr, fsc;
44
43
45
+/* Return the exception level to which SVE-disabled exceptions should
44
if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
46
+ * be taken, or 0 if SVE is enabled.
45
arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
47
+ */
46
@@ -XXX,XX +XXX,XX @@ static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
48
+static int sve_exception_el(CPUARMState *env)
47
fsc = 0x3f;
49
+{
48
}
50
+#ifndef CONFIG_USER_ONLY
49
51
+ unsigned current_el = arm_current_el(env);
50
+ *ret_fsc = fsc;
52
+
51
+ return fsr;
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
+ }
76
+
77
+ /* Similarly for CPACR.FPEN, after having checked ZEN. */
78
+ switch (extract32(env->cp15.cpacr_el1, 20, 2)) {
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
+ }
95
+
96
+ /* CPTR_EL2. Check both TZ and TFP. */
97
+ if (current_el <= 2
98
+ && (env->cp15.cptr_el[2] & (CPTR_TFP | CPTR_TZ))
99
+ && !arm_is_secure_below_el3(env)) {
100
+ return 2;
101
+ }
102
+
103
+ /* CPTR_EL3. Check both EZ and TFP. */
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
+}
52
+}
111
+
53
+
112
+static CPAccessResult zcr_access(CPUARMState *env, const ARMCPRegInfo *ri,
54
+static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
113
+ bool isread)
55
+ MMUAccessType access_type,
56
+ int mmu_idx, ARMMMUFaultInfo *fi)
114
+{
57
+{
115
+ switch (sve_exception_el(env)) {
58
+ CPUARMState *env = &cpu->env;
116
+ case 3:
59
+ int target_el;
117
+ return CP_ACCESS_TRAP_EL3;
60
+ bool same_el;
118
+ case 2:
61
+ uint32_t syn, exc, fsr, fsc;
119
+ return CP_ACCESS_TRAP_EL2;
120
+ case 1:
121
+ return CP_ACCESS_TRAP;
122
+ }
123
+ return CP_ACCESS_OK;
124
+}
125
+
62
+
126
+static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
63
+ target_el = exception_target_el(env);
127
+ uint64_t value)
64
+ if (fi->stage2) {
128
+{
65
+ target_el = 2;
129
+ /* Bits other than [3:0] are RAZ/WI. */
66
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
130
+ raw_write(env, ri, value & 0xf);
67
+ if (arm_is_secure_below_el3(env) && fi->s1ns) {
131
+}
68
+ env->cp15.hpfar_el2 |= HPFAR_NS;
132
+
133
+static const ARMCPRegInfo zcr_el1_reginfo = {
134
+ .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
135
+ .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
136
+ .access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
137
+ .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
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
+ }
69
+ }
182
+ }
70
+ }
183
}
71
+ same_el = (arm_current_el(env) == target_el);
184
72
+
185
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
73
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
74
+
75
if (access_type == MMU_INST_FETCH) {
76
syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
77
exc = EXCP_PREFETCH_ABORT;
186
--
78
--
187
2.16.1
79
2.25.1
188
80
189
81
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This implements emulation of the new SM3 instructions that have
3
For A64, any input to an indirect branch can cause this.
4
been added as an optional extension to the ARMv8 Crypto Extensions
4
5
in ARM v8.2.
5
For A32, many indirect branch paths force the branch to be aligned,
6
6
but BXWritePC does not. This includes the BX instruction but also
7
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
7
other interworking changes to PC. Prior to v8, this case is UNDEFINED.
8
Message-id: 20180207111729.15737-4-ard.biesheuvel@linaro.org
8
With v8, this is CONSTRAINED UNPREDICTABLE and may either raise an
9
exception or force align the PC.
10
11
We choose to raise an exception because we have the infrastructure,
12
it makes the generated code for gen_bx simpler, and it has the
13
possibility of catching more guest bugs.
14
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
18
---
12
target/arm/cpu.h | 1 +
19
target/arm/helper.h | 1 +
13
target/arm/helper.h | 4 ++
20
target/arm/syndrome.h | 5 ++++
14
target/arm/crypto_helper.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++
21
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++++++---------------
15
target/arm/translate-a64.c | 88 ++++++++++++++++++++++++++++++++++++++++--
22
target/arm/tlb_helper.c | 18 ++++++++++++++
16
4 files changed, 186 insertions(+), 3 deletions(-)
23
target/arm/translate-a64.c | 15 ++++++++++++
17
24
target/arm/translate.c | 22 ++++++++++++++++-
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
6 files changed, 87 insertions(+), 20 deletions(-)
19
index XXXXXXX..XXXXXXX 100644
26
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ enum arm_features {
23
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
24
ARM_FEATURE_V8_SHA512, /* implements SHA512 part of v8 Crypto Extensions */
25
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
26
+ ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
27
};
28
29
static inline int arm_feature(CPUARMState *env, int feature)
30
diff --git a/target/arm/helper.h b/target/arm/helper.h
27
diff --git a/target/arm/helper.h b/target/arm/helper.h
31
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.h
29
--- a/target/arm/helper.h
33
+++ b/target/arm/helper.h
30
+++ b/target/arm/helper.h
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(crypto_sha512h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
31
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
35
DEF_HELPER_FLAGS_2(crypto_sha512su0, TCG_CALL_NO_RWG, void, ptr, ptr)
32
DEF_HELPER_2(exception_internal, void, env, i32)
36
DEF_HELPER_FLAGS_3(crypto_sha512su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
33
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
37
34
DEF_HELPER_2(exception_bkpt_insn, void, env, i32)
38
+DEF_HELPER_FLAGS_5(crypto_sm3tt, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32, i32)
35
+DEF_HELPER_2(exception_pc_alignment, noreturn, env, tl)
39
+DEF_HELPER_FLAGS_3(crypto_sm3partw1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
36
DEF_HELPER_1(setend, void, env)
40
+DEF_HELPER_FLAGS_3(crypto_sm3partw2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
37
DEF_HELPER_2(wfi, void, env, i32)
41
+
38
DEF_HELPER_1(wfe, void, env)
42
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
39
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
43
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
40
index XXXXXXX..XXXXXXX 100644
44
DEF_HELPER_2(dc_zva, void, env, i64)
41
--- a/target/arm/syndrome.h
45
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
42
+++ b/target/arm/syndrome.h
46
index XXXXXXX..XXXXXXX 100644
43
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_illegalstate(void)
47
--- a/target/arm/crypto_helper.c
44
return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
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
}
45
}
53
+
46
54
+void HELPER(crypto_sm3partw1)(void *vd, void *vn, void *vm)
47
+static inline uint32_t syn_pcalignment(void)
55
+{
48
+{
56
+ uint64_t *rd = vd;
49
+ return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
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
+}
50
+}
79
+
51
+
80
+void HELPER(crypto_sm3partw2)(void *vd, void *vn, void *vm)
52
#endif /* TARGET_ARM_SYNDROME_H */
53
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/linux-user/aarch64/cpu_loop.c
56
+++ b/linux-user/aarch64/cpu_loop.c
57
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
58
break;
59
case EXCP_PREFETCH_ABORT:
60
case EXCP_DATA_ABORT:
61
- /* We should only arrive here with EC in {DATAABORT, INSNABORT}. */
62
ec = syn_get_ec(env->exception.syndrome);
63
- assert(ec == EC_DATAABORT || ec == EC_INSNABORT);
64
-
65
- /* Both EC have the same format for FSC, or close enough. */
66
- fsc = extract32(env->exception.syndrome, 0, 6);
67
- switch (fsc) {
68
- case 0x04 ... 0x07: /* Translation fault, level {0-3} */
69
- si_signo = TARGET_SIGSEGV;
70
- si_code = TARGET_SEGV_MAPERR;
71
+ switch (ec) {
72
+ case EC_DATAABORT:
73
+ case EC_INSNABORT:
74
+ /* Both EC have the same format for FSC, or close enough. */
75
+ fsc = extract32(env->exception.syndrome, 0, 6);
76
+ switch (fsc) {
77
+ case 0x04 ... 0x07: /* Translation fault, level {0-3} */
78
+ si_signo = TARGET_SIGSEGV;
79
+ si_code = TARGET_SEGV_MAPERR;
80
+ break;
81
+ case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
82
+ case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
83
+ si_signo = TARGET_SIGSEGV;
84
+ si_code = TARGET_SEGV_ACCERR;
85
+ break;
86
+ case 0x11: /* Synchronous Tag Check Fault */
87
+ si_signo = TARGET_SIGSEGV;
88
+ si_code = TARGET_SEGV_MTESERR;
89
+ break;
90
+ case 0x21: /* Alignment fault */
91
+ si_signo = TARGET_SIGBUS;
92
+ si_code = TARGET_BUS_ADRALN;
93
+ break;
94
+ default:
95
+ g_assert_not_reached();
96
+ }
97
break;
98
- case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
99
- case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
100
- si_signo = TARGET_SIGSEGV;
101
- si_code = TARGET_SEGV_ACCERR;
102
- break;
103
- case 0x11: /* Synchronous Tag Check Fault */
104
- si_signo = TARGET_SIGSEGV;
105
- si_code = TARGET_SEGV_MTESERR;
106
- break;
107
- case 0x21: /* Alignment fault */
108
+ case EC_PCALIGNMENT:
109
si_signo = TARGET_SIGBUS;
110
si_code = TARGET_BUS_ADRALN;
111
break;
112
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/tlb_helper.c
115
+++ b/target/arm/tlb_helper.c
116
@@ -XXX,XX +XXX,XX @@
117
#include "cpu.h"
118
#include "internals.h"
119
#include "exec/exec-all.h"
120
+#include "exec/helper-proto.h"
121
122
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
123
unsigned int target_el,
124
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
125
arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
126
}
127
128
+void helper_exception_pc_alignment(CPUARMState *env, target_ulong pc)
81
+{
129
+{
82
+ uint64_t *rd = vd;
130
+ ARMMMUFaultInfo fi = { .type = ARMFault_Alignment };
83
+ uint64_t *rn = vn;
131
+ int target_el = exception_target_el(env);
84
+ uint64_t *rm = vm;
132
+ int mmu_idx = cpu_mmu_index(env, true);
85
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
133
+ uint32_t fsc;
86
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
134
+
87
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
135
+ env->exception.vaddress = pc;
88
+ uint32_t t = CR_ST_WORD(n, 0) ^ ror32(CR_ST_WORD(m, 0), 25);
136
+
89
+
137
+ /*
90
+ CR_ST_WORD(d, 0) ^= t;
138
+ * Note that the fsc is not applicable to this exception,
91
+ CR_ST_WORD(d, 1) ^= CR_ST_WORD(n, 1) ^ ror32(CR_ST_WORD(m, 1), 25);
139
+ * since any syndrome is pcalignment not insn_abort.
92
+ CR_ST_WORD(d, 2) ^= CR_ST_WORD(n, 2) ^ ror32(CR_ST_WORD(m, 2), 25);
140
+ */
93
+ CR_ST_WORD(d, 3) ^= CR_ST_WORD(n, 3) ^ ror32(CR_ST_WORD(m, 3), 25) ^
141
+ env->exception.fsr = compute_fsr_fsc(env, &fi, target_el, mmu_idx, &fsc);
94
+ ror32(t, 17) ^ ror32(t, 2) ^ ror32(t, 26);
142
+ raise_exception(env, EXCP_PREFETCH_ABORT, syn_pcalignment(), target_el);
95
+
96
+ rd[0] = d.l[0];
97
+ rd[1] = d.l[1];
98
+}
143
+}
99
+
144
+
100
+void HELPER(crypto_sm3tt)(void *vd, void *vn, void *vm, uint32_t imm2,
145
#if !defined(CONFIG_USER_ONLY)
101
+ uint32_t opcode)
146
102
+{
147
/*
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
148
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
150
index XXXXXXX..XXXXXXX 100644
149
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-a64.c
150
--- a/target/arm/translate-a64.c
152
+++ b/target/arm/translate-a64.c
151
+++ b/target/arm/translate-a64.c
153
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
152
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
154
break;
153
uint64_t pc = s->base.pc_next;
155
}
154
uint32_t insn;
156
} else {
155
157
- unallocated_encoding(s);
156
+ /* Singlestep exceptions have the highest priority. */
158
- return;
157
if (s->ss_active && !s->pstate_ss) {
159
+ switch (opcode) {
158
/* Singlestep state is Active-pending.
160
+ case 0: /* SM3PARTW1 */
159
* If we're in this state at the start of a TB then either
161
+ feature = ARM_FEATURE_V8_SM3;
160
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
162
+ genfn = gen_helper_crypto_sm3partw1;
161
return;
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
}
162
}
173
163
174
if (!arm_dc_feature(s, feature)) {
164
+ if (pc & 3) {
175
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
165
+ /*
176
case 1: /* BCAX */
166
+ * PC alignment fault. This has priority over the instruction abort
177
feature = ARM_FEATURE_V8_SHA3;
167
+ * that we would receive from a translation fault via arm_ldl_code.
178
break;
168
+ * This should only be possible after an indirect branch, at the
179
+ case 2: /* SM3SS1 */
169
+ * start of the TB.
180
+ feature = ARM_FEATURE_V8_SM3;
170
+ */
181
+ break;
171
+ assert(s->base.num_insns == 1);
182
default:
172
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
183
unallocated_encoding(s);
173
+ s->base.is_jmp = DISAS_NORETURN;
184
return;
174
+ s->base.pc_next = QEMU_ALIGN_UP(pc, 4);
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
}
218
}
219
220
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_xar(DisasContext *s, uint32_t insn)
221
tcg_temp_free_i64(tcg_res[1]);
222
}
223
224
+/* Crypto three-reg imm2
225
+ * 31 21 20 16 15 14 13 12 11 10 9 5 4 0
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;
175
+ return;
243
+ }
176
+ }
244
+
177
+
245
+ if (!fp_access_check(s)) {
178
s->pc_curr = pc;
179
insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
180
s->insn = insn;
181
diff --git a/target/arm/translate.c b/target/arm/translate.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/arm/translate.c
184
+++ b/target/arm/translate.c
185
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
186
uint32_t pc = dc->base.pc_next;
187
unsigned int insn;
188
189
- if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
190
+ /* Singlestep exceptions have the highest priority. */
191
+ if (arm_check_ss_active(dc)) {
192
+ dc->base.pc_next = pc + 4;
246
+ return;
193
+ return;
247
+ }
194
+ }
248
+
195
+
249
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
196
+ if (pc & 3) {
250
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
197
+ /*
251
+ tcg_rm_ptr = vec_full_reg_ptr(s, rm);
198
+ * PC alignment fault. This has priority over the instruction abort
252
+ tcg_imm2 = tcg_const_i32(imm2);
199
+ * that we would receive from a translation fault via arm_ldl_code
253
+ tcg_opcode = tcg_const_i32(opcode);
200
+ * (or the execution of the kernelpage entrypoint). This should only
254
+
201
+ * be possible after an indirect branch, at the start of the TB.
255
+ gen_helper_crypto_sm3tt(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr, tcg_imm2,
202
+ */
256
+ tcg_opcode);
203
+ assert(dc->base.num_insns == 1);
257
+
204
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
258
+ tcg_temp_free_ptr(tcg_rd_ptr);
205
+ dc->base.is_jmp = DISAS_NORETURN;
259
+ tcg_temp_free_ptr(tcg_rn_ptr);
206
+ dc->base.pc_next = QEMU_ALIGN_UP(pc, 4);
260
+ tcg_temp_free_ptr(tcg_rm_ptr);
207
+ return;
261
+ tcg_temp_free_i32(tcg_imm2);
208
+ }
262
+ tcg_temp_free_i32(tcg_opcode);
209
+
263
+}
210
+ if (arm_check_kernelpage(dc)) {
264
+
211
dc->base.pc_next = pc + 4;
265
/* C3.6 Data processing - SIMD, inc Crypto
212
return;
266
*
213
}
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
276
--
214
--
277
2.16.1
215
2.25.1
278
216
279
217
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Change vfp.regs as a uint64_t to vfp.zregs as an ARMVectorReg.
3
Misaligned thumb PC is architecturally impossible.
4
The previous patches have made the change in representation
4
Assert is better than proceeding, in case we've missed
5
relatively painless.
5
something somewhere.
6
6
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Expand a comment about aligning the pc in gdbstub.
8
Fail an incoming migrate if a thumb pc is misaligned.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
target/arm/cpu.h | 59 +++++++++++++++++++++++++++++++---------------
14
target/arm/gdbstub.c | 9 +++++++--
14
target/arm/machine.c | 35 ++++++++++++++++++++++++++-
15
target/arm/machine.c | 10 ++++++++++
15
target/arm/translate-a64.c | 8 +++----
16
target/arm/translate.c | 3 +++
16
target/arm/translate.c | 7 +++---
17
3 files changed, 20 insertions(+), 2 deletions(-)
17
4 files changed, 81 insertions(+), 28 deletions(-)
18
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
21
--- a/target/arm/gdbstub.c
22
+++ b/target/arm/cpu.h
22
+++ b/target/arm/gdbstub.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
24
uint32_t base_mask;
24
25
} TCR;
25
tmp = ldl_p(mem_buf);
26
26
27
+/* Define a maximum sized vector register.
27
- /* Mask out low bit of PC to workaround gdb bugs. This will probably
28
+ * For 32-bit, this is a 128-bit NEON/AdvSIMD register.
28
- cause problems if we ever implement the Jazelle DBX extensions. */
29
+ * For 64-bit, this is a 2048-bit SVE register.
29
+ /*
30
+ *
30
+ * Mask out low bits of PC to workaround gdb bugs.
31
+ * Note that the mapping between S, D, and Q views of the register bank
31
+ * This avoids an assert in thumb_tr_translate_insn, because it is
32
+ * differs between AArch64 and AArch32.
32
+ * architecturally impossible to misalign the pc.
33
+ * In AArch32:
33
+ * This will probably cause problems if we ever implement the
34
+ * Qn = regs[n].d[1]:regs[n].d[0]
34
+ * Jazelle DBX extensions.
35
+ * Dn = regs[n / 2].d[n & 1]
35
+ */
36
+ * Sn = regs[n / 4].d[n % 4 / 2],
36
if (n == 15) {
37
+ * bits 31..0 for even n, and bits 63..32 for odd n
37
tmp &= ~1;
38
+ * (and regs[16] to regs[31] are inaccessible)
38
}
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
39
diff --git a/target/arm/machine.c b/target/arm/machine.c
118
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/machine.c
41
--- a/target/arm/machine.c
120
+++ b/target/arm/machine.c
42
+++ b/target/arm/machine.c
121
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_vfp = {
43
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
122
.minimum_version_id = 3,
44
return -1;
123
.needed = vfp_needed,
45
}
124
.fields = (VMStateField[]) {
46
}
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
+
47
+
160
/* The xregs array is a little awkward because element 1 (FPSCR)
48
+ /*
161
* requires a specific accessor, so we have to split it up in
49
+ * Misaligned thumb pc is architecturally impossible.
162
* the vmstate:
50
+ * We have an assert in thumb_tr_translate_insn to verify this.
163
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
51
+ * Fail an incoming migrate to avoid this assert.
164
index XXXXXXX..XXXXXXX 100644
52
+ */
165
--- a/target/arm/translate-a64.c
53
+ if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
166
+++ b/target/arm/translate-a64.c
54
+ return -1;
167
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
55
+ }
168
{
56
+
169
int offs = 0;
57
if (!kvm_enabled()) {
170
#ifdef HOST_WORDS_BIGENDIAN
58
pmu_op_finish(&cpu->env);
171
- /* This is complicated slightly because vfp.regs[2n] is
59
}
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
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
197
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
198
--- a/target/arm/translate.c
62
--- a/target/arm/translate.c
199
+++ b/target/arm/translate.c
63
+++ b/target/arm/translate.c
200
@@ -XXX,XX +XXX,XX @@ static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
64
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
201
}
65
uint32_t insn;
202
}
66
bool is_16bit;
203
67
204
-static inline long
68
+ /* Misaligned thumb PC is architecturally impossible. */
205
-vfp_reg_offset (int dp, int reg)
69
+ assert((dc->base.pc_next & 1) == 0);
206
+static inline long vfp_reg_offset(bool dp, unsigned reg)
70
+
207
{
71
if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
208
if (dp) {
72
dc->base.pc_next = pc + 2;
209
- return offsetof(CPUARMState, vfp.regs[reg]);
73
return;
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
--
74
--
218
2.16.1
75
2.25.1
219
76
220
77
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
IP block found on several generations of i.MX family does not use
3
Both single-step and pc alignment faults have priority over
4
vanilla SDHCI implementation and it comes with a number of quirks.
4
breakpoint exceptions.
5
5
6
Introduce i.MX SDHCI subtype of SDHCI block to add code necessary to
7
support unmodified Linux guest driver.
8
9
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Jason Wang <jasowang@redhat.com>
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Cc: 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>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
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>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
9
---
23
hw/sd/sdhci-internal.h | 23 +++++
10
target/arm/debug_helper.c | 23 +++++++++++++++++++++++
24
include/hw/sd/sdhci.h | 13 +++
11
1 file changed, 23 insertions(+)
25
hw/sd/sdhci.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++-
26
3 files changed, 265 insertions(+), 1 deletion(-)
27
12
28
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
13
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
29
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/sd/sdhci-internal.h
15
--- a/target/arm/debug_helper.c
31
+++ b/hw/sd/sdhci-internal.h
16
+++ b/target/arm/debug_helper.c
32
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
33
18
{
34
/* R/W Host control Register 0x0 */
19
ARMCPU *cpu = ARM_CPU(cs);
35
#define SDHC_HOSTCTL 0x28
20
CPUARMState *env = &cpu->env;
36
+#define SDHC_CTRL_LED 0x01
21
+ target_ulong pc;
37
#define SDHC_CTRL_DMA_CHECK_MASK 0x18
22
int n;
38
#define SDHC_CTRL_SDMA 0x00
23
39
#define SDHC_CTRL_ADMA1_32 0x08
24
/*
40
#define SDHC_CTRL_ADMA2_32 0x10
25
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
41
#define SDHC_CTRL_ADMA2_64 0x18
26
return false;
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
}
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
}
27
}
136
28
137
sysbus_init_irq(sbd, &s->irq);
29
+ /*
138
+
30
+ * Single-step exceptions have priority over breakpoint exceptions.
139
+ memory_region_init_io(&s->iomem, OBJECT(s), s->io_ops, s, "sdhci",
31
+ * If single-step state is active-pending, suppress the bp.
140
+ SDHC_REGISTERS_MAP_SIZE);
32
+ */
141
+
33
+ if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {
142
sysbus_init_mmio(sbd, &s->iomem);
34
+ return false;
143
}
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
+ }
35
+ }
191
+
36
+
192
+ return ret;
37
+ /*
193
+}
38
+ * PC alignment faults have priority over breakpoint exceptions.
39
+ */
40
+ pc = is_a64(env) ? env->pc : env->regs[15];
41
+ if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {
42
+ return false;
43
+ }
194
+
44
+
195
+static void
45
+ /*
196
+usdhc_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
46
+ * Instruction aborts have priority over breakpoint exceptions.
197
+{
47
+ * TODO: We would need to look up the page for PC and verify that
198
+ SDHCIState *s = SYSBUS_SDHCI(opaque);
48
+ * it is present and executable.
199
+ uint8_t hostctl;
49
+ */
200
+ uint32_t value = (uint32_t)val;
201
+
50
+
202
+ switch (offset) {
51
for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
203
+ case ESDHC_DLL_CTRL:
52
if (bp_wp_matches(cpu, n, false)) {
204
+ case ESDHC_TUNE_CTRL_STATUS:
53
return true;
205
+ case ESDHC_UNDOCUMENTED_REG27:
206
+ case ESDHC_TUNING_CTRL:
207
+ case ESDHC_WTMK_LVL:
208
+ case ESDHC_VENDOR_SPEC:
209
+ break;
210
+
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
--
54
--
379
2.16.1
55
2.25.1
380
56
381
57
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add code to emulate Chipidea USB IP (used in i.MX SoCs). Tested to
4
work against:
5
6
-usb -drive if=none,id=stick,file=usb.img,format=raw -device \
7
usb-storage,bus=usb-bus.0,drive=stick
8
9
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Jason Wang <jasowang@redhat.com>
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Cc: 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>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
6
---
21
hw/usb/Makefile.objs | 1 +
7
tests/tcg/aarch64/pcalign-a64.c | 37 +++++++++++++++++++++++++
22
include/hw/usb/chipidea.h | 16 +++++
8
tests/tcg/arm/pcalign-a32.c | 46 +++++++++++++++++++++++++++++++
23
hw/usb/chipidea.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++
9
tests/tcg/aarch64/Makefile.target | 4 +--
24
3 files changed, 193 insertions(+)
10
tests/tcg/arm/Makefile.target | 4 +++
25
create mode 100644 include/hw/usb/chipidea.h
11
4 files changed, 89 insertions(+), 2 deletions(-)
26
create mode 100644 hw/usb/chipidea.c
12
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
13
create mode 100644 tests/tcg/arm/pcalign-a32.c
27
14
28
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
15
diff --git a/tests/tcg/aarch64/pcalign-a64.c b/tests/tcg/aarch64/pcalign-a64.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/usb/Makefile.objs
31
+++ b/hw/usb/Makefile.objs
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
16
new file mode 100644
42
index XXXXXXX..XXXXXXX
17
index XXXXXXX..XXXXXXX
43
--- /dev/null
18
--- /dev/null
44
+++ b/include/hw/usb/chipidea.h
19
+++ b/tests/tcg/aarch64/pcalign-a64.c
45
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
46
+#ifndef CHIPIDEA_H
21
+/* Test PC misalignment exception */
47
+#define CHIPIDEA_H
48
+
22
+
49
+#include "hw/usb/hcd-ehci.h"
23
+#include <assert.h>
24
+#include <signal.h>
25
+#include <stdlib.h>
26
+#include <stdio.h>
50
+
27
+
51
+typedef struct ChipideaState {
28
+static void *expected;
52
+ /*< private >*/
53
+ EHCISysBusState parent_obj;
54
+
29
+
55
+ MemoryRegion iomem[3];
30
+static void sigbus(int sig, siginfo_t *info, void *vuc)
56
+} ChipideaState;
31
+{
32
+ assert(info->si_code == BUS_ADRALN);
33
+ assert(info->si_addr == expected);
34
+ exit(EXIT_SUCCESS);
35
+}
57
+
36
+
58
+#define TYPE_CHIPIDEA "usb-chipidea"
37
+int main()
59
+#define CHIPIDEA(obj) OBJECT_CHECK(ChipideaState, (obj), TYPE_CHIPIDEA)
38
+{
39
+ void *tmp;
60
+
40
+
61
+#endif /* CHIPIDEA_H */
41
+ struct sigaction sa = {
62
diff --git a/hw/usb/chipidea.c b/hw/usb/chipidea.c
42
+ .sa_sigaction = sigbus,
43
+ .sa_flags = SA_SIGINFO
44
+ };
45
+
46
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
47
+ perror("sigaction");
48
+ return EXIT_FAILURE;
49
+ }
50
+
51
+ asm volatile("adr %0, 1f + 1\n\t"
52
+ "str %0, %1\n\t"
53
+ "br %0\n"
54
+ "1:"
55
+ : "=&r"(tmp), "=m"(expected));
56
+ abort();
57
+}
58
diff --git a/tests/tcg/arm/pcalign-a32.c b/tests/tcg/arm/pcalign-a32.c
63
new file mode 100644
59
new file mode 100644
64
index XXXXXXX..XXXXXXX
60
index XXXXXXX..XXXXXXX
65
--- /dev/null
61
--- /dev/null
66
+++ b/hw/usb/chipidea.c
62
+++ b/tests/tcg/arm/pcalign-a32.c
67
@@ -XXX,XX +XXX,XX @@
63
@@ -XXX,XX +XXX,XX @@
68
+/*
64
+/* Test PC misalignment exception */
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
+
65
+
79
+#include "qemu/osdep.h"
66
+#ifdef __thumb__
80
+#include "hw/usb/hcd-ehci.h"
67
+#error "This test must be compiled for ARM"
81
+#include "hw/usb/chipidea.h"
68
+#endif
82
+#include "qemu/log.h"
83
+
69
+
84
+enum {
70
+#include <assert.h>
85
+ CHIPIDEA_USBx_DCIVERSION = 0x000,
71
+#include <signal.h>
86
+ CHIPIDEA_USBx_DCCPARAMS = 0x004,
72
+#include <stdlib.h>
87
+ CHIPIDEA_USBx_DCCPARAMS_HC = BIT(8),
73
+#include <stdio.h>
88
+};
89
+
74
+
90
+static uint64_t chipidea_read(void *opaque, hwaddr offset,
75
+static void *expected;
91
+ unsigned size)
76
+
77
+static void sigbus(int sig, siginfo_t *info, void *vuc)
92
+{
78
+{
93
+ return 0;
79
+ assert(info->si_code == BUS_ADRALN);
80
+ assert(info->si_addr == expected);
81
+ exit(EXIT_SUCCESS);
94
+}
82
+}
95
+
83
+
96
+static void chipidea_write(void *opaque, hwaddr offset,
84
+int main()
97
+ uint64_t value, unsigned size)
98
+{
85
+{
99
+}
86
+ void *tmp;
100
+
87
+
101
+static const struct MemoryRegionOps chipidea_ops = {
88
+ struct sigaction sa = {
102
+ .read = chipidea_read,
89
+ .sa_sigaction = sigbus,
103
+ .write = chipidea_write,
90
+ .sa_flags = SA_SIGINFO
104
+ .endianness = DEVICE_NATIVE_ENDIAN,
91
+ };
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
+
92
+
118
+static uint64_t chipidea_dc_read(void *opaque, hwaddr offset,
93
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
119
+ unsigned size)
94
+ perror("sigaction");
120
+{
95
+ return EXIT_FAILURE;
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
+ }
96
+ }
133
+
97
+
134
+ return 0;
98
+ asm volatile("adr %0, 1f + 2\n\t"
135
+}
99
+ "str %0, %1\n\t"
136
+
100
+ "bx %0\n"
137
+static void chipidea_dc_write(void *opaque, hwaddr offset,
101
+ "1:"
138
+ uint64_t value, unsigned size)
102
+ : "=&r"(tmp), "=m"(expected));
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
+
103
+
219
+ /*
104
+ /*
220
+ * Offsets used were taken from i.MX7Dual Applications Processor
105
+ * From v8, it is CONSTRAINED UNPREDICTABLE whether BXWritePC aligns
221
+ * Reference Manual, Rev 0.1, p. 3177, Table 11-59
106
+ * the address or not. If so, we can legitimately fall through.
222
+ */
107
+ */
223
+ sec->capsbase = 0x100;
108
+ return EXIT_SUCCESS;
224
+ sec->opregbase = 0x140;
109
+}
225
+ sec->portnr = 1;
110
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
111
index XXXXXXX..XXXXXXX 100644
112
--- a/tests/tcg/aarch64/Makefile.target
113
+++ b/tests/tcg/aarch64/Makefile.target
114
@@ -XXX,XX +XXX,XX @@ VPATH         += $(ARM_SRC)
115
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
116
VPATH         += $(AARCH64_SRC)
117
118
-# Float-convert Tests
119
-AARCH64_TESTS=fcvt
120
+# Base architecture tests
121
+AARCH64_TESTS=fcvt pcalign-a64
122
123
fcvt: LDFLAGS+=-lm
124
125
diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target
126
index XXXXXXX..XXXXXXX 100644
127
--- a/tests/tcg/arm/Makefile.target
128
+++ b/tests/tcg/arm/Makefile.target
129
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
130
    $(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)")
131
    $(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
132
133
+# PC alignment test
134
+ARM_TESTS += pcalign-a32
135
+pcalign-a32: CFLAGS+=-marm
226
+
136
+
227
+ set_bit(DEVICE_CATEGORY_USB, dc->categories);
137
ifeq ($(CONFIG_ARM_COMPATIBLE_SEMIHOSTING),y)
228
+ dc->desc = "Chipidea USB Module";
138
229
+}
139
# Semihosting smoke test for linux-user
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
--
140
--
245
2.16.1
141
2.25.1
246
142
247
143
diff view generated by jsdifflib
1
Handle possible MPU faults, SAU faults or bus errors when
1
In the SSE decode function gen_sse(), we combine a byte
2
popping register state off the stack during exception return.
2
'b' and a value 'b1' which can be [0..3], and switch on them:
3
b |= (b1 << 8);
4
switch (b) {
5
...
6
default:
7
unknown_op:
8
gen_unknown_opcode(env, s);
9
return;
10
}
3
11
12
In three cases inside this switch, we were then also checking for
13
"if (b1 >= 2) { goto unknown_op; }".
14
However, this can never happen, because the 'case' values in each place
15
are 0x0nn or 0x1nn and the switch will have directed the b1 == (2, 3)
16
cases to the default already.
17
18
This check was added in commit c045af25a52e9 in 2010; the added code
19
was unnecessary then as well, and was apparently intended only to
20
ensure that we never accidentally ended up indexing off the end
21
of an sse_op_table with only 2 entries as a result of future bugs
22
in the decode logic.
23
24
Change the checks to assert() instead, and make sure they're always
25
immediately before the array access they are protecting.
26
27
Fixes: Coverity CID 1460207
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 1517324542-6607-8-git-send-email-peter.maydell@linaro.org
7
---
30
---
8
target/arm/helper.c | 115 ++++++++++++++++++++++++++++++++++++++++++----------
31
target/i386/tcg/translate.c | 12 +++---------
9
1 file changed, 94 insertions(+), 21 deletions(-)
32
1 file changed, 3 insertions(+), 9 deletions(-)
10
33
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
12
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
36
--- a/target/i386/tcg/translate.c
14
+++ b/target/arm/helper.c
37
+++ b/target/i386/tcg/translate.c
15
@@ -XXX,XX +XXX,XX @@ pend_fault:
38
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
16
return false;
39
case 0x171: /* shift xmm, im */
17
}
40
case 0x172:
18
41
case 0x173:
19
+static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
42
- if (b1 >= 2) {
20
+ ARMMMUIdx mmu_idx)
43
- goto unknown_op;
21
+{
44
- }
22
+ CPUState *cs = CPU(cpu);
45
val = x86_ldub_code(env, s);
23
+ CPUARMState *env = &cpu->env;
46
if (is_xmm) {
24
+ MemTxAttrs attrs = {};
47
tcg_gen_movi_tl(s->T0, val);
25
+ MemTxResult txres;
48
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
26
+ target_ulong page_size;
49
offsetof(CPUX86State, mmx_t0.MMX_L(1)));
27
+ hwaddr physaddr;
50
op1_offset = offsetof(CPUX86State,mmx_t0);
28
+ int prot;
29
+ ARMMMUFaultInfo fi;
30
+ bool secure = mmu_idx & ARM_MMU_IDX_M_S;
31
+ int exc;
32
+ bool exc_secure;
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
+ }
54
+
55
+ value = address_space_ldl(arm_addressspace(cs, attrs), physaddr,
56
+ attrs, &txres);
57
+ if (txres != MEMTX_OK) {
58
+ /* BusFault trying to read the data */
59
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
60
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_UNSTKERR_MASK;
61
+ exc = ARMV7M_EXCP_BUS;
62
+ exc_secure = false;
63
+ goto pend_fault;
64
+ }
65
+
66
+ *dest = value;
67
+ return true;
68
+
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
}
51
}
98
52
+ assert(b1 < 2);
99
- env->regs[4] = ldl_phys(cs->as, frameptr + 0x8);
53
sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
100
- env->regs[5] = ldl_phys(cs->as, frameptr + 0xc);
54
(((modrm >> 3)) & 7)][b1];
101
- env->regs[6] = ldl_phys(cs->as, frameptr + 0x10);
55
if (!sse_fn_epp) {
102
- env->regs[7] = ldl_phys(cs->as, frameptr + 0x14);
56
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
103
- env->regs[8] = ldl_phys(cs->as, frameptr + 0x18);
57
rm = modrm & 7;
104
- env->regs[9] = ldl_phys(cs->as, frameptr + 0x1c);
58
reg = ((modrm >> 3) & 7) | REX_R(s);
105
- env->regs[10] = ldl_phys(cs->as, frameptr + 0x20);
59
mod = (modrm >> 6) & 3;
106
- env->regs[11] = ldl_phys(cs->as, frameptr + 0x24);
60
- if (b1 >= 2) {
107
+ pop_ok =
61
- goto unknown_op;
108
+ v7m_stack_read(cpu, &env->regs[4], frameptr + 0x8, mmu_idx) &&
62
- }
109
+ v7m_stack_read(cpu, &env->regs[4], frameptr + 0x8, mmu_idx) &&
63
110
+ v7m_stack_read(cpu, &env->regs[5], frameptr + 0xc, mmu_idx) &&
64
+ assert(b1 < 2);
111
+ v7m_stack_read(cpu, &env->regs[6], frameptr + 0x10, mmu_idx) &&
65
sse_fn_epp = sse_op_table6[b].op[b1];
112
+ v7m_stack_read(cpu, &env->regs[7], frameptr + 0x14, mmu_idx) &&
66
if (!sse_fn_epp) {
113
+ v7m_stack_read(cpu, &env->regs[8], frameptr + 0x18, mmu_idx) &&
67
goto unknown_op;
114
+ v7m_stack_read(cpu, &env->regs[9], frameptr + 0x1c, mmu_idx) &&
68
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
115
+ v7m_stack_read(cpu, &env->regs[10], frameptr + 0x20, mmu_idx) &&
69
rm = modrm & 7;
116
+ v7m_stack_read(cpu, &env->regs[11], frameptr + 0x24, mmu_idx);
70
reg = ((modrm >> 3) & 7) | REX_R(s);
117
71
mod = (modrm >> 6) & 3;
118
frameptr += 0x28;
72
- if (b1 >= 2) {
119
}
73
- goto unknown_op;
120
74
- }
121
- /* Pop registers. TODO: make these accesses use the correct
75
122
- * attributes and address space (S/NS, priv/unpriv) and handle
76
+ assert(b1 < 2);
123
- * memory transaction failures.
77
sse_fn_eppi = sse_op_table7[b].op[b1];
124
- */
78
if (!sse_fn_eppi) {
125
- env->regs[0] = ldl_phys(cs->as, frameptr);
79
goto unknown_op;
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
--
80
--
163
2.16.1
81
2.25.1
164
82
165
83
diff view generated by jsdifflib
1
Make v7m_push_callee_stack() honour the MPU by using the
1
The qemu-common.h header is not supposed to be included from any
2
new v7m_stack_write() function. We return a flag to indicate
2
other header files, only from .c files (as documented in a comment at
3
whether the pushes failed, which we can then use in
3
the start of it).
4
v7m_exception_taken() to cause us to handle the derived
4
5
exception correctly.
5
include/hw/i386/x86.h and include/hw/i386/microvm.h break this rule.
6
In fact, the include is not required at all, so we can just drop it
7
from both files.
6
8
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 1517324542-6607-6-git-send-email-peter.maydell@linaro.org
12
Message-id: 20211129200510.1233037-2-peter.maydell@linaro.org
11
---
13
---
12
target/arm/helper.c | 64 ++++++++++++++++++++++++++++++++++++++++-------------
14
include/hw/i386/microvm.h | 1 -
13
1 file changed, 49 insertions(+), 15 deletions(-)
15
include/hw/i386/x86.h | 1 -
16
2 files changed, 2 deletions(-)
14
17
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
20
--- a/include/hw/i386/microvm.h
18
+++ b/target/arm/helper.c
21
+++ b/include/hw/i386/microvm.h
19
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
22
@@ -XXX,XX +XXX,XX @@
20
return addr;
23
#ifndef HW_I386_MICROVM_H
21
}
24
#define HW_I386_MICROVM_H
22
25
23
-static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
26
-#include "qemu-common.h"
24
+static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
27
#include "exec/hwaddr.h"
25
bool ignore_faults)
28
#include "qemu/notify.h"
26
{
29
27
/* For v8M, push the callee-saves register part of the stack frame.
30
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
28
@@ -XXX,XX +XXX,XX @@ static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
31
index XXXXXXX..XXXXXXX 100644
29
* In the tailchaining case this may not be the current stack.
32
--- a/include/hw/i386/x86.h
30
*/
33
+++ b/include/hw/i386/x86.h
31
CPUARMState *env = &cpu->env;
34
@@ -XXX,XX +XXX,XX @@
32
- CPUState *cs = CPU(cpu);
35
#ifndef HW_I386_X86_H
33
uint32_t *frame_sp_p;
36
#define HW_I386_X86_H
34
uint32_t frameptr;
37
35
+ ARMMMUIdx mmu_idx;
38
-#include "qemu-common.h"
36
+ bool stacked_ok;
39
#include "exec/hwaddr.h"
37
40
#include "qemu/notify.h"
38
if (dotailchain) {
41
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
}
52
53
frameptr = *frame_sp_p - 0x28;
54
55
- stl_phys(cs->as, frameptr, 0xfefa125b);
56
- stl_phys(cs->as, frameptr + 0x8, env->regs[4]);
57
- stl_phys(cs->as, frameptr + 0xc, env->regs[5]);
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
--
42
--
132
2.16.1
43
2.25.1
133
44
134
45
diff view generated by jsdifflib
1
The memory writes done to push registers on the stack
1
The qemu-common.h header is not supposed to be included from any
2
on exception entry in M profile CPUs are supposed to
2
other header files, only from .c files (as documented in a comment at
3
go via MPU permissions checks, which may cause us to
3
the start of it).
4
take a derived exception instead of the original one of
4
5
the MPU lookup fails. We were implementing these as
5
Move the include to linux-user/hexagon/cpu_loop.c, which needs it for
6
always-succeeds direct writes to physical memory.
6
the declaration of cpu_exec_step_atomic().
7
Rewrite v7m_push_stack() to do the necessary checks.
8
7
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 1517324542-6607-5-git-send-email-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Message-id: 20211129200510.1233037-3-peter.maydell@linaro.org
12
---
13
---
13
target/arm/helper.c | 103 ++++++++++++++++++++++++++++++++++++++++++++--------
14
target/hexagon/cpu.h | 1 -
14
1 file changed, 87 insertions(+), 16 deletions(-)
15
linux-user/hexagon/cpu_loop.c | 1 +
16
2 files changed, 1 insertion(+), 1 deletion(-)
15
17
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
20
--- a/target/hexagon/cpu.h
19
+++ b/target/arm/helper.c
21
+++ b/target/hexagon/cpu.h
20
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUHexagonState CPUHexagonState;
21
return target_el;
23
22
}
24
#include "fpu/softfloat-types.h"
23
25
24
-static void v7m_push(CPUARMState *env, uint32_t val)
26
-#include "qemu-common.h"
25
+static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
27
#include "exec/cpu-defs.h"
26
+ ARMMMUIdx mmu_idx, bool ignfault)
28
#include "hex_regs.h"
27
{
29
#include "mmvec/mmvec.h"
28
- CPUState *cs = CPU(arm_env_get_cpu(env));
30
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
29
+ CPUState *cs = CPU(cpu);
31
index XXXXXXX..XXXXXXX 100644
30
+ CPUARMState *env = &cpu->env;
32
--- a/linux-user/hexagon/cpu_loop.c
31
+ MemTxAttrs attrs = {};
33
+++ b/linux-user/hexagon/cpu_loop.c
32
+ MemTxResult txres;
34
@@ -XXX,XX +XXX,XX @@
33
+ target_ulong page_size;
35
*/
34
+ hwaddr physaddr;
36
35
+ int prot;
37
#include "qemu/osdep.h"
36
+ ARMMMUFaultInfo fi;
38
+#include "qemu-common.h"
37
+ bool secure = mmu_idx & ARM_MMU_IDX_M_S;
39
#include "qemu.h"
38
+ int exc;
40
#include "user-internals.h"
39
+ bool exc_secure;
41
#include "cpu_loop-common.h"
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
+ }
61
+ address_space_stl_le(arm_addressspace(cs, attrs), physaddr, value,
62
+ attrs, &txres);
63
+ if (txres != MEMTX_OK) {
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
--
42
--
148
2.16.1
43
2.25.1
149
44
150
45
diff view generated by jsdifflib
1
Currently armv7m_nvic_acknowledge_irq() does three things:
1
The qemu-common.h header is not supposed to be included from any
2
* make the current highest priority pending interrupt active
2
other header files, only from .c files (as documented in a comment at
3
* return a bool indicating whether that interrupt is targeting
3
the start of it).
4
Secure or NonSecure state
5
* implicitly tell the caller which is the highest priority
6
pending interrupt by setting env->v7m.exception
7
4
8
We need to split these jobs, because v7m_exception_taken()
5
Nothing actually relies on target/rx/cpu.h including it, so we can
9
needs to know whether the pending interrupt targets Secure so
6
just drop the include.
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
7
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
27
Message-id: 1517324542-6607-3-git-send-email-peter.maydell@linaro.org
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
13
Message-id: 20211129200510.1233037-4-peter.maydell@linaro.org
28
---
14
---
29
target/arm/cpu.h | 19 ++++++++++++++++---
15
target/rx/cpu.h | 1 -
30
hw/intc/armv7m_nvic.c | 30 +++++++++++++++++++++++-------
16
1 file changed, 1 deletion(-)
31
target/arm/helper.c | 16 ++++++++++++----
32
hw/intc/trace-events | 3 ++-
33
4 files changed, 53 insertions(+), 15 deletions(-)
34
17
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
36
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.h
20
--- a/target/rx/cpu.h
38
+++ b/target/arm/cpu.h
21
+++ b/target/rx/cpu.h
39
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
22
@@ -XXX,XX +XXX,XX @@
40
* a different exception).
23
#define RX_CPU_H
41
*/
24
42
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
25
#include "qemu/bitops.h"
43
+/**
26
-#include "qemu-common.h"
44
+ * armv7m_nvic_get_pending_irq_info: return highest priority pending
27
#include "hw/registerfields.h"
45
+ * exception, and whether it targets Secure state
28
#include "cpu-qom.h"
46
+ * @opaque: the NVIC
29
47
+ * @pirq: set to pending exception number
48
+ * @ptargets_secure: set to whether pending exception targets Secure
49
+ *
50
+ * This function writes the number of the highest priority pending
51
+ * exception (the one which would be made active by
52
+ * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
53
+ * to true if the current highest priority pending exception should
54
+ * be taken to Secure state, false for NS.
55
+ */
56
+void armv7m_nvic_get_pending_irq_info(void *opaque, int *pirq,
57
+ bool *ptargets_secure);
58
/**
59
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
60
* @opaque: the NVIC
61
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
62
* Move the current highest priority pending exception from the pending
63
* state to the active state, and update v7m.exception to indicate that
64
* it is the exception currently being handled.
65
- *
66
- * Returns: true if exception should be taken to Secure state, false for NS
67
*/
68
-bool armv7m_nvic_acknowledge_irq(void *opaque);
69
+void armv7m_nvic_acknowledge_irq(void *opaque);
70
/**
71
* armv7m_nvic_complete_irq: complete specified interrupt or exception
72
* @opaque: the NVIC
73
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/intc/armv7m_nvic.c
76
+++ b/hw/intc/armv7m_nvic.c
77
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
78
}
79
80
/* Make pending IRQ active. */
81
-bool armv7m_nvic_acknowledge_irq(void *opaque)
82
+void armv7m_nvic_acknowledge_irq(void *opaque)
83
{
84
NVICState *s = (NVICState *)opaque;
85
CPUARMState *env = &s->cpu->env;
86
const int pending = s->vectpending;
87
const int running = nvic_exec_prio(s);
88
VecInfo *vec;
89
- bool targets_secure;
90
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
144
--- a/target/arm/helper.c
145
+++ b/target/arm/helper.c
146
@@ -XXX,XX +XXX,XX @@ static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
147
}
148
}
149
150
-static uint32_t arm_v7m_load_vector(ARMCPU *cpu, bool targets_secure)
151
+static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
152
{
153
CPUState *cs = CPU(cpu);
154
CPUARMState *env = &cpu->env;
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
197
--- a/hw/intc/trace-events
198
+++ b/hw/intc/trace-events
199
@@ -XXX,XX +XXX,XX @@ nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
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)"
201
nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
202
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
203
-nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)"
204
+nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (prio %d)"
205
+nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d"
206
nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)"
207
nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d"
208
nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
209
--
30
--
210
2.16.1
31
2.25.1
211
32
212
33
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
A lot of C files in hw/arm include qemu-common.h when they don't
2
need anything from it. Drop the include lines.
2
3
3
Move virt's PSCI DT fixup code to arm/boot.c and set this fixup to
4
omap1.c, pxa2xx.c and strongarm.c retain the include because they
4
happen automatically for every board that doesn't mark "psci-conduit"
5
use it for the prototype of qemu_get_timedate().
5
as disabled. This way emulated boards other than "virt" that rely on
6
PSIC for SMP could benefit from that code.
7
6
8
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Cc: Jason Wang <jasowang@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
12
Cc: Michael S. Tsirkin <mst@redhat.com>
13
Cc: qemu-devel@nongnu.org
14
Cc: qemu-arm@nongnu.org
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>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
11
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
12
Message-id: 20211129200510.1233037-5-peter.maydell@linaro.org
20
---
13
---
21
hw/arm/boot.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
14
hw/arm/boot.c | 1 -
22
hw/arm/virt.c | 61 -------------------------------------------------------
15
hw/arm/digic_boards.c | 1 -
23
2 files changed, 65 insertions(+), 61 deletions(-)
16
hw/arm/highbank.c | 1 -
17
hw/arm/npcm7xx_boards.c | 1 -
18
hw/arm/sbsa-ref.c | 1 -
19
hw/arm/stm32f405_soc.c | 1 -
20
hw/arm/vexpress.c | 1 -
21
hw/arm/virt.c | 1 -
22
8 files changed, 8 deletions(-)
24
23
25
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
24
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
26
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/boot.c
26
--- a/hw/arm/boot.c
28
+++ b/hw/arm/boot.c
27
+++ b/hw/arm/boot.c
29
@@ -XXX,XX +XXX,XX @@ static void set_kernel_args_old(const struct arm_boot_info *info)
28
@@ -XXX,XX +XXX,XX @@
30
}
29
*/
31
}
30
32
31
#include "qemu/osdep.h"
33
+static void fdt_add_psci_node(void *fdt)
32
-#include "qemu-common.h"
34
+{
33
#include "qemu/datadir.h"
35
+ uint32_t cpu_suspend_fn;
34
#include "qemu/error-report.h"
36
+ uint32_t cpu_off_fn;
35
#include "qapi/error.h"
37
+ uint32_t cpu_on_fn;
36
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
38
+ uint32_t migrate_fn;
37
index XXXXXXX..XXXXXXX 100644
39
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
38
--- a/hw/arm/digic_boards.c
40
+ const char *psci_method;
39
+++ b/hw/arm/digic_boards.c
41
+ int64_t psci_conduit;
40
@@ -XXX,XX +XXX,XX @@
42
+
41
43
+ psci_conduit = object_property_get_int(OBJECT(armcpu),
42
#include "qemu/osdep.h"
44
+ "psci-conduit",
43
#include "qapi/error.h"
45
+ &error_abort);
44
-#include "qemu-common.h"
46
+ switch (psci_conduit) {
45
#include "qemu/datadir.h"
47
+ case QEMU_PSCI_CONDUIT_DISABLED:
46
#include "hw/boards.h"
48
+ return;
47
#include "qemu/error-report.h"
49
+ case QEMU_PSCI_CONDUIT_HVC:
48
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
50
+ psci_method = "hvc";
49
index XXXXXXX..XXXXXXX 100644
51
+ break;
50
--- a/hw/arm/highbank.c
52
+ case QEMU_PSCI_CONDUIT_SMC:
51
+++ b/hw/arm/highbank.c
53
+ psci_method = "smc";
52
@@ -XXX,XX +XXX,XX @@
54
+ break;
53
*/
55
+ default:
54
56
+ g_assert_not_reached();
55
#include "qemu/osdep.h"
57
+ }
56
-#include "qemu-common.h"
58
+
57
#include "qemu/datadir.h"
59
+ qemu_fdt_add_subnode(fdt, "/psci");
58
#include "qapi/error.h"
60
+ if (armcpu->psci_version == 2) {
59
#include "hw/sysbus.h"
61
+ const char comp[] = "arm,psci-0.2\0arm,psci";
60
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
62
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
61
index XXXXXXX..XXXXXXX 100644
63
+
62
--- a/hw/arm/npcm7xx_boards.c
64
+ cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
63
+++ b/hw/arm/npcm7xx_boards.c
65
+ if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
64
@@ -XXX,XX +XXX,XX @@
66
+ cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND;
65
#include "hw/qdev-core.h"
67
+ cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON;
66
#include "hw/qdev-properties.h"
68
+ migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE;
67
#include "qapi/error.h"
69
+ } else {
68
-#include "qemu-common.h"
70
+ cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND;
69
#include "qemu/datadir.h"
71
+ cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON;
70
#include "qemu/units.h"
72
+ migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE;
71
#include "sysemu/blockdev.h"
73
+ }
72
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
74
+ } else {
73
index XXXXXXX..XXXXXXX 100644
75
+ qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci");
74
--- a/hw/arm/sbsa-ref.c
76
+
75
+++ b/hw/arm/sbsa-ref.c
77
+ cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND;
76
@@ -XXX,XX +XXX,XX @@
78
+ cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF;
77
*/
79
+ cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON;
78
80
+ migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE;
79
#include "qemu/osdep.h"
81
+ }
80
-#include "qemu-common.h"
82
+
81
#include "qemu/datadir.h"
83
+ /* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer
82
#include "qapi/error.h"
84
+ * to the instruction that should be used to invoke PSCI functions.
83
#include "qemu/error-report.h"
85
+ * However, the device tree binding uses 'method' instead, so that is
84
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
86
+ * what we should use here.
85
index XXXXXXX..XXXXXXX 100644
87
+ */
86
--- a/hw/arm/stm32f405_soc.c
88
+ qemu_fdt_setprop_string(fdt, "/psci", "method", psci_method);
87
+++ b/hw/arm/stm32f405_soc.c
89
+
88
@@ -XXX,XX +XXX,XX @@
90
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn);
89
91
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn);
90
#include "qemu/osdep.h"
92
+ qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn);
91
#include "qapi/error.h"
93
+ qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
92
-#include "qemu-common.h"
94
+}
93
#include "exec/address-spaces.h"
95
+
94
#include "sysemu/sysemu.h"
96
/**
95
#include "hw/arm/stm32f405_soc.h"
97
* load_dtb() - load a device tree binary image into memory
96
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
98
* @addr: the address to load the image at
97
index XXXXXXX..XXXXXXX 100644
99
@@ -XXX,XX +XXX,XX @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
98
--- a/hw/arm/vexpress.c
100
}
99
+++ b/hw/arm/vexpress.c
101
}
100
@@ -XXX,XX +XXX,XX @@
102
101
103
+ fdt_add_psci_node(fdt);
102
#include "qemu/osdep.h"
104
+
103
#include "qapi/error.h"
105
if (binfo->modify_dtb) {
104
-#include "qemu-common.h"
106
binfo->modify_dtb(binfo, fdt);
105
#include "qemu/datadir.h"
107
}
106
#include "cpu.h"
107
#include "hw/sysbus.h"
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
109
index XXXXXXX..XXXXXXX 100644
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/virt.c
110
--- a/hw/arm/virt.c
111
+++ b/hw/arm/virt.c
111
+++ b/hw/arm/virt.c
112
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
112
@@ -XXX,XX +XXX,XX @@
113
}
113
*/
114
}
114
115
115
#include "qemu/osdep.h"
116
-static void fdt_add_psci_node(const VirtMachineState *vms)
116
-#include "qemu-common.h"
117
-{
117
#include "qemu/datadir.h"
118
- uint32_t cpu_suspend_fn;
118
#include "qemu/units.h"
119
- uint32_t cpu_off_fn;
119
#include "qemu/option.h"
120
- uint32_t cpu_on_fn;
121
- uint32_t migrate_fn;
122
- void *fdt = vms->fdt;
123
- ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
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
--
120
--
188
2.16.1
121
2.25.1
189
122
190
123
diff view generated by jsdifflib
1
In the v8M architecture, if the process of taking an exception
1
The calculation of the length of TLB range invalidate operations
2
results in a further exception this is called a derived exception
2
in tlbi_aa64_range_get_length() is incorrect in two ways:
3
(for example, an MPU exception when writing the exception frame to
3
* the NUM field is 5 bits, but we read only 4 bits
4
memory). If the derived exception happens while pushing the initial
4
* we miscalculate the page_shift value, because of an
5
stack frame, we must ignore any subsequent possible exception
5
off-by-one error:
6
pushing the callee-saves registers.
6
TG 0b00 is invalid
7
TG 0b01 is 4K granule size == 4096 == 2^12
8
TG 0b10 is 16K granule size == 16384 == 2^14
9
TG 0b11 is 64K granule size == 65536 == 2^16
10
so page_shift should be (TG - 1) * 2 + 12
7
11
8
In preparation for making the stack writes check for exceptions,
12
Thanks to the bug report submitter Cha HyunSoo for identifying
9
add a return value from v7m_push_stack() and a new parameter to
13
both these errors.
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
14
15
(Note that the v8M ARM pseudocode structures this slightly differently:
15
Fixes: 84940ed82552d3c ("target/arm: Add support for FEAT_TLBIRANGE")
16
derived exceptions cause the attempt to process the original
16
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/734
17
exception to be abandoned; then at the top level it calls
18
DerivedLateArrival to prioritize the derived exception and call
19
TakeException from there. We choose to let the NVIC do the prioritization
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>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 1517324542-6607-4-git-send-email-peter.maydell@linaro.org
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20211130173257.1274194-1-peter.maydell@linaro.org
28
---
22
---
29
target/arm/helper.c | 35 +++++++++++++++++++++++------------
23
target/arm/helper.c | 6 +++---
30
1 file changed, 23 insertions(+), 12 deletions(-)
24
1 file changed, 3 insertions(+), 3 deletions(-)
31
25
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
28
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
29
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
30
@@ -XXX,XX +XXX,XX @@ static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
37
return addr;
31
uint64_t exponent;
38
}
32
uint64_t length;
39
33
40
-static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain)
34
- num = extract64(value, 39, 4);
41
+static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
35
+ num = extract64(value, 39, 5);
42
+ bool ignore_faults)
36
scale = extract64(value, 44, 2);
43
{
37
page_size_granule = extract64(value, 46, 2);
44
/* For v8M, push the callee-saves register part of the stack frame.
38
45
* Compare the v8M pseudocode PushCalleeStack().
39
- page_shift = page_size_granule * 2 + 12;
46
@@ -XXX,XX +XXX,XX @@ static void v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain)
40
-
47
*frame_sp_p = frameptr;
41
if (page_size_granule == 0) {
48
}
42
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
49
43
page_size_granule);
50
-static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain)
44
return 0;
51
+static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
45
}
52
+ bool ignore_stackfaults)
46
53
{
47
+ page_shift = (page_size_granule - 1) * 2 + 12;
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
+
48
+
86
+ return false;
49
exponent = (5 * scale) + 1;
87
}
50
length = (num + 1) << (exponent + page_shift);
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);
144
CPUARMState *env = &cpu->env;
145
uint32_t lr;
146
+ bool ignore_stackfaults;
147
148
arm_log_exception(cs->exception_index);
149
150
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
151
lr |= R_V7M_EXCRET_MODE_MASK;
152
}
153
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
51
161
--
52
--
162
2.16.1
53
2.25.1
163
54
164
55
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
Add minimal code needed to allow upstream Linux guest to boot.
3
The rx_active boolean change to true should always trigger a try_read
4
call that flushes the queue.
4
5
5
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Patrick Venture <venture@google.com>
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: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20211203221002.1719306-1-venture@google.com
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
include/hw/timer/imx_gpt.h | 1 +
11
hw/net/npcm7xx_emc.c | 18 ++++++++----------
19
hw/timer/imx_gpt.c | 25 +++++++++++++++++++++++++
12
1 file changed, 8 insertions(+), 10 deletions(-)
20
2 files changed, 26 insertions(+)
21
13
22
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
14
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/timer/imx_gpt.h
16
--- a/hw/net/npcm7xx_emc.c
25
+++ b/include/hw/timer/imx_gpt.h
17
+++ b/hw/net/npcm7xx_emc.c
26
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
27
#define TYPE_IMX25_GPT "imx25.gpt"
19
emc_set_mista(emc, mista_flag);
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
}
20
}
59
21
60
+static void imx7_gpt_init(Object *obj)
22
+static void emc_enable_rx_and_flush(NPCM7xxEMCState *emc)
61
+{
23
+{
62
+ IMXGPTState *s = IMX_GPT(obj);
24
+ emc->rx_active = true;
63
+
25
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
64
+ s->clocks = imx7_gpt_clocks;
65
+}
26
+}
66
+
27
+
67
static const TypeInfo imx25_gpt_info = {
28
static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc,
68
.name = TYPE_IMX25_GPT,
29
const NPCM7xxEMCTxDesc *tx_desc,
69
.parent = TYPE_SYS_BUS_DEVICE,
30
uint32_t desc_addr)
70
@@ -XXX,XX +XXX,XX @@ static const TypeInfo imx6_gpt_info = {
31
@@ -XXX,XX +XXX,XX @@ static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
71
.instance_init = imx6_gpt_init,
32
return len;
72
};
33
}
73
34
74
+static const TypeInfo imx7_gpt_info = {
35
-static void emc_try_receive_next_packet(NPCM7xxEMCState *emc)
75
+ .name = TYPE_IMX7_GPT,
36
-{
76
+ .parent = TYPE_IMX25_GPT,
37
- if (emc_can_receive(qemu_get_queue(emc->nic))) {
77
+ .instance_init = imx7_gpt_init,
38
- qemu_flush_queued_packets(qemu_get_queue(emc->nic));
78
+};
39
- }
79
+
40
-}
80
static void imx_gpt_register_types(void)
41
-
42
static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
81
{
43
{
82
type_register_static(&imx25_gpt_info);
44
NPCM7xxEMCState *emc = opaque;
83
type_register_static(&imx31_gpt_info);
45
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
84
type_register_static(&imx6_gpt_info);
46
emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
85
+ type_register_static(&imx7_gpt_info);
47
}
86
}
48
if (value & REG_MCMDR_RXON) {
87
49
- emc->rx_active = true;
88
type_init(imx_gpt_register_types)
50
+ emc_enable_rx_and_flush(emc);
51
} else {
52
emc_halt_rx(emc, 0);
53
}
54
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
55
break;
56
case REG_RSDR:
57
if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
58
- emc->rx_active = true;
59
- emc_try_receive_next_packet(emc);
60
+ emc_enable_rx_and_flush(emc);
61
}
62
break;
63
case REG_MIIDA:
89
--
64
--
90
2.16.1
65
2.25.1
91
66
92
67
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 minimal code needed to allow upstream Linux guest to boot.
3
When a virtio-iommu is instantiated, describe it using the ACPI VIOT
4
table.
4
5
5
Cc: Peter Maydell <peter.maydell@linaro.org>
6
Acked-by: Igor Mammedov <imammedo@redhat.com>
6
Cc: Jason Wang <jasowang@redhat.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
9
Message-id: 20211210170415.583179-2-jean-philippe@linaro.org
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
hw/arm/virt-acpi-build.c | 7 +++++++
19
include/hw/misc/imx7_gpr.h | 28 ++++++++++
13
hw/arm/Kconfig | 1 +
20
hw/misc/imx7_gpr.c | 124 +++++++++++++++++++++++++++++++++++++++++++++
14
2 files changed, 8 insertions(+)
21
hw/misc/trace-events | 4 ++
22
4 files changed, 157 insertions(+)
23
create mode 100644 include/hw/misc/imx7_gpr.h
24
create mode 100644 hw/misc/imx7_gpr.c
25
15
26
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
16
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/misc/Makefile.objs
18
--- a/hw/arm/virt-acpi-build.c
29
+++ b/hw/misc/Makefile.objs
19
+++ b/hw/arm/virt-acpi-build.c
30
@@ -XXX,XX +XXX,XX @@ 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_IMX) += imx7_gpr.o
35
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
36
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
37
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
38
diff --git a/include/hw/misc/imx7_gpr.h b/include/hw/misc/imx7_gpr.h
39
new file mode 100644
40
index XXXXXXX..XXXXXXX
41
--- /dev/null
42
+++ b/include/hw/misc/imx7_gpr.h
43
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
44
+/*
21
#include "kvm_arm.h"
45
+ * Copyright (c) 2017, Impinj, Inc.
22
#include "migration/vmstate.h"
46
+ *
23
#include "hw/acpi/ghes.h"
47
+ * i.MX7 GPR IP block emulation code
24
+#include "hw/acpi/viot.h"
48
+ *
25
49
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
26
#define ARM_SPI_BASE 32
50
+ *
27
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
28
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
52
+ * See the COPYING file in the top-level directory.
29
}
53
+ */
30
#endif
54
+
31
55
+#ifndef IMX7_GPR_H
32
+ if (vms->iommu == VIRT_IOMMU_VIRTIO) {
56
+#define IMX7_GPR_H
33
+ acpi_add_table(table_offsets, tables_blob);
57
+
34
+ build_viot(ms, tables_blob, tables->linker, vms->virtio_iommu_bdf,
58
+#include "qemu/bitops.h"
35
+ vms->oem_id, vms->oem_table_id);
59
+#include "hw/sysbus.h"
60
+
61
+#define TYPE_IMX7_GPR "imx7.gpr"
62
+#define IMX7_GPR(obj) OBJECT_CHECK(IMX7GPRState, (obj), TYPE_IMX7_GPR)
63
+
64
+typedef struct IMX7GPRState {
65
+ /* <private> */
66
+ SysBusDevice parent_obj;
67
+
68
+ MemoryRegion mmio;
69
+} IMX7GPRState;
70
+
71
+#endif /* IMX7_GPR_H */
72
diff --git a/hw/misc/imx7_gpr.c b/hw/misc/imx7_gpr.c
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/hw/misc/imx7_gpr.c
77
@@ -XXX,XX +XXX,XX @@
78
+/*
79
+ * Copyright (c) 2018, Impinj, Inc.
80
+ *
81
+ * i.MX7 GPR IP block emulation code
82
+ *
83
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
84
+ *
85
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
86
+ * See the COPYING file in the top-level directory.
87
+ *
88
+ * Bare minimum emulation code needed to support being able to shut
89
+ * down linux guest gracefully.
90
+ */
91
+
92
+#include "qemu/osdep.h"
93
+#include "hw/misc/imx7_gpr.h"
94
+#include "qemu/log.h"
95
+#include "sysemu/sysemu.h"
96
+
97
+#include "trace.h"
98
+
99
+enum IMX7GPRRegisters {
100
+ IOMUXC_GPR0 = 0x00,
101
+ IOMUXC_GPR1 = 0x04,
102
+ IOMUXC_GPR2 = 0x08,
103
+ IOMUXC_GPR3 = 0x0c,
104
+ IOMUXC_GPR4 = 0x10,
105
+ IOMUXC_GPR5 = 0x14,
106
+ IOMUXC_GPR6 = 0x18,
107
+ IOMUXC_GPR7 = 0x1c,
108
+ IOMUXC_GPR8 = 0x20,
109
+ IOMUXC_GPR9 = 0x24,
110
+ IOMUXC_GPR10 = 0x28,
111
+ IOMUXC_GPR11 = 0x2c,
112
+ IOMUXC_GPR12 = 0x30,
113
+ IOMUXC_GPR13 = 0x34,
114
+ IOMUXC_GPR14 = 0x38,
115
+ IOMUXC_GPR15 = 0x3c,
116
+ IOMUXC_GPR16 = 0x40,
117
+ IOMUXC_GPR17 = 0x44,
118
+ IOMUXC_GPR18 = 0x48,
119
+ IOMUXC_GPR19 = 0x4c,
120
+ IOMUXC_GPR20 = 0x50,
121
+ IOMUXC_GPR21 = 0x54,
122
+ IOMUXC_GPR22 = 0x58,
123
+};
124
+
125
+#define IMX7D_GPR1_IRQ_MASK BIT(12)
126
+#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK BIT(13)
127
+#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK BIT(14)
128
+#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK (0x3 << 13)
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
+ }
36
+ }
145
+
37
+
146
+ return 0;
38
/* XSDT is pointed to by RSDP */
147
+}
39
xsdt = tables_blob->len;
148
+
40
build_xsdt(tables_blob, tables->linker, table_offsets, vms->oem_id,
149
+static void imx7_gpr_write(void *opaque, hwaddr offset,
41
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
150
+ uint64_t v, unsigned size)
151
+{
152
+ trace_imx7_gpr_write(offset, v);
153
+}
154
+
155
+static const struct MemoryRegionOps imx7_gpr_ops = {
156
+ .read = imx7_gpr_read,
157
+ .write = imx7_gpr_write,
158
+ .endianness = DEVICE_NATIVE_ENDIAN,
159
+ .impl = {
160
+ /*
161
+ * Our device would not work correctly if the guest was doing
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,
169
+ },
170
+};
171
+
172
+static void imx7_gpr_init(Object *obj)
173
+{
174
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
175
+ IMX7GPRState *s = IMX7_GPR(obj);
176
+
177
+ memory_region_init_io(&s->mmio, obj, &imx7_gpr_ops, s,
178
+ TYPE_IMX7_GPR, 64 * 1024);
179
+ sysbus_init_mmio(sd, &s->mmio);
180
+}
181
+
182
+static void imx7_gpr_class_init(ObjectClass *klass, void *data)
183
+{
184
+ DeviceClass *dc = DEVICE_CLASS(klass);
185
+
186
+ dc->desc = "i.MX7 General Purpose Registers Module";
187
+}
188
+
189
+static const TypeInfo imx7_gpr_info = {
190
+ .name = TYPE_IMX7_GPR,
191
+ .parent = TYPE_SYS_BUS_DEVICE,
192
+ .instance_size = sizeof(IMX7GPRState),
193
+ .instance_init = imx7_gpr_init,
194
+ .class_init = imx7_gpr_class_init,
195
+};
196
+
197
+static void imx7_gpr_register_type(void)
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
42
index XXXXXXX..XXXXXXX 100644
204
--- a/hw/misc/trace-events
43
--- a/hw/arm/Kconfig
205
+++ b/hw/misc/trace-events
44
+++ b/hw/arm/Kconfig
206
@@ -XXX,XX +XXX,XX @@ mps2_scc_cfg_read(unsigned function, unsigned device, uint32_t value) "MPS2 SCC
45
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
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
46
select DIMM
208
msf2_sysreg_read(uint64_t offset, uint32_t val) "msf2-sysreg read: addr 0x%08" HWADDR_PRIx " data 0x%08" PRIx32
47
select ACPI_HW_REDUCED
209
msf2_sysreg_write_pll_status(void) "Invalid write to read only PLL status register"
48
select ACPI_APEI
210
+
49
+ select ACPI_VIOT
211
+#hw/misc/imx7_gpr.c
50
212
+imx7_gpr_read(uint64_t offset) "addr 0x%08" HWADDR_PRIx
51
config CHEETAH
213
+imx7_gpr_write(uint64_t offset, uint64_t value) "addr 0x%08" HWADDR_PRIx "value 0x%08" HWADDR_PRIx
52
bool
214
--
53
--
215
2.16.1
54
2.25.1
216
55
217
56
diff view generated by jsdifflib
1
Make the load of the exception vector from the vector table honour
1
From: Jean-Philippe Brucker <jean-philippe@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
virtio-iommu is now supported with ACPI VIOT as well as device tree.
4
Remove the restriction that prevents from instantiating a virtio-iommu
5
device under ACPI.
6
7
Acked-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Message-id: 20211210170415.583179-3-jean-philippe@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
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
---
12
---
9
target/arm/helper.c | 71 +++++++++++++++++++++++++++++++++++++++++------------
13
hw/arm/virt.c | 10 ++--------
10
1 file changed, 55 insertions(+), 16 deletions(-)
14
hw/virtio/virtio-iommu-pci.c | 12 ++----------
15
2 files changed, 4 insertions(+), 18 deletions(-)
11
16
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
19
--- a/hw/arm/virt.c
15
+++ b/target/arm/helper.c
20
+++ b/hw/arm/virt.c
16
@@ -XXX,XX +XXX,XX @@ static uint32_t *get_v7m_sp_ptr(CPUARMState *env, bool secure, bool threadmode,
21
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
22
MachineClass *mc = MACHINE_GET_CLASS(machine);
23
24
if (device_is_dynamic_sysbus(mc, dev) ||
25
- (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
26
+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
27
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
28
return HOTPLUG_HANDLER(machine);
17
}
29
}
30
- if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
31
- VirtMachineState *vms = VIRT_MACHINE(machine);
32
-
33
- if (!vms->bootinfo.firmware_loaded || !virt_is_acpi_enabled(vms)) {
34
- return HOTPLUG_HANDLER(machine);
35
- }
36
- }
37
return NULL;
18
}
38
}
19
39
20
-static uint32_t arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure)
40
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
21
+static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
41
index XXXXXXX..XXXXXXX 100644
22
+ uint32_t *pvec)
42
--- a/hw/virtio/virtio-iommu-pci.c
23
{
43
+++ b/hw/virtio/virtio-iommu-pci.c
24
CPUState *cs = CPU(cpu);
44
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
25
CPUARMState *env = &cpu->env;
45
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
26
MemTxResult result;
46
27
- hwaddr vec = env->v7m.vecbase[targets_secure] + exc * 4;
47
if (!qdev_get_machine_hotplug_handler(DEVICE(vpci_dev))) {
28
- uint32_t addr;
48
- MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
29
+ uint32_t addr = env->v7m.vecbase[targets_secure] + exc * 4;
49
-
30
+ uint32_t vector_entry;
50
- error_setg(errp,
31
+ MemTxAttrs attrs = {};
51
- "%s machine fails to create iommu-map device tree bindings",
32
+ ARMMMUIdx mmu_idx;
52
- mc->name);
33
+ bool exc_secure;
53
- error_append_hint(errp,
34
+
54
- "Check your machine implements a hotplug handler "
35
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targets_secure, true);
55
- "for the virtio-iommu-pci device\n");
36
56
- error_append_hint(errp, "Check the guest is booted without FW or with "
37
- addr = address_space_ldl(cs->as, vec,
57
- "-no-acpi\n");
38
- MEMTXATTRS_UNSPECIFIED, &result);
58
+ error_setg(errp, "Check your machine implements a hotplug handler "
39
+ /* We don't do a get_phys_addr() here because the rules for vector
59
+ "for the virtio-iommu-pci device");
40
+ * loads are special: they always use the default memory map, and
41
+ * the default memory map permits reads from all addresses.
42
+ * Since there's no easy way to pass through to pmsav8_mpu_lookup()
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;
60
return;
97
}
61
}
98
62
for (int i = 0; i < s->nb_reserved_regions; i++) {
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
--
63
--
109
2.16.1
64
2.25.1
110
65
111
66
diff view generated by jsdifflib
1
In order to support derived exceptions (exceptions generated in
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
the course of trying to take an exception), we need to be able
3
to handle prioritizing whether to take the original exception
4
or the derived exception.
5
2
6
We do this by introducing a new function
3
We do not support instantiating multiple IOMMUs. Before adding a
7
armv7m_nvic_set_pending_derived() which the exception-taking code in
4
virtio-iommu, check that no other IOMMU is present. This will detect
8
helper.c will call when a derived exception occurs. Derived
5
both "iommu=smmuv3" machine parameter and another virtio-iommu instance.
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
6
13
Note that the way we structure this is significantly different
7
Fixes: 70e89132c9 ("hw/arm/virt: Add the virtio-iommu device tree mappings")
14
from the v8M Arm ARM pseudocode: that does all the prioritization
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
15
logic in the DerivedLateArrival() function, whereas we choose to
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
16
let the existing "identify highest priority exception" logic
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
17
do the prioritization for us. The effect is the same, though.
11
Message-id: 20211210170415.583179-4-jean-philippe@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/virt.c | 5 +++++
15
1 file changed, 5 insertions(+)
18
16
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 1517324542-6607-2-git-send-email-peter.maydell@linaro.org
22
---
23
target/arm/cpu.h | 13 ++++++++++
24
hw/intc/armv7m_nvic.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++--
25
hw/intc/trace-events | 2 +-
26
3 files changed, 80 insertions(+), 3 deletions(-)
27
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
19
--- a/hw/arm/virt.c
31
+++ b/target/arm/cpu.h
20
+++ b/hw/arm/virt.c
32
@@ -XXX,XX +XXX,XX @@ static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
33
* of architecturally banked exceptions.
22
hwaddr db_start = 0, db_end = 0;
34
*/
23
char *resv_prop_str;
35
void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
24
36
+/**
25
+ if (vms->iommu != VIRT_IOMMU_NONE) {
37
+ * armv7m_nvic_set_pending_derived: mark this derived exception as pending
26
+ error_setg(errp, "virt machine does not support multiple IOMMUs");
38
+ * @opaque: the NVIC
39
+ * @irq: the exception number to mark pending
40
+ * @secure: false for non-banked exceptions or for the nonsecure
41
+ * version of a banked exception, true for the secure version of a banked
42
+ * exception.
43
+ *
44
+ * Similar to armv7m_nvic_set_pending(), but specifically for derived
45
+ * exceptions (exceptions generated in the course of trying to take
46
+ * a different exception).
47
+ */
48
+void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
49
/**
50
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
51
* @opaque: the NVIC
52
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/intc/armv7m_nvic.c
55
+++ b/hw/intc/armv7m_nvic.c
56
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_clear_pending(void *opaque, int irq, bool secure)
57
}
58
}
59
60
-void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
61
+static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
62
+ bool derived)
63
{
64
+ /* Pend an exception, including possibly escalating it to HardFault.
65
+ *
66
+ * This function handles both "normal" pending of interrupts and
67
+ * exceptions, and also derived exceptions (ones which occur as
68
+ * a result of trying to take some other exception).
69
+ *
70
+ * If derived == true, the caller guarantees that we are part way through
71
+ * trying to take an exception (but have not yet called
72
+ * armv7m_nvic_acknowledge_irq() to make it active), and so:
73
+ * - s->vectpending is the "original exception" we were trying to take
74
+ * - irq is the "derived exception"
75
+ * - nvic_exec_prio(s) gives the priority before exception entry
76
+ * Here we handle the prioritization logic which the pseudocode puts
77
+ * in the DerivedLateArrival() function.
78
+ */
79
+
80
NVICState *s = (NVICState *)opaque;
81
bool banked = exc_is_banked(irq);
82
VecInfo *vec;
83
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
84
85
vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
86
87
- trace_nvic_set_pending(irq, secure, vec->enabled, vec->prio);
88
+ trace_nvic_set_pending(irq, secure, derived, vec->enabled, vec->prio);
89
+
90
+ if (derived) {
91
+ /* Derived exceptions are always synchronous. */
92
+ assert(irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV);
93
+
94
+ if (irq == ARMV7M_EXCP_DEBUG &&
95
+ exc_group_prio(s, vec->prio, secure) >= nvic_exec_prio(s)) {
96
+ /* DebugMonitorFault, but its priority is lower than the
97
+ * preempted exception priority: just ignore it.
98
+ */
99
+ return;
27
+ return;
100
+ }
28
+ }
101
+
29
+
102
+ if (irq == ARMV7M_EXCP_HARD && vec->prio >= s->vectpending_prio) {
30
switch (vms->msi_controller) {
103
+ /* If this is a terminal exception (one which means we cannot
31
case VIRT_MSI_CTRL_NONE:
104
+ * take the original exception, like a failure to read its
32
return;
105
+ * vector table entry), then we must take the derived exception.
106
+ * If the derived exception can't take priority over the
107
+ * original exception, then we go into Lockup.
108
+ *
109
+ * For QEMU, we rely on the fact that a derived exception is
110
+ * terminal if and only if it's reported to us as HardFault,
111
+ * which saves having to have an extra argument is_terminal
112
+ * that we'd only use in one place.
113
+ */
114
+ cpu_abort(&s->cpu->parent_obj,
115
+ "Lockup: can't take terminal derived exception "
116
+ "(original exception priority %d)\n",
117
+ s->vectpending_prio);
118
+ }
119
+ /* We now continue with the same code as for a normal pending
120
+ * exception, which will cause us to pend the derived exception.
121
+ * We'll then take either the original or the derived exception
122
+ * based on which is higher priority by the usual mechanism
123
+ * for selecting the highest priority pending interrupt.
124
+ */
125
+ }
126
127
if (irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV) {
128
/* If a synchronous exception is pending then it may be
129
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
130
}
131
}
132
133
+void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
134
+{
135
+ do_armv7m_nvic_set_pending(opaque, irq, secure, false);
136
+}
137
+
138
+void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
139
+{
140
+ do_armv7m_nvic_set_pending(opaque, irq, secure, true);
141
+}
142
+
143
/* Make pending IRQ active. */
144
bool armv7m_nvic_acknowledge_irq(void *opaque)
145
{
146
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/intc/trace-events
149
+++ b/hw/intc/trace-events
150
@@ -XXX,XX +XXX,XX @@ nvic_set_prio(int irq, bool secure, uint8_t prio) "NVIC set irq %d secure-bank %
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"
152
nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d"
153
nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
154
-nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending irq %d secure-bank %d (enabled: %d priority %d)"
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)"
156
nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
157
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
158
nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)"
159
--
33
--
160
2.16.1
34
2.25.1
161
35
162
36
diff view generated by jsdifflib
1
From: Christoffer Dall <christoffer.dall@linaro.org>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
KVM doesn't support emulating a GICv3 in userspace, only GICv2. We
3
To propagate errors to the caller of the pre_plug callback, use the
4
currently attempt this anyway, and as a result a KVM guest doesn't
4
object_poperty_set*() functions directly instead of the qdev_prop_set*()
5
receive interrupts and the user is left wondering why. Report an error
5
helpers.
6
to the user if this particular combination is requested.
7
6
8
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
7
Suggested-by: Igor Mammedov <imammedo@redhat.com>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Message-id: 20180201205307.30343-1-christoffer.dall@linaro.org
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-5-jean-philippe@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
hw/arm/virt.c | 5 +++--
14
1 file changed, 4 insertions(+)
15
1 file changed, 3 insertions(+), 2 deletions(-)
15
16
16
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/kvm_arm.h
19
--- a/hw/arm/virt.c
19
+++ b/target/arm/kvm_arm.h
20
+++ b/hw/arm/virt.c
20
@@ -XXX,XX +XXX,XX @@ static inline const char *gicv3_class_name(void)
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
21
exit(1);
22
db_start, db_end,
22
#endif
23
VIRTIO_IOMMU_RESV_MEM_T_MSI);
23
} else {
24
24
+ if (kvm_enabled()) {
25
- qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
25
+ error_report("Userspace GICv3 is not supported with KVM");
26
- qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
26
+ exit(1);
27
+ object_property_set_uint(OBJECT(dev), "len-reserved-regions", 1, errp);
27
+ }
28
+ object_property_set_str(OBJECT(dev), "reserved-regions[0]",
28
return "arm-gicv3";
29
+ resv_prop_str, errp);
30
g_free(resv_prop_str);
29
}
31
}
30
}
32
}
31
--
33
--
32
2.16.1
34
2.25.1
33
35
34
36
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
Create empty data files and allow updates for the upcoming VIOT tests.
4
be able to emulate machine shutdown are implemented.
5
4
6
Cc: Peter Maydell <peter.maydell@linaro.org>
5
Acked-by: Igor Mammedov <imammedo@redhat.com>
7
Cc: Jason Wang <jasowang@redhat.com>
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
9
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
8
Message-id: 20211210170415.583179-6-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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
hw/misc/Makefile.objs | 1 +
11
tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
19
include/hw/misc/imx7_snvs.h | 35 +++++++++++++++++++
12
tests/data/acpi/q35/DSDT.viot | 0
20
hw/misc/imx7_snvs.c | 83 +++++++++++++++++++++++++++++++++++++++++++++
13
tests/data/acpi/q35/VIOT.viot | 0
21
3 files changed, 119 insertions(+)
14
tests/data/acpi/virt/VIOT | 0
22
create mode 100644 include/hw/misc/imx7_snvs.h
15
4 files changed, 3 insertions(+)
23
create mode 100644 hw/misc/imx7_snvs.c
16
create mode 100644 tests/data/acpi/q35/DSDT.viot
17
create mode 100644 tests/data/acpi/q35/VIOT.viot
18
create mode 100644 tests/data/acpi/virt/VIOT
24
19
25
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
20
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
26
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/misc/Makefile.objs
22
--- a/tests/qtest/bios-tables-test-allowed-diff.h
28
+++ b/hw/misc/Makefile.objs
23
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx6_ccm.o
24
@@ -1 +1,4 @@
30
obj-$(CONFIG_IMX) += imx6_src.o
25
/* List of comma-separated changed AML files to ignore */
31
obj-$(CONFIG_IMX) += imx7_ccm.o
26
+"tests/data/acpi/virt/VIOT",
32
obj-$(CONFIG_IMX) += imx2_wdt.o
27
+"tests/data/acpi/q35/DSDT.viot",
33
+obj-$(CONFIG_IMX) += imx7_snvs.o
28
+"tests/data/acpi/q35/VIOT.viot",
34
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
29
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
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
30
new file mode 100644
39
index XXXXXXX..XXXXXXX
31
index XXXXXXX..XXXXXXX
40
--- /dev/null
32
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
41
+++ b/include/hw/misc/imx7_snvs.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Copyright (c) 2017, Impinj, Inc.
45
+ *
46
+ * i.MX7 SNVS block emulation code
47
+ *
48
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
49
+ *
50
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
51
+ * See the COPYING file in the top-level directory.
52
+ */
53
+
54
+#ifndef IMX7_SNVS_H
55
+#define IMX7_SNVS_H
56
+
57
+#include "qemu/bitops.h"
58
+#include "hw/sysbus.h"
59
+
60
+
61
+enum IMX7SNVSRegisters {
62
+ SNVS_LPCR = 0x38,
63
+ SNVS_LPCR_TOP = BIT(6),
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
33
new file mode 100644
80
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
81
--- /dev/null
35
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
82
+++ b/hw/misc/imx7_snvs.c
36
new file mode 100644
83
@@ -XXX,XX +XXX,XX @@
37
index XXXXXXX..XXXXXXX
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
--
38
--
168
2.16.1
39
2.25.1
169
40
170
41
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 minimal code needed to allow upstream Linux guest to boot.
3
Add two test cases for VIOT, one on the q35 machine and the other on
4
virt. To test complex topologies the q35 test has two PCIe buses that
5
bypass the IOMMU (and are therefore not described by VIOT), and two
6
buses that are translated by virtio-iommu.
4
7
5
Cc: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
6
Cc: Jason Wang <jasowang@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
7
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
8
Cc: Marcel Apfelbaum <marcel.apfelbaum@zoho.com>
11
Message-id: 20211210170415.583179-7-jean-philippe@linaro.org
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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
13
---
17
hw/misc/Makefile.objs | 1 +
14
tests/qtest/bios-tables-test.c | 38 ++++++++++++++++++++++++++++++++++
18
include/hw/misc/imx7_ccm.h | 139 +++++++++++++++++++++++
15
1 file changed, 38 insertions(+)
19
hw/misc/imx7_ccm.c | 277 +++++++++++++++++++++++++++++++++++++++++++++
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
16
24
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
17
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/misc/Makefile.objs
19
--- a/tests/qtest/bios-tables-test.c
27
+++ b/hw/misc/Makefile.objs
20
+++ b/tests/qtest/bios-tables-test.c
28
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx31_ccm.o
21
@@ -XXX,XX +XXX,XX @@ static void test_acpi_virt_tcg(void)
29
obj-$(CONFIG_IMX) += imx25_ccm.o
22
free_test_data(&data);
30
obj-$(CONFIG_IMX) += imx6_ccm.o
23
}
31
obj-$(CONFIG_IMX) += imx6_src.o
24
32
+obj-$(CONFIG_IMX) += imx7_ccm.o
25
+static void test_acpi_q35_viot(void)
33
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
34
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
35
obj-$(CONFIG_MAINSTONE) += mst_fpga.o
36
diff --git a/include/hw/misc/imx7_ccm.h b/include/hw/misc/imx7_ccm.h
37
new file mode 100644
38
index XXXXXXX..XXXXXXX
39
--- /dev/null
40
+++ b/include/hw/misc/imx7_ccm.h
41
@@ -XXX,XX +XXX,XX @@
42
+/*
43
+ * Copyright (c) 2017, Impinj, Inc.
44
+ *
45
+ * i.MX7 CCM, PMU and ANALOG IP blocks emulation code
46
+ *
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
+
53
+#ifndef IMX7_CCM_H
54
+#define IMX7_CCM_H
55
+
56
+#include "hw/misc/imx_ccm.h"
57
+#include "qemu/bitops.h"
58
+
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
+{
26
+{
205
+ IMX7AnalogState *s = IMX7_ANALOG(dev);
27
+ test_data data = {
206
+
28
+ .machine = MACHINE_Q35,
207
+ memset(s->pmu, 0, sizeof(s->pmu));
29
+ .variant = ".viot",
208
+ memset(s->analog, 0, sizeof(s->analog));
30
+ };
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
+
31
+
240
+ /*
32
+ /*
241
+ * Since I couldn't find any info about this in the reference
33
+ * To keep things interesting, two buses bypass the IOMMU.
242
+ * manual the value of this register is based strictly on matching
34
+ * VIOT should only describes the other two buses.
243
+ * what Linux kernel expects it to be.
244
+ */
35
+ */
245
+ s->analog[ANALOG_DIGPROG] = 0x720000;
36
+ test_acpi_one("-machine default_bus_bypass_iommu=on "
246
+ /*
37
+ "-device virtio-iommu-pci "
247
+ * Set revision to be 1.0 (Arbitrary choice, no particular
38
+ "-device pxb-pcie,bus_nr=0x10,id=pcie.100,bus=pcie.0 "
248
+ * reason).
39
+ "-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on "
249
+ */
40
+ "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0",
250
+ s->analog[ANALOG_DIGPROG] |= 0x000010;
41
+ &data);
42
+ free_test_data(&data);
251
+}
43
+}
252
+
44
+
253
+static void imx7_ccm_reset(DeviceState *dev)
45
+static void test_acpi_virt_viot(void)
254
+{
46
+{
255
+ IMX7CCMState *s = IMX7_CCM(dev);
47
+ test_data data = {
48
+ .machine = "virt",
49
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
50
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
51
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
52
+ .ram_start = 0x40000000ULL,
53
+ .scan_len = 128ULL * 1024 * 1024,
54
+ };
256
+
55
+
257
+ memset(s->ccm, 0, sizeof(s->ccm));
56
+ test_acpi_one("-cpu cortex-a57 "
57
+ "-device virtio-iommu-pci", &data);
58
+ free_test_data(&data);
258
+}
59
+}
259
+
60
+
260
+#define CCM_INDEX(offset) (((offset) & ~(hwaddr)0xF) / sizeof(uint32_t))
61
static void test_oem_fields(test_data *data)
261
+#define CCM_BITOP(offset) ((offset) & (hwaddr)0xF)
62
{
262
+
63
int i;
263
+enum {
64
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
264
+ CCM_BITOP_NONE = 0x00,
65
qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic);
265
+ CCM_BITOP_SET = 0x04,
66
qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar);
266
+ CCM_BITOP_CLR = 0x08,
67
}
267
+ CCM_BITOP_TOG = 0x0C,
68
+ qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
268
+};
69
} else if (strcmp(arch, "aarch64") == 0) {
269
+
70
if (has_tcg) {
270
+static uint64_t imx7_set_clr_tog_read(void *opaque, hwaddr offset,
71
qtest_add_func("acpi/virt", test_acpi_virt_tcg);
271
+ unsigned size)
72
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
272
+{
73
qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
273
+ const uint32_t *mmio = opaque;
74
qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb);
274
+
75
qtest_add_func("acpi/virt/oem-fields", test_acpi_oem_fields_virt);
275
+ return mmio[CCM_INDEX(offset)];
76
+ qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
276
+}
77
}
277
+
78
}
278
+static void imx7_set_clr_tog_write(void *opaque, hwaddr offset,
79
ret = g_test_run();
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
--
80
--
465
2.16.1
81
2.25.1
466
82
467
83
diff view generated by jsdifflib
New patch
1
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
3
Add expected blobs of the VIOT and DSDT table for the VIOT test on the
4
q35 machine.
5
6
Since the test instantiates a virtio device and two PCIe expander
7
bridges, DSDT.viot has more blocks than the base DSDT.
8
9
The VIOT table generated for the q35 test is:
10
11
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
12
[004h 0004 4] Table Length : 00000070
13
[008h 0008 1] Revision : 00
14
[009h 0009 1] Checksum : 3D
15
[00Ah 0010 6] Oem ID : "BOCHS "
16
[010h 0016 8] Oem Table ID : "BXPC "
17
[018h 0024 4] Oem Revision : 00000001
18
[01Ch 0028 4] Asl Compiler ID : "BXPC"
19
[020h 0032 4] Asl Compiler Revision : 00000001
20
21
[024h 0036 2] Node count : 0003
22
[026h 0038 2] Node offset : 0030
23
[028h 0040 8] Reserved : 0000000000000000
24
25
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
26
[031h 0049 1] Reserved : 00
27
[032h 0050 2] Length : 0010
28
29
[034h 0052 2] PCI Segment : 0000
30
[036h 0054 2] PCI BDF number : 0010
31
[038h 0056 8] Reserved : 0000000000000000
32
33
[040h 0064 1] Type : 01 [PCI Range]
34
[041h 0065 1] Reserved : 00
35
[042h 0066 2] Length : 0018
36
37
[044h 0068 4] Endpoint start : 00003000
38
[048h 0072 2] PCI Segment start : 0000
39
[04Ah 0074 2] PCI Segment end : 0000
40
[04Ch 0076 2] PCI BDF start : 3000
41
[04Eh 0078 2] PCI BDF end : 30FF
42
[050h 0080 2] Output node : 0030
43
[052h 0082 6] Reserved : 000000000000
44
45
[058h 0088 1] Type : 01 [PCI Range]
46
[059h 0089 1] Reserved : 00
47
[05Ah 0090 2] Length : 0018
48
49
[05Ch 0092 4] Endpoint start : 00001000
50
[060h 0096 2] PCI Segment start : 0000
51
[062h 0098 2] PCI Segment end : 0000
52
[064h 0100 2] PCI BDF start : 1000
53
[066h 0102 2] PCI BDF end : 10FF
54
[068h 0104 2] Output node : 0030
55
[06Ah 0106 6] Reserved : 000000000000
56
57
And the DSDT diff is:
58
59
@@ -XXX,XX +XXX,XX @@
60
*
61
* Disassembling to symbolic ASL+ operators
62
*
63
- * Disassembly of tests/data/acpi/q35/DSDT, Fri Dec 10 15:03:08 2021
64
+ * Disassembly of /tmp/aml-H9Y5D1, Fri Dec 10 15:02:27 2021
65
*
66
* Original Table Header:
67
* Signature "DSDT"
68
- * Length 0x00002061 (8289)
69
+ * Length 0x000024B6 (9398)
70
* Revision 0x01 **** 32-bit table (V1), no 64-bit math support
71
- * Checksum 0xFA
72
+ * Checksum 0xA7
73
* OEM ID "BOCHS "
74
* OEM Table ID "BXPC "
75
* OEM Revision 0x00000001 (1)
76
@@ -XXX,XX +XXX,XX @@
77
}
78
}
79
80
+ Scope (\_SB)
81
+ {
82
+ Device (PC30)
83
+ {
84
+ Name (_UID, 0x30) // _UID: Unique ID
85
+ Name (_BBN, 0x30) // _BBN: BIOS Bus Number
86
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
87
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
88
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
89
+ {
90
+ CreateDWordField (Arg3, Zero, CDW1)
91
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
92
+ {
93
+ CreateDWordField (Arg3, 0x04, CDW2)
94
+ CreateDWordField (Arg3, 0x08, CDW3)
95
+ Local0 = CDW3 /* \_SB_.PC30._OSC.CDW3 */
96
+ Local0 &= 0x1F
97
+ If ((Arg1 != One))
98
+ {
99
+ CDW1 |= 0x08
100
+ }
101
+
102
+ If ((CDW3 != Local0))
103
+ {
104
+ CDW1 |= 0x10
105
+ }
106
+
107
+ CDW3 = Local0
108
+ }
109
+ Else
110
+ {
111
+ CDW1 |= 0x04
112
+ }
113
+
114
+ Return (Arg3)
115
+ }
116
+
117
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
118
+ {
119
+ Local0 = Package (0x80){}
120
+ Local1 = Zero
121
+ While ((Local1 < 0x80))
122
+ {
123
+ Local2 = (Local1 >> 0x02)
124
+ Local3 = ((Local1 + Local2) & 0x03)
125
+ If ((Local3 == Zero))
126
+ {
127
+ Local4 = Package (0x04)
128
+ {
129
+ Zero,
130
+ Zero,
131
+ LNKD,
132
+ Zero
133
+ }
134
+ }
135
+
136
+ If ((Local3 == One))
137
+ {
138
+ Local4 = Package (0x04)
139
+ {
140
+ Zero,
141
+ Zero,
142
+ LNKA,
143
+ Zero
144
+ }
145
+ }
146
+
147
+ If ((Local3 == 0x02))
148
+ {
149
+ Local4 = Package (0x04)
150
+ {
151
+ Zero,
152
+ Zero,
153
+ LNKB,
154
+ Zero
155
+ }
156
+ }
157
+
158
+ If ((Local3 == 0x03))
159
+ {
160
+ Local4 = Package (0x04)
161
+ {
162
+ Zero,
163
+ Zero,
164
+ LNKC,
165
+ Zero
166
+ }
167
+ }
168
+
169
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
170
+ Local4 [One] = (Local1 & 0x03)
171
+ Local0 [Local1] = Local4
172
+ Local1++
173
+ }
174
+
175
+ Return (Local0)
176
+ }
177
+
178
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
179
+ {
180
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
181
+ 0x0000, // Granularity
182
+ 0x0030, // Range Minimum
183
+ 0x0030, // Range Maximum
184
+ 0x0000, // Translation Offset
185
+ 0x0001, // Length
186
+ ,, )
187
+ })
188
+ }
189
+ }
190
+
191
+ Scope (\_SB)
192
+ {
193
+ Device (PC20)
194
+ {
195
+ Name (_UID, 0x20) // _UID: Unique ID
196
+ Name (_BBN, 0x20) // _BBN: BIOS Bus Number
197
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
198
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
199
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
200
+ {
201
+ CreateDWordField (Arg3, Zero, CDW1)
202
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
203
+ {
204
+ CreateDWordField (Arg3, 0x04, CDW2)
205
+ CreateDWordField (Arg3, 0x08, CDW3)
206
+ Local0 = CDW3 /* \_SB_.PC20._OSC.CDW3 */
207
+ Local0 &= 0x1F
208
+ If ((Arg1 != One))
209
+ {
210
+ CDW1 |= 0x08
211
+ }
212
+
213
+ If ((CDW3 != Local0))
214
+ {
215
+ CDW1 |= 0x10
216
+ }
217
+
218
+ CDW3 = Local0
219
+ }
220
+ Else
221
+ {
222
+ CDW1 |= 0x04
223
+ }
224
+
225
+ Return (Arg3)
226
+ }
227
+
228
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
229
+ {
230
+ Local0 = Package (0x80){}
231
+ Local1 = Zero
232
+ While ((Local1 < 0x80))
233
+ {
234
+ Local2 = (Local1 >> 0x02)
235
+ Local3 = ((Local1 + Local2) & 0x03)
236
+ If ((Local3 == Zero))
237
+ {
238
+ Local4 = Package (0x04)
239
+ {
240
+ Zero,
241
+ Zero,
242
+ LNKD,
243
+ Zero
244
+ }
245
+ }
246
+
247
+ If ((Local3 == One))
248
+ {
249
+ Local4 = Package (0x04)
250
+ {
251
+ Zero,
252
+ Zero,
253
+ LNKA,
254
+ Zero
255
+ }
256
+ }
257
+
258
+ If ((Local3 == 0x02))
259
+ {
260
+ Local4 = Package (0x04)
261
+ {
262
+ Zero,
263
+ Zero,
264
+ LNKB,
265
+ Zero
266
+ }
267
+ }
268
+
269
+ If ((Local3 == 0x03))
270
+ {
271
+ Local4 = Package (0x04)
272
+ {
273
+ Zero,
274
+ Zero,
275
+ LNKC,
276
+ Zero
277
+ }
278
+ }
279
+
280
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
281
+ Local4 [One] = (Local1 & 0x03)
282
+ Local0 [Local1] = Local4
283
+ Local1++
284
+ }
285
+
286
+ Return (Local0)
287
+ }
288
+
289
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
290
+ {
291
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
292
+ 0x0000, // Granularity
293
+ 0x0020, // Range Minimum
294
+ 0x0020, // Range Maximum
295
+ 0x0000, // Translation Offset
296
+ 0x0001, // Length
297
+ ,, )
298
+ })
299
+ }
300
+ }
301
+
302
+ Scope (\_SB)
303
+ {
304
+ Device (PC10)
305
+ {
306
+ Name (_UID, 0x10) // _UID: Unique ID
307
+ Name (_BBN, 0x10) // _BBN: BIOS Bus Number
308
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
309
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
310
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
311
+ {
312
+ CreateDWordField (Arg3, Zero, CDW1)
313
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
314
+ {
315
+ CreateDWordField (Arg3, 0x04, CDW2)
316
+ CreateDWordField (Arg3, 0x08, CDW3)
317
+ Local0 = CDW3 /* \_SB_.PC10._OSC.CDW3 */
318
+ Local0 &= 0x1F
319
+ If ((Arg1 != One))
320
+ {
321
+ CDW1 |= 0x08
322
+ }
323
+
324
+ If ((CDW3 != Local0))
325
+ {
326
+ CDW1 |= 0x10
327
+ }
328
+
329
+ CDW3 = Local0
330
+ }
331
+ Else
332
+ {
333
+ CDW1 |= 0x04
334
+ }
335
+
336
+ Return (Arg3)
337
+ }
338
+
339
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
340
+ {
341
+ Local0 = Package (0x80){}
342
+ Local1 = Zero
343
+ While ((Local1 < 0x80))
344
+ {
345
+ Local2 = (Local1 >> 0x02)
346
+ Local3 = ((Local1 + Local2) & 0x03)
347
+ If ((Local3 == Zero))
348
+ {
349
+ Local4 = Package (0x04)
350
+ {
351
+ Zero,
352
+ Zero,
353
+ LNKD,
354
+ Zero
355
+ }
356
+ }
357
+
358
+ If ((Local3 == One))
359
+ {
360
+ Local4 = Package (0x04)
361
+ {
362
+ Zero,
363
+ Zero,
364
+ LNKA,
365
+ Zero
366
+ }
367
+ }
368
+
369
+ If ((Local3 == 0x02))
370
+ {
371
+ Local4 = Package (0x04)
372
+ {
373
+ Zero,
374
+ Zero,
375
+ LNKB,
376
+ Zero
377
+ }
378
+ }
379
+
380
+ If ((Local3 == 0x03))
381
+ {
382
+ Local4 = Package (0x04)
383
+ {
384
+ Zero,
385
+ Zero,
386
+ LNKC,
387
+ Zero
388
+ }
389
+ }
390
+
391
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
392
+ Local4 [One] = (Local1 & 0x03)
393
+ Local0 [Local1] = Local4
394
+ Local1++
395
+ }
396
+
397
+ Return (Local0)
398
+ }
399
+
400
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
401
+ {
402
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
403
+ 0x0000, // Granularity
404
+ 0x0010, // Range Minimum
405
+ 0x0010, // Range Maximum
406
+ 0x0000, // Translation Offset
407
+ 0x0001, // Length
408
+ ,, )
409
+ })
410
+ }
411
+ }
412
+
413
Scope (\_SB.PCI0)
414
{
415
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
416
@@ -XXX,XX +XXX,XX @@
417
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
418
0x0000, // Granularity
419
0x0000, // Range Minimum
420
- 0x00FF, // Range Maximum
421
+ 0x000F, // Range Maximum
422
0x0000, // Translation Offset
423
- 0x0100, // Length
424
+ 0x0010, // Length
425
,, )
426
IO (Decode16,
427
0x0CF8, // Range Minimum
428
@@ -XXX,XX +XXX,XX @@
429
}
430
}
431
432
+ Device (S10)
433
+ {
434
+ Name (_ADR, 0x00020000) // _ADR: Address
435
+ }
436
+
437
+ Device (S18)
438
+ {
439
+ Name (_ADR, 0x00030000) // _ADR: Address
440
+ }
441
+
442
+ Device (S20)
443
+ {
444
+ Name (_ADR, 0x00040000) // _ADR: Address
445
+ }
446
+
447
+ Device (S28)
448
+ {
449
+ Name (_ADR, 0x00050000) // _ADR: Address
450
+ }
451
+
452
Method (PCNT, 0, NotSerialized)
453
{
454
}
455
456
Reviewed-by: Eric Auger <eric.auger@redhat.com>
457
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
458
Message-id: 20211210170415.583179-8-jean-philippe@linaro.org
459
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
460
---
461
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
462
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
463
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
464
3 files changed, 2 deletions(-)
465
466
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
467
index XXXXXXX..XXXXXXX 100644
468
--- a/tests/qtest/bios-tables-test-allowed-diff.h
469
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
470
@@ -XXX,XX +XXX,XX @@
471
/* List of comma-separated changed AML files to ignore */
472
"tests/data/acpi/virt/VIOT",
473
-"tests/data/acpi/q35/DSDT.viot",
474
-"tests/data/acpi/q35/VIOT.viot",
475
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
476
index XXXXXXX..XXXXXXX 100644
477
GIT binary patch
478
literal 9398
479
zcmeHNO>7&-8J*>iv|O&FB}G~Oi$yp||57BBoWHhc5OS9yDTx$CQgH$r;8Idr*-4Q_
480
z5(9Az1F`}niVsB-)<KW7p`g9Br(A2Gm-gmc1N78GFS!;)e2V(MnH_0{q<{#yMgn&C
481
zn|*J-d9yqFhO_H6z19~`FlPL*u<DkZ*}|)JH;X@mF-FI<cPg<fti9tEN*yB^i5czN
482
zNq&q?!OZ;BE3B7{KWzJ-`Tn~f`9?Qj8~2^N8{Oc8J%57{==w%rS#;nOCp*nTr@iZ1
483
zb+?i;JLQUJ=O0?8*>S~D)a>NF1~WVB6^~_B#yhJ`H+JU@=6aXs`?Yv)J2h=N?drcS
484
zeLZ*n<<Bm^n}6`jfBx#u8&(W}1?)}iF9o#mZ~E2+zwdn7yK3AbIzKnxpZ>JRPm3~#
485
z&ICS{+_OayRW-l=Mtk=~uaS3o8z<_udd|(wqg`&JnVPfCe>BUOO`Su3e>pff_^UW%
486
z&JE^NO`)=Amg~iqRB1pPscP?(>#ZuY8GHCmlEvD$9g3%4Db~Dfz2SATnddvrR-Oe^
487
z;s;dJec!hnzi)ri^I6YN9vtkm{^TdUF8h7gX8-<Qe4p)GQ=)AtYx2VcwdLVAEXEjG
488
z^Mj|UHPqkj-LsWuzQem1>F3atdZn=zv3$#RmZzSHN+6-yyU#8cJb=YDilX&sl}vNm
489
znkgAR^O<3kj4if>{ly5fwRfMWuC5=lrlvKPX~i#654Cp}R_d*JS$9laZ$ra6)<ns8
490
zFZy28G%xP(nit&F>LDi%G<tIc=TY=gl$jSD&Uv!Yat~XR46h%rI$!}a%!|xG7u8Zn
491
zeY8_|n=K>xz_v_W8VX$W-Fg-qFWcT}7MCyz{%%{ia7hZ>Law-k6NOr}VI&_48U=2l
492
zwqDKFE8eTwwozDdms#e?x?5a|v>&JF;2_v0L~z5n%BYU^52<*cWuD4|GYUm@1+?))
493
zte^45>Rz)t*<T5V#={r>@t@{%?^i#W{i=HAZ*Dc9y59Va-+#P!jrGs;u38a{fLr`N
494
zvT@rUu>DljxJ?^&Z?-?vyJn3C>3D=qux{Y*bs5|5n)Qmi$TD^Zdn4GU$ocJS2Hh-<
495
z`xPI^^+v0nUVdjMos8k`WGl7hA`{03ju%<lrgAHSpd^DRf-*}_#Ly0mB!LSfVgWcQ
496
z&T$@~G9)JI=hz5m0vkrel+Xy{Oh7pkAu-V!j*W7rY(bO}Q$nMH2`FbGB&N)QaV4<4
497
zo)~9JXiP9=;}NPl<C@MmXG&;XFlFNrsyfFsonxFSp<}vEgsRSQP3O3#b6nSnP}ON_
498
zI!#Tdsp~|j>ckUB>FI=~GokB5sOq#dotCE4(sd$KbtW~PNlj-`*NIToiD#j5J#9^=
499
zt?NXn>YUJYPG~wObe#xQos*i*NloXZt`niEb4t@WrRki~bs|)CI+{*L)9L6s5vn><
500
zn$DD_Go|Z9sOn5>I@6lYw5}7Os&iV?Ij!lO)^#FOb!If38BJ$K*NIToIiu;E(R9w}
501
zIuWWmPiZ<&X*y5oIuWWmF_XaEC!a&Jn$B5WCqh-{X-(&8P3LJ{Cqh-{8P3dyPr@^t
502
zSqL9?X9Uwd3W@23*s~h*tj0X6GZCuHa~kuU#yqDp5vt7d8uPryJg+kms?5hU=3^T3
503
zF`bD}WnSP+=`t5MQ$FJ_2&Q~+BP6E0f^%BVIW6a$o)e+SX~IDBih-7z6{O~7YTy`&
504
zLjy&Cv?7QikV#>n0>>@MV8oK`Gmun34-FKdlm-J8SZSaNlnhir4-FI{S|bfqV8e)V
505
zss<{chX#reE#g=hsKAC%sF6d-Km}BWs!kZFsFpKfpbC@>6rprQGEjt4Ck#|zITHq|
506
zK*>M_l;<P^MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=xY&!axO<
507
zGhv_#lnhirIg<<&q0|Wj6<E%MfhtfkPyyvkGEjt4Ck#|zITHq|K*>M_lrzad5lWpf
508
zP=V!47^ngz0~JutBm+e#b;3XemNQ|X3X}{~Ksl2P6rt1!0~J`#gn=qhGEf2KOfpb}
509
zQYQ>lU^x>8szAv=1(Y+%KoLrvFi?TzOc<yFB?A>u&LjgxD0RX>1(q{mpbC@>R6seC
510
z3>2Z%2?G^a&V+#~P%=;f<xDbAgi<FARA4z12C6{GKn0XD$v_cGoiI>=<xCi;0wn_#
511
zP|hR+MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=rz^3{+q_69%e4
512
z$v_2^Gs!>^N}VuJf#pmXr~)Me6;RG314Srx!axxz28u{EP=u<1B2)}iVZuNaCK;&0
513
zBm-5LFi?dF167!0pbC==RAItE6($T+VUmF=Ofpb~2?JG_Fi?d_2C6X0Kouqo6p_5T
514
zFi=FeV!SiSKoR0H$dH(_Z(*Q_WZ%L-5y`$K14StNmJAdjmWs}HV4<vU_xO+1efmLq
515
zZ;W>N_U)fP6Qy6Nw5mbt9Y(#emWSi66=>tq#xoh#Ue=0qyhxi8ZOUe5y0V7VfPUhp
516
zwX=;ymc+i5%sg9Ja~lZ&8oAV@mHc>&CHP9v4R(jhtT?un;O4e9#pno)Xkh7OWgK&a
517
zyj=3Iv0OuoK_;5rOr5f(Kb~ZXDBO+V`OWYo#_C08imwChQxnjdd?wZLDou8aj;$SD
518
zGDYiA3<$Tu<JnHL(KPOChi#zrR32t83}naR$+ym4P_h?z_5#|cW-nw$XD_sOtE62l
519
zrD3@*)NVyiklt0&yF9%+klsBey&I<Y2E<!f(E8TuJte)z(|ZHyy<^gQVfx}=`q&B5
520
z7nSryp1wGczIaUfVwiq$Fn#<4=@*ssi#+|}K>EdF(l3VTOM~ghPLRH&q%ZOGrGfON
521
zW73zx^yR_y<0nX8R??Sw`tm^f@-gYlNFSp|*<gA{q?Zp5Oe-+l#rmyYmKozi9y=P>
522
zVReJU*h=ZuVXiS$ohTbw-O#v9>(yZbGE|)?8(H1ZIKvV!jWa0>vy!3eMA^vdhQ>`s
523
zuMSg{q3T50$m)j1!HixV<}X9liL#N^4c*tL^y)CF8LCc{jjV3yKAqL8!%SzWI#H%q
524
z=bSrQ&)%JCRttF5g4Zf`6l?y@>PzD7MA^D>wBlcH6r1ucwJ<p0O%rZ?JzIY3-QdmZ
525
zzs|n>`a5r3e|z)wcUaqS>nqFQ-8x}eCF4u`OWUxqst-@1rSmUs%WmKP5e0dcb?e2N
526
z;Z|x*!);VwF|Yuhqs^khqOM!@u*jY!WYldISF(V6`BoNd&6Qfk3>X#SuD^7J>p_D=
527
zBPa51y^_n#=cpOt#Zf$ya$Ae9Mfz56n|<i!a=ELS@)%a{^NIH3SDuN<R~sah1km#P
528
zU@?*f%<rG=4W1wgfi;C?_n|W@%lm$&8YfvNOJodIg&IcIpIJQRHr<+ej11GQ6)&eF
529
z2Lam*jIH}#y0>KnY%4JQfOYS$*uU%f#@$U6`N8I3N-lV?5ErFCdv~xDmu2(wexld4
530
z4v^;aVAT2k6GJ^m*FD(Wqc(Qg^)6a<?}h$zLoj}4;PP!+(O{@!a1y-hoAhF_7!z+6
531
zslpAmNtYbjHrw-~#SPVk_FUf>-Obg6yV`8o$8_`PyJe_;bY5_EMBfBfWU!Q=*9HsG
532
z%_Cda{@_Krr!oHVhv9+y+T5qR8zZ2aZ>5r!$*|f$^U%yBUYfR&B!+EYy_PwL!BeUi
533
zJH^}r3r9Q+B)X@Z)fk=P13w&7x#wBtXTZ)g>WITPg5r&pQc!nmyrmk#S(>>b9xnNr
534
zx_b#v9Xv-Y><Wb%?S^0Xe&<)bbKl_=Z|3C$tf|F<bYzE*mfHB;uC)`q-?buaBe?l?
535
zcLTpK*k<49Z32`K?|nSBMFqxTK^_IE-li2fEGdK~(ZdoKBl6ab4a;Hler#`xvEXJG
536
zb?<E%EZExfX>jcOVhS*0rS~RS1dA#xhkv@Nct@#q?LyeKS<$uFec!bw>{@uu$gZ6a
537
zyVen1i{1BKd%~`D7|m$;U0a<I*3I7%^N%N%lGYdU_GS!gaR8T$NA@GzFi~z`l7hdl
538
zarZy6590|88pi(1zq;V(>38zM0sT&<zX;R5$1w3;`_JMG`;&I&0Y23DMx1%@(w(R9
539
z4M$j;D5J+Gy%fijRQsctzFKf&cv|BAz#YLq3CZJWDdtL4u1u1|mkdcUp7|sxJC+?Y
540
z_@@s`v3j}Q7*z>6X~cwUxUL8G1KT)_XTp!KAbs;vCp{K3&~_X@+ew=-D}v`2MbFV0
541
zQsVsL=rXi-pI*G|iiz;VTCutgUs)hDzV1+4?8KcoP3xROf<M%qC6lgVdpFt4<-|uM
542
z=#rl_b1#YjSIl6Toj2z_hOZcKupkdE(LozC(fN=FY(x|sk)ym|;Rq2E1xJWD%Z!ol
543
Gu>S+TT-130
544
545
literal 0
546
HcmV?d00001
547
548
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
549
index XXXXXXX..XXXXXXX 100644
550
GIT binary patch
551
literal 112
552
zcmWIZ^baXu00LVle`k+i1*eDrX9XZ&1PX!JAex!M0Hgv8m>C3sGzdcgBZCA3T-xBj
553
Q0Zb)W9Hva*zW_`e0M!8s0RR91
554
555
literal 0
556
HcmV?d00001
557
558
--
559
2.25.1
560
561
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Add support for the new ARMv8.2 SHA-3, SM3, SM4 and SHA-512 instructions to
3
The VIOT blob contains the following:
4
AArch64 user mode emulation.
5
4
6
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
5
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
7
Message-id: 20180207111729.15737-6-ard.biesheuvel@linaro.org
6
[004h 0004 4] Table Length : 00000058
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
[008h 0008 1] Revision : 00
8
[009h 0009 1] Checksum : 66
9
[00Ah 0010 6] Oem ID : "BOCHS "
10
[010h 0016 8] Oem Table ID : "BXPC "
11
[018h 0024 4] Oem Revision : 00000001
12
[01Ch 0028 4] Asl Compiler ID : "BXPC"
13
[020h 0032 4] Asl Compiler Revision : 00000001
14
15
[024h 0036 2] Node count : 0002
16
[026h 0038 2] Node offset : 0030
17
[028h 0040 8] Reserved : 0000000000000000
18
19
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
20
[031h 0049 1] Reserved : 00
21
[032h 0050 2] Length : 0010
22
23
[034h 0052 2] PCI Segment : 0000
24
[036h 0054 2] PCI BDF number : 0008
25
[038h 0056 8] Reserved : 0000000000000000
26
27
[040h 0064 1] Type : 01 [PCI Range]
28
[041h 0065 1] Reserved : 00
29
[042h 0066 2] Length : 0018
30
31
[044h 0068 4] Endpoint start : 00000000
32
[048h 0072 2] PCI Segment start : 0000
33
[04Ah 0074 2] PCI Segment end : 0000
34
[04Ch 0076 2] PCI BDF start : 0000
35
[04Eh 0078 2] PCI BDF end : 00FF
36
[050h 0080 2] Output node : 0030
37
[052h 0082 6] Reserved : 000000000000
38
39
Acked-by: Ani Sinha <ani@anisinha.ca>
40
Reviewed-by: Eric Auger <eric.auger@redhat.com>
41
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
42
Message-id: 20211210170415.583179-9-jean-philippe@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
44
---
11
linux-user/elfload.c | 19 +++++++++++++++++++
45
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
12
target/arm/cpu64.c | 4 ++++
46
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
13
2 files changed, 23 insertions(+)
47
2 files changed, 1 deletion(-)
14
48
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
49
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
16
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
51
--- a/tests/qtest/bios-tables-test-allowed-diff.h
18
+++ b/linux-user/elfload.c
52
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
19
@@ -XXX,XX +XXX,XX @@ enum {
53
@@ -1,2 +1 @@
20
ARM_HWCAP_A64_SHA1 = 1 << 5,
54
/* List of comma-separated changed AML files to ignore */
21
ARM_HWCAP_A64_SHA2 = 1 << 6,
55
-"tests/data/acpi/virt/VIOT",
22
ARM_HWCAP_A64_CRC32 = 1 << 7,
56
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
23
+ ARM_HWCAP_A64_ATOMICS = 1 << 8,
24
+ ARM_HWCAP_A64_FPHP = 1 << 9,
25
+ ARM_HWCAP_A64_ASIMDHP = 1 << 10,
26
+ ARM_HWCAP_A64_CPUID = 1 << 11,
27
+ ARM_HWCAP_A64_ASIMDRDM = 1 << 12,
28
+ ARM_HWCAP_A64_JSCVT = 1 << 13,
29
+ ARM_HWCAP_A64_FCMA = 1 << 14,
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
57
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu64.c
58
GIT binary patch
55
+++ b/target/arm/cpu64.c
59
literal 88
56
@@ -XXX,XX +XXX,XX @@ static void aarch64_any_initfn(Object *obj)
60
zcmWIZ^bd((0D?3pe`k+i1*eDrX9XZ&1PX!JAexE60Hgv8m>C3sGzXN&z`)2L0cSHX
57
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
61
I{D-Rq0Q5fy0RR91
58
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
62
59
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
63
literal 0
60
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
64
HcmV?d00001
61
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
65
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
--
66
--
68
2.16.1
67
2.25.1
69
68
70
69
diff view generated by jsdifflib