1
Arm pullreq for the 2.12 codefreeze...
1
Hi; here's a relatively small target-arm queue, pretty much all
2
bug fixes. (There are a few non-arm patches that I've thrown in
3
there too for my convenience :-))
2
4
3
thanks
5
thanks
4
-- PMM
6
-- PMM
5
7
6
The following changes since commit b39b61e410022f96ceb53d4381d25cba5126ac44:
8
The following changes since commit 278238505d28d292927bff7683f39fb4fbca7fd1:
7
9
8
memory: fix flatview_access_valid RCU read lock/unlock imbalance (2018-03-09 15:55:20 +0000)
10
Merge tag 'pull-tcg-20230511-2' of https://gitlab.com/rth7680/qemu into staging (2023-05-11 11:44:23 +0100)
9
11
10
are available in the Git repository at:
12
are available in the Git repository at:
11
13
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180309
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230512
13
15
14
for you to fetch changes up to 076a0fc32a73a9b960e0f73f04a531bc1bd94308:
16
for you to fetch changes up to 478dccbb99db0bf8f00537dd0b4d0de88d5cb537:
15
17
16
MAINTAINERS: Add entries for SD (SDHCI, SDBus, SDCard) (2018-03-09 17:09:45 +0000)
18
target/arm: Correct AArch64.S2MinTxSZ 32-bit EL1 input size check (2023-05-12 16:01:25 +0100)
17
19
18
----------------------------------------------------------------
20
----------------------------------------------------------------
19
target-arm queue:
21
target-arm queue:
20
* i.MX: Add i.MX7 SOC implementation and i.MX7 Sabre board
22
* More refactoring of files into tcg/
21
* Report the correct core count in A53 L2CTLR on the ZynqMP board
23
* Don't allow stage 2 page table walks to downgrade to NS
22
* linux-user: preliminary SVE support work (signal handling)
24
* Fix handling of SW and NSW bits for stage 2 walks
23
* hw/arm/boot: fix memory leak in case of error loading ELF file
25
* MAINTAINERS: Update Akihiko Odaki's email address
24
* hw/arm/boot: avoid reading off end of buffer if passed very
26
* ui: Fix pixel colour channel order for PNG screenshots
25
small image file
27
* docs: Remove unused weirdly-named cross-reference targets
26
* hw/arm: Use more CONFIG switches for the object files
28
* hw/mips/malta: Fix minor dead code issue
27
* target/arm: Add "-cpu max" support
29
* Fixes for the "allow CONFIG_TCG=n" changes
28
* hw/arm/virt: Support -machine gic-version=max
30
* tests/qtest: Don't run cdrom boot tests if no accelerator is present
29
* hw/sd: improve debug tracing
31
* target/arm: Correct AArch64.S2MinTxSZ 32-bit EL1 input size check
30
* hw/sd: sdcard: Add the Tuning Command (CMD 19)
31
* MAINTAINERS: add Philippe as odd-fixes maintainer for SD
32
32
33
----------------------------------------------------------------
33
----------------------------------------------------------------
34
Alistair Francis (2):
34
Akihiko Odaki (1):
35
target/arm: Add a core count property
35
MAINTAINERS: Update Akihiko Odaki's email address
36
hw/arm: Set the core count for Xilinx's ZynqMP
37
36
38
Andrey Smirnov (3):
37
Fabiano Rosas (3):
39
pci: Add support for Designware IP block
38
target/arm: Select SEMIHOSTING when using TCG
40
i.MX: Add i.MX7 SOC implementation.
39
target/arm: Select CONFIG_ARM_V7M when TCG is enabled
41
Implement support for i.MX7 Sabre board
40
tests/qtest: Don't run cdrom boot tests if no accelerator is present
42
43
Marc-André Lureau (2):
44
arm: fix load ELF error leak
45
arm: avoid heap-buffer-overflow in load_aarch64_image
46
41
47
Peter Maydell (6):
42
Peter Maydell (6):
48
target/arm: Query host CPU features on-demand at instance init
43
target/arm: Don't allow stage 2 page table walks to downgrade to NS
49
target/arm: Move definition of 'host' cpu type into cpu.c
44
target/arm: Fix handling of SW and NSW bits for stage 2 walks
50
target/arm: Add "-cpu max" support
45
ui: Fix pixel colour channel order for PNG screenshots
51
target/arm: Make 'any' CPU just an alias for 'max'
46
docs: Remove unused weirdly-named cross-reference targets
52
hw/arm/virt: Add "max" to the list of CPU types "virt" supports
47
hw/mips/malta: Fix minor dead code issue
53
hw/arm/virt: Support -machine gic-version=max
48
target/arm: Correct AArch64.S2MinTxSZ 32-bit EL1 input size check
54
49
55
Philippe Mathieu-Daudé (6):
50
Richard Henderson (2):
56
sdcard: Do not trace CMD55, except when we already expect an ACMD
51
target/arm: Move translate-a32.h, arm_ldst.h, sve_ldst_internal.h to tcg/
57
sdcard: Display command name when tracing CMD/ACMD
52
target/arm: Move helper-{a64,mve,sme,sve}.h to tcg/
58
sdcard: Display which protocol is used when tracing (SD or SPI)
59
sdcard: Add the Tuning Command (CMD19)
60
sdhci: Fix a typo in comment
61
MAINTAINERS: Add entries for SD (SDHCI, SDBus, SDCard)
62
53
63
Richard Henderson (5):
54
MAINTAINERS | 4 +-
64
linux-user: Implement aarch64 PR_SVE_SET/GET_VL
55
docs/system/devices/igb.rst | 2 +-
65
aarch64-linux-user: Split out helpers for guest signal handling
56
docs/system/devices/ivshmem.rst | 2 -
66
aarch64-linux-user: Remove struct target_aux_context
57
docs/system/devices/net.rst | 2 +-
67
aarch64-linux-user: Add support for EXTRA signal frame records
58
docs/system/devices/usb.rst | 2 -
68
aarch64-linux-user: Add support for SVE signal frame records
59
docs/system/keys.rst | 2 +-
69
60
docs/system/linuxboot.rst | 2 +-
70
Thomas Huth (1):
61
docs/system/target-i386.rst | 4 --
71
hw/arm: Use more CONFIG switches for the object files
62
target/arm/helper.h | 8 +--
72
63
target/arm/internals.h | 12 +++-
73
hw/arm/Makefile.objs | 31 +-
64
target/arm/{ => tcg}/arm_ldst.h | 0
74
hw/pci-host/Makefile.objs | 2 +
65
target/arm/{ => tcg}/helper-a64.h | 0
75
hw/sd/Makefile.objs | 2 +-
66
target/arm/{ => tcg}/helper-mve.h | 0
76
hw/sd/sdmmc-internal.h | 24 ++
67
target/arm/{ => tcg}/helper-sme.h | 0
77
include/hw/arm/fsl-imx7.h | 222 +++++++++++
68
target/arm/{ => tcg}/helper-sve.h | 0
78
include/hw/pci-host/designware.h | 102 +++++
69
target/arm/{ => tcg}/sve_ldst_internal.h | 0
79
include/hw/pci/pci_ids.h | 2 +
70
target/arm/{ => tcg}/translate-a32.h | 0
80
linux-user/aarch64/target_syscall.h | 3 +
71
hw/mips/malta.c | 5 +-
81
target/arm/cpu-qom.h | 2 +
72
target/arm/gdbstub64.c | 2 +-
82
target/arm/cpu.h | 11 +
73
target/arm/helper.c | 15 ++++-
83
target/arm/kvm_arm.h | 35 +-
74
target/arm/ptw.c | 95 +++++++++++++++++++-------------
84
hw/arm/boot.c | 4 +-
75
target/arm/tcg/pauth_helper.c | 6 +-
85
hw/arm/fsl-imx7.c | 582 ++++++++++++++++++++++++++++
76
tests/qtest/cdrom-test.c | 10 ++++
86
hw/arm/mcimx7d-sabre.c | 90 +++++
77
ui/console.c | 4 +-
87
hw/arm/virt.c | 30 +-
78
target/arm/Kconfig | 9 +--
88
hw/arm/xlnx-zynqmp.c | 2 +
79
25 files changed, 109 insertions(+), 77 deletions(-)
89
hw/pci-host/designware.c | 754 ++++++++++++++++++++++++++++++++++++
80
rename target/arm/{ => tcg}/arm_ldst.h (100%)
90
hw/sd/sd.c | 55 ++-
81
rename target/arm/{ => tcg}/helper-a64.h (100%)
91
hw/sd/sdhci.c | 4 +-
82
rename target/arm/{ => tcg}/helper-mve.h (100%)
92
hw/sd/sdmmc-internal.c | 72 ++++
83
rename target/arm/{ => tcg}/helper-sme.h (100%)
93
linux-user/signal.c | 415 ++++++++++++++++----
84
rename target/arm/{ => tcg}/helper-sve.h (100%)
94
linux-user/syscall.c | 27 ++
85
rename target/arm/{ => tcg}/sve_ldst_internal.h (100%)
95
target/arm/cpu.c | 103 ++++-
86
rename target/arm/{ => tcg}/translate-a32.h (100%)
96
target/arm/cpu64.c | 113 ++++--
97
target/arm/kvm.c | 53 +--
98
target/arm/kvm32.c | 8 +-
99
target/arm/kvm64.c | 8 +-
100
MAINTAINERS | 8 +
101
default-configs/arm-softmmu.mak | 9 +
102
hw/sd/trace-events | 8 +-
103
30 files changed, 2583 insertions(+), 198 deletions(-)
104
create mode 100644 include/hw/arm/fsl-imx7.h
105
create mode 100644 include/hw/pci-host/designware.h
106
create mode 100644 hw/arm/fsl-imx7.c
107
create mode 100644 hw/arm/mcimx7d-sabre.c
108
create mode 100644 hw/pci-host/designware.c
109
create mode 100644 hw/sd/sdmmc-internal.c
110
diff view generated by jsdifflib
Deleted patch
1
From: Alistair Francis <alistair.francis@xilinx.com>
2
1
3
The cortex A53 TRM specifies that bits 24 and 25 of the L2CTLR register
4
specify the number of cores in the processor, not the total number of
5
cores in the system. To report this correctly on machines with multiple
6
CPU clusters (ARM's big.LITTLE or Xilinx's ZynqMP) we need to allow
7
the machine to overwrite this value. To do this let's add an optional
8
property.
9
10
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
11
Message-id: ef01d95c0759e88f47f22d11b14c91512a658b4f.1520018138.git.alistair.francis@xilinx.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/cpu.h | 5 +++++
16
target/arm/cpu.c | 6 ++++++
17
target/arm/cpu64.c | 6 ++++--
18
3 files changed, 15 insertions(+), 2 deletions(-)
19
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
25
/* Uniprocessor system with MP extensions */
26
bool mp_is_up;
27
28
+ /* Specify the number of cores in this CPU cluster. Used for the L2CTLR
29
+ * register.
30
+ */
31
+ int32_t core_count;
32
+
33
/* The instance init functions for implementation-specific subclasses
34
* set these fields to specify the implementation-dependent values of
35
* various constant registers and reset values of non-constant
36
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu.c
39
+++ b/target/arm/cpu.c
40
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
41
cs->num_ases = 1;
42
}
43
cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory);
44
+
45
+ /* No core_count specified, default to smp_cpus. */
46
+ if (cpu->core_count == -1) {
47
+ cpu->core_count = smp_cpus;
48
+ }
49
#endif
50
51
qemu_init_vcpu(cs);
52
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_properties[] = {
53
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
54
mp_affinity, ARM64_AFFINITY_INVALID),
55
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
56
+ DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1),
57
DEFINE_PROP_END_OF_LIST()
58
};
59
60
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/cpu64.c
63
+++ b/target/arm/cpu64.c
64
@@ -XXX,XX +XXX,XX @@ static inline void unset_feature(CPUARMState *env, int feature)
65
#ifndef CONFIG_USER_ONLY
66
static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
67
{
68
- /* Number of processors is in [25:24]; otherwise we RAZ */
69
- return (smp_cpus - 1) << 24;
70
+ ARMCPU *cpu = arm_env_get_cpu(env);
71
+
72
+ /* Number of cores is in [25:24]; otherwise we RAZ */
73
+ return (cpu->core_count - 1) << 24;
74
}
75
#endif
76
77
--
78
2.16.2
79
80
diff view generated by jsdifflib
Deleted patch
1
From: Alistair Francis <alistair.francis@xilinx.com>
2
1
3
Set the ARM CPU core count property for the A53's attached to the Xilnx
4
ZynqMP machine.
5
6
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: fe0dd90b85ac73f9fc9548c253bededa70a07006.1520018138.git.alistair.francis@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/xlnx-zynqmp.c | 2 ++
12
1 file changed, 2 insertions(+)
13
14
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-zynqmp.c
17
+++ b/hw/arm/xlnx-zynqmp.c
18
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
19
s->virt, "has_el2", NULL);
20
object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR,
21
"reset-cbar", &error_abort);
22
+ object_property_set_int(OBJECT(&s->apu_cpu[i]), num_apus,
23
+ "core-count", &error_abort);
24
object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "realized",
25
&err);
26
if (err) {
27
--
28
2.16.2
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Add code needed to get a functional PCI subsytem when using in
4
conjunction with upstream Linux guest (4.13+). Tested to work against
5
"e1000e" (network adapter, using MSI interrupts) as well as
6
"usb-ehci" (USB controller, using legacy PCI interrupts).
7
8
Based on "i.MX6 Applications Processor Reference Manual" (Document
9
Number: IMX6DQRM Rev. 4) as well as corresponding dirver in Linux
10
kernel (circa 4.13 - 4.16 found in drivers/pci/dwc/*)
11
12
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/pci-host/Makefile.objs | 2 +
17
include/hw/pci-host/designware.h | 102 ++++++
18
include/hw/pci/pci_ids.h | 2 +
19
hw/pci-host/designware.c | 754 +++++++++++++++++++++++++++++++++++++++
20
default-configs/arm-softmmu.mak | 1 +
21
5 files changed, 861 insertions(+)
22
create mode 100644 include/hw/pci-host/designware.h
23
create mode 100644 hw/pci-host/designware.c
24
25
diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/pci-host/Makefile.objs
28
+++ b/hw/pci-host/Makefile.objs
29
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PCI_PIIX) += piix.o
30
common-obj-$(CONFIG_PCI_Q35) += q35.o
31
common-obj-$(CONFIG_PCI_GENERIC) += gpex.o
32
common-obj-$(CONFIG_PCI_XILINX) += xilinx-pcie.o
33
+
34
+common-obj-$(CONFIG_PCI_DESIGNWARE) += designware.o
35
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/include/hw/pci-host/designware.h
40
@@ -XXX,XX +XXX,XX @@
41
+/*
42
+ * Copyright (c) 2017, Impinj, Inc.
43
+ *
44
+ * Designware PCIe IP block emulation
45
+ *
46
+ * This library is free software; you can redistribute it and/or
47
+ * modify it under the terms of the GNU Lesser General Public
48
+ * License as published by the Free Software Foundation; either
49
+ * version 2 of the License, or (at your option) any later version.
50
+ *
51
+ * This library is distributed in the hope that it will be useful,
52
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
53
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
54
+ * Lesser General Public License for more details.
55
+ *
56
+ * You should have received a copy of the GNU Lesser General Public
57
+ * License along with this library; if not, see
58
+ * <http://www.gnu.org/licenses/>.
59
+ */
60
+
61
+#ifndef DESIGNWARE_H
62
+#define DESIGNWARE_H
63
+
64
+#include "hw/hw.h"
65
+#include "hw/sysbus.h"
66
+#include "hw/pci/pci.h"
67
+#include "hw/pci/pci_bus.h"
68
+#include "hw/pci/pcie_host.h"
69
+#include "hw/pci/pci_bridge.h"
70
+
71
+#define TYPE_DESIGNWARE_PCIE_HOST "designware-pcie-host"
72
+#define DESIGNWARE_PCIE_HOST(obj) \
73
+ OBJECT_CHECK(DesignwarePCIEHost, (obj), TYPE_DESIGNWARE_PCIE_HOST)
74
+
75
+#define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root"
76
+#define DESIGNWARE_PCIE_ROOT(obj) \
77
+ OBJECT_CHECK(DesignwarePCIERoot, (obj), TYPE_DESIGNWARE_PCIE_ROOT)
78
+
79
+struct DesignwarePCIERoot;
80
+typedef struct DesignwarePCIERoot DesignwarePCIERoot;
81
+
82
+typedef struct DesignwarePCIEViewport {
83
+ DesignwarePCIERoot *root;
84
+
85
+ MemoryRegion cfg;
86
+ MemoryRegion mem;
87
+
88
+ uint64_t base;
89
+ uint64_t target;
90
+ uint32_t limit;
91
+ uint32_t cr[2];
92
+
93
+ bool inbound;
94
+} DesignwarePCIEViewport;
95
+
96
+typedef struct DesignwarePCIEMSIBank {
97
+ uint32_t enable;
98
+ uint32_t mask;
99
+ uint32_t status;
100
+} DesignwarePCIEMSIBank;
101
+
102
+typedef struct DesignwarePCIEMSI {
103
+ uint64_t base;
104
+ MemoryRegion iomem;
105
+
106
+#define DESIGNWARE_PCIE_NUM_MSI_BANKS 1
107
+
108
+ DesignwarePCIEMSIBank intr[DESIGNWARE_PCIE_NUM_MSI_BANKS];
109
+} DesignwarePCIEMSI;
110
+
111
+struct DesignwarePCIERoot {
112
+ PCIBridge parent_obj;
113
+
114
+ uint32_t atu_viewport;
115
+
116
+#define DESIGNWARE_PCIE_VIEWPORT_OUTBOUND 0
117
+#define DESIGNWARE_PCIE_VIEWPORT_INBOUND 1
118
+#define DESIGNWARE_PCIE_NUM_VIEWPORTS 4
119
+
120
+ DesignwarePCIEViewport viewports[2][DESIGNWARE_PCIE_NUM_VIEWPORTS];
121
+ DesignwarePCIEMSI msi;
122
+};
123
+
124
+typedef struct DesignwarePCIEHost {
125
+ PCIHostState parent_obj;
126
+
127
+ DesignwarePCIERoot root;
128
+
129
+ struct {
130
+ AddressSpace address_space;
131
+ MemoryRegion address_space_root;
132
+
133
+ MemoryRegion memory;
134
+ MemoryRegion io;
135
+
136
+ qemu_irq irqs[4];
137
+ } pci;
138
+
139
+ MemoryRegion mmio;
140
+} DesignwarePCIEHost;
141
+
142
+#endif /* DESIGNWARE_H */
143
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
144
index XXXXXXX..XXXXXXX 100644
145
--- a/include/hw/pci/pci_ids.h
146
+++ b/include/hw/pci/pci_ids.h
147
@@ -XXX,XX +XXX,XX @@
148
#define PCI_VENDOR_ID_VMWARE 0x15ad
149
#define PCI_DEVICE_ID_VMWARE_PVRDMA 0x0820
150
151
+#define PCI_VENDOR_ID_SYNOPSYS 0x16C3
152
+
153
#endif
154
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
155
new file mode 100644
156
index XXXXXXX..XXXXXXX
157
--- /dev/null
158
+++ b/hw/pci-host/designware.c
159
@@ -XXX,XX +XXX,XX @@
160
+/*
161
+ * Copyright (c) 2018, Impinj, Inc.
162
+ *
163
+ * Designware PCIe IP block emulation
164
+ *
165
+ * This library is free software; you can redistribute it and/or
166
+ * modify it under the terms of the GNU Lesser General Public
167
+ * License as published by the Free Software Foundation; either
168
+ * version 2 of the License, or (at your option) any later version.
169
+ *
170
+ * This library is distributed in the hope that it will be useful,
171
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
172
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
173
+ * Lesser General Public License for more details.
174
+ *
175
+ * You should have received a copy of the GNU Lesser General Public
176
+ * License along with this library; if not, see
177
+ * <http://www.gnu.org/licenses/>.
178
+ */
179
+
180
+#include "qemu/osdep.h"
181
+#include "qapi/error.h"
182
+#include "hw/pci/msi.h"
183
+#include "hw/pci/pci_bridge.h"
184
+#include "hw/pci/pci_host.h"
185
+#include "hw/pci/pcie_port.h"
186
+#include "hw/pci-host/designware.h"
187
+
188
+#define DESIGNWARE_PCIE_PORT_LINK_CONTROL 0x710
189
+#define DESIGNWARE_PCIE_PHY_DEBUG_R1 0x72C
190
+#define DESIGNWARE_PCIE_PHY_DEBUG_R1_XMLH_LINK_UP BIT(4)
191
+#define DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
192
+#define DESIGNWARE_PCIE_PORT_LOGIC_SPEED_CHANGE BIT(17)
193
+#define DESIGNWARE_PCIE_MSI_ADDR_LO 0x820
194
+#define DESIGNWARE_PCIE_MSI_ADDR_HI 0x824
195
+#define DESIGNWARE_PCIE_MSI_INTR0_ENABLE 0x828
196
+#define DESIGNWARE_PCIE_MSI_INTR0_MASK 0x82C
197
+#define DESIGNWARE_PCIE_MSI_INTR0_STATUS 0x830
198
+#define DESIGNWARE_PCIE_ATU_VIEWPORT 0x900
199
+#define DESIGNWARE_PCIE_ATU_REGION_INBOUND BIT(31)
200
+#define DESIGNWARE_PCIE_ATU_CR1 0x904
201
+#define DESIGNWARE_PCIE_ATU_TYPE_MEM (0x0 << 0)
202
+#define DESIGNWARE_PCIE_ATU_CR2 0x908
203
+#define DESIGNWARE_PCIE_ATU_ENABLE BIT(31)
204
+#define DESIGNWARE_PCIE_ATU_LOWER_BASE 0x90C
205
+#define DESIGNWARE_PCIE_ATU_UPPER_BASE 0x910
206
+#define DESIGNWARE_PCIE_ATU_LIMIT 0x914
207
+#define DESIGNWARE_PCIE_ATU_LOWER_TARGET 0x918
208
+#define DESIGNWARE_PCIE_ATU_BUS(x) (((x) >> 24) & 0xff)
209
+#define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff)
210
+#define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C
211
+
212
+static DesignwarePCIEHost *
213
+designware_pcie_root_to_host(DesignwarePCIERoot *root)
214
+{
215
+ BusState *bus = qdev_get_parent_bus(DEVICE(root));
216
+ return DESIGNWARE_PCIE_HOST(bus->parent);
217
+}
218
+
219
+static void designware_pcie_root_msi_write(void *opaque, hwaddr addr,
220
+ uint64_t val, unsigned len)
221
+{
222
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(opaque);
223
+ DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
224
+
225
+ root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable;
226
+
227
+ if (root->msi.intr[0].status & ~root->msi.intr[0].mask) {
228
+ qemu_set_irq(host->pci.irqs[0], 1);
229
+ }
230
+}
231
+
232
+static const MemoryRegionOps designware_pci_host_msi_ops = {
233
+ .write = designware_pcie_root_msi_write,
234
+ .endianness = DEVICE_LITTLE_ENDIAN,
235
+ .valid = {
236
+ .min_access_size = 4,
237
+ .max_access_size = 4,
238
+ },
239
+};
240
+
241
+static void designware_pcie_root_update_msi_mapping(DesignwarePCIERoot *root)
242
+
243
+{
244
+ MemoryRegion *mem = &root->msi.iomem;
245
+ const uint64_t base = root->msi.base;
246
+ const bool enable = root->msi.intr[0].enable;
247
+
248
+ memory_region_set_address(mem, base);
249
+ memory_region_set_enabled(mem, enable);
250
+}
251
+
252
+static DesignwarePCIEViewport *
253
+designware_pcie_root_get_current_viewport(DesignwarePCIERoot *root)
254
+{
255
+ const unsigned int idx = root->atu_viewport & 0xF;
256
+ const unsigned int dir =
257
+ !!(root->atu_viewport & DESIGNWARE_PCIE_ATU_REGION_INBOUND);
258
+ return &root->viewports[dir][idx];
259
+}
260
+
261
+static uint32_t
262
+designware_pcie_root_config_read(PCIDevice *d, uint32_t address, int len)
263
+{
264
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(d);
265
+ DesignwarePCIEViewport *viewport =
266
+ designware_pcie_root_get_current_viewport(root);
267
+
268
+ uint32_t val;
269
+
270
+ switch (address) {
271
+ case DESIGNWARE_PCIE_PORT_LINK_CONTROL:
272
+ /*
273
+ * Linux guest uses this register only to configure number of
274
+ * PCIE lane (which in our case is irrelevant) and doesn't
275
+ * really care about the value it reads from this register
276
+ */
277
+ val = 0xDEADBEEF;
278
+ break;
279
+
280
+ case DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL:
281
+ /*
282
+ * To make sure that any code in guest waiting for speed
283
+ * change does not time out we always report
284
+ * PORT_LOGIC_SPEED_CHANGE as set
285
+ */
286
+ val = DESIGNWARE_PCIE_PORT_LOGIC_SPEED_CHANGE;
287
+ break;
288
+
289
+ case DESIGNWARE_PCIE_MSI_ADDR_LO:
290
+ val = root->msi.base;
291
+ break;
292
+
293
+ case DESIGNWARE_PCIE_MSI_ADDR_HI:
294
+ val = root->msi.base >> 32;
295
+ break;
296
+
297
+ case DESIGNWARE_PCIE_MSI_INTR0_ENABLE:
298
+ val = root->msi.intr[0].enable;
299
+ break;
300
+
301
+ case DESIGNWARE_PCIE_MSI_INTR0_MASK:
302
+ val = root->msi.intr[0].mask;
303
+ break;
304
+
305
+ case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
306
+ val = root->msi.intr[0].status;
307
+ break;
308
+
309
+ case DESIGNWARE_PCIE_PHY_DEBUG_R1:
310
+ val = DESIGNWARE_PCIE_PHY_DEBUG_R1_XMLH_LINK_UP;
311
+ break;
312
+
313
+ case DESIGNWARE_PCIE_ATU_VIEWPORT:
314
+ val = root->atu_viewport;
315
+ break;
316
+
317
+ case DESIGNWARE_PCIE_ATU_LOWER_BASE:
318
+ val = viewport->base;
319
+ break;
320
+
321
+ case DESIGNWARE_PCIE_ATU_UPPER_BASE:
322
+ val = viewport->base >> 32;
323
+ break;
324
+
325
+ case DESIGNWARE_PCIE_ATU_LOWER_TARGET:
326
+ val = viewport->target;
327
+ break;
328
+
329
+ case DESIGNWARE_PCIE_ATU_UPPER_TARGET:
330
+ val = viewport->target >> 32;
331
+ break;
332
+
333
+ case DESIGNWARE_PCIE_ATU_LIMIT:
334
+ val = viewport->limit;
335
+ break;
336
+
337
+ case DESIGNWARE_PCIE_ATU_CR1:
338
+ case DESIGNWARE_PCIE_ATU_CR2: /* FALLTHROUGH */
339
+ val = viewport->cr[(address - DESIGNWARE_PCIE_ATU_CR1) /
340
+ sizeof(uint32_t)];
341
+ break;
342
+
343
+ default:
344
+ val = pci_default_read_config(d, address, len);
345
+ break;
346
+ }
347
+
348
+ return val;
349
+}
350
+
351
+static uint64_t designware_pcie_root_data_access(void *opaque, hwaddr addr,
352
+ uint64_t *val, unsigned len)
353
+{
354
+ DesignwarePCIEViewport *viewport = opaque;
355
+ DesignwarePCIERoot *root = viewport->root;
356
+
357
+ const uint8_t busnum = DESIGNWARE_PCIE_ATU_BUS(viewport->target);
358
+ const uint8_t devfn = DESIGNWARE_PCIE_ATU_DEVFN(viewport->target);
359
+ PCIBus *pcibus = pci_get_bus(PCI_DEVICE(root));
360
+ PCIDevice *pcidev = pci_find_device(pcibus, busnum, devfn);
361
+
362
+ if (pcidev) {
363
+ addr &= pci_config_size(pcidev) - 1;
364
+
365
+ if (val) {
366
+ pci_host_config_write_common(pcidev, addr,
367
+ pci_config_size(pcidev),
368
+ *val, len);
369
+ } else {
370
+ return pci_host_config_read_common(pcidev, addr,
371
+ pci_config_size(pcidev),
372
+ len);
373
+ }
374
+ }
375
+
376
+ return UINT64_MAX;
377
+}
378
+
379
+static uint64_t designware_pcie_root_data_read(void *opaque, hwaddr addr,
380
+ unsigned len)
381
+{
382
+ return designware_pcie_root_data_access(opaque, addr, NULL, len);
383
+}
384
+
385
+static void designware_pcie_root_data_write(void *opaque, hwaddr addr,
386
+ uint64_t val, unsigned len)
387
+{
388
+ designware_pcie_root_data_access(opaque, addr, &val, len);
389
+}
390
+
391
+static const MemoryRegionOps designware_pci_host_conf_ops = {
392
+ .read = designware_pcie_root_data_read,
393
+ .write = designware_pcie_root_data_write,
394
+ .endianness = DEVICE_LITTLE_ENDIAN,
395
+ .valid = {
396
+ .min_access_size = 1,
397
+ .max_access_size = 4,
398
+ },
399
+};
400
+
401
+static void designware_pcie_update_viewport(DesignwarePCIERoot *root,
402
+ DesignwarePCIEViewport *viewport)
403
+{
404
+ const uint64_t target = viewport->target;
405
+ const uint64_t base = viewport->base;
406
+ const uint64_t size = (uint64_t)viewport->limit - base + 1;
407
+ const bool enabled = viewport->cr[1] & DESIGNWARE_PCIE_ATU_ENABLE;
408
+
409
+ MemoryRegion *current, *other;
410
+
411
+ if (viewport->cr[0] == DESIGNWARE_PCIE_ATU_TYPE_MEM) {
412
+ current = &viewport->mem;
413
+ other = &viewport->cfg;
414
+ memory_region_set_alias_offset(current, target);
415
+ } else {
416
+ current = &viewport->cfg;
417
+ other = &viewport->mem;
418
+ }
419
+
420
+ /*
421
+ * An outbound viewport can be reconfigure from being MEM to CFG,
422
+ * to account for that we disable the "other" memory region that
423
+ * becomes unused due to that fact.
424
+ */
425
+ memory_region_set_enabled(other, false);
426
+ if (enabled) {
427
+ memory_region_set_size(current, size);
428
+ memory_region_set_address(current, base);
429
+ }
430
+ memory_region_set_enabled(current, enabled);
431
+}
432
+
433
+static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address,
434
+ uint32_t val, int len)
435
+{
436
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(d);
437
+ DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
438
+ DesignwarePCIEViewport *viewport =
439
+ designware_pcie_root_get_current_viewport(root);
440
+
441
+ switch (address) {
442
+ case DESIGNWARE_PCIE_PORT_LINK_CONTROL:
443
+ case DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL:
444
+ case DESIGNWARE_PCIE_PHY_DEBUG_R1:
445
+ /* No-op */
446
+ break;
447
+
448
+ case DESIGNWARE_PCIE_MSI_ADDR_LO:
449
+ root->msi.base &= 0xFFFFFFFF00000000ULL;
450
+ root->msi.base |= val;
451
+ break;
452
+
453
+ case DESIGNWARE_PCIE_MSI_ADDR_HI:
454
+ root->msi.base &= 0x00000000FFFFFFFFULL;
455
+ root->msi.base |= (uint64_t)val << 32;
456
+ break;
457
+
458
+ case DESIGNWARE_PCIE_MSI_INTR0_ENABLE: {
459
+ const bool update_msi_mapping = !root->msi.intr[0].enable ^ !!val;
460
+
461
+ root->msi.intr[0].enable = val;
462
+
463
+ if (update_msi_mapping) {
464
+ designware_pcie_root_update_msi_mapping(root);
465
+ }
466
+ break;
467
+ }
468
+
469
+ case DESIGNWARE_PCIE_MSI_INTR0_MASK:
470
+ root->msi.intr[0].mask = val;
471
+ break;
472
+
473
+ case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
474
+ root->msi.intr[0].status ^= val;
475
+ if (!root->msi.intr[0].status) {
476
+ qemu_set_irq(host->pci.irqs[0], 0);
477
+ }
478
+ break;
479
+
480
+ case DESIGNWARE_PCIE_ATU_VIEWPORT:
481
+ root->atu_viewport = val;
482
+ break;
483
+
484
+ case DESIGNWARE_PCIE_ATU_LOWER_BASE:
485
+ viewport->base &= 0xFFFFFFFF00000000ULL;
486
+ viewport->base |= val;
487
+ break;
488
+
489
+ case DESIGNWARE_PCIE_ATU_UPPER_BASE:
490
+ viewport->base &= 0x00000000FFFFFFFFULL;
491
+ viewport->base |= (uint64_t)val << 32;
492
+ break;
493
+
494
+ case DESIGNWARE_PCIE_ATU_LOWER_TARGET:
495
+ viewport->target &= 0xFFFFFFFF00000000ULL;
496
+ viewport->target |= val;
497
+ break;
498
+
499
+ case DESIGNWARE_PCIE_ATU_UPPER_TARGET:
500
+ viewport->target &= 0x00000000FFFFFFFFULL;
501
+ viewport->target |= val;
502
+ break;
503
+
504
+ case DESIGNWARE_PCIE_ATU_LIMIT:
505
+ viewport->limit = val;
506
+ break;
507
+
508
+ case DESIGNWARE_PCIE_ATU_CR1:
509
+ viewport->cr[0] = val;
510
+ break;
511
+ case DESIGNWARE_PCIE_ATU_CR2:
512
+ viewport->cr[1] = val;
513
+ designware_pcie_update_viewport(root, viewport);
514
+ break;
515
+
516
+ default:
517
+ pci_bridge_write_config(d, address, val, len);
518
+ break;
519
+ }
520
+}
521
+
522
+static char *designware_pcie_viewport_name(const char *direction,
523
+ unsigned int i,
524
+ const char *type)
525
+{
526
+ return g_strdup_printf("PCI %s Viewport %u [%s]",
527
+ direction, i, type);
528
+}
529
+
530
+static void designware_pcie_root_realize(PCIDevice *dev, Error **errp)
531
+{
532
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(dev);
533
+ DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
534
+ MemoryRegion *address_space = &host->pci.memory;
535
+ PCIBridge *br = PCI_BRIDGE(dev);
536
+ DesignwarePCIEViewport *viewport;
537
+ /*
538
+ * Dummy values used for initial configuration of MemoryRegions
539
+ * that belong to a given viewport
540
+ */
541
+ const hwaddr dummy_offset = 0;
542
+ const uint64_t dummy_size = 4;
543
+ size_t i;
544
+
545
+ br->bus_name = "dw-pcie";
546
+
547
+ pci_set_word(dev->config + PCI_COMMAND,
548
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
549
+
550
+ pci_config_set_interrupt_pin(dev->config, 1);
551
+ pci_bridge_initfn(dev, TYPE_PCIE_BUS);
552
+
553
+ pcie_port_init_reg(dev);
554
+
555
+ pcie_cap_init(dev, 0x70, PCI_EXP_TYPE_ROOT_PORT,
556
+ 0, &error_fatal);
557
+
558
+ msi_nonbroken = true;
559
+ msi_init(dev, 0x50, 32, true, true, &error_fatal);
560
+
561
+ for (i = 0; i < DESIGNWARE_PCIE_NUM_VIEWPORTS; i++) {
562
+ MemoryRegion *source, *destination, *mem;
563
+ const char *direction;
564
+ char *name;
565
+
566
+ viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][i];
567
+ viewport->inbound = true;
568
+ viewport->base = 0x0000000000000000ULL;
569
+ viewport->target = 0x0000000000000000ULL;
570
+ viewport->limit = UINT32_MAX;
571
+ viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM;
572
+
573
+ source = &host->pci.address_space_root;
574
+ destination = get_system_memory();
575
+ direction = "Inbound";
576
+
577
+ /*
578
+ * Configure MemoryRegion implementing PCI -> CPU memory
579
+ * access
580
+ */
581
+ mem = &viewport->mem;
582
+ name = designware_pcie_viewport_name(direction, i, "MEM");
583
+ memory_region_init_alias(mem, OBJECT(root), name, destination,
584
+ dummy_offset, dummy_size);
585
+ memory_region_add_subregion_overlap(source, dummy_offset, mem, -1);
586
+ memory_region_set_enabled(mem, false);
587
+ g_free(name);
588
+
589
+ viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_OUTBOUND][i];
590
+ viewport->root = root;
591
+ viewport->inbound = false;
592
+ viewport->base = 0x0000000000000000ULL;
593
+ viewport->target = 0x0000000000000000ULL;
594
+ viewport->limit = UINT32_MAX;
595
+ viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM;
596
+
597
+ destination = &host->pci.memory;
598
+ direction = "Outbound";
599
+ source = get_system_memory();
600
+
601
+ /*
602
+ * Configure MemoryRegion implementing CPU -> PCI memory
603
+ * access
604
+ */
605
+ mem = &viewport->mem;
606
+ name = designware_pcie_viewport_name(direction, i, "MEM");
607
+ memory_region_init_alias(mem, OBJECT(root), name, destination,
608
+ dummy_offset, dummy_size);
609
+ memory_region_add_subregion(source, dummy_offset, mem);
610
+ memory_region_set_enabled(mem, false);
611
+ g_free(name);
612
+
613
+ /*
614
+ * Configure MemoryRegion implementing access to configuration
615
+ * space
616
+ */
617
+ mem = &viewport->cfg;
618
+ name = designware_pcie_viewport_name(direction, i, "CFG");
619
+ memory_region_init_io(&viewport->cfg, OBJECT(root),
620
+ &designware_pci_host_conf_ops,
621
+ viewport, name, dummy_size);
622
+ memory_region_add_subregion(source, dummy_offset, mem);
623
+ memory_region_set_enabled(mem, false);
624
+ g_free(name);
625
+ }
626
+
627
+ /*
628
+ * If no inbound iATU windows are configured, HW defaults to
629
+ * letting inbound TLPs to pass in. We emulate that by exlicitly
630
+ * configuring first inbound window to cover all of target's
631
+ * address space.
632
+ *
633
+ * NOTE: This will not work correctly for the case when first
634
+ * configured inbound window is window 0
635
+ */
636
+ viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][0];
637
+ viewport->cr[1] = DESIGNWARE_PCIE_ATU_ENABLE;
638
+ designware_pcie_update_viewport(root, viewport);
639
+
640
+ memory_region_init_io(&root->msi.iomem, OBJECT(root),
641
+ &designware_pci_host_msi_ops,
642
+ root, "pcie-msi", 0x4);
643
+ /*
644
+ * We initially place MSI interrupt I/O region a adress 0 and
645
+ * disable it. It'll be later moved to correct offset and enabled
646
+ * in designware_pcie_root_update_msi_mapping() as a part of
647
+ * initialization done by guest OS
648
+ */
649
+ memory_region_add_subregion(address_space, dummy_offset, &root->msi.iomem);
650
+ memory_region_set_enabled(&root->msi.iomem, false);
651
+}
652
+
653
+static void designware_pcie_set_irq(void *opaque, int irq_num, int level)
654
+{
655
+ DesignwarePCIEHost *host = DESIGNWARE_PCIE_HOST(opaque);
656
+
657
+ qemu_set_irq(host->pci.irqs[irq_num], level);
658
+}
659
+
660
+static const char *
661
+designware_pcie_host_root_bus_path(PCIHostState *host_bridge, PCIBus *rootbus)
662
+{
663
+ return "0000:00";
664
+}
665
+
666
+static const VMStateDescription vmstate_designware_pcie_msi_bank = {
667
+ .name = "designware-pcie-msi-bank",
668
+ .version_id = 1,
669
+ .minimum_version_id = 1,
670
+ .fields = (VMStateField[]) {
671
+ VMSTATE_UINT32(enable, DesignwarePCIEMSIBank),
672
+ VMSTATE_UINT32(mask, DesignwarePCIEMSIBank),
673
+ VMSTATE_UINT32(status, DesignwarePCIEMSIBank),
674
+ VMSTATE_END_OF_LIST()
675
+ }
676
+};
677
+
678
+static const VMStateDescription vmstate_designware_pcie_msi = {
679
+ .name = "designware-pcie-msi",
680
+ .version_id = 1,
681
+ .minimum_version_id = 1,
682
+ .fields = (VMStateField[]) {
683
+ VMSTATE_UINT64(base, DesignwarePCIEMSI),
684
+ VMSTATE_STRUCT_ARRAY(intr,
685
+ DesignwarePCIEMSI,
686
+ DESIGNWARE_PCIE_NUM_MSI_BANKS,
687
+ 1,
688
+ vmstate_designware_pcie_msi_bank,
689
+ DesignwarePCIEMSIBank),
690
+ VMSTATE_END_OF_LIST()
691
+ }
692
+};
693
+
694
+static const VMStateDescription vmstate_designware_pcie_viewport = {
695
+ .name = "designware-pcie-viewport",
696
+ .version_id = 1,
697
+ .minimum_version_id = 1,
698
+ .fields = (VMStateField[]) {
699
+ VMSTATE_UINT64(base, DesignwarePCIEViewport),
700
+ VMSTATE_UINT64(target, DesignwarePCIEViewport),
701
+ VMSTATE_UINT32(limit, DesignwarePCIEViewport),
702
+ VMSTATE_UINT32_ARRAY(cr, DesignwarePCIEViewport, 2),
703
+ VMSTATE_END_OF_LIST()
704
+ }
705
+};
706
+
707
+static const VMStateDescription vmstate_designware_pcie_root = {
708
+ .name = "designware-pcie-root",
709
+ .version_id = 1,
710
+ .minimum_version_id = 1,
711
+ .fields = (VMStateField[]) {
712
+ VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
713
+ VMSTATE_UINT32(atu_viewport, DesignwarePCIERoot),
714
+ VMSTATE_STRUCT_2DARRAY(viewports,
715
+ DesignwarePCIERoot,
716
+ 2,
717
+ DESIGNWARE_PCIE_NUM_VIEWPORTS,
718
+ 1,
719
+ vmstate_designware_pcie_viewport,
720
+ DesignwarePCIEViewport),
721
+ VMSTATE_STRUCT(msi,
722
+ DesignwarePCIERoot,
723
+ 1,
724
+ vmstate_designware_pcie_msi,
725
+ DesignwarePCIEMSI),
726
+ VMSTATE_END_OF_LIST()
727
+ }
728
+};
729
+
730
+static void designware_pcie_root_class_init(ObjectClass *klass, void *data)
731
+{
732
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
733
+ DeviceClass *dc = DEVICE_CLASS(klass);
734
+
735
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
736
+
737
+ k->vendor_id = PCI_VENDOR_ID_SYNOPSYS;
738
+ k->device_id = 0xABCD;
739
+ k->revision = 0;
740
+ k->class_id = PCI_CLASS_BRIDGE_PCI;
741
+ k->is_bridge = true;
742
+ k->exit = pci_bridge_exitfn;
743
+ k->realize = designware_pcie_root_realize;
744
+ k->config_read = designware_pcie_root_config_read;
745
+ k->config_write = designware_pcie_root_config_write;
746
+
747
+ dc->reset = pci_bridge_reset;
748
+ /*
749
+ * PCI-facing part of the host bridge, not usable without the
750
+ * host-facing part, which can't be device_add'ed, yet.
751
+ */
752
+ dc->user_creatable = false;
753
+ dc->vmsd = &vmstate_designware_pcie_root;
754
+}
755
+
756
+static uint64_t designware_pcie_host_mmio_read(void *opaque, hwaddr addr,
757
+ unsigned int size)
758
+{
759
+ PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
760
+ PCIDevice *device = pci_find_device(pci->bus, 0, 0);
761
+
762
+ return pci_host_config_read_common(device,
763
+ addr,
764
+ pci_config_size(device),
765
+ size);
766
+}
767
+
768
+static void designware_pcie_host_mmio_write(void *opaque, hwaddr addr,
769
+ uint64_t val, unsigned int size)
770
+{
771
+ PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
772
+ PCIDevice *device = pci_find_device(pci->bus, 0, 0);
773
+
774
+ return pci_host_config_write_common(device,
775
+ addr,
776
+ pci_config_size(device),
777
+ val, size);
778
+}
779
+
780
+static const MemoryRegionOps designware_pci_mmio_ops = {
781
+ .read = designware_pcie_host_mmio_read,
782
+ .write = designware_pcie_host_mmio_write,
783
+ .endianness = DEVICE_LITTLE_ENDIAN,
784
+ .impl = {
785
+ /*
786
+ * Our device would not work correctly if the guest was doing
787
+ * unaligned access. This might not be a limitation on the real
788
+ * device but in practice there is no reason for a guest to access
789
+ * this device unaligned.
790
+ */
791
+ .min_access_size = 4,
792
+ .max_access_size = 4,
793
+ .unaligned = false,
794
+ },
795
+};
796
+
797
+static AddressSpace *designware_pcie_host_set_iommu(PCIBus *bus, void *opaque,
798
+ int devfn)
799
+{
800
+ DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(opaque);
801
+
802
+ return &s->pci.address_space;
803
+}
804
+
805
+static void designware_pcie_host_realize(DeviceState *dev, Error **errp)
806
+{
807
+ PCIHostState *pci = PCI_HOST_BRIDGE(dev);
808
+ DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(dev);
809
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
810
+ size_t i;
811
+
812
+ for (i = 0; i < ARRAY_SIZE(s->pci.irqs); i++) {
813
+ sysbus_init_irq(sbd, &s->pci.irqs[i]);
814
+ }
815
+
816
+ memory_region_init_io(&s->mmio,
817
+ OBJECT(s),
818
+ &designware_pci_mmio_ops,
819
+ s,
820
+ "pcie.reg", 4 * 1024);
821
+ sysbus_init_mmio(sbd, &s->mmio);
822
+
823
+ memory_region_init(&s->pci.io, OBJECT(s), "pcie-pio", 16);
824
+ memory_region_init(&s->pci.memory, OBJECT(s),
825
+ "pcie-bus-memory",
826
+ UINT64_MAX);
827
+
828
+ pci->bus = pci_register_root_bus(dev, "pcie",
829
+ designware_pcie_set_irq,
830
+ pci_swizzle_map_irq_fn,
831
+ s,
832
+ &s->pci.memory,
833
+ &s->pci.io,
834
+ 0, 4,
835
+ TYPE_PCIE_BUS);
836
+
837
+ memory_region_init(&s->pci.address_space_root,
838
+ OBJECT(s),
839
+ "pcie-bus-address-space-root",
840
+ UINT64_MAX);
841
+ memory_region_add_subregion(&s->pci.address_space_root,
842
+ 0x0, &s->pci.memory);
843
+ address_space_init(&s->pci.address_space,
844
+ &s->pci.address_space_root,
845
+ "pcie-bus-address-space");
846
+ pci_setup_iommu(pci->bus, designware_pcie_host_set_iommu, s);
847
+
848
+ qdev_set_parent_bus(DEVICE(&s->root), BUS(pci->bus));
849
+ qdev_init_nofail(DEVICE(&s->root));
850
+}
851
+
852
+static const VMStateDescription vmstate_designware_pcie_host = {
853
+ .name = "designware-pcie-host",
854
+ .version_id = 1,
855
+ .minimum_version_id = 1,
856
+ .fields = (VMStateField[]) {
857
+ VMSTATE_STRUCT(root,
858
+ DesignwarePCIEHost,
859
+ 1,
860
+ vmstate_designware_pcie_root,
861
+ DesignwarePCIERoot),
862
+ VMSTATE_END_OF_LIST()
863
+ }
864
+};
865
+
866
+static void designware_pcie_host_class_init(ObjectClass *klass, void *data)
867
+{
868
+ DeviceClass *dc = DEVICE_CLASS(klass);
869
+ PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
870
+
871
+ hc->root_bus_path = designware_pcie_host_root_bus_path;
872
+ dc->realize = designware_pcie_host_realize;
873
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
874
+ dc->fw_name = "pci";
875
+ dc->vmsd = &vmstate_designware_pcie_host;
876
+}
877
+
878
+static void designware_pcie_host_init(Object *obj)
879
+{
880
+ DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(obj);
881
+ DesignwarePCIERoot *root = &s->root;
882
+
883
+ object_initialize(root, sizeof(*root), TYPE_DESIGNWARE_PCIE_ROOT);
884
+ object_property_add_child(obj, "root", OBJECT(root), NULL);
885
+ qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
886
+ qdev_prop_set_bit(DEVICE(root), "multifunction", false);
887
+}
888
+
889
+static const TypeInfo designware_pcie_root_info = {
890
+ .name = TYPE_DESIGNWARE_PCIE_ROOT,
891
+ .parent = TYPE_PCI_BRIDGE,
892
+ .instance_size = sizeof(DesignwarePCIERoot),
893
+ .class_init = designware_pcie_root_class_init,
894
+ .interfaces = (InterfaceInfo[]) {
895
+ { INTERFACE_PCIE_DEVICE },
896
+ { }
897
+ },
898
+};
899
+
900
+static const TypeInfo designware_pcie_host_info = {
901
+ .name = TYPE_DESIGNWARE_PCIE_HOST,
902
+ .parent = TYPE_PCI_HOST_BRIDGE,
903
+ .instance_size = sizeof(DesignwarePCIEHost),
904
+ .instance_init = designware_pcie_host_init,
905
+ .class_init = designware_pcie_host_class_init,
906
+};
907
+
908
+static void designware_pcie_register(void)
909
+{
910
+ type_register_static(&designware_pcie_root_info);
911
+ type_register_static(&designware_pcie_host_info);
912
+}
913
+type_init(designware_pcie_register)
914
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
915
index XXXXXXX..XXXXXXX 100644
916
--- a/default-configs/arm-softmmu.mak
917
+++ b/default-configs/arm-softmmu.mak
918
@@ -XXX,XX +XXX,XX @@ CONFIG_GPIO_KEY=y
919
CONFIG_MSF2=y
920
CONFIG_FW_CFG_DMA=y
921
CONFIG_XILINX_AXI=y
922
+CONFIG_PCI_DESIGNWARE=y
923
--
924
2.16.2
925
926
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
The following interfaces are partially or fully emulated:
4
5
* up to 2 Cortex A9 cores (SMP works with PSCI)
6
* A7 MPCORE (identical to A15 MPCORE)
7
* 4 GPTs modules
8
* 7 GPIO controllers
9
* 2 IOMUXC controllers
10
* 1 CCM module
11
* 1 SVNS module
12
* 1 SRC module
13
* 1 GPCv2 controller
14
* 4 eCSPI controllers
15
* 4 I2C controllers
16
* 7 i.MX UART controllers
17
* 2 FlexCAN controllers
18
* 2 Ethernet controllers (FEC)
19
* 3 SD controllers (USDHC)
20
* 4 WDT modules
21
* 1 SDMA module
22
* 1 GPR module
23
* 2 USBMISC modules
24
* 2 ADC modules
25
* 1 PCIe controller
26
27
Tested to boot and work with upstream Linux (4.13+) guest.
28
29
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
31
[PMM: folded a couple of long lines]
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
---
34
hw/arm/Makefile.objs | 1 +
35
include/hw/arm/fsl-imx7.h | 222 +++++++++++++++
36
hw/arm/fsl-imx7.c | 582 ++++++++++++++++++++++++++++++++++++++++
37
default-configs/arm-softmmu.mak | 1 +
38
4 files changed, 806 insertions(+)
39
create mode 100644 include/hw/arm/fsl-imx7.h
40
create mode 100644 hw/arm/fsl-imx7.c
41
42
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/Makefile.objs
45
+++ b/hw/arm/Makefile.objs
46
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2.o
47
obj-$(CONFIG_MPS2) += mps2-tz.o
48
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
49
obj-$(CONFIG_IOTKIT) += iotkit.o
50
+obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o
51
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
52
new file mode 100644
53
index XXXXXXX..XXXXXXX
54
--- /dev/null
55
+++ b/include/hw/arm/fsl-imx7.h
56
@@ -XXX,XX +XXX,XX @@
57
+/*
58
+ * Copyright (c) 2018, Impinj, Inc.
59
+ *
60
+ * i.MX7 SoC definitions
61
+ *
62
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
63
+ *
64
+ * This program is free software; you can redistribute it and/or modify
65
+ * it under the terms of the GNU General Public License as published by
66
+ * the Free Software Foundation; either version 2 of the License, or
67
+ * (at your option) any later version.
68
+ *
69
+ * This program is distributed in the hope that it will be useful,
70
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
71
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72
+ * GNU General Public License for more details.
73
+ */
74
+
75
+#ifndef FSL_IMX7_H
76
+#define FSL_IMX7_H
77
+
78
+#include "hw/arm/arm.h"
79
+#include "hw/cpu/a15mpcore.h"
80
+#include "hw/intc/imx_gpcv2.h"
81
+#include "hw/misc/imx7_ccm.h"
82
+#include "hw/misc/imx7_snvs.h"
83
+#include "hw/misc/imx7_gpr.h"
84
+#include "hw/misc/imx6_src.h"
85
+#include "hw/misc/imx2_wdt.h"
86
+#include "hw/gpio/imx_gpio.h"
87
+#include "hw/char/imx_serial.h"
88
+#include "hw/timer/imx_gpt.h"
89
+#include "hw/timer/imx_epit.h"
90
+#include "hw/i2c/imx_i2c.h"
91
+#include "hw/gpio/imx_gpio.h"
92
+#include "hw/sd/sdhci.h"
93
+#include "hw/ssi/imx_spi.h"
94
+#include "hw/net/imx_fec.h"
95
+#include "hw/pci-host/designware.h"
96
+#include "hw/usb/chipidea.h"
97
+#include "exec/memory.h"
98
+#include "cpu.h"
99
+
100
+#define TYPE_FSL_IMX7 "fsl,imx7"
101
+#define FSL_IMX7(obj) OBJECT_CHECK(FslIMX7State, (obj), TYPE_FSL_IMX7)
102
+
103
+enum FslIMX7Configuration {
104
+ FSL_IMX7_NUM_CPUS = 2,
105
+ FSL_IMX7_NUM_UARTS = 7,
106
+ FSL_IMX7_NUM_ETHS = 2,
107
+ FSL_IMX7_ETH_NUM_TX_RINGS = 3,
108
+ FSL_IMX7_NUM_USDHCS = 3,
109
+ FSL_IMX7_NUM_WDTS = 4,
110
+ FSL_IMX7_NUM_GPTS = 4,
111
+ FSL_IMX7_NUM_IOMUXCS = 2,
112
+ FSL_IMX7_NUM_GPIOS = 7,
113
+ FSL_IMX7_NUM_I2CS = 4,
114
+ FSL_IMX7_NUM_ECSPIS = 4,
115
+ FSL_IMX7_NUM_USBS = 3,
116
+ FSL_IMX7_NUM_ADCS = 2,
117
+};
118
+
119
+typedef struct FslIMX7State {
120
+ /*< private >*/
121
+ DeviceState parent_obj;
122
+
123
+ /*< public >*/
124
+ ARMCPU cpu[FSL_IMX7_NUM_CPUS];
125
+ A15MPPrivState a7mpcore;
126
+ IMXGPTState gpt[FSL_IMX7_NUM_GPTS];
127
+ IMXGPIOState gpio[FSL_IMX7_NUM_GPIOS];
128
+ IMX7CCMState ccm;
129
+ IMX7AnalogState analog;
130
+ IMX7SNVSState snvs;
131
+ IMXGPCv2State gpcv2;
132
+ IMXSPIState spi[FSL_IMX7_NUM_ECSPIS];
133
+ IMXI2CState i2c[FSL_IMX7_NUM_I2CS];
134
+ IMXSerialState uart[FSL_IMX7_NUM_UARTS];
135
+ IMXFECState eth[FSL_IMX7_NUM_ETHS];
136
+ SDHCIState usdhc[FSL_IMX7_NUM_USDHCS];
137
+ IMX2WdtState wdt[FSL_IMX7_NUM_WDTS];
138
+ IMX7GPRState gpr;
139
+ ChipideaState usb[FSL_IMX7_NUM_USBS];
140
+ DesignwarePCIEHost pcie;
141
+} FslIMX7State;
142
+
143
+enum FslIMX7MemoryMap {
144
+ FSL_IMX7_MMDC_ADDR = 0x80000000,
145
+ FSL_IMX7_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL,
146
+
147
+ FSL_IMX7_GPIO1_ADDR = 0x30200000,
148
+ FSL_IMX7_GPIO2_ADDR = 0x30210000,
149
+ FSL_IMX7_GPIO3_ADDR = 0x30220000,
150
+ FSL_IMX7_GPIO4_ADDR = 0x30230000,
151
+ FSL_IMX7_GPIO5_ADDR = 0x30240000,
152
+ FSL_IMX7_GPIO6_ADDR = 0x30250000,
153
+ FSL_IMX7_GPIO7_ADDR = 0x30260000,
154
+
155
+ FSL_IMX7_IOMUXC_LPSR_GPR_ADDR = 0x30270000,
156
+
157
+ FSL_IMX7_WDOG1_ADDR = 0x30280000,
158
+ FSL_IMX7_WDOG2_ADDR = 0x30290000,
159
+ FSL_IMX7_WDOG3_ADDR = 0x302A0000,
160
+ FSL_IMX7_WDOG4_ADDR = 0x302B0000,
161
+
162
+ FSL_IMX7_IOMUXC_LPSR_ADDR = 0x302C0000,
163
+
164
+ FSL_IMX7_GPT1_ADDR = 0x302D0000,
165
+ FSL_IMX7_GPT2_ADDR = 0x302E0000,
166
+ FSL_IMX7_GPT3_ADDR = 0x302F0000,
167
+ FSL_IMX7_GPT4_ADDR = 0x30300000,
168
+
169
+ FSL_IMX7_IOMUXC_ADDR = 0x30330000,
170
+ FSL_IMX7_IOMUXC_GPR_ADDR = 0x30340000,
171
+ FSL_IMX7_IOMUXCn_SIZE = 0x1000,
172
+
173
+ FSL_IMX7_ANALOG_ADDR = 0x30360000,
174
+ FSL_IMX7_SNVS_ADDR = 0x30370000,
175
+ FSL_IMX7_CCM_ADDR = 0x30380000,
176
+
177
+ FSL_IMX7_SRC_ADDR = 0x30390000,
178
+ FSL_IMX7_SRC_SIZE = 0x1000,
179
+
180
+ FSL_IMX7_ADC1_ADDR = 0x30610000,
181
+ FSL_IMX7_ADC2_ADDR = 0x30620000,
182
+ FSL_IMX7_ADCn_SIZE = 0x1000,
183
+
184
+ FSL_IMX7_GPC_ADDR = 0x303A0000,
185
+
186
+ FSL_IMX7_I2C1_ADDR = 0x30A20000,
187
+ FSL_IMX7_I2C2_ADDR = 0x30A30000,
188
+ FSL_IMX7_I2C3_ADDR = 0x30A40000,
189
+ FSL_IMX7_I2C4_ADDR = 0x30A50000,
190
+
191
+ FSL_IMX7_ECSPI1_ADDR = 0x30820000,
192
+ FSL_IMX7_ECSPI2_ADDR = 0x30830000,
193
+ FSL_IMX7_ECSPI3_ADDR = 0x30840000,
194
+ FSL_IMX7_ECSPI4_ADDR = 0x30630000,
195
+
196
+ FSL_IMX7_LCDIF_ADDR = 0x30730000,
197
+ FSL_IMX7_LCDIF_SIZE = 0x1000,
198
+
199
+ FSL_IMX7_UART1_ADDR = 0x30860000,
200
+ /*
201
+ * Some versions of the reference manual claim that UART2 is @
202
+ * 0x30870000, but experiments with HW + DT files in upstream
203
+ * Linux kernel show that not to be true and that block is
204
+ * acutally located @ 0x30890000
205
+ */
206
+ FSL_IMX7_UART2_ADDR = 0x30890000,
207
+ FSL_IMX7_UART3_ADDR = 0x30880000,
208
+ FSL_IMX7_UART4_ADDR = 0x30A60000,
209
+ FSL_IMX7_UART5_ADDR = 0x30A70000,
210
+ FSL_IMX7_UART6_ADDR = 0x30A80000,
211
+ FSL_IMX7_UART7_ADDR = 0x30A90000,
212
+
213
+ FSL_IMX7_ENET1_ADDR = 0x30BE0000,
214
+ FSL_IMX7_ENET2_ADDR = 0x30BF0000,
215
+
216
+ FSL_IMX7_USB1_ADDR = 0x30B10000,
217
+ FSL_IMX7_USBMISC1_ADDR = 0x30B10200,
218
+ FSL_IMX7_USB2_ADDR = 0x30B20000,
219
+ FSL_IMX7_USBMISC2_ADDR = 0x30B20200,
220
+ FSL_IMX7_USB3_ADDR = 0x30B30000,
221
+ FSL_IMX7_USBMISC3_ADDR = 0x30B30200,
222
+ FSL_IMX7_USBMISCn_SIZE = 0x200,
223
+
224
+ FSL_IMX7_USDHC1_ADDR = 0x30B40000,
225
+ FSL_IMX7_USDHC2_ADDR = 0x30B50000,
226
+ FSL_IMX7_USDHC3_ADDR = 0x30B60000,
227
+
228
+ FSL_IMX7_SDMA_ADDR = 0x30BD0000,
229
+ FSL_IMX7_SDMA_SIZE = 0x1000,
230
+
231
+ FSL_IMX7_A7MPCORE_ADDR = 0x31000000,
232
+ FSL_IMX7_A7MPCORE_DAP_ADDR = 0x30000000,
233
+
234
+ FSL_IMX7_PCIE_REG_ADDR = 0x33800000,
235
+ FSL_IMX7_PCIE_REG_SIZE = 16 * 1024,
236
+
237
+ FSL_IMX7_GPR_ADDR = 0x30340000,
238
+};
239
+
240
+enum FslIMX7IRQs {
241
+ FSL_IMX7_USDHC1_IRQ = 22,
242
+ FSL_IMX7_USDHC2_IRQ = 23,
243
+ FSL_IMX7_USDHC3_IRQ = 24,
244
+
245
+ FSL_IMX7_UART1_IRQ = 26,
246
+ FSL_IMX7_UART2_IRQ = 27,
247
+ FSL_IMX7_UART3_IRQ = 28,
248
+ FSL_IMX7_UART4_IRQ = 29,
249
+ FSL_IMX7_UART5_IRQ = 30,
250
+ FSL_IMX7_UART6_IRQ = 16,
251
+
252
+ FSL_IMX7_ECSPI1_IRQ = 31,
253
+ FSL_IMX7_ECSPI2_IRQ = 32,
254
+ FSL_IMX7_ECSPI3_IRQ = 33,
255
+ FSL_IMX7_ECSPI4_IRQ = 34,
256
+
257
+ FSL_IMX7_I2C1_IRQ = 35,
258
+ FSL_IMX7_I2C2_IRQ = 36,
259
+ FSL_IMX7_I2C3_IRQ = 37,
260
+ FSL_IMX7_I2C4_IRQ = 38,
261
+
262
+ FSL_IMX7_USB1_IRQ = 43,
263
+ FSL_IMX7_USB2_IRQ = 42,
264
+ FSL_IMX7_USB3_IRQ = 40,
265
+
266
+ FSL_IMX7_PCI_INTA_IRQ = 122,
267
+ FSL_IMX7_PCI_INTB_IRQ = 123,
268
+ FSL_IMX7_PCI_INTC_IRQ = 124,
269
+ FSL_IMX7_PCI_INTD_IRQ = 125,
270
+
271
+ FSL_IMX7_UART7_IRQ = 126,
272
+
273
+#define FSL_IMX7_ENET_IRQ(i, n) ((n) + ((i) ? 100 : 118))
274
+
275
+ FSL_IMX7_MAX_IRQ = 128,
276
+};
277
+
278
+#endif /* FSL_IMX7_H */
279
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
280
new file mode 100644
281
index XXXXXXX..XXXXXXX
282
--- /dev/null
283
+++ b/hw/arm/fsl-imx7.c
284
@@ -XXX,XX +XXX,XX @@
285
+/*
286
+ * Copyright (c) 2018, Impinj, Inc.
287
+ *
288
+ * i.MX7 SoC definitions
289
+ *
290
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
291
+ *
292
+ * Based on hw/arm/fsl-imx6.c
293
+ *
294
+ * This program is free software; you can redistribute it and/or modify
295
+ * it under the terms of the GNU General Public License as published by
296
+ * the Free Software Foundation; either version 2 of the License, or
297
+ * (at your option) any later version.
298
+ *
299
+ * This program is distributed in the hope that it will be useful,
300
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
301
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
302
+ * GNU General Public License for more details.
303
+ */
304
+
305
+#include "qemu/osdep.h"
306
+#include "qapi/error.h"
307
+#include "qemu-common.h"
308
+#include "hw/arm/fsl-imx7.h"
309
+#include "hw/misc/unimp.h"
310
+#include "sysemu/sysemu.h"
311
+#include "qemu/error-report.h"
312
+
313
+#define NAME_SIZE 20
314
+
315
+static void fsl_imx7_init(Object *obj)
316
+{
317
+ BusState *sysbus = sysbus_get_default();
318
+ FslIMX7State *s = FSL_IMX7(obj);
319
+ char name[NAME_SIZE];
320
+ int i;
321
+
322
+ if (smp_cpus > FSL_IMX7_NUM_CPUS) {
323
+ error_report("%s: Only %d CPUs are supported (%d requested)",
324
+ TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus);
325
+ exit(1);
326
+ }
327
+
328
+ for (i = 0; i < smp_cpus; i++) {
329
+ object_initialize(&s->cpu[i], sizeof(s->cpu[i]),
330
+ ARM_CPU_TYPE_NAME("cortex-a7"));
331
+ snprintf(name, NAME_SIZE, "cpu%d", i);
332
+ object_property_add_child(obj, name, OBJECT(&s->cpu[i]),
333
+ &error_fatal);
334
+ }
335
+
336
+ /*
337
+ * A7MPCORE
338
+ */
339
+ object_initialize(&s->a7mpcore, sizeof(s->a7mpcore), TYPE_A15MPCORE_PRIV);
340
+ qdev_set_parent_bus(DEVICE(&s->a7mpcore), sysbus);
341
+ object_property_add_child(obj, "a7mpcore",
342
+ OBJECT(&s->a7mpcore), &error_fatal);
343
+
344
+ /*
345
+ * GPIOs 1 to 7
346
+ */
347
+ for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
348
+ object_initialize(&s->gpio[i], sizeof(s->gpio[i]),
349
+ TYPE_IMX_GPIO);
350
+ qdev_set_parent_bus(DEVICE(&s->gpio[i]), sysbus);
351
+ snprintf(name, NAME_SIZE, "gpio%d", i);
352
+ object_property_add_child(obj, name,
353
+ OBJECT(&s->gpio[i]), &error_fatal);
354
+ }
355
+
356
+ /*
357
+ * GPT1, 2, 3, 4
358
+ */
359
+ for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
360
+ object_initialize(&s->gpt[i], sizeof(s->gpt[i]), TYPE_IMX7_GPT);
361
+ qdev_set_parent_bus(DEVICE(&s->gpt[i]), sysbus);
362
+ snprintf(name, NAME_SIZE, "gpt%d", i);
363
+ object_property_add_child(obj, name, OBJECT(&s->gpt[i]),
364
+ &error_fatal);
365
+ }
366
+
367
+ /*
368
+ * CCM
369
+ */
370
+ object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX7_CCM);
371
+ qdev_set_parent_bus(DEVICE(&s->ccm), sysbus);
372
+ object_property_add_child(obj, "ccm", OBJECT(&s->ccm), &error_fatal);
373
+
374
+ /*
375
+ * Analog
376
+ */
377
+ object_initialize(&s->analog, sizeof(s->analog), TYPE_IMX7_ANALOG);
378
+ qdev_set_parent_bus(DEVICE(&s->analog), sysbus);
379
+ object_property_add_child(obj, "analog", OBJECT(&s->analog), &error_fatal);
380
+
381
+ /*
382
+ * GPCv2
383
+ */
384
+ object_initialize(&s->gpcv2, sizeof(s->gpcv2), TYPE_IMX_GPCV2);
385
+ qdev_set_parent_bus(DEVICE(&s->gpcv2), sysbus);
386
+ object_property_add_child(obj, "gpcv2", OBJECT(&s->gpcv2), &error_fatal);
387
+
388
+ for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
389
+ object_initialize(&s->spi[i], sizeof(s->spi[i]), TYPE_IMX_SPI);
390
+ qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
391
+ snprintf(name, NAME_SIZE, "spi%d", i + 1);
392
+ object_property_add_child(obj, name, OBJECT(&s->spi[i]), NULL);
393
+ }
394
+
395
+
396
+ for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
397
+ object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
398
+ qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
399
+ snprintf(name, NAME_SIZE, "i2c%d", i + 1);
400
+ object_property_add_child(obj, name, OBJECT(&s->i2c[i]), NULL);
401
+ }
402
+
403
+ /*
404
+ * UART
405
+ */
406
+ for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
407
+ object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
408
+ qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus);
409
+ snprintf(name, NAME_SIZE, "uart%d", i);
410
+ object_property_add_child(obj, name, OBJECT(&s->uart[i]),
411
+ &error_fatal);
412
+ }
413
+
414
+ /*
415
+ * Ethernet
416
+ */
417
+ for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
418
+ object_initialize(&s->eth[i], sizeof(s->eth[i]), TYPE_IMX_ENET);
419
+ qdev_set_parent_bus(DEVICE(&s->eth[i]), sysbus);
420
+ snprintf(name, NAME_SIZE, "eth%d", i);
421
+ object_property_add_child(obj, name, OBJECT(&s->eth[i]),
422
+ &error_fatal);
423
+ }
424
+
425
+ /*
426
+ * SDHCI
427
+ */
428
+ for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
429
+ object_initialize(&s->usdhc[i], sizeof(s->usdhc[i]),
430
+ TYPE_IMX_USDHC);
431
+ qdev_set_parent_bus(DEVICE(&s->usdhc[i]), sysbus);
432
+ snprintf(name, NAME_SIZE, "usdhc%d", i);
433
+ object_property_add_child(obj, name, OBJECT(&s->usdhc[i]),
434
+ &error_fatal);
435
+ }
436
+
437
+ /*
438
+ * SNVS
439
+ */
440
+ object_initialize(&s->snvs, sizeof(s->snvs), TYPE_IMX7_SNVS);
441
+ qdev_set_parent_bus(DEVICE(&s->snvs), sysbus);
442
+ object_property_add_child(obj, "snvs", OBJECT(&s->snvs), &error_fatal);
443
+
444
+ /*
445
+ * Watchdog
446
+ */
447
+ for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
448
+ object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_IMX2_WDT);
449
+ qdev_set_parent_bus(DEVICE(&s->wdt[i]), sysbus);
450
+ snprintf(name, NAME_SIZE, "wdt%d", i);
451
+ object_property_add_child(obj, name, OBJECT(&s->wdt[i]),
452
+ &error_fatal);
453
+ }
454
+
455
+ /*
456
+ * GPR
457
+ */
458
+ object_initialize(&s->gpr, sizeof(s->gpr), TYPE_IMX7_GPR);
459
+ qdev_set_parent_bus(DEVICE(&s->gpr), sysbus);
460
+ object_property_add_child(obj, "gpr", OBJECT(&s->gpr), &error_fatal);
461
+
462
+ object_initialize(&s->pcie, sizeof(s->pcie), TYPE_DESIGNWARE_PCIE_HOST);
463
+ qdev_set_parent_bus(DEVICE(&s->pcie), sysbus);
464
+ object_property_add_child(obj, "pcie", OBJECT(&s->pcie), &error_fatal);
465
+
466
+ for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
467
+ object_initialize(&s->usb[i],
468
+ sizeof(s->usb[i]), TYPE_CHIPIDEA);
469
+ qdev_set_parent_bus(DEVICE(&s->usb[i]), sysbus);
470
+ snprintf(name, NAME_SIZE, "usb%d", i);
471
+ object_property_add_child(obj, name,
472
+ OBJECT(&s->usb[i]), &error_fatal);
473
+ }
474
+}
475
+
476
+static void fsl_imx7_realize(DeviceState *dev, Error **errp)
477
+{
478
+ FslIMX7State *s = FSL_IMX7(dev);
479
+ Object *o;
480
+ int i;
481
+ qemu_irq irq;
482
+ char name[NAME_SIZE];
483
+
484
+ for (i = 0; i < smp_cpus; i++) {
485
+ o = OBJECT(&s->cpu[i]);
486
+
487
+ object_property_set_int(o, QEMU_PSCI_CONDUIT_SMC,
488
+ "psci-conduit", &error_abort);
489
+
490
+ /* On uniprocessor, the CBAR is set to 0 */
491
+ if (smp_cpus > 1) {
492
+ object_property_set_int(o, FSL_IMX7_A7MPCORE_ADDR,
493
+ "reset-cbar", &error_abort);
494
+ }
495
+
496
+ if (i) {
497
+ /* Secondary CPUs start in PSCI powered-down state */
498
+ object_property_set_bool(o, true,
499
+ "start-powered-off", &error_abort);
500
+ }
501
+
502
+ object_property_set_bool(o, true, "realized", &error_abort);
503
+ }
504
+
505
+ /*
506
+ * A7MPCORE
507
+ */
508
+ object_property_set_int(OBJECT(&s->a7mpcore), smp_cpus, "num-cpu",
509
+ &error_abort);
510
+ object_property_set_int(OBJECT(&s->a7mpcore),
511
+ FSL_IMX7_MAX_IRQ + GIC_INTERNAL,
512
+ "num-irq", &error_abort);
513
+
514
+ object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized",
515
+ &error_abort);
516
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX7_A7MPCORE_ADDR);
517
+
518
+ for (i = 0; i < smp_cpus; i++) {
519
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
520
+ DeviceState *d = DEVICE(qemu_get_cpu(i));
521
+
522
+ irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
523
+ sysbus_connect_irq(sbd, i, irq);
524
+ irq = qdev_get_gpio_in(d, ARM_CPU_FIQ);
525
+ sysbus_connect_irq(sbd, i + smp_cpus, irq);
526
+ }
527
+
528
+ /*
529
+ * A7MPCORE DAP
530
+ */
531
+ create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
532
+ 0x100000);
533
+
534
+ /*
535
+ * GPT1, 2, 3, 4
536
+ */
537
+ for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
538
+ static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
539
+ FSL_IMX7_GPT1_ADDR,
540
+ FSL_IMX7_GPT2_ADDR,
541
+ FSL_IMX7_GPT3_ADDR,
542
+ FSL_IMX7_GPT4_ADDR,
543
+ };
544
+
545
+ s->gpt[i].ccm = IMX_CCM(&s->ccm);
546
+ object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized",
547
+ &error_abort);
548
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, FSL_IMX7_GPTn_ADDR[i]);
549
+ }
550
+
551
+ for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
552
+ static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
553
+ FSL_IMX7_GPIO1_ADDR,
554
+ FSL_IMX7_GPIO2_ADDR,
555
+ FSL_IMX7_GPIO3_ADDR,
556
+ FSL_IMX7_GPIO4_ADDR,
557
+ FSL_IMX7_GPIO5_ADDR,
558
+ FSL_IMX7_GPIO6_ADDR,
559
+ FSL_IMX7_GPIO7_ADDR,
560
+ };
561
+
562
+ object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized",
563
+ &error_abort);
564
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, FSL_IMX7_GPIOn_ADDR[i]);
565
+ }
566
+
567
+ /*
568
+ * IOMUXC and IOMUXC_LPSR
569
+ */
570
+ for (i = 0; i < FSL_IMX7_NUM_IOMUXCS; i++) {
571
+ static const hwaddr FSL_IMX7_IOMUXCn_ADDR[FSL_IMX7_NUM_IOMUXCS] = {
572
+ FSL_IMX7_IOMUXC_ADDR,
573
+ FSL_IMX7_IOMUXC_LPSR_ADDR,
574
+ };
575
+
576
+ snprintf(name, NAME_SIZE, "iomuxc%d", i);
577
+ create_unimplemented_device(name, FSL_IMX7_IOMUXCn_ADDR[i],
578
+ FSL_IMX7_IOMUXCn_SIZE);
579
+ }
580
+
581
+ /*
582
+ * CCM
583
+ */
584
+ object_property_set_bool(OBJECT(&s->ccm), true, "realized", &error_abort);
585
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX7_CCM_ADDR);
586
+
587
+ /*
588
+ * Analog
589
+ */
590
+ object_property_set_bool(OBJECT(&s->analog), true, "realized",
591
+ &error_abort);
592
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->analog), 0, FSL_IMX7_ANALOG_ADDR);
593
+
594
+ /*
595
+ * GPCv2
596
+ */
597
+ object_property_set_bool(OBJECT(&s->gpcv2), true,
598
+ "realized", &error_abort);
599
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX7_GPC_ADDR);
600
+
601
+ /* Initialize all ECSPI */
602
+ for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
603
+ static const hwaddr FSL_IMX7_SPIn_ADDR[FSL_IMX7_NUM_ECSPIS] = {
604
+ FSL_IMX7_ECSPI1_ADDR,
605
+ FSL_IMX7_ECSPI2_ADDR,
606
+ FSL_IMX7_ECSPI3_ADDR,
607
+ FSL_IMX7_ECSPI4_ADDR,
608
+ };
609
+
610
+ static const hwaddr FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
611
+ FSL_IMX7_ECSPI1_IRQ,
612
+ FSL_IMX7_ECSPI2_IRQ,
613
+ FSL_IMX7_ECSPI3_IRQ,
614
+ FSL_IMX7_ECSPI4_IRQ,
615
+ };
616
+
617
+ /* Initialize the SPI */
618
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
619
+ &error_abort);
620
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
621
+ FSL_IMX7_SPIn_ADDR[i]);
622
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
623
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
624
+ FSL_IMX7_SPIn_IRQ[i]));
625
+ }
626
+
627
+ for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
628
+ static const hwaddr FSL_IMX7_I2Cn_ADDR[FSL_IMX7_NUM_I2CS] = {
629
+ FSL_IMX7_I2C1_ADDR,
630
+ FSL_IMX7_I2C2_ADDR,
631
+ FSL_IMX7_I2C3_ADDR,
632
+ FSL_IMX7_I2C4_ADDR,
633
+ };
634
+
635
+ static const hwaddr FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
636
+ FSL_IMX7_I2C1_IRQ,
637
+ FSL_IMX7_I2C2_IRQ,
638
+ FSL_IMX7_I2C3_IRQ,
639
+ FSL_IMX7_I2C4_IRQ,
640
+ };
641
+
642
+ object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized",
643
+ &error_abort);
644
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX7_I2Cn_ADDR[i]);
645
+
646
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
647
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
648
+ FSL_IMX7_I2Cn_IRQ[i]));
649
+ }
650
+
651
+ /*
652
+ * UART
653
+ */
654
+ for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
655
+ static const hwaddr FSL_IMX7_UARTn_ADDR[FSL_IMX7_NUM_UARTS] = {
656
+ FSL_IMX7_UART1_ADDR,
657
+ FSL_IMX7_UART2_ADDR,
658
+ FSL_IMX7_UART3_ADDR,
659
+ FSL_IMX7_UART4_ADDR,
660
+ FSL_IMX7_UART5_ADDR,
661
+ FSL_IMX7_UART6_ADDR,
662
+ FSL_IMX7_UART7_ADDR,
663
+ };
664
+
665
+ static const int FSL_IMX7_UARTn_IRQ[FSL_IMX7_NUM_UARTS] = {
666
+ FSL_IMX7_UART1_IRQ,
667
+ FSL_IMX7_UART2_IRQ,
668
+ FSL_IMX7_UART3_IRQ,
669
+ FSL_IMX7_UART4_IRQ,
670
+ FSL_IMX7_UART5_IRQ,
671
+ FSL_IMX7_UART6_IRQ,
672
+ FSL_IMX7_UART7_IRQ,
673
+ };
674
+
675
+
676
+ if (i < MAX_SERIAL_PORTS) {
677
+ qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hds[i]);
678
+ }
679
+
680
+ object_property_set_bool(OBJECT(&s->uart[i]), true, "realized",
681
+ &error_abort);
682
+
683
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, FSL_IMX7_UARTn_ADDR[i]);
684
+
685
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_UARTn_IRQ[i]);
686
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, irq);
687
+ }
688
+
689
+ /*
690
+ * Ethernet
691
+ */
692
+ for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
693
+ static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = {
694
+ FSL_IMX7_ENET1_ADDR,
695
+ FSL_IMX7_ENET2_ADDR,
696
+ };
697
+
698
+ object_property_set_uint(OBJECT(&s->eth[i]), FSL_IMX7_ETH_NUM_TX_RINGS,
699
+ "tx-ring-num", &error_abort);
700
+ qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
701
+ object_property_set_bool(OBJECT(&s->eth[i]), true, "realized",
702
+ &error_abort);
703
+
704
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0, FSL_IMX7_ENETn_ADDR[i]);
705
+
706
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 0));
707
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0, irq);
708
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 3));
709
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1, irq);
710
+ }
711
+
712
+ /*
713
+ * USDHC
714
+ */
715
+ for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
716
+ static const hwaddr FSL_IMX7_USDHCn_ADDR[FSL_IMX7_NUM_USDHCS] = {
717
+ FSL_IMX7_USDHC1_ADDR,
718
+ FSL_IMX7_USDHC2_ADDR,
719
+ FSL_IMX7_USDHC3_ADDR,
720
+ };
721
+
722
+ static const int FSL_IMX7_USDHCn_IRQ[FSL_IMX7_NUM_USDHCS] = {
723
+ FSL_IMX7_USDHC1_IRQ,
724
+ FSL_IMX7_USDHC2_IRQ,
725
+ FSL_IMX7_USDHC3_IRQ,
726
+ };
727
+
728
+ object_property_set_bool(OBJECT(&s->usdhc[i]), true, "realized",
729
+ &error_abort);
730
+
731
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
732
+ FSL_IMX7_USDHCn_ADDR[i]);
733
+
734
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USDHCn_IRQ[i]);
735
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, irq);
736
+ }
737
+
738
+ /*
739
+ * SNVS
740
+ */
741
+ object_property_set_bool(OBJECT(&s->snvs), true, "realized", &error_abort);
742
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_ADDR);
743
+
744
+ /*
745
+ * SRC
746
+ */
747
+ create_unimplemented_device("sdma", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
748
+
749
+ /*
750
+ * Watchdog
751
+ */
752
+ for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
753
+ static const hwaddr FSL_IMX7_WDOGn_ADDR[FSL_IMX7_NUM_WDTS] = {
754
+ FSL_IMX7_WDOG1_ADDR,
755
+ FSL_IMX7_WDOG2_ADDR,
756
+ FSL_IMX7_WDOG3_ADDR,
757
+ FSL_IMX7_WDOG4_ADDR,
758
+ };
759
+
760
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
761
+ &error_abort);
762
+
763
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX7_WDOGn_ADDR[i]);
764
+ }
765
+
766
+ /*
767
+ * SDMA
768
+ */
769
+ create_unimplemented_device("sdma", FSL_IMX7_SDMA_ADDR, FSL_IMX7_SDMA_SIZE);
770
+
771
+
772
+ object_property_set_bool(OBJECT(&s->gpr), true, "realized",
773
+ &error_abort);
774
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_GPR_ADDR);
775
+
776
+ object_property_set_bool(OBJECT(&s->pcie), true,
777
+ "realized", &error_abort);
778
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
779
+
780
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ);
781
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
782
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ);
783
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
784
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ);
785
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
786
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_IRQ);
787
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
788
+
789
+
790
+ for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
791
+ static const hwaddr FSL_IMX7_USBMISCn_ADDR[FSL_IMX7_NUM_USBS] = {
792
+ FSL_IMX7_USBMISC1_ADDR,
793
+ FSL_IMX7_USBMISC2_ADDR,
794
+ FSL_IMX7_USBMISC3_ADDR,
795
+ };
796
+
797
+ static const hwaddr FSL_IMX7_USBn_ADDR[FSL_IMX7_NUM_USBS] = {
798
+ FSL_IMX7_USB1_ADDR,
799
+ FSL_IMX7_USB2_ADDR,
800
+ FSL_IMX7_USB3_ADDR,
801
+ };
802
+
803
+ static const hwaddr FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
804
+ FSL_IMX7_USB1_IRQ,
805
+ FSL_IMX7_USB2_IRQ,
806
+ FSL_IMX7_USB3_IRQ,
807
+ };
808
+
809
+ object_property_set_bool(OBJECT(&s->usb[i]), true, "realized",
810
+ &error_abort);
811
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
812
+ FSL_IMX7_USBn_ADDR[i]);
813
+
814
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USBn_IRQ[i]);
815
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0, irq);
816
+
817
+ snprintf(name, NAME_SIZE, "usbmisc%d", i);
818
+ create_unimplemented_device(name, FSL_IMX7_USBMISCn_ADDR[i],
819
+ FSL_IMX7_USBMISCn_SIZE);
820
+ }
821
+
822
+ /*
823
+ * ADCs
824
+ */
825
+ for (i = 0; i < FSL_IMX7_NUM_ADCS; i++) {
826
+ static const hwaddr FSL_IMX7_ADCn_ADDR[FSL_IMX7_NUM_ADCS] = {
827
+ FSL_IMX7_ADC1_ADDR,
828
+ FSL_IMX7_ADC2_ADDR,
829
+ };
830
+
831
+ snprintf(name, NAME_SIZE, "adc%d", i);
832
+ create_unimplemented_device(name, FSL_IMX7_ADCn_ADDR[i],
833
+ FSL_IMX7_ADCn_SIZE);
834
+ }
835
+
836
+ /*
837
+ * LCD
838
+ */
839
+ create_unimplemented_device("lcdif", FSL_IMX7_LCDIF_ADDR,
840
+ FSL_IMX7_LCDIF_SIZE);
841
+}
842
+
843
+static void fsl_imx7_class_init(ObjectClass *oc, void *data)
844
+{
845
+ DeviceClass *dc = DEVICE_CLASS(oc);
846
+
847
+ dc->realize = fsl_imx7_realize;
848
+
849
+ /* Reason: Uses serial_hds and nd_table in realize() directly */
850
+ dc->user_creatable = false;
851
+ dc->desc = "i.MX7 SOC";
852
+}
853
+
854
+static const TypeInfo fsl_imx7_type_info = {
855
+ .name = TYPE_FSL_IMX7,
856
+ .parent = TYPE_DEVICE,
857
+ .instance_size = sizeof(FslIMX7State),
858
+ .instance_init = fsl_imx7_init,
859
+ .class_init = fsl_imx7_class_init,
860
+};
861
+
862
+static void fsl_imx7_register_types(void)
863
+{
864
+ type_register_static(&fsl_imx7_type_info);
865
+}
866
+type_init(fsl_imx7_register_types)
867
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
868
index XXXXXXX..XXXXXXX 100644
869
--- a/default-configs/arm-softmmu.mak
870
+++ b/default-configs/arm-softmmu.mak
871
@@ -XXX,XX +XXX,XX @@ CONFIG_ALLWINNER_A10=y
872
CONFIG_FSL_IMX6=y
873
CONFIG_FSL_IMX31=y
874
CONFIG_FSL_IMX25=y
875
+CONFIG_FSL_IMX7=y
876
877
CONFIG_IMX_I2C=y
878
879
--
880
2.16.2
881
882
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The EXTRA record allows for additional space to be allocated
3
These files got missed when populating tcg/.
4
beyon what is currently reserved. Add code to emit and read
4
Because they are included with "", no change to the users required.
5
this record type.
6
7
Nothing uses extra space yet.
8
5
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180303143823.27055-5-richard.henderson@linaro.org
7
Reviewed-by: Fabiano Rosas <farosas@suse.de>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20230504110412.1892411-2-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
linux-user/signal.c | 74 +++++++++++++++++++++++++++++++++++++++++++++--------
12
target/arm/{ => tcg}/arm_ldst.h | 0
16
1 file changed, 63 insertions(+), 11 deletions(-)
13
target/arm/{ => tcg}/sve_ldst_internal.h | 0
14
target/arm/{ => tcg}/translate-a32.h | 0
15
3 files changed, 0 insertions(+), 0 deletions(-)
16
rename target/arm/{ => tcg}/arm_ldst.h (100%)
17
rename target/arm/{ => tcg}/sve_ldst_internal.h (100%)
18
rename target/arm/{ => tcg}/translate-a32.h (100%)
17
19
18
diff --git a/linux-user/signal.c b/linux-user/signal.c
20
diff --git a/target/arm/arm_ldst.h b/target/arm/tcg/arm_ldst.h
19
index XXXXXXX..XXXXXXX 100644
21
similarity index 100%
20
--- a/linux-user/signal.c
22
rename from target/arm/arm_ldst.h
21
+++ b/linux-user/signal.c
23
rename to target/arm/tcg/arm_ldst.h
22
@@ -XXX,XX +XXX,XX @@ struct target_fpsimd_context {
24
diff --git a/target/arm/sve_ldst_internal.h b/target/arm/tcg/sve_ldst_internal.h
23
uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
25
similarity index 100%
24
};
26
rename from target/arm/sve_ldst_internal.h
25
27
rename to target/arm/tcg/sve_ldst_internal.h
26
+#define TARGET_EXTRA_MAGIC 0x45585401
28
diff --git a/target/arm/translate-a32.h b/target/arm/tcg/translate-a32.h
27
+
29
similarity index 100%
28
+struct target_extra_context {
30
rename from target/arm/translate-a32.h
29
+ struct target_aarch64_ctx head;
31
rename to target/arm/tcg/translate-a32.h
30
+ uint64_t datap; /* 16-byte aligned pointer to extra space cast to __u64 */
31
+ uint32_t size; /* size in bytes of the extra space */
32
+ uint32_t reserved[3];
33
+};
34
+
35
struct target_rt_sigframe {
36
struct target_siginfo info;
37
struct target_ucontext uc;
38
@@ -XXX,XX +XXX,XX @@ static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
39
}
40
}
41
42
+static void target_setup_extra_record(struct target_extra_context *extra,
43
+ uint64_t datap, uint32_t extra_size)
44
+{
45
+ __put_user(TARGET_EXTRA_MAGIC, &extra->head.magic);
46
+ __put_user(sizeof(struct target_extra_context), &extra->head.size);
47
+ __put_user(datap, &extra->datap);
48
+ __put_user(extra_size, &extra->size);
49
+}
50
+
51
static void target_setup_end_record(struct target_aarch64_ctx *end)
52
{
53
__put_user(0, &end->magic);
54
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
55
static int target_restore_sigframe(CPUARMState *env,
56
struct target_rt_sigframe *sf)
57
{
58
- struct target_aarch64_ctx *ctx;
59
+ struct target_aarch64_ctx *ctx, *extra = NULL;
60
struct target_fpsimd_context *fpsimd = NULL;
61
+ uint64_t extra_datap = 0;
62
+ bool used_extra = false;
63
+ bool err = false;
64
65
target_restore_general_frame(env, sf);
66
67
ctx = (struct target_aarch64_ctx *)sf->uc.tuc_mcontext.__reserved;
68
while (ctx) {
69
- uint32_t magic, size;
70
+ uint32_t magic, size, extra_size;
71
72
__get_user(magic, &ctx->magic);
73
__get_user(size, &ctx->size);
74
switch (magic) {
75
case 0:
76
if (size != 0) {
77
- return 1;
78
+ err = true;
79
+ goto exit;
80
+ }
81
+ if (used_extra) {
82
+ ctx = NULL;
83
+ } else {
84
+ ctx = extra;
85
+ used_extra = true;
86
}
87
- ctx = NULL;
88
continue;
89
90
case TARGET_FPSIMD_MAGIC:
91
if (fpsimd || size != sizeof(struct target_fpsimd_context)) {
92
- return 1;
93
+ err = true;
94
+ goto exit;
95
}
96
fpsimd = (struct target_fpsimd_context *)ctx;
97
break;
98
99
+ case TARGET_EXTRA_MAGIC:
100
+ if (extra || size != sizeof(struct target_extra_context)) {
101
+ err = true;
102
+ goto exit;
103
+ }
104
+ __get_user(extra_datap,
105
+ &((struct target_extra_context *)ctx)->datap);
106
+ __get_user(extra_size,
107
+ &((struct target_extra_context *)ctx)->size);
108
+ extra = lock_user(VERIFY_READ, extra_datap, extra_size, 0);
109
+ break;
110
+
111
default:
112
/* Unknown record -- we certainly didn't generate it.
113
* Did we in fact get out of sync?
114
*/
115
- return 1;
116
+ err = true;
117
+ goto exit;
118
}
119
ctx = (void *)ctx + size;
120
}
121
122
/* Require FPSIMD always. */
123
- if (!fpsimd) {
124
- return 1;
125
+ if (fpsimd) {
126
+ target_restore_fpsimd_record(env, fpsimd);
127
+ } else {
128
+ err = true;
129
}
130
- target_restore_fpsimd_record(env, fpsimd);
131
132
- return 0;
133
+ exit:
134
+ unlock_user(extra, extra_datap, 0);
135
+ return err;
136
}
137
138
static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
139
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
140
CPUARMState *env)
141
{
142
int size = offsetof(struct target_rt_sigframe, uc.tuc_mcontext.__reserved);
143
- int fpsimd_ofs, end1_ofs, fr_ofs;
144
+ int fpsimd_ofs, end1_ofs, fr_ofs, end2_ofs = 0;
145
+ int extra_ofs = 0, extra_base = 0, extra_size = 0;
146
struct target_rt_sigframe *frame;
147
struct target_rt_frame_record *fr;
148
abi_ulong frame_addr, return_addr;
149
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
150
151
target_setup_general_frame(frame, env, set);
152
target_setup_fpsimd_record((void *)frame + fpsimd_ofs, env);
153
+ if (extra_ofs) {
154
+ target_setup_extra_record((void *)frame + extra_ofs,
155
+ frame_addr + extra_base, extra_size);
156
+ }
157
target_setup_end_record((void *)frame + end1_ofs);
158
+ if (end2_ofs) {
159
+ target_setup_end_record((void *)frame + end2_ofs);
160
+ }
161
162
/* Set up the stack frame for unwinding. */
163
fr = (void *)frame + fr_ofs;
164
--
32
--
165
2.16.2
33
2.34.1
166
34
167
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
As an implementation choice, widening VL has zeroed the
3
While we cannot move the main "helper.h" out of target/arm/,
4
previously inaccessible portion of the sve registers.
4
due to usage by generic code, we can move the sub-includes.
5
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Acked-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Fabiano Rosas <farosas@suse.de>
9
Message-id: 20180303143823.27055-2-richard.henderson@linaro.org
8
Message-id: 20230504110412.1892411-3-richard.henderson@linaro.org
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
linux-user/aarch64/target_syscall.h | 3 +++
12
target/arm/helper.h | 8 ++++----
13
target/arm/cpu.h | 1 +
13
target/arm/{ => tcg}/helper-a64.h | 0
14
linux-user/syscall.c | 27 ++++++++++++++++++++++++
14
target/arm/{ => tcg}/helper-mve.h | 0
15
target/arm/cpu64.c | 41 +++++++++++++++++++++++++++++++++++++
15
target/arm/{ => tcg}/helper-sme.h | 0
16
4 files changed, 72 insertions(+)
16
target/arm/{ => tcg}/helper-sve.h | 0
17
5 files changed, 4 insertions(+), 4 deletions(-)
18
rename target/arm/{ => tcg}/helper-a64.h (100%)
19
rename target/arm/{ => tcg}/helper-mve.h (100%)
20
rename target/arm/{ => tcg}/helper-sme.h (100%)
21
rename target/arm/{ => tcg}/helper-sve.h (100%)
17
22
18
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
23
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/aarch64/target_syscall.h
25
--- a/target/arm/helper.h
21
+++ b/linux-user/aarch64/target_syscall.h
26
+++ b/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_uclamp_d, TCG_CALL_NO_RWG,
23
#define TARGET_MLOCKALL_MCL_CURRENT 1
28
void, ptr, ptr, ptr, ptr, i32)
24
#define TARGET_MLOCKALL_MCL_FUTURE 2
29
25
26
+#define TARGET_PR_SVE_SET_VL 50
27
+#define TARGET_PR_SVE_GET_VL 51
28
+
29
#endif /* AARCH64_TARGET_SYSCALL_H */
30
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.h
33
+++ b/target/arm/cpu.h
34
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
35
#ifdef TARGET_AARCH64
30
#ifdef TARGET_AARCH64
36
int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
31
-#include "helper-a64.h"
37
int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
32
-#include "helper-sve.h"
38
+void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
33
-#include "helper-sme.h"
34
+#include "tcg/helper-a64.h"
35
+#include "tcg/helper-sve.h"
36
+#include "tcg/helper-sme.h"
39
#endif
37
#endif
40
38
41
target_ulong do_arm_semihosting(CPUARMState *env);
39
-#include "helper-mve.h"
42
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
40
+#include "tcg/helper-mve.h"
43
index XXXXXXX..XXXXXXX 100644
41
diff --git a/target/arm/helper-a64.h b/target/arm/tcg/helper-a64.h
44
--- a/linux-user/syscall.c
42
similarity index 100%
45
+++ b/linux-user/syscall.c
43
rename from target/arm/helper-a64.h
46
@@ -XXX,XX +XXX,XX @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
44
rename to target/arm/tcg/helper-a64.h
47
break;
45
diff --git a/target/arm/helper-mve.h b/target/arm/tcg/helper-mve.h
48
}
46
similarity index 100%
49
#endif
47
rename from target/arm/helper-mve.h
50
+#ifdef TARGET_AARCH64
48
rename to target/arm/tcg/helper-mve.h
51
+ case TARGET_PR_SVE_SET_VL:
49
diff --git a/target/arm/helper-sme.h b/target/arm/tcg/helper-sme.h
52
+ /* We cannot support either PR_SVE_SET_VL_ONEXEC
50
similarity index 100%
53
+ or PR_SVE_VL_INHERIT. Therefore, anything above
51
rename from target/arm/helper-sme.h
54
+ ARM_MAX_VQ results in EINVAL. */
52
rename to target/arm/tcg/helper-sme.h
55
+ ret = -TARGET_EINVAL;
53
diff --git a/target/arm/helper-sve.h b/target/arm/tcg/helper-sve.h
56
+ if (arm_feature(cpu_env, ARM_FEATURE_SVE)
54
similarity index 100%
57
+ && arg2 >= 0 && arg2 <= ARM_MAX_VQ * 16 && !(arg2 & 15)) {
55
rename from target/arm/helper-sve.h
58
+ CPUARMState *env = cpu_env;
56
rename to target/arm/tcg/helper-sve.h
59
+ int old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
60
+ int vq = MAX(arg2 / 16, 1);
61
+
62
+ if (vq < old_vq) {
63
+ aarch64_sve_narrow_vq(env, vq);
64
+ }
65
+ env->vfp.zcr_el[1] = vq - 1;
66
+ ret = vq * 16;
67
+ }
68
+ break;
69
+ case TARGET_PR_SVE_GET_VL:
70
+ ret = -TARGET_EINVAL;
71
+ if (arm_feature(cpu_env, ARM_FEATURE_SVE)) {
72
+ CPUARMState *env = cpu_env;
73
+ ret = ((env->vfp.zcr_el[1] & 0xf) + 1) * 16;
74
+ }
75
+ break;
76
+#endif /* AARCH64 */
77
case PR_GET_SECCOMP:
78
case PR_SET_SECCOMP:
79
/* Disable seccomp to prevent the target disabling syscalls we
80
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/cpu64.c
83
+++ b/target/arm/cpu64.c
84
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_register_types(void)
85
}
86
87
type_init(aarch64_cpu_register_types)
88
+
89
+/* The manual says that when SVE is enabled and VQ is widened the
90
+ * implementation is allowed to zero the previously inaccessible
91
+ * portion of the registers. The corollary to that is that when
92
+ * SVE is enabled and VQ is narrowed we are also allowed to zero
93
+ * the now inaccessible portion of the registers.
94
+ *
95
+ * The intent of this is that no predicate bit beyond VQ is ever set.
96
+ * Which means that some operations on predicate registers themselves
97
+ * may operate on full uint64_t or even unrolled across the maximum
98
+ * uint64_t[4]. Performing 4 bits of host arithmetic unconditionally
99
+ * may well be cheaper than conditionals to restrict the operation
100
+ * to the relevant portion of a uint16_t[16].
101
+ *
102
+ * TODO: Need to call this for changes to the real system registers
103
+ * and EL state changes.
104
+ */
105
+void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
106
+{
107
+ int i, j;
108
+ uint64_t pmask;
109
+
110
+ assert(vq >= 1 && vq <= ARM_MAX_VQ);
111
+
112
+ /* Zap the high bits of the zregs. */
113
+ for (i = 0; i < 32; i++) {
114
+ memset(&env->vfp.zregs[i].d[2 * vq], 0, 16 * (ARM_MAX_VQ - vq));
115
+ }
116
+
117
+ /* Zap the high bits of the pregs and ffr. */
118
+ pmask = 0;
119
+ if (vq & 3) {
120
+ pmask = ~(-1ULL << (16 * (vq & 3)));
121
+ }
122
+ for (j = vq / 4; j < ARM_MAX_VQ / 4; j++) {
123
+ for (i = 0; i < 17; ++i) {
124
+ env->vfp.pregs[i].p[j] &= pmask;
125
+ }
126
+ pmask = 0;
127
+ }
128
+}
129
--
57
--
130
2.16.2
58
2.34.1
131
59
132
60
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Bit 63 in a Table descriptor is only the NSTable bit for stage 1
2
translations; in stage 2 it is RES0. We were incorrectly looking at
3
it all the time.
2
4
3
From the "Physical Layer Simplified Specification Version 3.01":
5
This causes problems if:
6
* the stage 2 table descriptor was incorrectly setting the RES0 bit
7
* we are doing a stage 2 translation in Secure address space for
8
a NonSecure stage 1 regime -- in this case we would incorrectly
9
do an immediate downgrade to NonSecure
4
10
5
A known data block ("Tuning block") can be used to tune sampling
11
A bug elsewhere in the code currently prevents us from getting
6
point for tuning required hosts. [...]
12
to the second situation, but when we fix that it will be possible.
7
This procedure gives the system optimal timing for each specific
8
host and card combination and compensates for static delays in
9
the timing budget including process, voltage and different PCB
10
loads and skews. [...]
11
Data block, carried by DAT[3:0], contains a pattern for tuning
12
sampling position to receive data on the CMD and DAT[3:0] line.
13
13
14
[based on a patch from Alistair Francis <alistair.francis@xilinx.com>
14
Cc: qemu-stable@nongnu.org
15
from qemu/xilinx tag xilinx-v2015.2]
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
18
Message-id: 20180309153654.13518-5-f4bug@amsat.org
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Message-id: 20230504135425.2748672-2-peter.maydell@linaro.org
20
---
19
---
21
hw/sd/sd.c | 29 +++++++++++++++++++++++++++++
20
target/arm/ptw.c | 5 +++--
22
1 file changed, 29 insertions(+)
21
1 file changed, 3 insertions(+), 2 deletions(-)
23
22
24
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
23
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
25
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/sd/sd.c
25
--- a/target/arm/ptw.c
27
+++ b/hw/sd/sd.c
26
+++ b/target/arm/ptw.c
28
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
27
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
29
}
28
descaddrmask &= ~indexmask_grainsize;
30
break;
29
31
30
/*
32
+ case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */
31
- * Secure accesses start with the page table in secure memory and
33
+ if (sd->state == sd_transfer_state) {
32
+ * Secure stage 1 accesses start with the page table in secure memory and
34
+ sd->state = sd_sendingdata_state;
33
* can be downgraded to non-secure at any step. Non-secure accesses
35
+ sd->data_offset = 0;
34
* remain non-secure. We implement this by just ORing in the NSTable/NS
36
+ return sd_r1;
35
* bits at each step.
37
+ }
36
+ * Stage 2 never gets this kind of downgrade.
38
+ break;
37
*/
39
+
38
tableattrs = is_secure ? 0 : (1 << 4);
40
case 23: /* CMD23: SET_BLOCK_COUNT */
39
41
switch (sd->state) {
40
next_level:
42
case sd_transfer_state:
41
descaddr |= (address >> (stride * (4 - level))) & indexmask;
43
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
42
descaddr &= ~7ULL;
44
}
43
- nstable = extract32(tableattrs, 4, 1);
45
}
44
+ nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
46
45
if (nstable) {
47
+#define SD_TUNING_BLOCK_SIZE 64
46
/*
48
+
47
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
49
+static const uint8_t sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
50
+ /* See: Physical Layer Simplified Specification Version 3.01, Table 4-2 */
51
+ 0xff, 0x0f, 0xff, 0x00, 0x0f, 0xfc, 0xc3, 0xcc,
52
+ 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
53
+ 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
54
+ 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
55
+ 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
56
+ 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
57
+ 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
58
+ 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
59
+};
60
+
61
uint8_t sd_read_data(SDState *sd)
62
{
63
/* TODO: Append CRCs */
64
@@ -XXX,XX +XXX,XX @@ uint8_t sd_read_data(SDState *sd)
65
}
66
break;
67
68
+ case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */
69
+ if (sd->data_offset >= SD_TUNING_BLOCK_SIZE - 1) {
70
+ sd->state = sd_transfer_state;
71
+ }
72
+ ret = sd_tuning_block_pattern[sd->data_offset++];
73
+ break;
74
+
75
case 22:    /* ACMD22: SEND_NUM_WR_BLOCKS */
76
ret = sd->data[sd->data_offset ++];
77
78
--
48
--
79
2.16.2
49
2.34.1
80
50
81
51
diff view generated by jsdifflib
1
Move the definition of the 'host' cpu type into cpu.c, where all the
1
We currently don't correctly handle the VSTCR_EL2.SW and VTCR_EL2.NSW
2
other CPU types are defined. We can do this now we've decoupled it
2
configuration bits. These allow configuration of whether the stage 2
3
from the KVM-specific host feature probing. This means we now create
3
page table walks for Secure IPA and NonSecure IPA should do their
4
the type unconditionally (assuming we were built with KVM support at
4
descriptor reads from Secure or NonSecure physical addresses. (This
5
all), but if you try to use it without -enable-kvm this will end
5
is separate from how the translation table base address and other
6
up in the "host cpu probe failed and KVM not enabled" path in
6
parameters are set: an NS IPA always uses VTTBR_EL2 and VTCR_EL2
7
arm_cpu_realizefn(), for an appropriate error message.
7
for its base address and walk parameters, regardless of the NSW bit,
8
and similarly for Secure.)
8
9
10
Provide a new function ptw_idx_for_stage_2() which returns the
11
MMU index to use for descriptor reads, and use it to set up
12
the .in_ptw_idx wherever we call get_phys_addr_lpae().
13
14
For a stage 2 walk, wherever we call get_phys_addr_lpae():
15
* .in_ptw_idx should be ptw_idx_for_stage_2() of the .in_mmu_idx
16
* .in_secure should be true if .in_mmu_idx is Stage2_S
17
18
This allows us to correct S1_ptw_translate() so that it consistently
19
always sets its (out_secure, out_phys) to the result it gets from the
20
S2 walk (either by calling get_phys_addr_lpae() or by TLB lookup).
21
This makes better conceptual sense because the S2 walk should return
22
us an (address space, address) tuple, not an address that we then
23
randomly assign to S or NS.
24
25
Our previous handling of SW and NSW was broken, so guest code
26
trying to use these bits to put the s2 page tables in the "other"
27
address space wouldn't work correctly.
28
29
Cc: qemu-stable@nongnu.org
30
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1600
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
32
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
33
Message-id: 20230504135425.2748672-3-peter.maydell@linaro.org
12
Message-id: 20180308130626.12393-3-peter.maydell@linaro.org
13
---
34
---
14
target/arm/cpu.c | 24 ++++++++++++++++++++++++
35
target/arm/ptw.c | 76 ++++++++++++++++++++++++++++++++----------------
15
target/arm/kvm.c | 19 -------------------
36
1 file changed, 51 insertions(+), 25 deletions(-)
16
2 files changed, 24 insertions(+), 19 deletions(-)
17
37
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
38
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
19
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
40
--- a/target/arm/ptw.c
21
+++ b/target/arm/cpu.c
41
+++ b/target/arm/ptw.c
22
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
42
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
23
#endif
43
return stage_1_mmu_idx(arm_mmu_idx(env));
24
}
44
}
25
45
26
+#ifdef CONFIG_KVM
46
+/*
27
+static void arm_host_initfn(Object *obj)
47
+ * Return where we should do ptw loads from for a stage 2 walk.
48
+ * This depends on whether the address we are looking up is a
49
+ * Secure IPA or a NonSecure IPA, which we know from whether this is
50
+ * Stage2 or Stage2_S.
51
+ * If this is the Secure EL1&0 regime we need to check the NSW and SW bits.
52
+ */
53
+static ARMMMUIdx ptw_idx_for_stage_2(CPUARMState *env, ARMMMUIdx stage2idx)
28
+{
54
+{
29
+ ARMCPU *cpu = ARM_CPU(obj);
55
+ bool s2walk_secure;
30
+
56
+
31
+ kvm_arm_set_cpu_features_from_host(cpu);
57
+ /*
58
+ * We're OK to check the current state of the CPU here because
59
+ * (1) we always invalidate all TLBs when the SCR_EL3.NS bit changes
60
+ * (2) there's no way to do a lookup that cares about Stage 2 for a
61
+ * different security state to the current one for AArch64, and AArch32
62
+ * never has a secure EL2. (AArch32 ATS12NSO[UP][RW] allow EL3 to do
63
+ * an NS stage 1+2 lookup while the NS bit is 0.)
64
+ */
65
+ if (!arm_is_secure_below_el3(env) || !arm_el_is_aa64(env, 3)) {
66
+ return ARMMMUIdx_Phys_NS;
67
+ }
68
+ if (stage2idx == ARMMMUIdx_Stage2_S) {
69
+ s2walk_secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
70
+ } else {
71
+ s2walk_secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
72
+ }
73
+ return s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
74
+
32
+}
75
+}
33
+
76
+
34
+static const TypeInfo host_arm_cpu_type_info = {
77
static bool regime_translation_big_endian(CPUARMState *env, ARMMMUIdx mmu_idx)
35
+ .name = TYPE_ARM_HOST_CPU,
78
{
36
+#ifdef TARGET_AARCH64
79
return (regime_sctlr(env, mmu_idx) & SCTLR_EE) != 0;
37
+ .parent = TYPE_AARCH64_CPU,
80
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
38
+#else
81
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
39
+ .parent = TYPE_ARM_CPU,
82
ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
40
+#endif
83
uint8_t pte_attrs;
41
+ .instance_init = arm_host_initfn,
84
- bool pte_secure;
42
+};
85
86
ptw->out_virt = addr;
87
88
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
89
if (regime_is_stage2(s2_mmu_idx)) {
90
S1Translate s2ptw = {
91
.in_mmu_idx = s2_mmu_idx,
92
- .in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS,
93
- .in_secure = is_secure,
94
+ .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
95
+ .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
96
.in_debug = true,
97
};
98
GetPhysAddrResult s2 = { };
99
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
100
}
101
ptw->out_phys = s2.f.phys_addr;
102
pte_attrs = s2.cacheattrs.attrs;
103
- pte_secure = s2.f.attrs.secure;
104
+ ptw->out_secure = s2.f.attrs.secure;
105
} else {
106
/* Regime is physical. */
107
ptw->out_phys = addr;
108
pte_attrs = 0;
109
- pte_secure = is_secure;
110
+ ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
111
}
112
ptw->out_host = NULL;
113
ptw->out_rw = false;
114
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
115
ptw->out_phys = full->phys_addr | (addr & ~TARGET_PAGE_MASK);
116
ptw->out_rw = full->prot & PAGE_WRITE;
117
pte_attrs = full->pte_attrs;
118
- pte_secure = full->attrs.secure;
119
+ ptw->out_secure = full->attrs.secure;
120
#else
121
g_assert_not_reached();
122
#endif
123
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
124
}
125
}
126
127
- /* Check if page table walk is to secure or non-secure PA space. */
128
- ptw->out_secure = (is_secure
129
- && !(pte_secure
130
- ? env->cp15.vstcr_el2 & VSTCR_SW
131
- : env->cp15.vtcr_el2 & VTCR_NSW));
132
ptw->out_be = regime_translation_big_endian(env, mmu_idx);
133
return true;
134
135
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
136
hwaddr ipa;
137
int s1_prot, s1_lgpgsz;
138
bool is_secure = ptw->in_secure;
139
- bool ret, ipa_secure, s2walk_secure;
140
+ bool ret, ipa_secure;
141
ARMCacheAttrs cacheattrs1;
142
bool is_el0;
143
uint64_t hcr;
144
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
145
146
ipa = result->f.phys_addr;
147
ipa_secure = result->f.attrs.secure;
148
- if (is_secure) {
149
- /* Select TCR based on the NS bit from the S1 walk. */
150
- s2walk_secure = !(ipa_secure
151
- ? env->cp15.vstcr_el2 & VSTCR_SW
152
- : env->cp15.vtcr_el2 & VTCR_NSW);
153
- } else {
154
- assert(!ipa_secure);
155
- s2walk_secure = false;
156
- }
157
158
is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
159
- ptw->in_mmu_idx = s2walk_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
160
- ptw->in_ptw_idx = s2walk_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
161
- ptw->in_secure = s2walk_secure;
162
+ ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
163
+ ptw->in_secure = ipa_secure;
164
+ ptw->in_ptw_idx = ptw_idx_for_stage_2(env, ptw->in_mmu_idx);
165
166
/*
167
* S1 is done, now do S2 translation.
168
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
169
ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
170
break;
171
172
+ case ARMMMUIdx_Stage2:
173
+ case ARMMMUIdx_Stage2_S:
174
+ /*
175
+ * Second stage lookup uses physical for ptw; whether this is S or
176
+ * NS may depend on the SW/NSW bits if this is a stage 2 lookup for
177
+ * the Secure EL2&0 regime.
178
+ */
179
+ ptw->in_ptw_idx = ptw_idx_for_stage_2(env, mmu_idx);
180
+ break;
43
+
181
+
44
+#endif
182
case ARMMMUIdx_E10_0:
45
+
183
s1_mmu_idx = ARMMMUIdx_Stage1_E0;
46
static void cpu_register(const ARMCPUInfo *info)
184
goto do_twostage;
47
{
185
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
48
TypeInfo type_info = {
186
/* fall through */
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
187
50
cpu_register(info);
188
default:
51
info++;
189
- /* Single stage and second stage uses physical for ptw. */
190
+ /* Single stage uses physical for ptw. */
191
ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
192
break;
52
}
193
}
53
+
54
+#ifdef CONFIG_KVM
55
+ type_register_static(&host_arm_cpu_type_info);
56
+#endif
57
}
58
59
type_init(arm_cpu_register_types)
60
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/kvm.c
63
+++ b/target/arm/kvm.c
64
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
65
env->features = arm_host_cpu_features.features;
66
}
67
68
-static void kvm_arm_host_cpu_initfn(Object *obj)
69
-{
70
- ARMCPU *cpu = ARM_CPU(obj);
71
-
72
- kvm_arm_set_cpu_features_from_host(cpu);
73
-}
74
-
75
-static const TypeInfo host_arm_cpu_type_info = {
76
- .name = TYPE_ARM_HOST_CPU,
77
-#ifdef TARGET_AARCH64
78
- .parent = TYPE_AARCH64_CPU,
79
-#else
80
- .parent = TYPE_ARM_CPU,
81
-#endif
82
- .instance_init = kvm_arm_host_cpu_initfn,
83
-};
84
-
85
int kvm_arch_init(MachineState *ms, KVMState *s)
86
{
87
/* For ARM interrupt delivery is always asynchronous,
88
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
89
90
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
91
92
- type_register_static(&host_arm_cpu_type_info);
93
-
94
return 0;
95
}
96
97
--
194
--
98
2.16.2
195
2.34.1
99
100
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Akihiko Odaki <akihiko.odaki@gmail.com>
2
2
3
After spending months studying all the different SD Specifications
3
I am now employed by Daynix. Although my role as a reviewer of
4
from the SD Association, voluntarily add myself as maintainer
4
macOS-related change is not very relevant to the employment, I decided
5
for the SD code.
5
to use the company email address to avoid confusions from different
6
addresses.
6
7
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
9
Message-id: 20180309153654.13518-9-f4bug@amsat.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20230506072333.32510-1-akihiko.odaki@daynix.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
MAINTAINERS | 8 ++++++++
14
MAINTAINERS | 4 ++--
13
1 file changed, 8 insertions(+)
15
1 file changed, 2 insertions(+), 2 deletions(-)
14
16
15
diff --git a/MAINTAINERS b/MAINTAINERS
17
diff --git a/MAINTAINERS b/MAINTAINERS
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
19
--- a/MAINTAINERS
18
+++ b/MAINTAINERS
20
+++ b/MAINTAINERS
19
@@ -XXX,XX +XXX,XX @@ M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
21
@@ -XXX,XX +XXX,XX @@ Core Audio framework backend
20
S: Maintained
21
F: hw/ssi/xilinx_*
22
23
+SD (Secure Card)
24
+M: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
+S: Odd Fixes
26
+F: include/hw/sd/sd*
27
+F: hw/sd/core.c
28
+F: hw/sd/sd*
29
+F: tests/sd*
30
+
31
USB
32
M: Gerd Hoffmann <kraxel@redhat.com>
22
M: Gerd Hoffmann <kraxel@redhat.com>
33
S: Maintained
23
M: Philippe Mathieu-Daudé <philmd@linaro.org>
24
R: Christian Schoenebeck <qemu_oss@crudebyte.com>
25
-R: Akihiko Odaki <akihiko.odaki@gmail.com>
26
+R: Akihiko Odaki <akihiko.odaki@daynix.com>
27
S: Odd Fixes
28
F: audio/coreaudio.c
29
30
@@ -XXX,XX +XXX,XX @@ F: docs/devel/ui.rst
31
Cocoa graphics
32
M: Peter Maydell <peter.maydell@linaro.org>
33
M: Philippe Mathieu-Daudé <philmd@linaro.org>
34
-R: Akihiko Odaki <akihiko.odaki@gmail.com>
35
+R: Akihiko Odaki <akihiko.odaki@daynix.com>
36
S: Odd Fixes
37
F: ui/cocoa.m
38
34
--
39
--
35
2.16.2
40
2.34.1
36
41
37
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
When we take a PNG screenshot the ordering of the colour channels in
2
the data is not correct, resulting in the image having weird
3
colouring compared to the actual display. (Specifically, on a
4
little-endian host the blue and red channels are swapped; on
5
big-endian everything is wrong.)
2
6
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
This happens because the pixman idea of the pixel data and the libpng
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
idea differ. PIXMAN_a8r8g8b8 defines that pixels are 32-bit values,
5
Message-id: 20180309153654.13518-8-f4bug@amsat.org
9
with A in bits 24-31, R in bits 16-23, G in bits 8-15 and B in bits
10
0-7. This means that on little-endian systems the bytes in memory
11
are
12
B G R A
13
and on big-endian systems they are
14
A R G B
15
16
libpng, on the other hand, thinks of pixels as being a series of
17
values for each channel, so its format PNG_COLOR_TYPE_RGB_ALPHA
18
always wants bytes in the order
19
R G B A
20
21
This isn't the same as the pixman order for either big or little
22
endian hosts.
23
24
The alpha channel is also unnecessary bulk in the output PNG file,
25
because there is no alpha information in a screenshot.
26
27
To handle the endianness issue, we already define in ui/qemu-pixman.h
28
various PIXMAN_BE_* and PIXMAN_LE_* values that give consistent
29
byte-order pixel channel formats. So we can use PIXMAN_BE_r8g8b8 and
30
PNG_COLOR_TYPE_RGB, which both have an in-memory byte order of
31
R G B
32
and 3 bytes per pixel.
33
34
(PPM format screenshots get this right; they already use the
35
PIXMAN_BE_r8g8b8 format.)
36
37
Cc: qemu-stable@nongnu.org
38
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1622
39
Fixes: 9a0a119a382867 ("Added parameter to take screenshot with screendump as PNG")
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
41
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
42
Message-id: 20230502135548.2451309-1-peter.maydell@linaro.org
7
---
43
---
8
hw/sd/sdhci.c | 4 ++--
44
ui/console.c | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
45
1 file changed, 2 insertions(+), 2 deletions(-)
10
46
11
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
47
diff --git a/ui/console.c b/ui/console.c
12
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/sdhci.c
49
--- a/ui/console.c
14
+++ b/hw/sd/sdhci.c
50
+++ b/ui/console.c
15
@@ -XXX,XX +XXX,XX @@ static void sdhci_read_block_from_card(SDHCIState *s)
51
@@ -XXX,XX +XXX,XX @@ static bool png_save(int fd, pixman_image_t *image, Error **errp)
16
for (index = 0; index < blk_size; index++) {
52
png_struct *png_ptr;
17
data = sdbus_read_data(&s->sdbus);
53
png_info *info_ptr;
18
if (!FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, EXECUTE_TUNING)) {
54
g_autoptr(pixman_image_t) linebuf =
19
- /* Device is not in tunning */
55
- qemu_pixman_linebuf_create(PIXMAN_a8r8g8b8, width);
20
+ /* Device is not in tuning */
56
+ qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
21
s->fifo_buffer[index] = data;
57
uint8_t *buf = (uint8_t *)pixman_image_get_data(linebuf);
22
}
58
FILE *f = fdopen(fd, "wb");
23
}
59
int y;
24
60
@@ -XXX,XX +XXX,XX @@ static bool png_save(int fd, pixman_image_t *image, Error **errp)
25
if (FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, EXECUTE_TUNING)) {
61
png_init_io(png_ptr, f);
26
- /* Device is in tunning */
62
27
+ /* Device is in tuning */
63
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
28
s->hostctl2 &= ~R_SDHC_HOSTCTL2_EXECUTE_TUNING_MASK;
64
- PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
29
s->hostctl2 |= R_SDHC_HOSTCTL2_SAMPLING_CLKSEL_MASK;
65
+ PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
30
s->prnsts &= ~(SDHC_DAT_LINE_ACTIVE | SDHC_DOING_READ |
66
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
67
68
png_write_info(png_ptr, info_ptr);
31
--
69
--
32
2.16.2
70
2.34.1
33
71
34
72
diff view generated by jsdifflib
1
Now we have a working '-cpu max', the linux-user-only
1
In the doc sources, we have a few cross-reference targets with odd
2
'any' CPU is pretty much the same thing, so implement it
2
names "pcsys_005fxyz". These are the legacy of the semi-automated
3
that way.
3
conversion of the old info docs to rST (the '005f' is because ASCII
4
0x5f is '_' and the old info link names had underscores in them).
4
5
5
For the moment we don't add any of the extra feature bits
6
Remove the targets which nothing links to, and rename the two targets
6
to the system-emulation "max", because we don't set the
7
which are used to something a bit more descriptive.
7
ID register bits we would need to to advertise those
8
features as present.
9
8
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180308130626.12393-5-peter.maydell@linaro.org
10
Message-id: 20230421163642.1151904-1-peter.maydell@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Markus Armbruster <armbru@redhat.com>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
---
12
---
15
target/arm/cpu.c | 52 +++++++++++++++++++++++++----------------------
13
docs/system/devices/igb.rst | 2 +-
16
target/arm/cpu64.c | 59 ++++++++++++++++++++++++++----------------------------
14
docs/system/devices/ivshmem.rst | 2 --
17
2 files changed, 56 insertions(+), 55 deletions(-)
15
docs/system/devices/net.rst | 2 +-
16
docs/system/devices/usb.rst | 2 --
17
docs/system/keys.rst | 2 +-
18
docs/system/linuxboot.rst | 2 +-
19
docs/system/target-i386.rst | 4 ----
20
7 files changed, 4 insertions(+), 12 deletions(-)
18
21
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
22
diff --git a/docs/system/devices/igb.rst b/docs/system/devices/igb.rst
20
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
24
--- a/docs/system/devices/igb.rst
22
+++ b/target/arm/cpu.c
25
+++ b/docs/system/devices/igb.rst
23
@@ -XXX,XX +XXX,XX @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
26
@@ -XXX,XX +XXX,XX @@ Using igb
24
ObjectClass *oc;
27
=========
25
char *typename;
28
26
char **cpuname;
29
Using igb should be nothing different from using another network device. See
27
+ const char *cpunamestr;
30
-:ref:`pcsys_005fnetwork` in general.
28
31
+:ref:`Network_emulation` in general.
29
cpuname = g_strsplit(cpu_model, ",", 1);
32
30
- typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpuname[0]);
33
However, you may also need to perform additional steps to activate SR-IOV
31
+ cpunamestr = cpuname[0];
34
feature on your guest. For Linux, refer to [4]_.
32
+#ifdef CONFIG_USER_ONLY
35
diff --git a/docs/system/devices/ivshmem.rst b/docs/system/devices/ivshmem.rst
33
+ /* For backwards compatibility usermode emulation allows "-cpu any",
36
index XXXXXXX..XXXXXXX 100644
34
+ * which has the same semantics as "-cpu max".
37
--- a/docs/system/devices/ivshmem.rst
35
+ */
38
+++ b/docs/system/devices/ivshmem.rst
36
+ if (!strcmp(cpunamestr, "any")) {
39
@@ -XXX,XX +XXX,XX @@
37
+ cpunamestr = "max";
40
-.. _pcsys_005fivshmem:
38
+ }
39
+#endif
40
+ typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpunamestr);
41
oc = object_class_by_name(typename);
42
g_strfreev(cpuname);
43
g_free(typename);
44
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
45
kvm_arm_set_cpu_features_from_host(cpu);
46
} else {
47
cortex_a15_initfn(obj);
48
- /* In future we might add feature bits here even if the
49
- * real-world A15 doesn't implement them.
50
- */
51
- }
52
-}
53
-#endif
54
-
41
-
55
#ifdef CONFIG_USER_ONLY
42
Inter-VM Shared Memory device
56
-static void arm_any_initfn(Object *obj)
43
-----------------------------
57
-{
44
58
- ARMCPU *cpu = ARM_CPU(obj);
45
diff --git a/docs/system/devices/net.rst b/docs/system/devices/net.rst
59
- set_feature(&cpu->env, ARM_FEATURE_V8);
60
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
61
- set_feature(&cpu->env, ARM_FEATURE_NEON);
62
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
63
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
64
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
65
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
66
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
67
- set_feature(&cpu->env, ARM_FEATURE_CRC);
68
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
69
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
70
- cpu->midr = 0xffffffff;
71
+ /* We don't set these in system emulation mode for the moment,
72
+ * since we don't correctly set the ID registers to advertise them,
73
+ */
74
+ set_feature(&cpu->env, ARM_FEATURE_V8);
75
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
76
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
77
+ set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
78
+ set_feature(&cpu->env, ARM_FEATURE_V8_AES);
79
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
80
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
81
+ set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
82
+ set_feature(&cpu->env, ARM_FEATURE_CRC);
83
+ set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
84
+ set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
85
+#endif
86
+ }
87
}
88
#endif
89
90
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
91
{ .name = "max", .initfn = arm_max_initfn },
92
#endif
93
#ifdef CONFIG_USER_ONLY
94
- { .name = "any", .initfn = arm_any_initfn },
95
+ { .name = "any", .initfn = arm_max_initfn },
96
#endif
97
#endif
98
{ .name = NULL }
99
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
100
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/cpu64.c
47
--- a/docs/system/devices/net.rst
102
+++ b/target/arm/cpu64.c
48
+++ b/docs/system/devices/net.rst
103
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
49
@@ -XXX,XX +XXX,XX @@
104
kvm_arm_set_cpu_features_from_host(cpu);
50
-.. _pcsys_005fnetwork:
105
} else {
51
+.. _Network_Emulation:
106
aarch64_a57_initfn(obj);
52
107
- /* In future we might add feature bits here even if the
53
Network emulation
108
- * real-world A57 doesn't implement them.
54
-----------------
109
+#ifdef CONFIG_USER_ONLY
55
diff --git a/docs/system/devices/usb.rst b/docs/system/devices/usb.rst
110
+ /* We don't set these in system emulation mode for the moment,
56
index XXXXXXX..XXXXXXX 100644
111
+ * since we don't correctly set the ID registers to advertise them,
57
--- a/docs/system/devices/usb.rst
112
+ * and in some cases they're only available in AArch64 and not AArch32,
58
+++ b/docs/system/devices/usb.rst
113
+ * whereas the architecture requires them to be present in both if
59
@@ -XXX,XX +XXX,XX @@
114
+ * present in either.
60
-.. _pcsys_005fusb:
115
*/
116
+ set_feature(&cpu->env, ARM_FEATURE_V8);
117
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
118
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
119
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
120
+ set_feature(&cpu->env, ARM_FEATURE_V8_AES);
121
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
122
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
123
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
124
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
125
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
126
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
127
+ set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
128
+ set_feature(&cpu->env, ARM_FEATURE_CRC);
129
+ set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
130
+ set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
131
+ set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
132
+ /* For usermode -cpu max we can use a larger and more efficient DCZ
133
+ * blocksize since we don't have to follow what the hardware does.
134
+ */
135
+ cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
136
+ cpu->dcz_blocksize = 7; /* 512 bytes */
137
+#endif
138
}
139
}
140
141
-#ifdef CONFIG_USER_ONLY
142
-static void aarch64_any_initfn(Object *obj)
143
-{
144
- ARMCPU *cpu = ARM_CPU(obj);
145
-
61
-
146
- set_feature(&cpu->env, ARM_FEATURE_V8);
62
USB emulation
147
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
63
-------------
148
- set_feature(&cpu->env, ARM_FEATURE_NEON);
64
149
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
65
diff --git a/docs/system/keys.rst b/docs/system/keys.rst
150
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
66
index XXXXXXX..XXXXXXX 100644
151
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
67
--- a/docs/system/keys.rst
152
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
68
+++ b/docs/system/keys.rst
153
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
69
@@ -XXX,XX +XXX,XX @@
154
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
70
-.. _pcsys_005fkeys:
155
- set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
71
+.. _GUI_keys:
156
- set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
72
157
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
73
Keys in the graphical frontends
158
- set_feature(&cpu->env, ARM_FEATURE_CRC);
74
-------------------------------
159
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
75
diff --git a/docs/system/linuxboot.rst b/docs/system/linuxboot.rst
160
- set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
76
index XXXXXXX..XXXXXXX 100644
161
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
77
--- a/docs/system/linuxboot.rst
162
- cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
78
+++ b/docs/system/linuxboot.rst
163
- cpu->dcz_blocksize = 7; /* 512 bytes */
79
@@ -XXX,XX +XXX,XX @@ virtual serial port and the QEMU monitor to the console with the
164
-}
80
-append "root=/dev/hda console=ttyS0" -nographic
165
-#endif
81
82
Use Ctrl-a c to switch between the serial console and the monitor (see
83
-:ref:`pcsys_005fkeys`).
84
+:ref:`GUI_keys`).
85
diff --git a/docs/system/target-i386.rst b/docs/system/target-i386.rst
86
index XXXXXXX..XXXXXXX 100644
87
--- a/docs/system/target-i386.rst
88
+++ b/docs/system/target-i386.rst
89
@@ -XXX,XX +XXX,XX @@
90
x86 System emulator
91
-------------------
92
93
-.. _pcsys_005fdevices:
166
-
94
-
167
typedef struct ARMCPUInfo {
95
Board-specific documentation
168
const char *name;
96
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169
void (*initfn)(Object *obj);
97
170
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
98
@@ -XXX,XX +XXX,XX @@ Architectural features
171
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
99
i386/sgx
172
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
100
i386/amd-memory-encryption
173
{ .name = "max", .initfn = aarch64_max_initfn },
101
174
-#ifdef CONFIG_USER_ONLY
102
-.. _pcsys_005freq:
175
- { .name = "any", .initfn = aarch64_any_initfn },
103
-
176
-#endif
104
OS requirements
177
{ .name = NULL }
105
~~~~~~~~~~~~~~~
178
};
179
106
180
--
107
--
181
2.16.2
108
2.34.1
182
183
diff view generated by jsdifflib
1
Add support for passing 'max' to -machine gic-version. By analogy
1
Coverity points out (in CID 1508390) that write_bootloader has
2
with the -cpu max option, this picks the "best available" GIC version
2
some dead code, where we assign to 'p' and then in the following
3
whether you're using KVM or TCG, so it behaves like 'host' when
3
line assign to it again. This happened as a result of the
4
using KVM, and gives you GICv3 when using TCG.
4
refactoring in commit cd5066f8618b.
5
5
6
Also like '-cpu host', using -machine gic-version=max' means there
6
Fix the dead code by removing the 'void *v' variable entirely and
7
is no guarantee of migration compatibility between QEMU versions;
7
instead adding a cast when calling bl_setup_gt64120_jump_kernel(), as
8
in future 'max' might mean '4'.
8
we do at its other callsite in write_bootloader_nanomips().
9
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180308130626.12393-7-peter.maydell@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
---
12
---
14
hw/arm/virt.c | 29 +++++++++++++++++++----------
13
hw/mips/malta.c | 5 +----
15
1 file changed, 19 insertions(+), 10 deletions(-)
14
1 file changed, 1 insertion(+), 4 deletions(-)
16
15
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
16
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt.c
18
--- a/hw/mips/malta.c
20
+++ b/hw/arm/virt.c
19
+++ b/hw/mips/malta.c
21
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
20
@@ -XXX,XX +XXX,XX @@ static void write_bootloader(uint8_t *base, uint64_t run_addr,
22
/* We can probe only here because during property set
21
uint64_t kernel_entry)
23
* KVM is not available yet
22
{
23
uint32_t *p;
24
- void *v;
25
26
/* Small bootloader */
27
p = (uint32_t *)base;
28
@@ -XXX,XX +XXX,XX @@ static void write_bootloader(uint8_t *base, uint64_t run_addr,
29
*
24
*/
30
*/
25
- if (!vms->gic_version) {
31
26
+ if (vms->gic_version <= 0) {
32
- v = p;
27
+ /* "host" or "max" */
33
- bl_setup_gt64120_jump_kernel(&v, run_addr, kernel_entry);
28
if (!kvm_enabled()) {
34
- p = v;
29
- error_report("gic-version=host requires KVM");
35
+ bl_setup_gt64120_jump_kernel((void **)&p, run_addr, kernel_entry);
30
- exit(1);
36
31
- }
37
/* YAMON subroutines */
32
-
38
p = (uint32_t *) (base + 0x800);
33
- vms->gic_version = kvm_arm_vgic_probe();
34
- if (!vms->gic_version) {
35
- error_report("Unable to determine GIC version supported by host");
36
- exit(1);
37
+ if (vms->gic_version == 0) {
38
+ error_report("gic-version=host requires KVM");
39
+ exit(1);
40
+ } else {
41
+ /* "max": currently means 3 for TCG */
42
+ vms->gic_version = 3;
43
+ }
44
+ } else {
45
+ vms->gic_version = kvm_arm_vgic_probe();
46
+ if (!vms->gic_version) {
47
+ error_report(
48
+ "Unable to determine GIC version supported by host");
49
+ exit(1);
50
+ }
51
}
52
}
53
54
@@ -XXX,XX +XXX,XX @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
55
vms->gic_version = 2;
56
} else if (!strcmp(value, "host")) {
57
vms->gic_version = 0; /* Will probe later */
58
+ } else if (!strcmp(value, "max")) {
59
+ vms->gic_version = -1; /* Will probe later */
60
} else {
61
error_setg(errp, "Invalid gic-version value");
62
- error_append_hint(errp, "Valid values are 3, 2, host.\n");
63
+ error_append_hint(errp, "Valid values are 3, 2, host, max.\n");
64
}
65
}
66
67
--
39
--
68
2.16.2
40
2.34.1
69
41
70
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Semihosting has been made a 'default y' entry in Kconfig, which does
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
not work because when building --without-default-devices, the
5
Message-id: 20180309153654.13518-4-f4bug@amsat.org
5
semihosting code would not be available.
6
7
Make semihosting unconditional when TCG is present.
8
9
Fixes: 29d9efca16 ("arm/Kconfig: Do not build TCG-only boards on a KVM-only build")
10
Signed-off-by: Fabiano Rosas <farosas@suse.de>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20230508181611.2621-2-farosas@suse.de
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
14
---
8
hw/sd/sd.c | 14 ++++++++++----
15
target/arm/Kconfig | 8 +-------
9
hw/sd/trace-events | 8 ++++----
16
1 file changed, 1 insertion(+), 7 deletions(-)
10
2 files changed, 14 insertions(+), 8 deletions(-)
11
17
12
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
18
diff --git a/target/arm/Kconfig b/target/arm/Kconfig
13
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sd.c
20
--- a/target/arm/Kconfig
15
+++ b/hw/sd/sd.c
21
+++ b/target/arm/Kconfig
16
@@ -XXX,XX +XXX,XX @@ struct SDState {
22
@@ -XXX,XX +XXX,XX @@
17
qemu_irq readonly_cb;
23
config ARM
18
qemu_irq inserted_cb;
24
bool
19
QEMUTimer *ocr_power_timer;
25
+ select ARM_COMPATIBLE_SEMIHOSTING if TCG
20
+ const char *proto_name;
26
21
bool enable;
27
config AARCH64
22
uint8_t dat_lines;
28
bool
23
bool cmd_line;
29
select ARM
24
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
30
-
25
* However there is no ACMD55, so we want to trace this particular case.
31
-# This config exists just so we can make SEMIHOSTING default when TCG
26
*/
32
-# is selected without also changing it for other architectures.
27
if (req.cmd != 55 || sd->expecting_acmd) {
33
-config ARM_SEMIHOSTING
28
- trace_sdcard_normal_command(sd_cmd_name(req.cmd), req.cmd,
34
- bool
29
+ trace_sdcard_normal_command(sd->proto_name,
35
- default y if TCG && ARM
30
+ sd_cmd_name(req.cmd), req.cmd,
36
- select ARM_COMPATIBLE_SEMIHOSTING
31
req.arg, sd_state_name(sd->state));
32
}
33
34
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
35
static sd_rsp_type_t sd_app_command(SDState *sd,
36
SDRequest req)
37
{
38
- trace_sdcard_app_command(sd_acmd_name(req.cmd),
39
+ trace_sdcard_app_command(sd->proto_name, sd_acmd_name(req.cmd),
40
req.cmd, req.arg, sd_state_name(sd->state));
41
sd->card_status |= APP_CMD;
42
switch (req.cmd) {
43
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
44
if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
45
return;
46
47
- trace_sdcard_write_data(sd_acmd_name(sd->current_cmd),
48
+ trace_sdcard_write_data(sd->proto_name,
49
+ sd_acmd_name(sd->current_cmd),
50
sd->current_cmd, value);
51
switch (sd->current_cmd) {
52
case 24:    /* CMD24: WRITE_SINGLE_BLOCK */
53
@@ -XXX,XX +XXX,XX @@ uint8_t sd_read_data(SDState *sd)
54
55
io_len = (sd->ocr & (1 << 30)) ? 512 : sd->blk_len;
56
57
- trace_sdcard_read_data(sd_acmd_name(sd->current_cmd),
58
+ trace_sdcard_read_data(sd->proto_name,
59
+ sd_acmd_name(sd->current_cmd),
60
sd->current_cmd, io_len);
61
switch (sd->current_cmd) {
62
case 6:    /* CMD6: SWITCH_FUNCTION */
63
@@ -XXX,XX +XXX,XX @@ static void sd_realize(DeviceState *dev, Error **errp)
64
SDState *sd = SD_CARD(dev);
65
int ret;
66
67
+ sd->proto_name = sd->spi ? "SPI" : "SD";
68
+
69
if (sd->blk && blk_is_read_only(sd->blk)) {
70
error_setg(errp, "Cannot use read-only drive as SD card");
71
return;
72
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/sd/trace-events
75
+++ b/hw/sd/trace-events
76
@@ -XXX,XX +XXX,XX @@ sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of
77
sdhci_capareg(const char *desc, uint16_t val) "%s: %u"
78
79
# hw/sd/sd.c
80
-sdcard_normal_command(const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%20s/ CMD%02d arg 0x%08x (state %s)"
81
-sdcard_app_command(const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%23s/ACMD%02d arg 0x%08x (state %s)"
82
+sdcard_normal_command(const char *proto, const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%s %20s/ CMD%02d arg 0x%08x (state %s)"
83
+sdcard_app_command(const char *proto, const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%s %23s/ACMD%02d arg 0x%08x (state %s)"
84
sdcard_response(const char *rspdesc, int rsplen) "%s (sz:%d)"
85
sdcard_powerup(void) ""
86
sdcard_inquiry_cmd41(void) ""
87
@@ -XXX,XX +XXX,XX @@ sdcard_lock(void) ""
88
sdcard_unlock(void) ""
89
sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
90
sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
91
-sdcard_write_data(const char *cmd_desc, uint8_t cmd, uint8_t value) "%20s/ CMD%02d value 0x%02x"
92
-sdcard_read_data(const char *cmd_desc, uint8_t cmd, int length) "%20s/ CMD%02d len %d"
93
+sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint8_t value) "%s %20s/ CMD%02d value 0x%02x"
94
+sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, int length) "%s %20s/ CMD%02d len %d"
95
sdcard_set_voltage(uint16_t millivolts) "%u mV"
96
97
# hw/sd/milkymist-memcard.c
98
--
37
--
99
2.16.2
38
2.34.1
100
101
diff view generated by jsdifflib
1
From: Marc-André Lureau <marcandre.lureau@redhat.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Spotted by ASAN:
3
We cannot allow this config to be disabled at the moment as not all of
4
QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 tests/boot-serial-test
4
the relevant code is protected by it.
5
5
6
Direct leak of 48 byte(s) in 1 object(s) allocated from:
6
Commit 29d9efca16 ("arm/Kconfig: Do not build TCG-only boards on a
7
#0 0x7ff8a9b0ca38 in __interceptor_calloc (/lib64/libasan.so.4+0xdea38)
7
KVM-only build") moved the CONFIGs of several boards to Kconfig, so it
8
#1 0x7ff8a8ea7f75 in g_malloc0 ../glib/gmem.c:124
8
is now possible that nothing selects ARM_V7M (e.g. when doing a
9
#2 0x55fef3d99129 in error_setv /home/elmarco/src/qemu/util/error.c:59
9
--without-default-devices build).
10
#3 0x55fef3d99738 in error_setg_internal /home/elmarco/src/qemu/util/error.c:95
11
#4 0x55fef323acb2 in load_elf_hdr /home/elmarco/src/qemu/hw/core/loader.c:393
12
#5 0x55fef2d15776 in arm_load_elf /home/elmarco/src/qemu/hw/arm/boot.c:830
13
#6 0x55fef2d16d39 in arm_load_kernel_notify /home/elmarco/src/qemu/hw/arm/boot.c:1022
14
#7 0x55fef3dc634d in notifier_list_notify /home/elmarco/src/qemu/util/notify.c:40
15
#8 0x55fef2fc3182 in qemu_run_machine_init_done_notifiers /home/elmarco/src/qemu/vl.c:2716
16
#9 0x55fef2fcbbd1 in main /home/elmarco/src/qemu/vl.c:4679
17
#10 0x7ff89dfed009 in __libc_start_main (/lib64/libc.so.6+0x21009)
18
10
19
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
11
Return the CONFIG_ARM_V7M entry to a state where it is always selected
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
whenever TCG is available.
13
14
Fixes: 29d9efca16 ("arm/Kconfig: Do not build TCG-only boards on a KVM-only build")
15
Signed-off-by: Fabiano Rosas <farosas@suse.de>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20230508181611.2621-3-farosas@suse.de
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
19
---
23
hw/arm/boot.c | 1 +
20
target/arm/Kconfig | 1 +
24
1 file changed, 1 insertion(+)
21
1 file changed, 1 insertion(+)
25
22
26
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
23
diff --git a/target/arm/Kconfig b/target/arm/Kconfig
27
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/boot.c
25
--- a/target/arm/Kconfig
29
+++ b/hw/arm/boot.c
26
+++ b/target/arm/Kconfig
30
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
27
@@ -XXX,XX +XXX,XX @@
31
28
config ARM
32
load_elf_hdr(info->kernel_filename, &elf_header, &elf_is64, &err);
29
bool
33
if (err) {
30
select ARM_COMPATIBLE_SEMIHOSTING if TCG
34
+ error_free(err);
31
+ select ARM_V7M if TCG
35
return ret;
32
36
}
33
config AARCH64
37
34
bool
38
--
35
--
39
2.16.2
36
2.34.1
40
41
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Implement code needed to set up emulation of MCIMX7SABRE board from
3
On a build configured with: --disable-tcg --enable-xen it is possible
4
NXP. For more info about the HW see:
4
to produce a QEMU binary with no TCG nor KVM support. Skip the cdrom
5
boot tests if that's the case.
5
6
6
https://www.nxp.com/support/developer-resources/hardware-development-tools/sabre-development-system/sabre-board-for-smart-devices-based-on-the-i.mx-7dual-applications-processors:MCIMX7SABRE
7
Fixes: 0c1ae3ff9d ("tests/qtest: Fix tests when no KVM or TCG are present")
7
8
Signed-off-by: Fabiano Rosas <farosas@suse.de>
8
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Thomas Huth <thuth@redhat.com>
9
Cc: Jason Wang <jasowang@redhat.com>
10
Message-id: 20230508181611.2621-4-farosas@suse.de
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
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
12
---
20
hw/arm/Makefile.objs | 2 +-
13
tests/qtest/cdrom-test.c | 10 ++++++++++
21
hw/arm/mcimx7d-sabre.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++
14
1 file changed, 10 insertions(+)
22
2 files changed, 91 insertions(+), 1 deletion(-)
23
create mode 100644 hw/arm/mcimx7d-sabre.c
24
15
25
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
16
diff --git a/tests/qtest/cdrom-test.c b/tests/qtest/cdrom-test.c
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/Makefile.objs
18
--- a/tests/qtest/cdrom-test.c
28
+++ b/hw/arm/Makefile.objs
19
+++ b/tests/qtest/cdrom-test.c
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2.o
20
@@ -XXX,XX +XXX,XX @@ static void test_cdboot(gconstpointer data)
30
obj-$(CONFIG_MPS2) += mps2-tz.o
21
31
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
22
static void add_x86_tests(void)
32
obj-$(CONFIG_IOTKIT) += iotkit.o
23
{
33
-obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o
24
+ if (!qtest_has_accel("tcg") && !qtest_has_accel("kvm")) {
34
+obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
25
+ g_test_skip("No KVM or TCG accelerator available, skipping boot tests");
35
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
26
+ return;
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/hw/arm/mcimx7d-sabre.c
40
@@ -XXX,XX +XXX,XX @@
41
+/*
42
+ * Copyright (c) 2018, Impinj, Inc.
43
+ *
44
+ * MCIMX7D_SABRE Board System emulation.
45
+ *
46
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
47
+ *
48
+ * This code is licensed under the GPL, version 2 or later.
49
+ * See the file `COPYING' in the top level directory.
50
+ *
51
+ * It (partially) emulates a mcimx7d_sabre board, with a Freescale
52
+ * i.MX7 SoC
53
+ */
54
+
55
+#include "qemu/osdep.h"
56
+#include "qapi/error.h"
57
+#include "qemu-common.h"
58
+#include "hw/arm/fsl-imx7.h"
59
+#include "hw/boards.h"
60
+#include "sysemu/sysemu.h"
61
+#include "sysemu/device_tree.h"
62
+#include "qemu/error-report.h"
63
+#include "sysemu/qtest.h"
64
+#include "net/net.h"
65
+
66
+typedef struct {
67
+ FslIMX7State soc;
68
+ MemoryRegion ram;
69
+} MCIMX7Sabre;
70
+
71
+static void mcimx7d_sabre_init(MachineState *machine)
72
+{
73
+ static struct arm_boot_info boot_info;
74
+ MCIMX7Sabre *s = g_new0(MCIMX7Sabre, 1);
75
+ Object *soc;
76
+ int i;
77
+
78
+ if (machine->ram_size > FSL_IMX7_MMDC_SIZE) {
79
+ error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
80
+ machine->ram_size, FSL_IMX7_MMDC_SIZE);
81
+ exit(1);
82
+ }
27
+ }
83
+
28
+
84
+ boot_info = (struct arm_boot_info) {
29
qtest_add_data_func("cdrom/boot/default", "-cdrom ", test_cdboot);
85
+ .loader_start = FSL_IMX7_MMDC_ADDR,
30
qtest_add_data_func("cdrom/boot/virtio-scsi",
86
+ .board_id = -1,
31
"-device virtio-scsi -device scsi-cd,drive=cdr "
87
+ .ram_size = machine->ram_size,
32
@@ -XXX,XX +XXX,XX @@ static void add_x86_tests(void)
88
+ .kernel_filename = machine->kernel_filename,
33
89
+ .kernel_cmdline = machine->kernel_cmdline,
34
static void add_s390x_tests(void)
90
+ .initrd_filename = machine->initrd_filename,
35
{
91
+ .nb_cpus = smp_cpus,
36
+ if (!qtest_has_accel("tcg") && !qtest_has_accel("kvm")) {
92
+ };
37
+ g_test_skip("No KVM or TCG accelerator available, skipping boot tests");
93
+
38
+ return;
94
+ object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX7);
95
+ soc = OBJECT(&s->soc);
96
+ object_property_add_child(OBJECT(machine), "soc", soc, &error_fatal);
97
+ object_property_set_bool(soc, true, "realized", &error_fatal);
98
+
99
+ memory_region_allocate_system_memory(&s->ram, NULL, "mcimx7d-sabre.ram",
100
+ machine->ram_size);
101
+ memory_region_add_subregion(get_system_memory(),
102
+ FSL_IMX7_MMDC_ADDR, &s->ram);
103
+
104
+ for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
105
+ BusState *bus;
106
+ DeviceState *carddev;
107
+ DriveInfo *di;
108
+ BlockBackend *blk;
109
+
110
+ di = drive_get_next(IF_SD);
111
+ blk = di ? blk_by_legacy_dinfo(di) : NULL;
112
+ bus = qdev_get_child_bus(DEVICE(&s->soc.usdhc[i]), "sd-bus");
113
+ carddev = qdev_create(bus, TYPE_SD_CARD);
114
+ qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
115
+ object_property_set_bool(OBJECT(carddev), true,
116
+ "realized", &error_fatal);
117
+ }
39
+ }
118
+
40
+
119
+ if (!qtest_enabled()) {
41
qtest_add_data_func("cdrom/boot/default", "-cdrom ", test_cdboot);
120
+ arm_load_kernel(&s->soc.cpu[0], &boot_info);
42
qtest_add_data_func("cdrom/boot/virtio-scsi",
121
+ }
43
"-device virtio-scsi -device scsi-cd,drive=cdr "
122
+}
123
+
124
+static void mcimx7d_sabre_machine_init(MachineClass *mc)
125
+{
126
+ mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex A7)";
127
+ mc->init = mcimx7d_sabre_init;
128
+ mc->max_cpus = FSL_IMX7_NUM_CPUS;
129
+}
130
+DEFINE_MACHINE("mcimx7d-sabre", mcimx7d_sabre_machine_init)
131
--
44
--
132
2.16.2
45
2.34.1
133
134
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Split out helpers from target_setup_frame and target_restore_sigframe
4
for dealing with general registers, fpsimd registers, and the end record.
5
6
When we add support for sve registers, the relative positions of
7
these will change.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180303143823.27055-3-richard.henderson@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
linux-user/signal.c | 120 ++++++++++++++++++++++++++++++----------------------
16
1 file changed, 69 insertions(+), 51 deletions(-)
17
18
diff --git a/linux-user/signal.c b/linux-user/signal.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/signal.c
21
+++ b/linux-user/signal.c
22
@@ -XXX,XX +XXX,XX @@ struct target_rt_sigframe {
23
uint32_t tramp[2];
24
};
25
26
-static int target_setup_sigframe(struct target_rt_sigframe *sf,
27
- CPUARMState *env, target_sigset_t *set)
28
+static void target_setup_general_frame(struct target_rt_sigframe *sf,
29
+ CPUARMState *env, target_sigset_t *set)
30
{
31
int i;
32
- struct target_aux_context *aux =
33
- (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
34
35
- /* set up the stack frame for unwinding */
36
- __put_user(env->xregs[29], &sf->fp);
37
- __put_user(env->xregs[30], &sf->lr);
38
+ __put_user(0, &sf->uc.tuc_flags);
39
+ __put_user(0, &sf->uc.tuc_link);
40
+
41
+ __put_user(target_sigaltstack_used.ss_sp, &sf->uc.tuc_stack.ss_sp);
42
+ __put_user(sas_ss_flags(env->xregs[31]), &sf->uc.tuc_stack.ss_flags);
43
+ __put_user(target_sigaltstack_used.ss_size, &sf->uc.tuc_stack.ss_size);
44
45
for (i = 0; i < 31; i++) {
46
__put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
47
@@ -XXX,XX +XXX,XX @@ static int target_setup_sigframe(struct target_rt_sigframe *sf,
48
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
49
__put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
50
}
51
+}
52
+
53
+static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
54
+ CPUARMState *env)
55
+{
56
+ int i;
57
+
58
+ __put_user(TARGET_FPSIMD_MAGIC, &fpsimd->head.magic);
59
+ __put_user(sizeof(struct target_fpsimd_context), &fpsimd->head.size);
60
+ __put_user(vfp_get_fpsr(env), &fpsimd->fpsr);
61
+ __put_user(vfp_get_fpcr(env), &fpsimd->fpcr);
62
63
for (i = 0; i < 32; i++) {
64
uint64_t *q = aa64_vfp_qreg(env, i);
65
#ifdef TARGET_WORDS_BIGENDIAN
66
- __put_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
67
- __put_user(q[1], &aux->fpsimd.vregs[i * 2]);
68
+ __put_user(q[0], &fpsimd->vregs[i * 2 + 1]);
69
+ __put_user(q[1], &fpsimd->vregs[i * 2]);
70
#else
71
- __put_user(q[0], &aux->fpsimd.vregs[i * 2]);
72
- __put_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
73
+ __put_user(q[0], &fpsimd->vregs[i * 2]);
74
+ __put_user(q[1], &fpsimd->vregs[i * 2 + 1]);
75
#endif
76
}
77
- __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
78
- __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
79
- __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
80
- __put_user(sizeof(struct target_fpsimd_context),
81
- &aux->fpsimd.head.size);
82
-
83
- /* set the "end" magic */
84
- __put_user(0, &aux->end.magic);
85
- __put_user(0, &aux->end.size);
86
-
87
- return 0;
88
}
89
90
-static int target_restore_sigframe(CPUARMState *env,
91
- struct target_rt_sigframe *sf)
92
+static void target_setup_end_record(struct target_aarch64_ctx *end)
93
+{
94
+ __put_user(0, &end->magic);
95
+ __put_user(0, &end->size);
96
+}
97
+
98
+static void target_restore_general_frame(CPUARMState *env,
99
+ struct target_rt_sigframe *sf)
100
{
101
sigset_t set;
102
- int i;
103
- struct target_aux_context *aux =
104
- (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
105
- uint32_t magic, size, fpsr, fpcr;
106
uint64_t pstate;
107
+ int i;
108
109
target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
110
set_sigmask(&set);
111
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
112
__get_user(env->pc, &sf->uc.tuc_mcontext.pc);
113
__get_user(pstate, &sf->uc.tuc_mcontext.pstate);
114
pstate_write(env, pstate);
115
+}
116
117
- __get_user(magic, &aux->fpsimd.head.magic);
118
- __get_user(size, &aux->fpsimd.head.size);
119
+static void target_restore_fpsimd_record(CPUARMState *env,
120
+ struct target_fpsimd_context *fpsimd)
121
+{
122
+ uint32_t fpsr, fpcr;
123
+ int i;
124
125
- if (magic != TARGET_FPSIMD_MAGIC
126
- || size != sizeof(struct target_fpsimd_context)) {
127
- return 1;
128
- }
129
+ __get_user(fpsr, &fpsimd->fpsr);
130
+ vfp_set_fpsr(env, fpsr);
131
+ __get_user(fpcr, &fpsimd->fpcr);
132
+ vfp_set_fpcr(env, fpcr);
133
134
for (i = 0; i < 32; i++) {
135
uint64_t *q = aa64_vfp_qreg(env, i);
136
#ifdef TARGET_WORDS_BIGENDIAN
137
- __get_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
138
- __get_user(q[1], &aux->fpsimd.vregs[i * 2]);
139
+ __get_user(q[0], &fpsimd->vregs[i * 2 + 1]);
140
+ __get_user(q[1], &fpsimd->vregs[i * 2]);
141
#else
142
- __get_user(q[0], &aux->fpsimd.vregs[i * 2]);
143
- __get_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
144
+ __get_user(q[0], &fpsimd->vregs[i * 2]);
145
+ __get_user(q[1], &fpsimd->vregs[i * 2 + 1]);
146
#endif
147
}
148
- __get_user(fpsr, &aux->fpsimd.fpsr);
149
- vfp_set_fpsr(env, fpsr);
150
- __get_user(fpcr, &aux->fpsimd.fpcr);
151
- vfp_set_fpcr(env, fpcr);
152
+}
153
154
+static int target_restore_sigframe(CPUARMState *env,
155
+ struct target_rt_sigframe *sf)
156
+{
157
+ struct target_aux_context *aux
158
+ = (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
159
+ uint32_t magic, size;
160
+
161
+ target_restore_general_frame(env, sf);
162
+
163
+ __get_user(magic, &aux->fpsimd.head.magic);
164
+ __get_user(size, &aux->fpsimd.head.size);
165
+ if (magic == TARGET_FPSIMD_MAGIC
166
+ && size == sizeof(struct target_fpsimd_context)) {
167
+ target_restore_fpsimd_record(env, &aux->fpsimd);
168
+ } else {
169
+ return 1;
170
+ }
171
return 0;
172
}
173
174
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
175
CPUARMState *env)
176
{
177
struct target_rt_sigframe *frame;
178
+ struct target_aux_context *aux;
179
abi_ulong frame_addr, return_addr;
180
181
frame_addr = get_sigframe(ka, env);
182
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
183
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
184
goto give_sigsegv;
185
}
186
+ aux = (struct target_aux_context *)frame->uc.tuc_mcontext.__reserved;
187
188
- __put_user(0, &frame->uc.tuc_flags);
189
- __put_user(0, &frame->uc.tuc_link);
190
+ target_setup_general_frame(frame, env, set);
191
+ target_setup_fpsimd_record(&aux->fpsimd, env);
192
+ target_setup_end_record(&aux->end);
193
194
- __put_user(target_sigaltstack_used.ss_sp,
195
- &frame->uc.tuc_stack.ss_sp);
196
- __put_user(sas_ss_flags(env->xregs[31]),
197
- &frame->uc.tuc_stack.ss_flags);
198
- __put_user(target_sigaltstack_used.ss_size,
199
- &frame->uc.tuc_stack.ss_size);
200
- target_setup_sigframe(frame, env, set);
201
if (ka->sa_flags & TARGET_SA_RESTORER) {
202
return_addr = ka->sa_restorer;
203
} else {
204
--
205
2.16.2
206
207
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This changes the qemu signal frame layout to be more like the kernel's,
4
in that the various records are dynamically allocated rather than fixed
5
in place by a structure.
6
7
For now, all of the allocation is out of uc.tuc_mcontext.__reserved,
8
so the allocation is actually trivial. That will change with SVE support.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20180303143823.27055-4-richard.henderson@linaro.org
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
linux-user/signal.c | 89 ++++++++++++++++++++++++++++++++++++-----------------
17
1 file changed, 61 insertions(+), 28 deletions(-)
18
19
diff --git a/linux-user/signal.c b/linux-user/signal.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/linux-user/signal.c
22
+++ b/linux-user/signal.c
23
@@ -XXX,XX +XXX,XX @@ struct target_fpsimd_context {
24
uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
25
};
26
27
-/*
28
- * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
29
- * user space as it will change with the addition of new context. User space
30
- * should check the magic/size information.
31
- */
32
-struct target_aux_context {
33
- struct target_fpsimd_context fpsimd;
34
- /* additional context to be added before "end" */
35
- struct target_aarch64_ctx end;
36
-};
37
-
38
struct target_rt_sigframe {
39
struct target_siginfo info;
40
struct target_ucontext uc;
41
+};
42
+
43
+struct target_rt_frame_record {
44
uint64_t fp;
45
uint64_t lr;
46
uint32_t tramp[2];
47
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
48
static int target_restore_sigframe(CPUARMState *env,
49
struct target_rt_sigframe *sf)
50
{
51
- struct target_aux_context *aux
52
- = (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
53
- uint32_t magic, size;
54
+ struct target_aarch64_ctx *ctx;
55
+ struct target_fpsimd_context *fpsimd = NULL;
56
57
target_restore_general_frame(env, sf);
58
59
- __get_user(magic, &aux->fpsimd.head.magic);
60
- __get_user(size, &aux->fpsimd.head.size);
61
- if (magic == TARGET_FPSIMD_MAGIC
62
- && size == sizeof(struct target_fpsimd_context)) {
63
- target_restore_fpsimd_record(env, &aux->fpsimd);
64
- } else {
65
+ ctx = (struct target_aarch64_ctx *)sf->uc.tuc_mcontext.__reserved;
66
+ while (ctx) {
67
+ uint32_t magic, size;
68
+
69
+ __get_user(magic, &ctx->magic);
70
+ __get_user(size, &ctx->size);
71
+ switch (magic) {
72
+ case 0:
73
+ if (size != 0) {
74
+ return 1;
75
+ }
76
+ ctx = NULL;
77
+ continue;
78
+
79
+ case TARGET_FPSIMD_MAGIC:
80
+ if (fpsimd || size != sizeof(struct target_fpsimd_context)) {
81
+ return 1;
82
+ }
83
+ fpsimd = (struct target_fpsimd_context *)ctx;
84
+ break;
85
+
86
+ default:
87
+ /* Unknown record -- we certainly didn't generate it.
88
+ * Did we in fact get out of sync?
89
+ */
90
+ return 1;
91
+ }
92
+ ctx = (void *)ctx + size;
93
+ }
94
+
95
+ /* Require FPSIMD always. */
96
+ if (!fpsimd) {
97
return 1;
98
}
99
+ target_restore_fpsimd_record(env, fpsimd);
100
+
101
return 0;
102
}
103
104
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
105
target_siginfo_t *info, target_sigset_t *set,
106
CPUARMState *env)
107
{
108
+ int size = offsetof(struct target_rt_sigframe, uc.tuc_mcontext.__reserved);
109
+ int fpsimd_ofs, end1_ofs, fr_ofs;
110
struct target_rt_sigframe *frame;
111
- struct target_aux_context *aux;
112
+ struct target_rt_frame_record *fr;
113
abi_ulong frame_addr, return_addr;
114
115
+ fpsimd_ofs = size;
116
+ size += sizeof(struct target_fpsimd_context);
117
+ end1_ofs = size;
118
+ size += sizeof(struct target_aarch64_ctx);
119
+ fr_ofs = size;
120
+ size += sizeof(struct target_rt_frame_record);
121
+
122
frame_addr = get_sigframe(ka, env);
123
trace_user_setup_frame(env, frame_addr);
124
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
125
goto give_sigsegv;
126
}
127
- aux = (struct target_aux_context *)frame->uc.tuc_mcontext.__reserved;
128
129
target_setup_general_frame(frame, env, set);
130
- target_setup_fpsimd_record(&aux->fpsimd, env);
131
- target_setup_end_record(&aux->end);
132
+ target_setup_fpsimd_record((void *)frame + fpsimd_ofs, env);
133
+ target_setup_end_record((void *)frame + end1_ofs);
134
+
135
+ /* Set up the stack frame for unwinding. */
136
+ fr = (void *)frame + fr_ofs;
137
+ __put_user(env->xregs[29], &fr->fp);
138
+ __put_user(env->xregs[30], &fr->lr);
139
140
if (ka->sa_flags & TARGET_SA_RESTORER) {
141
return_addr = ka->sa_restorer;
142
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
143
* Since these are instructions they need to be put as little-endian
144
* regardless of target default or current CPU endianness.
145
*/
146
- __put_user_e(0xd2801168, &frame->tramp[0], le);
147
- __put_user_e(0xd4000001, &frame->tramp[1], le);
148
- return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
149
+ __put_user_e(0xd2801168, &fr->tramp[0], le);
150
+ __put_user_e(0xd4000001, &fr->tramp[1], le);
151
+ return_addr = frame_addr + fr_ofs
152
+ + offsetof(struct target_rt_frame_record, tramp);
153
}
154
env->xregs[0] = usig;
155
env->xregs[31] = frame_addr;
156
- env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
157
+ env->xregs[29] = frame_addr + fr_ofs;
158
env->pc = ka->_sa_handler;
159
env->xregs[30] = return_addr;
160
if (info) {
161
--
162
2.16.2
163
164
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In check_s2_mmu_setup() we have a check that is attempting to
2
implement the part of AArch64.S2MinTxSZ that is specific to when EL1
3
is AArch32:
2
4
3
Depending on the currently selected size of the SVE vector registers,
5
if !s1aarch64 then
4
we can either store the data within the "standard" allocation, or we
6
// EL1 is AArch32
5
may beedn to allocate additional space with an EXTRA record.
7
min_txsz = Min(min_txsz, 24);
6
8
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Unfortunately we got this wrong in two ways:
8
Message-id: 20180303143823.27055-6-richard.henderson@linaro.org
10
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
(1) The minimum txsz corresponds to a maximum inputsize, but we got
12
the sense of the comparison wrong and were faulting for all
13
inputsizes less than 40 bits
14
15
(2) We try to implement this as an extra check that happens after
16
we've done the same txsz checks we would do for an AArch64 EL1, but
17
in fact the pseudocode is *loosening* the requirements, so that txsz
18
values that would fault for an AArch64 EL1 do not fault for AArch32
19
EL1, because it does Min(old_min, 24), not Max(old_min, 24).
20
21
You can see this also in the text of the Arm ARM in table D8-8, which
22
shows that where the implemented PA size is less than 40 bits an
23
AArch32 EL1 is still OK with a configured stage2 T0SZ for a 40 bit
24
IPA, whereas if EL1 is AArch64 then the T0SZ must be big enough to
25
constrain the IPA to the implemented PA size.
26
27
Because of part (2), we can't do this as a separate check, but
28
have to integrate it into aa64_va_parameters(). Add a new argument
29
to that function to indicate that EL1 is 32-bit. All the existing
30
callsites except the one in get_phys_addr_lpae() can pass 'false',
31
because they are either doing a lookup for a stage 1 regime or
32
else they don't care about the tsz/tsz_oob fields.
33
34
Cc: qemu-stable@nongnu.org
35
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1627
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
37
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
38
Message-id: 20230509092059.3176487-1-peter.maydell@linaro.org
11
---
39
---
12
linux-user/signal.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++-----
40
target/arm/internals.h | 12 +++++++++++-
13
1 file changed, 192 insertions(+), 18 deletions(-)
41
target/arm/gdbstub64.c | 2 +-
42
target/arm/helper.c | 15 +++++++++++++--
43
target/arm/ptw.c | 14 ++------------
44
target/arm/tcg/pauth_helper.c | 6 +++---
45
5 files changed, 30 insertions(+), 19 deletions(-)
14
46
15
diff --git a/linux-user/signal.c b/linux-user/signal.c
47
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/signal.c
49
--- a/target/arm/internals.h
18
+++ b/linux-user/signal.c
50
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ struct target_extra_context {
51
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
20
uint32_t reserved[3];
52
ARMGranuleSize gran : 2;
21
};
53
} ARMVAParameters;
22
54
23
+#define TARGET_SVE_MAGIC 0x53564501
55
+/**
24
+
56
+ * aa64_va_parameters: Return parameters for an AArch64 virtual address
25
+struct target_sve_context {
57
+ * @env: CPU
26
+ struct target_aarch64_ctx head;
58
+ * @va: virtual address to look up
27
+ uint16_t vl;
59
+ * @mmu_idx: determines translation regime to use
28
+ uint16_t reserved[3];
60
+ * @data: true if this is a data access
29
+ /* The actual SVE data immediately follows. It is layed out
61
+ * @el1_is_aa32: true if we are asking about stage 2 when EL1 is AArch32
30
+ * according to TARGET_SVE_SIG_{Z,P}REG_OFFSET, based off of
62
+ * (ignored if @mmu_idx is for a stage 1 regime; only affects tsz/tsz_oob)
31
+ * the original struct pointer.
63
+ */
32
+ */
64
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
33
+};
65
- ARMMMUIdx mmu_idx, bool data);
34
+
66
+ ARMMMUIdx mmu_idx, bool data,
35
+#define TARGET_SVE_VQ_BYTES 16
67
+ bool el1_is_aa32);
36
+
68
37
+#define TARGET_SVE_SIG_ZREG_SIZE(VQ) ((VQ) * TARGET_SVE_VQ_BYTES)
69
int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx);
38
+#define TARGET_SVE_SIG_PREG_SIZE(VQ) ((VQ) * (TARGET_SVE_VQ_BYTES / 8))
70
int aa64_va_parameter_tbid(uint64_t tcr, ARMMMUIdx mmu_idx);
39
+
71
diff --git a/target/arm/gdbstub64.c b/target/arm/gdbstub64.c
40
+#define TARGET_SVE_SIG_REGS_OFFSET \
72
index XXXXXXX..XXXXXXX 100644
41
+ QEMU_ALIGN_UP(sizeof(struct target_sve_context), TARGET_SVE_VQ_BYTES)
73
--- a/target/arm/gdbstub64.c
42
+#define TARGET_SVE_SIG_ZREG_OFFSET(VQ, N) \
74
+++ b/target/arm/gdbstub64.c
43
+ (TARGET_SVE_SIG_REGS_OFFSET + TARGET_SVE_SIG_ZREG_SIZE(VQ) * (N))
75
@@ -XXX,XX +XXX,XX @@ int aarch64_gdb_get_pauth_reg(CPUARMState *env, GByteArray *buf, int reg)
44
+#define TARGET_SVE_SIG_PREG_OFFSET(VQ, N) \
76
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
45
+ (TARGET_SVE_SIG_ZREG_OFFSET(VQ, 32) + TARGET_SVE_SIG_PREG_SIZE(VQ) * (N))
77
ARMVAParameters param;
46
+#define TARGET_SVE_SIG_FFR_OFFSET(VQ) \
78
47
+ (TARGET_SVE_SIG_PREG_OFFSET(VQ, 16))
79
- param = aa64_va_parameters(env, -is_high, mmu_idx, is_data);
48
+#define TARGET_SVE_SIG_CONTEXT_SIZE(VQ) \
80
+ param = aa64_va_parameters(env, -is_high, mmu_idx, is_data, false);
49
+ (TARGET_SVE_SIG_PREG_OFFSET(VQ, 17))
81
return gdb_get_reg64(buf, pauth_ptr_mask(param));
50
+
82
}
51
struct target_rt_sigframe {
83
default:
52
struct target_siginfo info;
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
53
struct target_ucontext uc;
85
index XXXXXXX..XXXXXXX 100644
54
@@ -XXX,XX +XXX,XX @@ static void target_setup_end_record(struct target_aarch64_ctx *end)
86
--- a/target/arm/helper.c
55
__put_user(0, &end->size);
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
89
unsigned int page_size_granule, page_shift, num, scale, exponent;
90
/* Extract one bit to represent the va selector in use. */
91
uint64_t select = sextract64(value, 36, 1);
92
- ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
93
+ ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true, false);
94
TLBIRange ret = { };
95
ARMGranuleSize gran;
96
97
@@ -XXX,XX +XXX,XX @@ static ARMGranuleSize sanitize_gran_size(ARMCPU *cpu, ARMGranuleSize gran,
56
}
98
}
57
99
58
+static void target_setup_sve_record(struct target_sve_context *sve,
100
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
59
+ CPUARMState *env, int vq, int size)
101
- ARMMMUIdx mmu_idx, bool data)
60
+{
102
+ ARMMMUIdx mmu_idx, bool data,
61
+ int i, j;
103
+ bool el1_is_aa32)
62
+
63
+ __put_user(TARGET_SVE_MAGIC, &sve->head.magic);
64
+ __put_user(size, &sve->head.size);
65
+ __put_user(vq * TARGET_SVE_VQ_BYTES, &sve->vl);
66
+
67
+ /* Note that SVE regs are stored as a byte stream, with each byte element
68
+ * at a subsequent address. This corresponds to a little-endian store
69
+ * of our 64-bit hunks.
70
+ */
71
+ for (i = 0; i < 32; ++i) {
72
+ uint64_t *z = (void *)sve + TARGET_SVE_SIG_ZREG_OFFSET(vq, i);
73
+ for (j = 0; j < vq * 2; ++j) {
74
+ __put_user_e(env->vfp.zregs[i].d[j], z + j, le);
75
+ }
76
+ }
77
+ for (i = 0; i <= 16; ++i) {
78
+ uint16_t *p = (void *)sve + TARGET_SVE_SIG_PREG_OFFSET(vq, i);
79
+ for (j = 0; j < vq; ++j) {
80
+ uint64_t r = env->vfp.pregs[i].p[j >> 2];
81
+ __put_user_e(r >> ((j & 3) * 16), p + j, le);
82
+ }
83
+ }
84
+}
85
+
86
static void target_restore_general_frame(CPUARMState *env,
87
struct target_rt_sigframe *sf)
88
{
104
{
89
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
105
uint64_t tcr = regime_tcr(env, mmu_idx);
106
bool epd, hpd, tsz_oob, ds, ha, hd;
107
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
108
}
90
}
109
}
91
}
110
92
111
+ if (stage2 && el1_is_aa32) {
93
+static void target_restore_sve_record(CPUARMState *env,
112
+ /*
94
+ struct target_sve_context *sve, int vq)
113
+ * For AArch32 EL1 the min txsz (and thus max IPA size) requirements
95
+{
114
+ * are loosened: a configured IPA of 40 bits is permitted even if
96
+ int i, j;
115
+ * the implemented PA is less than that (and so a 40 bit IPA would
97
+
116
+ * fault for an AArch64 EL1). See R_DTLMN.
98
+ /* Note that SVE regs are stored as a byte stream, with each byte element
117
+ */
99
+ * at a subsequent address. This corresponds to a little-endian load
118
+ min_tsz = MIN(min_tsz, 24);
100
+ * of our 64-bit hunks.
101
+ */
102
+ for (i = 0; i < 32; ++i) {
103
+ uint64_t *z = (void *)sve + TARGET_SVE_SIG_ZREG_OFFSET(vq, i);
104
+ for (j = 0; j < vq * 2; ++j) {
105
+ __get_user_e(env->vfp.zregs[i].d[j], z + j, le);
106
+ }
107
+ }
108
+ for (i = 0; i <= 16; ++i) {
109
+ uint16_t *p = (void *)sve + TARGET_SVE_SIG_PREG_OFFSET(vq, i);
110
+ for (j = 0; j < vq; ++j) {
111
+ uint16_t r;
112
+ __get_user_e(r, p + j, le);
113
+ if (j & 3) {
114
+ env->vfp.pregs[i].p[j >> 2] |= (uint64_t)r << ((j & 3) * 16);
115
+ } else {
116
+ env->vfp.pregs[i].p[j >> 2] = r;
117
+ }
118
+ }
119
+ }
120
+}
121
+
122
static int target_restore_sigframe(CPUARMState *env,
123
struct target_rt_sigframe *sf)
124
{
125
struct target_aarch64_ctx *ctx, *extra = NULL;
126
struct target_fpsimd_context *fpsimd = NULL;
127
+ struct target_sve_context *sve = NULL;
128
uint64_t extra_datap = 0;
129
bool used_extra = false;
130
bool err = false;
131
+ int vq = 0, sve_size = 0;
132
133
target_restore_general_frame(env, sf);
134
135
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
136
fpsimd = (struct target_fpsimd_context *)ctx;
137
break;
138
139
+ case TARGET_SVE_MAGIC:
140
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
141
+ vq = (env->vfp.zcr_el[1] & 0xf) + 1;
142
+ sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
143
+ if (!sve && size == sve_size) {
144
+ sve = (struct target_sve_context *)ctx;
145
+ break;
146
+ }
147
+ }
148
+ err = true;
149
+ goto exit;
150
+
151
case TARGET_EXTRA_MAGIC:
152
if (extra || size != sizeof(struct target_extra_context)) {
153
err = true;
154
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
155
err = true;
156
}
157
158
+ /* SVE data, if present, overwrites FPSIMD data. */
159
+ if (sve) {
160
+ target_restore_sve_record(env, sve, vq);
161
+ }
119
+ }
162
+
120
+
163
exit:
121
if (tsz > max_tsz) {
164
unlock_user(extra, extra_datap, 0);
122
tsz = max_tsz;
165
return err;
123
tsz_oob = true;
124
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/target/arm/ptw.c
127
+++ b/target/arm/ptw.c
128
@@ -XXX,XX +XXX,XX @@ static int check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, uint64_t tcr,
129
130
sl0 = extract32(tcr, 6, 2);
131
if (is_aa64) {
132
- /*
133
- * AArch64.S2InvalidTxSZ: While we checked tsz_oob near the top of
134
- * get_phys_addr_lpae, that used aa64_va_parameters which apply
135
- * to aarch64. If Stage1 is aarch32, the min_txsz is larger.
136
- * See AArch64.S2MinTxSZ, where min_tsz is 24, translated to
137
- * inputsize is 64 - 24 = 40.
138
- */
139
- if (iasize < 40 && !arm_el_is_aa64(&cpu->env, 1)) {
140
- goto fail;
141
- }
142
-
143
/*
144
* AArch64.S2InvalidSL: Interpretation of SL depends on the page size,
145
* so interleave AArch64.S2StartLevel.
146
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
147
int ps;
148
149
param = aa64_va_parameters(env, address, mmu_idx,
150
- access_type != MMU_INST_FETCH);
151
+ access_type != MMU_INST_FETCH,
152
+ !arm_el_is_aa64(env, 1));
153
level = 0;
154
155
/*
156
diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/target/arm/tcg/pauth_helper.c
159
+++ b/target/arm/tcg/pauth_helper.c
160
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
161
ARMPACKey *key, bool data)
162
{
163
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
164
- ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
165
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data, false);
166
uint64_t pac, ext_ptr, ext, test;
167
int bot_bit, top_bit;
168
169
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
170
ARMPACKey *key, bool data, int keynumber)
171
{
172
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
173
- ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
174
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data, false);
175
int bot_bit, top_bit;
176
uint64_t pac, orig_ptr, test;
177
178
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
179
static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
180
{
181
ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
182
- ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
183
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data, false);
184
185
return pauth_original_ptr(ptr, param);
166
}
186
}
167
168
-static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
169
+static abi_ulong get_sigframe(struct target_sigaction *ka,
170
+ CPUARMState *env, int size)
171
{
172
abi_ulong sp;
173
174
@@ -XXX,XX +XXX,XX @@ static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
175
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
176
}
177
178
- sp = (sp - sizeof(struct target_rt_sigframe)) & ~15;
179
+ sp = (sp - size) & ~15;
180
181
return sp;
182
}
183
184
+typedef struct {
185
+ int total_size;
186
+ int extra_base;
187
+ int extra_size;
188
+ int std_end_ofs;
189
+ int extra_ofs;
190
+ int extra_end_ofs;
191
+} target_sigframe_layout;
192
+
193
+static int alloc_sigframe_space(int this_size, target_sigframe_layout *l)
194
+{
195
+ /* Make sure there will always be space for the end marker. */
196
+ const int std_size = sizeof(struct target_rt_sigframe)
197
+ - sizeof(struct target_aarch64_ctx);
198
+ int this_loc = l->total_size;
199
+
200
+ if (l->extra_base) {
201
+ /* Once we have begun an extra space, all allocations go there. */
202
+ l->extra_size += this_size;
203
+ } else if (this_size + this_loc > std_size) {
204
+ /* This allocation does not fit in the standard space. */
205
+ /* Allocate the extra record. */
206
+ l->extra_ofs = this_loc;
207
+ l->total_size += sizeof(struct target_extra_context);
208
+
209
+ /* Allocate the standard end record. */
210
+ l->std_end_ofs = l->total_size;
211
+ l->total_size += sizeof(struct target_aarch64_ctx);
212
+
213
+ /* Allocate the requested record. */
214
+ l->extra_base = this_loc = l->total_size;
215
+ l->extra_size = this_size;
216
+ }
217
+ l->total_size += this_size;
218
+
219
+ return this_loc;
220
+}
221
+
222
static void target_setup_frame(int usig, struct target_sigaction *ka,
223
target_siginfo_t *info, target_sigset_t *set,
224
CPUARMState *env)
225
{
226
- int size = offsetof(struct target_rt_sigframe, uc.tuc_mcontext.__reserved);
227
- int fpsimd_ofs, end1_ofs, fr_ofs, end2_ofs = 0;
228
- int extra_ofs = 0, extra_base = 0, extra_size = 0;
229
+ target_sigframe_layout layout = {
230
+ /* Begin with the size pointing to the reserved space. */
231
+ .total_size = offsetof(struct target_rt_sigframe,
232
+ uc.tuc_mcontext.__reserved),
233
+ };
234
+ int fpsimd_ofs, fr_ofs, sve_ofs = 0, vq = 0, sve_size = 0;
235
struct target_rt_sigframe *frame;
236
struct target_rt_frame_record *fr;
237
abi_ulong frame_addr, return_addr;
238
239
- fpsimd_ofs = size;
240
- size += sizeof(struct target_fpsimd_context);
241
- end1_ofs = size;
242
- size += sizeof(struct target_aarch64_ctx);
243
- fr_ofs = size;
244
- size += sizeof(struct target_rt_frame_record);
245
+ /* FPSIMD record is always in the standard space. */
246
+ fpsimd_ofs = alloc_sigframe_space(sizeof(struct target_fpsimd_context),
247
+ &layout);
248
249
- frame_addr = get_sigframe(ka, env);
250
+ /* SVE state needs saving only if it exists. */
251
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
252
+ vq = (env->vfp.zcr_el[1] & 0xf) + 1;
253
+ sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
254
+ sve_ofs = alloc_sigframe_space(sve_size, &layout);
255
+ }
256
+
257
+ if (layout.extra_ofs) {
258
+ /* Reserve space for the extra end marker. The standard end marker
259
+ * will have been allocated when we allocated the extra record.
260
+ */
261
+ layout.extra_end_ofs
262
+ = alloc_sigframe_space(sizeof(struct target_aarch64_ctx), &layout);
263
+ } else {
264
+ /* Reserve space for the standard end marker.
265
+ * Do not use alloc_sigframe_space because we cheat
266
+ * std_size therein to reserve space for this.
267
+ */
268
+ layout.std_end_ofs = layout.total_size;
269
+ layout.total_size += sizeof(struct target_aarch64_ctx);
270
+ }
271
+
272
+ /* Reserve space for the return code. On a real system this would
273
+ * be within the VDSO. So, despite the name this is not a "real"
274
+ * record within the frame.
275
+ */
276
+ fr_ofs = layout.total_size;
277
+ layout.total_size += sizeof(struct target_rt_frame_record);
278
+
279
+ frame_addr = get_sigframe(ka, env, layout.total_size);
280
trace_user_setup_frame(env, frame_addr);
281
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
282
goto give_sigsegv;
283
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
284
285
target_setup_general_frame(frame, env, set);
286
target_setup_fpsimd_record((void *)frame + fpsimd_ofs, env);
287
- if (extra_ofs) {
288
- target_setup_extra_record((void *)frame + extra_ofs,
289
- frame_addr + extra_base, extra_size);
290
+ target_setup_end_record((void *)frame + layout.std_end_ofs);
291
+ if (layout.extra_ofs) {
292
+ target_setup_extra_record((void *)frame + layout.extra_ofs,
293
+ frame_addr + layout.extra_base,
294
+ layout.extra_size);
295
+ target_setup_end_record((void *)frame + layout.extra_end_ofs);
296
}
297
- target_setup_end_record((void *)frame + end1_ofs);
298
- if (end2_ofs) {
299
- target_setup_end_record((void *)frame + end2_ofs);
300
+ if (sve_ofs) {
301
+ target_setup_sve_record((void *)frame + sve_ofs, env, vq, sve_size);
302
}
303
304
/* Set up the stack frame for unwinding. */
305
--
187
--
306
2.16.2
188
2.34.1
307
308
diff view generated by jsdifflib
Deleted patch
1
From: Thomas Huth <thuth@redhat.com>
2
1
3
A lot of ARM object files are linked into the executable unconditionally,
4
even though we have corresponding CONFIG switches like CONFIG_PXA2XX or
5
CONFIG_OMAP. We should make sure to use these switches in the Makefile so
6
that the users can disable certain unwanted boards and devices more easily.
7
While we're at it, also add some new switches for the boards that do not
8
have a CONFIG option yet.
9
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
11
Message-id: 1520266949-29817-1-git-send-email-thuth@redhat.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/arm/Makefile.objs | 30 +++++++++++++++++++++---------
17
default-configs/arm-softmmu.mak | 7 +++++++
18
2 files changed, 28 insertions(+), 9 deletions(-)
19
20
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/Makefile.objs
23
+++ b/hw/arm/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@
25
-obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
26
-obj-$(CONFIG_DIGIC) += digic_boards.o
27
-obj-y += integratorcp.o mainstone.o musicpal.o nseries.o
28
-obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
29
-obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
30
+obj-y += boot.o virt.o sysbus-fdt.o
31
obj-$(CONFIG_ACPI) += virt-acpi-build.o
32
-obj-y += netduino2.o
33
-obj-y += sysbus-fdt.o
34
+obj-$(CONFIG_DIGIC) += digic_boards.o
35
+obj-$(CONFIG_EXYNOS4) += exynos4_boards.o
36
+obj-$(CONFIG_HIGHBANK) += highbank.o
37
+obj-$(CONFIG_INTEGRATOR) += integratorcp.o
38
+obj-$(CONFIG_MAINSTONE) += mainstone.o
39
+obj-$(CONFIG_MUSICPAL) += musicpal.o
40
+obj-$(CONFIG_NETDUINO2) += netduino2.o
41
+obj-$(CONFIG_NSERIES) += nseries.o
42
+obj-$(CONFIG_OMAP) += omap_sx1.o palm.o
43
+obj-$(CONFIG_PXA2XX) += gumstix.o spitz.o tosa.o z2.o
44
+obj-$(CONFIG_REALVIEW) += realview.o
45
+obj-$(CONFIG_STELLARIS) += stellaris.o
46
+obj-$(CONFIG_STRONGARM) += collie.o
47
+obj-$(CONFIG_VERSATILE) += vexpress.o versatilepb.o
48
+obj-$(CONFIG_ZYNQ) += xilinx_zynq.o
49
50
-obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
51
+obj-$(CONFIG_ARM_V7M) += armv7m.o
52
+obj-$(CONFIG_EXYNOS4) += exynos4210.o
53
+obj-$(CONFIG_PXA2XX) += pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
54
obj-$(CONFIG_DIGIC) += digic.o
55
-obj-y += omap1.o omap2.o strongarm.o
56
+obj-$(CONFIG_OMAP) += omap1.o omap2.o
57
+obj-$(CONFIG_STRONGARM) += strongarm.o
58
obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
59
obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
60
obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
61
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
62
index XXXXXXX..XXXXXXX 100644
63
--- a/default-configs/arm-softmmu.mak
64
+++ b/default-configs/arm-softmmu.mak
65
@@ -XXX,XX +XXX,XX @@ CONFIG_A9MPCORE=y
66
CONFIG_A15MPCORE=y
67
68
CONFIG_ARM_V7M=y
69
+CONFIG_NETDUINO2=y
70
71
CONFIG_ARM_GIC=y
72
CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
73
@@ -XXX,XX +XXX,XX @@ CONFIG_TZ_PPC=y
74
CONFIG_IOTKIT=y
75
CONFIG_IOTKIT_SECCTL=y
76
77
+CONFIG_VERSATILE=y
78
CONFIG_VERSATILE_PCI=y
79
CONFIG_VERSATILE_I2C=y
80
81
@@ -XXX,XX +XXX,XX @@ CONFIG_VFIO_XGMAC=y
82
CONFIG_VFIO_AMD_XGBE=y
83
84
CONFIG_SDHCI=y
85
+CONFIG_INTEGRATOR=y
86
CONFIG_INTEGRATOR_DEBUG=y
87
88
CONFIG_ALLWINNER_A10_PIT=y
89
@@ -XXX,XX +XXX,XX @@ CONFIG_MSF2=y
90
CONFIG_FW_CFG_DMA=y
91
CONFIG_XILINX_AXI=y
92
CONFIG_PCI_DESIGNWARE=y
93
+
94
+CONFIG_STRONGARM=y
95
+CONFIG_HIGHBANK=y
96
+CONFIG_MUSICPAL=y
97
--
98
2.16.2
99
100
diff view generated by jsdifflib
Deleted patch
1
From: Marc-André Lureau <marcandre.lureau@redhat.com>
2
1
3
Spotted by ASAN:
4
5
elmarco@boraha:~/src/qemu/build (master *%)$ QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 tests/boot-serial-test
6
/aarch64/boot-serial/virt: ** (process:19740): DEBUG: 18:39:30.275: foo /tmp/qtest-boot-serial-cXaS94D
7
=================================================================
8
==19740==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000069648 at pc 0x7f1d2201cc54 bp 0x7fff331f6a40 sp 0x7fff331f61e8
9
READ of size 4 at 0x603000069648 thread T0
10
#0 0x7f1d2201cc53 (/lib64/libasan.so.4+0xafc53)
11
#1 0x55bc86685ee3 in load_aarch64_image /home/elmarco/src/qemu/hw/arm/boot.c:894
12
#2 0x55bc86687217 in arm_load_kernel_notify /home/elmarco/src/qemu/hw/arm/boot.c:1047
13
#3 0x55bc877363b5 in notifier_list_notify /home/elmarco/src/qemu/util/notify.c:40
14
#4 0x55bc869331ea in qemu_run_machine_init_done_notifiers /home/elmarco/src/qemu/vl.c:2716
15
#5 0x55bc8693bc39 in main /home/elmarco/src/qemu/vl.c:4679
16
#6 0x7f1d1652c009 in __libc_start_main (/lib64/libc.so.6+0x21009)
17
#7 0x55bc86255cc9 in _start (/home/elmarco/src/qemu/build/aarch64-softmmu/qemu-system-aarch64+0x1ae5cc9)
18
19
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/arm/boot.c | 3 ++-
24
1 file changed, 2 insertions(+), 1 deletion(-)
25
26
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/boot.c
29
+++ b/hw/arm/boot.c
30
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
31
}
32
33
/* check the arm64 magic header value -- very old kernels may not have it */
34
- if (memcmp(buffer + ARM64_MAGIC_OFFSET, "ARM\x64", 4) == 0) {
35
+ if (size > ARM64_MAGIC_OFFSET + 4 &&
36
+ memcmp(buffer + ARM64_MAGIC_OFFSET, "ARM\x64", 4) == 0) {
37
uint64_t hdrvals[2];
38
39
/* The arm64 Image header has text_offset and image_size fields at 8 and
40
--
41
2.16.2
42
43
diff view generated by jsdifflib
Deleted patch
1
Currently we query the host CPU features in the class init function
2
for the TYPE_ARM_HOST_CPU class, so that we can later copy them
3
from the class object into the instance object in the object
4
instance init function. This is awkward for implementing "-cpu max",
5
which should work like "-cpu host" for KVM but like "cpu with all
6
implemented features" for TCG.
7
1
8
Move the place where we store the information about the host CPU from
9
a class object to static variables in kvm.c, and then in the instance
10
init function call a new kvm_arm_set_cpu_features_from_host()
11
function which will query the host kernel if necessary and then
12
fill in the CPU instance fields.
13
14
This allows us to drop the special class struct and class init
15
function for TYPE_ARM_HOST_CPU entirely.
16
17
We can't delay the probe until realize, because the ARM
18
instance_post_init hook needs to look at the feature bits we
19
set, so we need to do it in the initfn. This is safe because
20
the probing doesn't affect the actual VM state (it creates a
21
separate scratch VM to do its testing), but the probe might fail.
22
Because we can't report errors in retrieving the host features
23
in the initfn, we check this belatedly in the realize function
24
(the intervening code will be able to cope with the relevant
25
fields in the CPU structure being zero).
26
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
29
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
30
Message-id: 20180308130626.12393-2-peter.maydell@linaro.org
31
---
32
target/arm/cpu.h | 5 +++++
33
target/arm/kvm_arm.h | 35 ++++++++++++++++++++++++-----------
34
target/arm/cpu.c | 13 +++++++++++++
35
target/arm/kvm.c | 36 +++++++++++++++++++-----------------
36
target/arm/kvm32.c | 8 ++++----
37
target/arm/kvm64.c | 8 ++++----
38
6 files changed, 69 insertions(+), 36 deletions(-)
39
40
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/cpu.h
43
+++ b/target/arm/cpu.h
44
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
45
/* Uniprocessor system with MP extensions */
46
bool mp_is_up;
47
48
+ /* True if we tried kvm_arm_host_cpu_features() during CPU instance_init
49
+ * and the probe failed (so we need to report the error in realize)
50
+ */
51
+ bool host_cpu_probe_failed;
52
+
53
/* Specify the number of cores in this CPU cluster. Used for the L2CTLR
54
* register.
55
*/
56
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/kvm_arm.h
59
+++ b/target/arm/kvm_arm.h
60
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
61
void kvm_arm_destroy_scratch_host_vcpu(int *fdarray);
62
63
#define TYPE_ARM_HOST_CPU "host-" TYPE_ARM_CPU
64
-#define ARM_HOST_CPU_CLASS(klass) \
65
- OBJECT_CLASS_CHECK(ARMHostCPUClass, (klass), TYPE_ARM_HOST_CPU)
66
-#define ARM_HOST_CPU_GET_CLASS(obj) \
67
- OBJECT_GET_CLASS(ARMHostCPUClass, (obj), TYPE_ARM_HOST_CPU)
68
-
69
-typedef struct ARMHostCPUClass {
70
- /*< private >*/
71
- ARMCPUClass parent_class;
72
- /*< public >*/
73
74
+/**
75
+ * ARMHostCPUFeatures: information about the host CPU (identified
76
+ * by asking the host kernel)
77
+ */
78
+typedef struct ARMHostCPUFeatures {
79
uint64_t features;
80
uint32_t target;
81
const char *dtb_compatible;
82
-} ARMHostCPUClass;
83
+} ARMHostCPUFeatures;
84
85
/**
86
* kvm_arm_get_host_cpu_features:
87
@@ -XXX,XX +XXX,XX @@ typedef struct ARMHostCPUClass {
88
* Probe the capabilities of the host kernel's preferred CPU and fill
89
* in the ARMHostCPUClass struct accordingly.
90
*/
91
-bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc);
92
+bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
93
94
+/**
95
+ * kvm_arm_set_cpu_features_from_host:
96
+ * @cpu: ARMCPU to set the features for
97
+ *
98
+ * Set up the ARMCPU struct fields up to match the information probed
99
+ * from the host CPU.
100
+ */
101
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
102
103
/**
104
* kvm_arm_sync_mpstate_to_kvm
105
@@ -XXX,XX +XXX,XX @@ void kvm_arm_pmu_init(CPUState *cs);
106
107
#else
108
109
+static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
110
+{
111
+ /* This should never actually be called in the "not KVM" case,
112
+ * but set up the fields to indicate an error anyway.
113
+ */
114
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
115
+ cpu->host_cpu_probe_failed = true;
116
+}
117
+
118
static inline int kvm_arm_vgic_probe(void)
119
{
120
return 0;
121
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/target/arm/cpu.c
124
+++ b/target/arm/cpu.c
125
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
126
int pagebits;
127
Error *local_err = NULL;
128
129
+ /* If we needed to query the host kernel for the CPU features
130
+ * then it's possible that might have failed in the initfn, but
131
+ * this is the first point where we can report it.
132
+ */
133
+ if (cpu->host_cpu_probe_failed) {
134
+ if (!kvm_enabled()) {
135
+ error_setg(errp, "The 'host' CPU type can only be used with KVM");
136
+ } else {
137
+ error_setg(errp, "Failed to retrieve host CPU features");
138
+ }
139
+ return;
140
+ }
141
+
142
cpu_exec_realizefn(cs, &local_err);
143
if (local_err != NULL) {
144
error_propagate(errp, local_err);
145
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/kvm.c
148
+++ b/target/arm/kvm.c
149
@@ -XXX,XX +XXX,XX @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
150
151
static bool cap_has_mp_state;
152
153
+static ARMHostCPUFeatures arm_host_cpu_features;
154
+
155
int kvm_arm_vcpu_init(CPUState *cs)
156
{
157
ARMCPU *cpu = ARM_CPU(cs);
158
@@ -XXX,XX +XXX,XX @@ void kvm_arm_destroy_scratch_host_vcpu(int *fdarray)
159
}
160
}
161
162
-static void kvm_arm_host_cpu_class_init(ObjectClass *oc, void *data)
163
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
164
{
165
- ARMHostCPUClass *ahcc = ARM_HOST_CPU_CLASS(oc);
166
+ CPUARMState *env = &cpu->env;
167
168
- /* All we really need to set up for the 'host' CPU
169
- * is the feature bits -- we rely on the fact that the
170
- * various ID register values in ARMCPU are only used for
171
- * TCG CPUs.
172
- */
173
- if (!kvm_arm_get_host_cpu_features(ahcc)) {
174
- fprintf(stderr, "Failed to retrieve host CPU features!\n");
175
- abort();
176
+ if (!arm_host_cpu_features.dtb_compatible) {
177
+ if (!kvm_enabled() ||
178
+ !kvm_arm_get_host_cpu_features(&arm_host_cpu_features)) {
179
+ /* We can't report this error yet, so flag that we need to
180
+ * in arm_cpu_realizefn().
181
+ */
182
+ cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
183
+ cpu->host_cpu_probe_failed = true;
184
+ return;
185
+ }
186
}
187
+
188
+ cpu->kvm_target = arm_host_cpu_features.target;
189
+ cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
190
+ env->features = arm_host_cpu_features.features;
191
}
192
193
static void kvm_arm_host_cpu_initfn(Object *obj)
194
{
195
- ARMHostCPUClass *ahcc = ARM_HOST_CPU_GET_CLASS(obj);
196
ARMCPU *cpu = ARM_CPU(obj);
197
- CPUARMState *env = &cpu->env;
198
199
- cpu->kvm_target = ahcc->target;
200
- cpu->dtb_compatible = ahcc->dtb_compatible;
201
- env->features = ahcc->features;
202
+ kvm_arm_set_cpu_features_from_host(cpu);
203
}
204
205
static const TypeInfo host_arm_cpu_type_info = {
206
@@ -XXX,XX +XXX,XX @@ static const TypeInfo host_arm_cpu_type_info = {
207
.parent = TYPE_ARM_CPU,
208
#endif
209
.instance_init = kvm_arm_host_cpu_initfn,
210
- .class_init = kvm_arm_host_cpu_class_init,
211
- .class_size = sizeof(ARMHostCPUClass),
212
};
213
214
int kvm_arch_init(MachineState *ms, KVMState *s)
215
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
216
index XXXXXXX..XXXXXXX 100644
217
--- a/target/arm/kvm32.c
218
+++ b/target/arm/kvm32.c
219
@@ -XXX,XX +XXX,XX @@ static inline void set_feature(uint64_t *features, int feature)
220
*features |= 1ULL << feature;
221
}
222
223
-bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
224
+bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
225
{
226
/* Identify the feature bits corresponding to the host CPU, and
227
* fill out the ARMHostCPUClass fields accordingly. To do this
228
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
229
return false;
230
}
231
232
- ahcc->target = init.target;
233
+ ahcf->target = init.target;
234
235
/* This is not strictly blessed by the device tree binding docs yet,
236
* but in practice the kernel does not care about this string so
237
* there is no point maintaining an KVM_ARM_TARGET_* -> string table.
238
*/
239
- ahcc->dtb_compatible = "arm,arm-v7";
240
+ ahcf->dtb_compatible = "arm,arm-v7";
241
242
for (i = 0; i < ARRAY_SIZE(idregs); i++) {
243
ret = ioctl(fdarray[2], KVM_GET_ONE_REG, &idregs[i]);
244
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
245
set_feature(&features, ARM_FEATURE_VFP4);
246
}
247
248
- ahcc->features = features;
249
+ ahcf->features = features;
250
251
return true;
252
}
253
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
254
index XXXXXXX..XXXXXXX 100644
255
--- a/target/arm/kvm64.c
256
+++ b/target/arm/kvm64.c
257
@@ -XXX,XX +XXX,XX @@ static inline void unset_feature(uint64_t *features, int feature)
258
*features &= ~(1ULL << feature);
259
}
260
261
-bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
262
+bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
263
{
264
/* Identify the feature bits corresponding to the host CPU, and
265
* fill out the ARMHostCPUClass fields accordingly. To do this
266
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
267
return false;
268
}
269
270
- ahcc->target = init.target;
271
- ahcc->dtb_compatible = "arm,arm-v8";
272
+ ahcf->target = init.target;
273
+ ahcf->dtb_compatible = "arm,arm-v8";
274
275
kvm_arm_destroy_scratch_host_vcpu(fdarray);
276
277
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
278
set_feature(&features, ARM_FEATURE_AARCH64);
279
set_feature(&features, ARM_FEATURE_PMU);
280
281
- ahcc->features = features;
282
+ ahcf->features = features;
283
284
return true;
285
}
286
--
287
2.16.2
288
289
diff view generated by jsdifflib
Deleted patch
1
Add support for "-cpu max" for ARM guests. This CPU type behaves
2
like "-cpu host" when KVM is enabled, and like a system CPU with
3
the maximum possible feature set otherwise. (Note that this means
4
it won't be migratable across versions, as we will likely add
5
features to it in future.)
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180308130626.12393-4-peter.maydell@linaro.org
10
---
11
target/arm/cpu-qom.h | 2 ++
12
target/arm/cpu.c | 24 ++++++++++++++++++++++++
13
target/arm/cpu64.c | 21 +++++++++++++++++++++
14
3 files changed, 47 insertions(+)
15
16
diff --git a/target/arm/cpu-qom.h b/target/arm/cpu-qom.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu-qom.h
19
+++ b/target/arm/cpu-qom.h
20
@@ -XXX,XX +XXX,XX @@ struct arm_boot_info;
21
#define ARM_CPU_GET_CLASS(obj) \
22
OBJECT_GET_CLASS(ARMCPUClass, (obj), TYPE_ARM_CPU)
23
24
+#define TYPE_ARM_MAX_CPU "max-" TYPE_ARM_CPU
25
+
26
/**
27
* ARMCPUClass:
28
* @parent_realize: The parent class' realize handler.
29
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.c
32
+++ b/target/arm/cpu.c
33
@@ -XXX,XX +XXX,XX @@ static void pxa270c5_initfn(Object *obj)
34
cpu->reset_sctlr = 0x00000078;
35
}
36
37
+#ifndef TARGET_AARCH64
38
+/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
39
+ * otherwise, a CPU with as many features enabled as our emulation supports.
40
+ * The version of '-cpu max' for qemu-system-aarch64 is defined in cpu64.c;
41
+ * this only needs to handle 32 bits.
42
+ */
43
+static void arm_max_initfn(Object *obj)
44
+{
45
+ ARMCPU *cpu = ARM_CPU(obj);
46
+
47
+ if (kvm_enabled()) {
48
+ kvm_arm_set_cpu_features_from_host(cpu);
49
+ } else {
50
+ cortex_a15_initfn(obj);
51
+ /* In future we might add feature bits here even if the
52
+ * real-world A15 doesn't implement them.
53
+ */
54
+ }
55
+}
56
+#endif
57
+
58
#ifdef CONFIG_USER_ONLY
59
static void arm_any_initfn(Object *obj)
60
{
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
62
{ .name = "pxa270-b1", .initfn = pxa270b1_initfn },
63
{ .name = "pxa270-c0", .initfn = pxa270c0_initfn },
64
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
65
+#ifndef TARGET_AARCH64
66
+ { .name = "max", .initfn = arm_max_initfn },
67
+#endif
68
#ifdef CONFIG_USER_ONLY
69
{ .name = "any", .initfn = arm_any_initfn },
70
#endif
71
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/cpu64.c
74
+++ b/target/arm/cpu64.c
75
@@ -XXX,XX +XXX,XX @@
76
#include "hw/arm/arm.h"
77
#include "sysemu/sysemu.h"
78
#include "sysemu/kvm.h"
79
+#include "kvm_arm.h"
80
81
static inline void set_feature(CPUARMState *env, int feature)
82
{
83
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
84
define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
85
}
86
87
+/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
88
+ * otherwise, a CPU with as many features enabled as our emulation supports.
89
+ * The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
90
+ * this only needs to handle 64 bits.
91
+ */
92
+static void aarch64_max_initfn(Object *obj)
93
+{
94
+ ARMCPU *cpu = ARM_CPU(obj);
95
+
96
+ if (kvm_enabled()) {
97
+ kvm_arm_set_cpu_features_from_host(cpu);
98
+ } else {
99
+ aarch64_a57_initfn(obj);
100
+ /* In future we might add feature bits here even if the
101
+ * real-world A57 doesn't implement them.
102
+ */
103
+ }
104
+}
105
+
106
#ifdef CONFIG_USER_ONLY
107
static void aarch64_any_initfn(Object *obj)
108
{
109
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCPUInfo {
110
static const ARMCPUInfo aarch64_cpus[] = {
111
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
112
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
113
+ { .name = "max", .initfn = aarch64_max_initfn },
114
#ifdef CONFIG_USER_ONLY
115
{ .name = "any", .initfn = aarch64_any_initfn },
116
#endif
117
--
118
2.16.2
119
120
diff view generated by jsdifflib
Deleted patch
1
Allow the virt board to support '-cpu max' in the same way
2
it already handles '-cpu host'.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180308130626.12393-6-peter.maydell@linaro.org
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
---
9
hw/arm/virt.c | 1 +
10
1 file changed, 1 insertion(+)
11
12
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/virt.c
15
+++ b/hw/arm/virt.c
16
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
17
ARM_CPU_TYPE_NAME("cortex-a53"),
18
ARM_CPU_TYPE_NAME("cortex-a57"),
19
ARM_CPU_TYPE_NAME("host"),
20
+ ARM_CPU_TYPE_NAME("max"),
21
};
22
23
static bool cpu_type_valid(const char *cpu)
24
--
25
2.16.2
26
27
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
5
Message-id: 20180309153654.13518-2-f4bug@amsat.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
hw/sd/sd.c | 11 ++++++++---
10
1 file changed, 8 insertions(+), 3 deletions(-)
11
12
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sd.c
15
+++ b/hw/sd/sd.c
16
@@ -XXX,XX +XXX,XX @@ static void sd_lock_command(SDState *sd)
17
sd->card_status &= ~CARD_IS_LOCKED;
18
}
19
20
-static sd_rsp_type_t sd_normal_command(SDState *sd,
21
- SDRequest req)
22
+static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
23
{
24
uint32_t rca = 0x0000;
25
uint64_t addr = (sd->ocr & (1 << 30)) ? (uint64_t) req.arg << 9 : req.arg;
26
27
- trace_sdcard_normal_command(req.cmd, req.arg, sd_state_name(sd->state));
28
+ /* CMD55 precedes an ACMD, so we are not interested in tracing it.
29
+ * However there is no ACMD55, so we want to trace this particular case.
30
+ */
31
+ if (req.cmd != 55 || sd->expecting_acmd) {
32
+ trace_sdcard_normal_command(req.cmd, req.arg,
33
+ sd_state_name(sd->state));
34
+ }
35
36
/* Not interpreting this as an app command */
37
sd->card_status &= ~APP_CMD;
38
--
39
2.16.2
40
41
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
The SDBus will reuse these functions, so we put them in a new source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20180309153654.13518-3-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
[PMM: slight wordsmithing of comments, added note that string
9
returned does not need to be freed]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/sd/Makefile.objs | 2 +-
13
hw/sd/sdmmc-internal.h | 24 +++++++++++++++++
14
hw/sd/sd.c | 13 +++++----
15
hw/sd/sdmmc-internal.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
16
hw/sd/trace-events | 8 +++---
17
5 files changed, 109 insertions(+), 10 deletions(-)
18
create mode 100644 hw/sd/sdmmc-internal.c
19
20
diff --git a/hw/sd/Makefile.objs b/hw/sd/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/sd/Makefile.objs
23
+++ b/hw/sd/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@
25
common-obj-$(CONFIG_PL181) += pl181.o
26
common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
27
-common-obj-$(CONFIG_SD) += sd.o core.o
28
+common-obj-$(CONFIG_SD) += sd.o core.o sdmmc-internal.o
29
common-obj-$(CONFIG_SDHCI) += sdhci.o
30
31
obj-$(CONFIG_MILKYMIST) += milkymist-memcard.o
32
diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/sd/sdmmc-internal.h
35
+++ b/hw/sd/sdmmc-internal.h
36
@@ -XXX,XX +XXX,XX @@
37
38
#define SDMMC_CMD_MAX 64
39
40
+/**
41
+ * sd_cmd_name:
42
+ * @cmd: A SD "normal" command, up to SDMMC_CMD_MAX.
43
+ *
44
+ * Returns a human-readable name describing the command.
45
+ * The return value is always a static string which does not need
46
+ * to be freed after use.
47
+ *
48
+ * Returns: The command name of @cmd or "UNKNOWN_CMD".
49
+ */
50
+const char *sd_cmd_name(uint8_t cmd);
51
+
52
+/**
53
+ * sd_acmd_name:
54
+ * @cmd: A SD "Application-Specific" command, up to SDMMC_CMD_MAX.
55
+ *
56
+ * Returns a human-readable name describing the application command.
57
+ * The return value is always a static string which does not need
58
+ * to be freed after use.
59
+ *
60
+ * Returns: The application command name of @cmd or "UNKNOWN_ACMD".
61
+ */
62
+const char *sd_acmd_name(uint8_t cmd);
63
+
64
#endif
65
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/sd/sd.c
68
+++ b/hw/sd/sd.c
69
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
70
* However there is no ACMD55, so we want to trace this particular case.
71
*/
72
if (req.cmd != 55 || sd->expecting_acmd) {
73
- trace_sdcard_normal_command(req.cmd, req.arg,
74
- sd_state_name(sd->state));
75
+ trace_sdcard_normal_command(sd_cmd_name(req.cmd), req.cmd,
76
+ req.arg, sd_state_name(sd->state));
77
}
78
79
/* Not interpreting this as an app command */
80
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
81
static sd_rsp_type_t sd_app_command(SDState *sd,
82
SDRequest req)
83
{
84
- trace_sdcard_app_command(req.cmd, req.arg);
85
+ trace_sdcard_app_command(sd_acmd_name(req.cmd),
86
+ req.cmd, req.arg, sd_state_name(sd->state));
87
sd->card_status |= APP_CMD;
88
switch (req.cmd) {
89
case 6:    /* ACMD6: SET_BUS_WIDTH */
90
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
91
if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
92
return;
93
94
- trace_sdcard_write_data(sd->current_cmd, value);
95
+ trace_sdcard_write_data(sd_acmd_name(sd->current_cmd),
96
+ sd->current_cmd, value);
97
switch (sd->current_cmd) {
98
case 24:    /* CMD24: WRITE_SINGLE_BLOCK */
99
sd->data[sd->data_offset ++] = value;
100
@@ -XXX,XX +XXX,XX @@ uint8_t sd_read_data(SDState *sd)
101
102
io_len = (sd->ocr & (1 << 30)) ? 512 : sd->blk_len;
103
104
- trace_sdcard_read_data(sd->current_cmd, io_len);
105
+ trace_sdcard_read_data(sd_acmd_name(sd->current_cmd),
106
+ sd->current_cmd, io_len);
107
switch (sd->current_cmd) {
108
case 6:    /* CMD6: SWITCH_FUNCTION */
109
ret = sd->data[sd->data_offset ++];
110
diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
111
new file mode 100644
112
index XXXXXXX..XXXXXXX
113
--- /dev/null
114
+++ b/hw/sd/sdmmc-internal.c
115
@@ -XXX,XX +XXX,XX @@
116
+/*
117
+ * SD/MMC cards common helpers
118
+ *
119
+ * Copyright (c) 2018 Philippe Mathieu-Daudé <f4bug@amsat.org>
120
+ *
121
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
122
+ * See the COPYING file in the top-level directory.
123
+ * SPDX-License-Identifier: GPL-2.0-or-later
124
+ */
125
+
126
+#include "qemu/osdep.h"
127
+#include "sdmmc-internal.h"
128
+
129
+const char *sd_cmd_name(uint8_t cmd)
130
+{
131
+ static const char *cmd_abbrev[SDMMC_CMD_MAX] = {
132
+ [0] = "GO_IDLE_STATE",
133
+ [2] = "ALL_SEND_CID", [3] = "SEND_RELATIVE_ADDR",
134
+ [4] = "SET_DSR", [5] = "IO_SEND_OP_COND",
135
+ [6] = "SWITCH_FUNC", [7] = "SELECT/DESELECT_CARD",
136
+ [8] = "SEND_IF_COND", [9] = "SEND_CSD",
137
+ [10] = "SEND_CID", [11] = "VOLTAGE_SWITCH",
138
+ [12] = "STOP_TRANSMISSION", [13] = "SEND_STATUS",
139
+ [15] = "GO_INACTIVE_STATE",
140
+ [16] = "SET_BLOCKLEN", [17] = "READ_SINGLE_BLOCK",
141
+ [18] = "READ_MULTIPLE_BLOCK", [19] = "SEND_TUNING_BLOCK",
142
+ [20] = "SPEED_CLASS_CONTROL", [21] = "DPS_spec",
143
+ [23] = "SET_BLOCK_COUNT",
144
+ [24] = "WRITE_BLOCK", [25] = "WRITE_MULTIPLE_BLOCK",
145
+ [26] = "MANUF_RSVD", [27] = "PROGRAM_CSD",
146
+ [28] = "SET_WRITE_PROT", [29] = "CLR_WRITE_PROT",
147
+ [30] = "SEND_WRITE_PROT",
148
+ [32] = "ERASE_WR_BLK_START", [33] = "ERASE_WR_BLK_END",
149
+ [34] = "SW_FUNC_RSVD", [35] = "SW_FUNC_RSVD",
150
+ [36] = "SW_FUNC_RSVD", [37] = "SW_FUNC_RSVD",
151
+ [38] = "ERASE",
152
+ [40] = "DPS_spec",
153
+ [42] = "LOCK_UNLOCK", [43] = "Q_MANAGEMENT",
154
+ [44] = "Q_TASK_INFO_A", [45] = "Q_TASK_INFO_B",
155
+ [46] = "Q_RD_TASK", [47] = "Q_WR_TASK",
156
+ [48] = "READ_EXTR_SINGLE", [49] = "WRITE_EXTR_SINGLE",
157
+ [50] = "SW_FUNC_RSVD",
158
+ [52] = "IO_RW_DIRECT", [53] = "IO_RW_EXTENDED",
159
+ [54] = "SDIO_RSVD", [55] = "APP_CMD",
160
+ [56] = "GEN_CMD", [57] = "SW_FUNC_RSVD",
161
+ [58] = "READ_EXTR_MULTI", [59] = "WRITE_EXTR_MULTI",
162
+ [60] = "MANUF_RSVD", [61] = "MANUF_RSVD",
163
+ [62] = "MANUF_RSVD", [63] = "MANUF_RSVD",
164
+ };
165
+ return cmd_abbrev[cmd] ? cmd_abbrev[cmd] : "UNKNOWN_CMD";
166
+}
167
+
168
+const char *sd_acmd_name(uint8_t cmd)
169
+{
170
+ static const char *acmd_abbrev[SDMMC_CMD_MAX] = {
171
+ [6] = "SET_BUS_WIDTH",
172
+ [13] = "SD_STATUS",
173
+ [14] = "DPS_spec", [15] = "DPS_spec",
174
+ [16] = "DPS_spec",
175
+ [18] = "SECU_spec",
176
+ [22] = "SEND_NUM_WR_BLOCKS", [23] = "SET_WR_BLK_ERASE_COUNT",
177
+ [41] = "SD_SEND_OP_COND",
178
+ [42] = "SET_CLR_CARD_DETECT",
179
+ [51] = "SEND_SCR",
180
+ [52] = "SECU_spec", [53] = "SECU_spec",
181
+ [54] = "SECU_spec",
182
+ [56] = "SECU_spec", [57] = "SECU_spec",
183
+ [58] = "SECU_spec", [59] = "SECU_spec",
184
+ };
185
+
186
+ return acmd_abbrev[cmd] ? acmd_abbrev[cmd] : "UNKNOWN_ACMD";
187
+}
188
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
189
index XXXXXXX..XXXXXXX 100644
190
--- a/hw/sd/trace-events
191
+++ b/hw/sd/trace-events
192
@@ -XXX,XX +XXX,XX @@ sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of
193
sdhci_capareg(const char *desc, uint16_t val) "%s: %u"
194
195
# hw/sd/sd.c
196
-sdcard_normal_command(uint8_t cmd, uint32_t arg, const char *state) "CMD%d arg 0x%08x (state %s)"
197
-sdcard_app_command(uint8_t acmd, uint32_t arg) "ACMD%d arg 0x%08x"
198
+sdcard_normal_command(const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%20s/ CMD%02d arg 0x%08x (state %s)"
199
+sdcard_app_command(const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%23s/ACMD%02d arg 0x%08x (state %s)"
200
sdcard_response(const char *rspdesc, int rsplen) "%s (sz:%d)"
201
sdcard_powerup(void) ""
202
sdcard_inquiry_cmd41(void) ""
203
@@ -XXX,XX +XXX,XX @@ sdcard_lock(void) ""
204
sdcard_unlock(void) ""
205
sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
206
sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
207
-sdcard_write_data(uint8_t cmd, uint8_t value) "CMD%02d value 0x%02x"
208
-sdcard_read_data(uint8_t cmd, int length) "CMD%02d len %d"
209
+sdcard_write_data(const char *cmd_desc, uint8_t cmd, uint8_t value) "%20s/ CMD%02d value 0x%02x"
210
+sdcard_read_data(const char *cmd_desc, uint8_t cmd, int length) "%20s/ CMD%02d len %d"
211
sdcard_set_voltage(uint16_t millivolts) "%u mV"
212
213
# hw/sd/milkymist-memcard.c
214
--
215
2.16.2
216
217
diff view generated by jsdifflib