1
Arm pullreq for the 2.12 codefreeze...
1
Latest arm queue, a mixed bag of features and bug fixes.
2
2
3
thanks
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit b39b61e410022f96ceb53d4381d25cba5126ac44:
6
The following changes since commit cbf01142b2aef0c0b4e995cecd7e79d342bbc47e:
7
7
8
memory: fix flatview_access_valid RCU read lock/unlock imbalance (2018-03-09 15:55:20 +0000)
8
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20200115' into staging (2020-01-17 12:13:17 +0000)
9
9
10
are available in the Git repository at:
10
are available in the Git repository at:
11
11
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180309
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200117-1
13
13
14
for you to fetch changes up to 076a0fc32a73a9b960e0f73f04a531bc1bd94308:
14
for you to fetch changes up to 1a1fbc6cbb34c26d43d8360c66c1d21681af14a9:
15
15
16
MAINTAINERS: Add entries for SD (SDHCI, SDBus, SDCard) (2018-03-09 17:09:45 +0000)
16
target/arm: Set ISSIs16Bit in make_issinfo (2020-01-17 14:27:16 +0000)
17
17
18
----------------------------------------------------------------
18
----------------------------------------------------------------
19
target-arm queue:
19
Add model of the Netduino Plus 2 board
20
* i.MX: Add i.MX7 SOC implementation and i.MX7 Sabre board
20
Some allwinner-a10 code cleanup
21
* Report the correct core count in A53 L2CTLR on the ZynqMP board
21
New test cases for cubieboard
22
* linux-user: preliminary SVE support work (signal handling)
22
target/arm/arm-semi: fix SYS_OPEN to return nonzero filehandle
23
* hw/arm/boot: fix memory leak in case of error loading ELF file
23
i.MX: add an emulation for RNGC device
24
* hw/arm/boot: avoid reading off end of buffer if passed very
24
target/arm: adjust program counter for wfi exception in AArch32
25
small image file
25
arm/gicv3: update virtual irq state after IAR register read
26
* hw/arm: Use more CONFIG switches for the object files
26
Set IL bit correctly for syndrome information for data aborts
27
* target/arm: Add "-cpu max" support
28
* hw/arm/virt: Support -machine gic-version=max
29
* hw/sd: improve debug tracing
30
* hw/sd: sdcard: Add the Tuning Command (CMD 19)
31
* MAINTAINERS: add Philippe as odd-fixes maintainer for SD
32
27
33
----------------------------------------------------------------
28
----------------------------------------------------------------
34
Alistair Francis (2):
29
Alistair Francis (4):
35
target/arm: Add a core count property
30
hw/misc: Add the STM32F4xx Sysconfig device
36
hw/arm: Set the core count for Xilinx's ZynqMP
31
hw/misc: Add the STM32F4xx EXTI device
32
hw/arm: Add the STM32F4xx SoC
33
hw/arm: Add the Netduino Plus 2
37
34
38
Andrey Smirnov (3):
35
Jeff Kubascik (3):
39
pci: Add support for Designware IP block
36
target/arm: adjust program counter for wfi exception in AArch32
40
i.MX: Add i.MX7 SOC implementation.
37
arm/gicv3: update virtual irq state after IAR register read
41
Implement support for i.MX7 Sabre board
38
target/arm: Return correct IL bit in merge_syn_data_abort
42
39
43
Marc-André Lureau (2):
40
Martin Kaiser (1):
44
arm: fix load ELF error leak
41
i.MX: add an emulation for RNGC
45
arm: avoid heap-buffer-overflow in load_aarch64_image
46
42
47
Peter Maydell (6):
43
Masahiro Yamada (1):
48
target/arm: Query host CPU features on-demand at instance init
44
target/arm/arm-semi: fix SYS_OPEN to return nonzero filehandle
49
target/arm: Move definition of 'host' cpu type into cpu.c
50
target/arm: Add "-cpu max" support
51
target/arm: Make 'any' CPU just an alias for 'max'
52
hw/arm/virt: Add "max" to the list of CPU types "virt" supports
53
hw/arm/virt: Support -machine gic-version=max
54
45
55
Philippe Mathieu-Daudé (6):
46
Philippe Mathieu-Daudé (5):
56
sdcard: Do not trace CMD55, except when we already expect an ACMD
47
tests/boot_linux_console: Add initrd test for the CubieBoard
57
sdcard: Display command name when tracing CMD/ACMD
48
tests/boot_linux_console: Add a SD card test for the CubieBoard
58
sdcard: Display which protocol is used when tracing (SD or SPI)
49
hw/arm/allwinner-a10: Move SoC definitions out of header
59
sdcard: Add the Tuning Command (CMD19)
50
hw/arm/allwinner-a10: Simplify by passing IRQs with qdev_pass_gpios()
60
sdhci: Fix a typo in comment
51
hw/arm/allwinner-a10: Remove local qemu_irq variables
61
MAINTAINERS: Add entries for SD (SDHCI, SDBus, SDCard)
62
52
63
Richard Henderson (5):
53
Richard Henderson (1):
64
linux-user: Implement aarch64 PR_SVE_SET/GET_VL
54
target/arm: Set ISSIs16Bit in make_issinfo
65
aarch64-linux-user: Split out helpers for guest signal handling
66
aarch64-linux-user: Remove struct target_aux_context
67
aarch64-linux-user: Add support for EXTRA signal frame records
68
aarch64-linux-user: Add support for SVE signal frame records
69
55
70
Thomas Huth (1):
56
hw/arm/Makefile.objs | 2 +
71
hw/arm: Use more CONFIG switches for the object files
57
hw/misc/Makefile.objs | 3 +
58
include/hw/arm/allwinner-a10.h | 7 -
59
include/hw/arm/fsl-imx25.h | 5 +
60
include/hw/arm/stm32f405_soc.h | 73 ++++++++
61
include/hw/misc/imx_rngc.h | 35 ++++
62
include/hw/misc/stm32f4xx_exti.h | 60 +++++++
63
include/hw/misc/stm32f4xx_syscfg.h | 61 +++++++
64
hw/arm/allwinner-a10.c | 39 +++--
65
hw/arm/fsl-imx25.c | 11 ++
66
hw/arm/netduinoplus2.c | 52 ++++++
67
hw/arm/stm32f405_soc.c | 302 +++++++++++++++++++++++++++++++++
68
hw/intc/arm_gicv3_cpuif.c | 3 +
69
hw/misc/imx_rngc.c | 278 ++++++++++++++++++++++++++++++
70
hw/misc/stm32f4xx_exti.c | 188 ++++++++++++++++++++
71
hw/misc/stm32f4xx_syscfg.c | 171 +++++++++++++++++++
72
target/arm/arm-semi.c | 5 +-
73
target/arm/op_helper.c | 7 +-
74
target/arm/tlb_helper.c | 2 +-
75
target/arm/translate.c | 3 +
76
MAINTAINERS | 14 ++
77
default-configs/arm-softmmu.mak | 1 +
78
hw/arm/Kconfig | 10 ++
79
hw/misc/Kconfig | 6 +
80
hw/misc/trace-events | 11 ++
81
tests/acceptance/boot_linux_console.py | 85 ++++++++++
82
26 files changed, 1405 insertions(+), 29 deletions(-)
83
create mode 100644 include/hw/arm/stm32f405_soc.h
84
create mode 100644 include/hw/misc/imx_rngc.h
85
create mode 100644 include/hw/misc/stm32f4xx_exti.h
86
create mode 100644 include/hw/misc/stm32f4xx_syscfg.h
87
create mode 100644 hw/arm/netduinoplus2.c
88
create mode 100644 hw/arm/stm32f405_soc.c
89
create mode 100644 hw/misc/imx_rngc.c
90
create mode 100644 hw/misc/stm32f4xx_exti.c
91
create mode 100644 hw/misc/stm32f4xx_syscfg.c
72
92
73
hw/arm/Makefile.objs | 31 +-
74
hw/pci-host/Makefile.objs | 2 +
75
hw/sd/Makefile.objs | 2 +-
76
hw/sd/sdmmc-internal.h | 24 ++
77
include/hw/arm/fsl-imx7.h | 222 +++++++++++
78
include/hw/pci-host/designware.h | 102 +++++
79
include/hw/pci/pci_ids.h | 2 +
80
linux-user/aarch64/target_syscall.h | 3 +
81
target/arm/cpu-qom.h | 2 +
82
target/arm/cpu.h | 11 +
83
target/arm/kvm_arm.h | 35 +-
84
hw/arm/boot.c | 4 +-
85
hw/arm/fsl-imx7.c | 582 ++++++++++++++++++++++++++++
86
hw/arm/mcimx7d-sabre.c | 90 +++++
87
hw/arm/virt.c | 30 +-
88
hw/arm/xlnx-zynqmp.c | 2 +
89
hw/pci-host/designware.c | 754 ++++++++++++++++++++++++++++++++++++
90
hw/sd/sd.c | 55 ++-
91
hw/sd/sdhci.c | 4 +-
92
hw/sd/sdmmc-internal.c | 72 ++++
93
linux-user/signal.c | 415 ++++++++++++++++----
94
linux-user/syscall.c | 27 ++
95
target/arm/cpu.c | 103 ++++-
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
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Alistair Francis <alistair@alistair23.me>
2
2
3
Add code needed to get a functional PCI subsytem when using in
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
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>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 49b01423a09cef2ca832ff73a84a996568f1a8fc.1576658572.git.alistair@alistair23.me
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
7
---
16
hw/pci-host/Makefile.objs | 2 +
8
hw/misc/Makefile.objs | 1 +
17
include/hw/pci-host/designware.h | 102 ++++++
9
include/hw/misc/stm32f4xx_syscfg.h | 61 ++++++++++
18
include/hw/pci/pci_ids.h | 2 +
10
hw/misc/stm32f4xx_syscfg.c | 171 +++++++++++++++++++++++++++++
19
hw/pci-host/designware.c | 754 +++++++++++++++++++++++++++++++++++++++
11
default-configs/arm-softmmu.mak | 1 +
20
default-configs/arm-softmmu.mak | 1 +
12
hw/arm/Kconfig | 9 ++
21
5 files changed, 861 insertions(+)
13
hw/misc/Kconfig | 3 +
22
create mode 100644 include/hw/pci-host/designware.h
14
hw/misc/trace-events | 6 +
23
create mode 100644 hw/pci-host/designware.c
15
7 files changed, 252 insertions(+)
16
create mode 100644 include/hw/misc/stm32f4xx_syscfg.h
17
create mode 100644 hw/misc/stm32f4xx_syscfg.c
24
18
25
diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
26
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/pci-host/Makefile.objs
21
--- a/hw/misc/Makefile.objs
28
+++ b/hw/pci-host/Makefile.objs
22
+++ b/hw/misc/Makefile.objs
29
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PCI_PIIX) += piix.o
23
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_SLAVIO) += slavio_misc.o
30
common-obj-$(CONFIG_PCI_Q35) += q35.o
24
common-obj-$(CONFIG_ZYNQ) += zynq_slcr.o
31
common-obj-$(CONFIG_PCI_GENERIC) += gpex.o
25
common-obj-$(CONFIG_ZYNQ) += zynq-xadc.o
32
common-obj-$(CONFIG_PCI_XILINX) += xilinx-pcie.o
26
common-obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
33
+
27
+common-obj-$(CONFIG_STM32F4XX_SYSCFG) += stm32f4xx_syscfg.o
34
+common-obj-$(CONFIG_PCI_DESIGNWARE) += designware.o
28
obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
35
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
29
obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
30
obj-$(CONFIG_MIPS_ITU) += mips_itu.o
31
diff --git a/include/hw/misc/stm32f4xx_syscfg.h b/include/hw/misc/stm32f4xx_syscfg.h
36
new file mode 100644
32
new file mode 100644
37
index XXXXXXX..XXXXXXX
33
index XXXXXXX..XXXXXXX
38
--- /dev/null
34
--- /dev/null
39
+++ b/include/hw/pci-host/designware.h
35
+++ b/include/hw/misc/stm32f4xx_syscfg.h
40
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@
41
+/*
37
+/*
42
+ * Copyright (c) 2017, Impinj, Inc.
38
+ * STM32F4xx SYSCFG
43
+ *
39
+ *
44
+ * Designware PCIe IP block emulation
40
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
45
+ *
41
+ *
46
+ * This library is free software; you can redistribute it and/or
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
47
+ * modify it under the terms of the GNU Lesser General Public
43
+ * of this software and associated documentation files (the "Software"), to deal
48
+ * License as published by the Free Software Foundation; either
44
+ * in the Software without restriction, including without limitation the rights
49
+ * version 2 of the License, or (at your option) any later version.
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
50
+ *
46
+ * copies of the Software, and to permit persons to whom the Software is
51
+ * This library is distributed in the hope that it will be useful,
47
+ * furnished to do so, subject to the following conditions:
52
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
48
+ *
53
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
49
+ * The above copyright notice and this permission notice shall be included in
54
+ * Lesser General Public License for more details.
50
+ * all copies or substantial portions of the Software.
55
+ *
51
+ *
56
+ * You should have received a copy of the GNU Lesser General Public
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57
+ * License along with this library; if not, see
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
58
+ * <http://www.gnu.org/licenses/>.
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
55
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ * THE SOFTWARE.
59
+ */
59
+ */
60
+
60
+
61
+#ifndef DESIGNWARE_H
61
+#ifndef HW_STM_SYSCFG_H
62
+#define DESIGNWARE_H
62
+#define HW_STM_SYSCFG_H
63
+
63
+
64
+#include "hw/sysbus.h"
64
+#include "hw/hw.h"
65
+#include "hw/hw.h"
65
+#include "hw/sysbus.h"
66
+
66
+#include "hw/pci/pci.h"
67
+#define SYSCFG_MEMRMP 0x00
67
+#include "hw/pci/pci_bus.h"
68
+#define SYSCFG_PMC 0x04
68
+#include "hw/pci/pcie_host.h"
69
+#define SYSCFG_EXTICR1 0x08
69
+#include "hw/pci/pci_bridge.h"
70
+#define SYSCFG_EXTICR2 0x0C
70
+
71
+#define SYSCFG_EXTICR3 0x10
71
+#define TYPE_DESIGNWARE_PCIE_HOST "designware-pcie-host"
72
+#define SYSCFG_EXTICR4 0x14
72
+#define DESIGNWARE_PCIE_HOST(obj) \
73
+#define SYSCFG_CMPCR 0x20
73
+ OBJECT_CHECK(DesignwarePCIEHost, (obj), TYPE_DESIGNWARE_PCIE_HOST)
74
+
74
+
75
+#define TYPE_STM32F4XX_SYSCFG "stm32f4xx-syscfg"
75
+#define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root"
76
+#define STM32F4XX_SYSCFG(obj) \
76
+#define DESIGNWARE_PCIE_ROOT(obj) \
77
+ OBJECT_CHECK(STM32F4xxSyscfgState, (obj), TYPE_STM32F4XX_SYSCFG)
77
+ OBJECT_CHECK(DesignwarePCIERoot, (obj), TYPE_DESIGNWARE_PCIE_ROOT)
78
+
78
+
79
+#define SYSCFG_NUM_EXTICR 4
79
+struct DesignwarePCIERoot;
80
+
80
+typedef struct DesignwarePCIERoot DesignwarePCIERoot;
81
+typedef struct {
81
+
82
+ /* <private> */
82
+typedef struct DesignwarePCIEViewport {
83
+ SysBusDevice parent_obj;
83
+ DesignwarePCIERoot *root;
84
+
84
+
85
+ /* <public> */
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;
86
+ MemoryRegion mmio;
140
+} DesignwarePCIEHost;
87
+
141
+
88
+ uint32_t syscfg_memrmp;
142
+#endif /* DESIGNWARE_H */
89
+ uint32_t syscfg_pmc;
143
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
90
+ uint32_t syscfg_exticr[SYSCFG_NUM_EXTICR];
144
index XXXXXXX..XXXXXXX 100644
91
+ uint32_t syscfg_cmpcr;
145
--- a/include/hw/pci/pci_ids.h
92
+
146
+++ b/include/hw/pci/pci_ids.h
93
+ qemu_irq irq;
147
@@ -XXX,XX +XXX,XX @@
94
+ qemu_irq gpio_out[16];
148
#define PCI_VENDOR_ID_VMWARE 0x15ad
95
+} STM32F4xxSyscfgState;
149
#define PCI_DEVICE_ID_VMWARE_PVRDMA 0x0820
96
+
150
97
+#endif
151
+#define PCI_VENDOR_ID_SYNOPSYS 0x16C3
98
diff --git a/hw/misc/stm32f4xx_syscfg.c b/hw/misc/stm32f4xx_syscfg.c
152
+
153
#endif
154
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
155
new file mode 100644
99
new file mode 100644
156
index XXXXXXX..XXXXXXX
100
index XXXXXXX..XXXXXXX
157
--- /dev/null
101
--- /dev/null
158
+++ b/hw/pci-host/designware.c
102
+++ b/hw/misc/stm32f4xx_syscfg.c
159
@@ -XXX,XX +XXX,XX @@
103
@@ -XXX,XX +XXX,XX @@
160
+/*
104
+/*
161
+ * Copyright (c) 2018, Impinj, Inc.
105
+ * STM32F4xx SYSCFG
162
+ *
106
+ *
163
+ * Designware PCIe IP block emulation
107
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
164
+ *
108
+ *
165
+ * This library is free software; you can redistribute it and/or
109
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
166
+ * modify it under the terms of the GNU Lesser General Public
110
+ * of this software and associated documentation files (the "Software"), to deal
167
+ * License as published by the Free Software Foundation; either
111
+ * in the Software without restriction, including without limitation the rights
168
+ * version 2 of the License, or (at your option) any later version.
112
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
169
+ *
113
+ * copies of the Software, and to permit persons to whom the Software is
170
+ * This library is distributed in the hope that it will be useful,
114
+ * furnished to do so, subject to the following conditions:
171
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
115
+ *
172
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
116
+ * The above copyright notice and this permission notice shall be included in
173
+ * Lesser General Public License for more details.
117
+ * all copies or substantial portions of the Software.
174
+ *
118
+ *
175
+ * You should have received a copy of the GNU Lesser General Public
119
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
176
+ * License along with this library; if not, see
120
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177
+ * <http://www.gnu.org/licenses/>.
121
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
122
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
123
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
124
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
125
+ * THE SOFTWARE.
178
+ */
126
+ */
179
+
127
+
180
+#include "qemu/osdep.h"
128
+#include "qemu/osdep.h"
181
+#include "qapi/error.h"
129
+#include "qemu/log.h"
182
+#include "hw/pci/msi.h"
130
+#include "trace.h"
183
+#include "hw/pci/pci_bridge.h"
131
+#include "hw/irq.h"
184
+#include "hw/pci/pci_host.h"
132
+#include "migration/vmstate.h"
185
+#include "hw/pci/pcie_port.h"
133
+#include "hw/misc/stm32f4xx_syscfg.h"
186
+#include "hw/pci-host/designware.h"
134
+
187
+
135
+static void stm32f4xx_syscfg_reset(DeviceState *dev)
188
+#define DESIGNWARE_PCIE_PORT_LINK_CONTROL 0x710
136
+{
189
+#define DESIGNWARE_PCIE_PHY_DEBUG_R1 0x72C
137
+ STM32F4xxSyscfgState *s = STM32F4XX_SYSCFG(dev);
190
+#define DESIGNWARE_PCIE_PHY_DEBUG_R1_XMLH_LINK_UP BIT(4)
138
+
191
+#define DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
139
+ s->syscfg_memrmp = 0x00000000;
192
+#define DESIGNWARE_PCIE_PORT_LOGIC_SPEED_CHANGE BIT(17)
140
+ s->syscfg_pmc = 0x00000000;
193
+#define DESIGNWARE_PCIE_MSI_ADDR_LO 0x820
141
+ s->syscfg_exticr[0] = 0x00000000;
194
+#define DESIGNWARE_PCIE_MSI_ADDR_HI 0x824
142
+ s->syscfg_exticr[1] = 0x00000000;
195
+#define DESIGNWARE_PCIE_MSI_INTR0_ENABLE 0x828
143
+ s->syscfg_exticr[2] = 0x00000000;
196
+#define DESIGNWARE_PCIE_MSI_INTR0_MASK 0x82C
144
+ s->syscfg_exticr[3] = 0x00000000;
197
+#define DESIGNWARE_PCIE_MSI_INTR0_STATUS 0x830
145
+ s->syscfg_cmpcr = 0x00000000;
198
+#define DESIGNWARE_PCIE_ATU_VIEWPORT 0x900
146
+}
199
+#define DESIGNWARE_PCIE_ATU_REGION_INBOUND BIT(31)
147
+
200
+#define DESIGNWARE_PCIE_ATU_CR1 0x904
148
+static void stm32f4xx_syscfg_set_irq(void *opaque, int irq, int level)
201
+#define DESIGNWARE_PCIE_ATU_TYPE_MEM (0x0 << 0)
149
+{
202
+#define DESIGNWARE_PCIE_ATU_CR2 0x908
150
+ STM32F4xxSyscfgState *s = opaque;
203
+#define DESIGNWARE_PCIE_ATU_ENABLE BIT(31)
151
+ int icrreg = irq / 4;
204
+#define DESIGNWARE_PCIE_ATU_LOWER_BASE 0x90C
152
+ int startbit = (irq & 3) * 4;
205
+#define DESIGNWARE_PCIE_ATU_UPPER_BASE 0x910
153
+ uint8_t config = config = irq / 16;
206
+#define DESIGNWARE_PCIE_ATU_LIMIT 0x914
154
+
207
+#define DESIGNWARE_PCIE_ATU_LOWER_TARGET 0x918
155
+ trace_stm32f4xx_syscfg_set_irq(irq / 16, irq % 16, level);
208
+#define DESIGNWARE_PCIE_ATU_BUS(x) (((x) >> 24) & 0xff)
156
+
209
+#define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff)
157
+ g_assert(icrreg < SYSCFG_NUM_EXTICR);
210
+#define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C
158
+
211
+
159
+ if (extract32(s->syscfg_exticr[icrreg], startbit, 4) == config) {
212
+static DesignwarePCIEHost *
160
+ qemu_set_irq(s->gpio_out[irq], level);
213
+designware_pcie_root_to_host(DesignwarePCIERoot *root)
161
+ trace_stm32f4xx_pulse_exti(irq);
214
+{
162
+ }
215
+ BusState *bus = qdev_get_parent_bus(DEVICE(root));
163
+}
216
+ return DESIGNWARE_PCIE_HOST(bus->parent);
164
+
217
+}
165
+static uint64_t stm32f4xx_syscfg_read(void *opaque, hwaddr addr,
218
+
166
+ unsigned int size)
219
+static void designware_pcie_root_msi_write(void *opaque, hwaddr addr,
167
+{
220
+ uint64_t val, unsigned len)
168
+ STM32F4xxSyscfgState *s = opaque;
221
+{
169
+
222
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(opaque);
170
+ trace_stm32f4xx_syscfg_read(addr);
223
+ DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
171
+
224
+
172
+ switch (addr) {
225
+ root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable;
173
+ case SYSCFG_MEMRMP:
226
+
174
+ return s->syscfg_memrmp;
227
+ if (root->msi.intr[0].status & ~root->msi.intr[0].mask) {
175
+ case SYSCFG_PMC:
228
+ qemu_set_irq(host->pci.irqs[0], 1);
176
+ return s->syscfg_pmc;
177
+ case SYSCFG_EXTICR1...SYSCFG_EXTICR4:
178
+ return s->syscfg_exticr[addr / 4 - SYSCFG_EXTICR1 / 4];
179
+ case SYSCFG_CMPCR:
180
+ return s->syscfg_cmpcr;
181
+ default:
182
+ qemu_log_mask(LOG_GUEST_ERROR,
183
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
184
+ return 0;
229
+ }
185
+ }
230
+}
186
+}
231
+
187
+
232
+static const MemoryRegionOps designware_pci_host_msi_ops = {
188
+static void stm32f4xx_syscfg_write(void *opaque, hwaddr addr,
233
+ .write = designware_pcie_root_msi_write,
189
+ uint64_t val64, unsigned int size)
234
+ .endianness = DEVICE_LITTLE_ENDIAN,
190
+{
235
+ .valid = {
191
+ STM32F4xxSyscfgState *s = opaque;
236
+ .min_access_size = 4,
192
+ uint32_t value = val64;
237
+ .max_access_size = 4,
193
+
238
+ },
194
+ trace_stm32f4xx_syscfg_write(value, addr);
195
+
196
+ switch (addr) {
197
+ case SYSCFG_MEMRMP:
198
+ qemu_log_mask(LOG_UNIMP,
199
+ "%s: Changing the memory mapping isn't supported " \
200
+ "in QEMU\n", __func__);
201
+ return;
202
+ case SYSCFG_PMC:
203
+ qemu_log_mask(LOG_UNIMP,
204
+ "%s: Changing the memory mapping isn't supported " \
205
+ "in QEMU\n", __func__);
206
+ return;
207
+ case SYSCFG_EXTICR1...SYSCFG_EXTICR4:
208
+ s->syscfg_exticr[addr / 4 - SYSCFG_EXTICR1 / 4] = (value & 0xFFFF);
209
+ return;
210
+ case SYSCFG_CMPCR:
211
+ s->syscfg_cmpcr = value;
212
+ return;
213
+ default:
214
+ qemu_log_mask(LOG_GUEST_ERROR,
215
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
216
+ }
217
+}
218
+
219
+static const MemoryRegionOps stm32f4xx_syscfg_ops = {
220
+ .read = stm32f4xx_syscfg_read,
221
+ .write = stm32f4xx_syscfg_write,
222
+ .endianness = DEVICE_NATIVE_ENDIAN,
239
+};
223
+};
240
+
224
+
241
+static void designware_pcie_root_update_msi_mapping(DesignwarePCIERoot *root)
225
+static void stm32f4xx_syscfg_init(Object *obj)
242
+
226
+{
243
+{
227
+ STM32F4xxSyscfgState *s = STM32F4XX_SYSCFG(obj);
244
+ MemoryRegion *mem = &root->msi.iomem;
228
+
245
+ const uint64_t base = root->msi.base;
229
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
246
+ const bool enable = root->msi.intr[0].enable;
230
+
247
+
231
+ memory_region_init_io(&s->mmio, obj, &stm32f4xx_syscfg_ops, s,
248
+ memory_region_set_address(mem, base);
232
+ TYPE_STM32F4XX_SYSCFG, 0x400);
249
+ memory_region_set_enabled(mem, enable);
233
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
250
+}
234
+
251
+
235
+ qdev_init_gpio_in(DEVICE(obj), stm32f4xx_syscfg_set_irq, 16 * 9);
252
+static DesignwarePCIEViewport *
236
+ qdev_init_gpio_out(DEVICE(obj), s->gpio_out, 16);
253
+designware_pcie_root_get_current_viewport(DesignwarePCIERoot *root)
237
+}
254
+{
238
+
255
+ const unsigned int idx = root->atu_viewport & 0xF;
239
+static const VMStateDescription vmstate_stm32f4xx_syscfg = {
256
+ const unsigned int dir =
240
+ .name = TYPE_STM32F4XX_SYSCFG,
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,
241
+ .version_id = 1,
669
+ .minimum_version_id = 1,
242
+ .minimum_version_id = 1,
670
+ .fields = (VMStateField[]) {
243
+ .fields = (VMStateField[]) {
671
+ VMSTATE_UINT32(enable, DesignwarePCIEMSIBank),
244
+ VMSTATE_UINT32(syscfg_memrmp, STM32F4xxSyscfgState),
672
+ VMSTATE_UINT32(mask, DesignwarePCIEMSIBank),
245
+ VMSTATE_UINT32(syscfg_pmc, STM32F4xxSyscfgState),
673
+ VMSTATE_UINT32(status, DesignwarePCIEMSIBank),
246
+ VMSTATE_UINT32_ARRAY(syscfg_exticr, STM32F4xxSyscfgState,
247
+ SYSCFG_NUM_EXTICR),
248
+ VMSTATE_UINT32(syscfg_cmpcr, STM32F4xxSyscfgState),
674
+ VMSTATE_END_OF_LIST()
249
+ VMSTATE_END_OF_LIST()
675
+ }
250
+ }
676
+};
251
+};
677
+
252
+
678
+static const VMStateDescription vmstate_designware_pcie_msi = {
253
+static void stm32f4xx_syscfg_class_init(ObjectClass *klass, void *data)
679
+ .name = "designware-pcie-msi",
254
+{
680
+ .version_id = 1,
255
+ DeviceClass *dc = DEVICE_CLASS(klass);
681
+ .minimum_version_id = 1,
256
+
682
+ .fields = (VMStateField[]) {
257
+ dc->reset = stm32f4xx_syscfg_reset;
683
+ VMSTATE_UINT64(base, DesignwarePCIEMSI),
258
+ dc->vmsd = &vmstate_stm32f4xx_syscfg;
684
+ VMSTATE_STRUCT_ARRAY(intr,
259
+}
685
+ DesignwarePCIEMSI,
260
+
686
+ DESIGNWARE_PCIE_NUM_MSI_BANKS,
261
+static const TypeInfo stm32f4xx_syscfg_info = {
687
+ 1,
262
+ .name = TYPE_STM32F4XX_SYSCFG,
688
+ vmstate_designware_pcie_msi_bank,
263
+ .parent = TYPE_SYS_BUS_DEVICE,
689
+ DesignwarePCIEMSIBank),
264
+ .instance_size = sizeof(STM32F4xxSyscfgState),
690
+ VMSTATE_END_OF_LIST()
265
+ .instance_init = stm32f4xx_syscfg_init,
691
+ }
266
+ .class_init = stm32f4xx_syscfg_class_init,
692
+};
267
+};
693
+
268
+
694
+static const VMStateDescription vmstate_designware_pcie_viewport = {
269
+static void stm32f4xx_syscfg_register_types(void)
695
+ .name = "designware-pcie-viewport",
270
+{
696
+ .version_id = 1,
271
+ type_register_static(&stm32f4xx_syscfg_info);
697
+ .minimum_version_id = 1,
272
+}
698
+ .fields = (VMStateField[]) {
273
+
699
+ VMSTATE_UINT64(base, DesignwarePCIEViewport),
274
+type_init(stm32f4xx_syscfg_register_types)
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
275
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
915
index XXXXXXX..XXXXXXX 100644
276
index XXXXXXX..XXXXXXX 100644
916
--- a/default-configs/arm-softmmu.mak
277
--- a/default-configs/arm-softmmu.mak
917
+++ b/default-configs/arm-softmmu.mak
278
+++ b/default-configs/arm-softmmu.mak
918
@@ -XXX,XX +XXX,XX @@ CONFIG_GPIO_KEY=y
279
@@ -XXX,XX +XXX,XX @@ CONFIG_Z2=y
919
CONFIG_MSF2=y
280
CONFIG_COLLIE=y
920
CONFIG_FW_CFG_DMA=y
281
CONFIG_ASPEED_SOC=y
921
CONFIG_XILINX_AXI=y
282
CONFIG_NETDUINO2=y
922
+CONFIG_PCI_DESIGNWARE=y
283
+CONFIG_NETDUINOPLUS2=y
284
CONFIG_MPS2=y
285
CONFIG_RASPI=y
286
CONFIG_DIGIC=y
287
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
288
index XXXXXXX..XXXXXXX 100644
289
--- a/hw/arm/Kconfig
290
+++ b/hw/arm/Kconfig
291
@@ -XXX,XX +XXX,XX @@ config NETDUINO2
292
bool
293
select STM32F205_SOC
294
295
+config NETDUINOPLUS2
296
+ bool
297
+ select STM32F405_SOC
298
+
299
config NSERIES
300
bool
301
select OMAP
302
@@ -XXX,XX +XXX,XX @@ config STM32F205_SOC
303
select STM32F2XX_ADC
304
select STM32F2XX_SPI
305
306
+config STM32F405_SOC
307
+ bool
308
+ select ARM_V7M
309
+ select STM32F4XX_SYSCFG
310
+
311
config XLNX_ZYNQMP_ARM
312
bool
313
select AHCI
314
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
315
index XXXXXXX..XXXXXXX 100644
316
--- a/hw/misc/Kconfig
317
+++ b/hw/misc/Kconfig
318
@@ -XXX,XX +XXX,XX @@ config IMX
319
config STM32F2XX_SYSCFG
320
bool
321
322
+config STM32F4XX_SYSCFG
323
+ bool
324
+
325
config MIPS_ITU
326
bool
327
328
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
329
index XXXXXXX..XXXXXXX 100644
330
--- a/hw/misc/trace-events
331
+++ b/hw/misc/trace-events
332
@@ -XXX,XX +XXX,XX @@ mos6522_set_sr_int(void) "set sr_int"
333
mos6522_write(uint64_t addr, uint64_t val) "reg=0x%"PRIx64 " val=0x%"PRIx64
334
mos6522_read(uint64_t addr, unsigned val) "reg=0x%"PRIx64 " val=0x%x"
335
336
+# stm32f4xx_syscfg
337
+stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interupt: GPIO: %d, Line: %d; Level: %d"
338
+stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d"
339
+stm32f4xx_syscfg_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
340
+stm32f4xx_syscfg_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
341
+
342
# tz-mpc.c
343
tz_mpc_reg_read(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs read: offset 0x%x data 0x%" PRIx64 " size %u"
344
tz_mpc_reg_write(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs write: offset 0x%x data 0x%" PRIx64 " size %u"
923
--
345
--
924
2.16.2
346
2.20.1
925
347
926
348
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Alistair Francis <alistair@alistair23.me>
2
2
3
Split out helpers from target_setup_frame and target_restore_sigframe
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
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>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: ef941d59fd8658589d34ed432e1d6dfdcf7fb1d0.1576658572.git.alistair@alistair23.me
11
Message-id: 20180303143823.27055-3-richard.henderson@linaro.org
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
8
---
15
linux-user/signal.c | 120 ++++++++++++++++++++++++++++++----------------------
9
hw/misc/Makefile.objs | 1 +
16
1 file changed, 69 insertions(+), 51 deletions(-)
10
include/hw/misc/stm32f4xx_exti.h | 60 ++++++++++
11
hw/misc/stm32f4xx_exti.c | 188 +++++++++++++++++++++++++++++++
12
hw/arm/Kconfig | 1 +
13
hw/misc/Kconfig | 3 +
14
hw/misc/trace-events | 5 +
15
6 files changed, 258 insertions(+)
16
create mode 100644 include/hw/misc/stm32f4xx_exti.h
17
create mode 100644 hw/misc/stm32f4xx_exti.c
17
18
18
diff --git a/linux-user/signal.c b/linux-user/signal.c
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/signal.c
21
--- a/hw/misc/Makefile.objs
21
+++ b/linux-user/signal.c
22
+++ b/hw/misc/Makefile.objs
22
@@ -XXX,XX +XXX,XX @@ struct target_rt_sigframe {
23
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_ZYNQ) += zynq_slcr.o
23
uint32_t tramp[2];
24
common-obj-$(CONFIG_ZYNQ) += zynq-xadc.o
24
};
25
common-obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
25
26
common-obj-$(CONFIG_STM32F4XX_SYSCFG) += stm32f4xx_syscfg.o
26
-static int target_setup_sigframe(struct target_rt_sigframe *sf,
27
+common-obj-$(CONFIG_STM32F4XX_EXTI) += stm32f4xx_exti.o
27
- CPUARMState *env, target_sigset_t *set)
28
obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
28
+static void target_setup_general_frame(struct target_rt_sigframe *sf,
29
obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
29
+ CPUARMState *env, target_sigset_t *set)
30
obj-$(CONFIG_MIPS_ITU) += mips_itu.o
30
{
31
diff --git a/include/hw/misc/stm32f4xx_exti.h b/include/hw/misc/stm32f4xx_exti.h
31
int i;
32
new file mode 100644
32
- struct target_aux_context *aux =
33
index XXXXXXX..XXXXXXX
33
- (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
34
--- /dev/null
34
35
+++ b/include/hw/misc/stm32f4xx_exti.h
35
- /* set up the stack frame for unwinding */
36
@@ -XXX,XX +XXX,XX @@
36
- __put_user(env->xregs[29], &sf->fp);
37
+/*
37
- __put_user(env->xregs[30], &sf->lr);
38
+ * STM32F4XX EXTI
38
+ __put_user(0, &sf->uc.tuc_flags);
39
+ *
39
+ __put_user(0, &sf->uc.tuc_link);
40
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
40
+
41
+ *
41
+ __put_user(target_sigaltstack_used.ss_sp, &sf->uc.tuc_stack.ss_sp);
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
42
+ __put_user(sas_ss_flags(env->xregs[31]), &sf->uc.tuc_stack.ss_flags);
43
+ * of this software and associated documentation files (the "Software"), to deal
43
+ __put_user(target_sigaltstack_used.ss_size, &sf->uc.tuc_stack.ss_size);
44
+ * in the Software without restriction, including without limitation the rights
44
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
45
for (i = 0; i < 31; i++) {
46
+ * copies of the Software, and to permit persons to whom the Software is
46
__put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
47
+ * furnished to do so, subject to the following conditions:
47
@@ -XXX,XX +XXX,XX @@ static int target_setup_sigframe(struct target_rt_sigframe *sf,
48
+ *
48
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
49
+ * The above copyright notice and this permission notice shall be included in
49
__put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
50
+ * all copies or substantial portions of the Software.
50
}
51
+ *
51
+}
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52
+
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53
+static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
54
+ CPUARMState *env)
55
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55
+{
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ * THE SOFTWARE.
59
+ */
60
+
61
+#ifndef HW_STM_EXTI_H
62
+#define HW_STM_EXTI_H
63
+
64
+#include "hw/sysbus.h"
65
+#include "hw/hw.h"
66
+
67
+#define EXTI_IMR 0x00
68
+#define EXTI_EMR 0x04
69
+#define EXTI_RTSR 0x08
70
+#define EXTI_FTSR 0x0C
71
+#define EXTI_SWIER 0x10
72
+#define EXTI_PR 0x14
73
+
74
+#define TYPE_STM32F4XX_EXTI "stm32f4xx-exti"
75
+#define STM32F4XX_EXTI(obj) \
76
+ OBJECT_CHECK(STM32F4xxExtiState, (obj), TYPE_STM32F4XX_EXTI)
77
+
78
+#define NUM_GPIO_EVENT_IN_LINES 16
79
+#define NUM_INTERRUPT_OUT_LINES 16
80
+
81
+typedef struct {
82
+ SysBusDevice parent_obj;
83
+
84
+ MemoryRegion mmio;
85
+
86
+ uint32_t exti_imr;
87
+ uint32_t exti_emr;
88
+ uint32_t exti_rtsr;
89
+ uint32_t exti_ftsr;
90
+ uint32_t exti_swier;
91
+ uint32_t exti_pr;
92
+
93
+ qemu_irq irq[NUM_INTERRUPT_OUT_LINES];
94
+} STM32F4xxExtiState;
95
+
96
+#endif
97
diff --git a/hw/misc/stm32f4xx_exti.c b/hw/misc/stm32f4xx_exti.c
98
new file mode 100644
99
index XXXXXXX..XXXXXXX
100
--- /dev/null
101
+++ b/hw/misc/stm32f4xx_exti.c
102
@@ -XXX,XX +XXX,XX @@
103
+/*
104
+ * STM32F4XX EXTI
105
+ *
106
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
107
+ *
108
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
109
+ * of this software and associated documentation files (the "Software"), to deal
110
+ * in the Software without restriction, including without limitation the rights
111
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
112
+ * copies of the Software, and to permit persons to whom the Software is
113
+ * furnished to do so, subject to the following conditions:
114
+ *
115
+ * The above copyright notice and this permission notice shall be included in
116
+ * all copies or substantial portions of the Software.
117
+ *
118
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
119
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
120
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
121
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
122
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
123
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
124
+ * THE SOFTWARE.
125
+ */
126
+
127
+#include "qemu/osdep.h"
128
+#include "qemu/log.h"
129
+#include "trace.h"
130
+#include "hw/irq.h"
131
+#include "migration/vmstate.h"
132
+#include "hw/misc/stm32f4xx_exti.h"
133
+
134
+static void stm32f4xx_exti_reset(DeviceState *dev)
135
+{
136
+ STM32F4xxExtiState *s = STM32F4XX_EXTI(dev);
137
+
138
+ s->exti_imr = 0x00000000;
139
+ s->exti_emr = 0x00000000;
140
+ s->exti_rtsr = 0x00000000;
141
+ s->exti_ftsr = 0x00000000;
142
+ s->exti_swier = 0x00000000;
143
+ s->exti_pr = 0x00000000;
144
+}
145
+
146
+static void stm32f4xx_exti_set_irq(void *opaque, int irq, int level)
147
+{
148
+ STM32F4xxExtiState *s = opaque;
149
+
150
+ trace_stm32f4xx_exti_set_irq(irq, level);
151
+
152
+ if (((1 << irq) & s->exti_rtsr) && level) {
153
+ /* Rising Edge */
154
+ s->exti_pr |= 1 << irq;
155
+ }
156
+
157
+ if (((1 << irq) & s->exti_ftsr) && !level) {
158
+ /* Falling Edge */
159
+ s->exti_pr |= 1 << irq;
160
+ }
161
+
162
+ if (!((1 << irq) & s->exti_imr)) {
163
+ /* Interrupt is masked */
164
+ return;
165
+ }
166
+ qemu_irq_pulse(s->irq[irq]);
167
+}
168
+
169
+static uint64_t stm32f4xx_exti_read(void *opaque, hwaddr addr,
170
+ unsigned int size)
171
+{
172
+ STM32F4xxExtiState *s = opaque;
173
+
174
+ trace_stm32f4xx_exti_read(addr);
175
+
176
+ switch (addr) {
177
+ case EXTI_IMR:
178
+ return s->exti_imr;
179
+ case EXTI_EMR:
180
+ return s->exti_emr;
181
+ case EXTI_RTSR:
182
+ return s->exti_rtsr;
183
+ case EXTI_FTSR:
184
+ return s->exti_ftsr;
185
+ case EXTI_SWIER:
186
+ return s->exti_swier;
187
+ case EXTI_PR:
188
+ return s->exti_pr;
189
+ default:
190
+ qemu_log_mask(LOG_GUEST_ERROR,
191
+ "STM32F4XX_exti_read: Bad offset %x\n", (int)addr);
192
+ return 0;
193
+ }
194
+ return 0;
195
+}
196
+
197
+static void stm32f4xx_exti_write(void *opaque, hwaddr addr,
198
+ uint64_t val64, unsigned int size)
199
+{
200
+ STM32F4xxExtiState *s = opaque;
201
+ uint32_t value = (uint32_t) val64;
202
+
203
+ trace_stm32f4xx_exti_write(addr, value);
204
+
205
+ switch (addr) {
206
+ case EXTI_IMR:
207
+ s->exti_imr = value;
208
+ return;
209
+ case EXTI_EMR:
210
+ s->exti_emr = value;
211
+ return;
212
+ case EXTI_RTSR:
213
+ s->exti_rtsr = value;
214
+ return;
215
+ case EXTI_FTSR:
216
+ s->exti_ftsr = value;
217
+ return;
218
+ case EXTI_SWIER:
219
+ s->exti_swier = value;
220
+ return;
221
+ case EXTI_PR:
222
+ /* This bit is cleared by writing a 1 to it */
223
+ s->exti_pr &= ~value;
224
+ return;
225
+ default:
226
+ qemu_log_mask(LOG_GUEST_ERROR,
227
+ "STM32F4XX_exti_write: Bad offset %x\n", (int)addr);
228
+ }
229
+}
230
+
231
+static const MemoryRegionOps stm32f4xx_exti_ops = {
232
+ .read = stm32f4xx_exti_read,
233
+ .write = stm32f4xx_exti_write,
234
+ .endianness = DEVICE_NATIVE_ENDIAN,
235
+};
236
+
237
+static void stm32f4xx_exti_init(Object *obj)
238
+{
239
+ STM32F4xxExtiState *s = STM32F4XX_EXTI(obj);
56
+ int i;
240
+ int i;
57
+
241
+
58
+ __put_user(TARGET_FPSIMD_MAGIC, &fpsimd->head.magic);
242
+ for (i = 0; i < NUM_INTERRUPT_OUT_LINES; i++) {
59
+ __put_user(sizeof(struct target_fpsimd_context), &fpsimd->head.size);
243
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
60
+ __put_user(vfp_get_fpsr(env), &fpsimd->fpsr);
244
+ }
61
+ __put_user(vfp_get_fpcr(env), &fpsimd->fpcr);
245
+
62
246
+ memory_region_init_io(&s->mmio, obj, &stm32f4xx_exti_ops, s,
63
for (i = 0; i < 32; i++) {
247
+ TYPE_STM32F4XX_EXTI, 0x400);
64
uint64_t *q = aa64_vfp_qreg(env, i);
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
65
#ifdef TARGET_WORDS_BIGENDIAN
249
+
66
- __put_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
250
+ qdev_init_gpio_in(DEVICE(obj), stm32f4xx_exti_set_irq,
67
- __put_user(q[1], &aux->fpsimd.vregs[i * 2]);
251
+ NUM_GPIO_EVENT_IN_LINES);
68
+ __put_user(q[0], &fpsimd->vregs[i * 2 + 1]);
252
+}
69
+ __put_user(q[1], &fpsimd->vregs[i * 2]);
253
+
70
#else
254
+static const VMStateDescription vmstate_stm32f4xx_exti = {
71
- __put_user(q[0], &aux->fpsimd.vregs[i * 2]);
255
+ .name = TYPE_STM32F4XX_EXTI,
72
- __put_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
256
+ .version_id = 1,
73
+ __put_user(q[0], &fpsimd->vregs[i * 2]);
257
+ .minimum_version_id = 1,
74
+ __put_user(q[1], &fpsimd->vregs[i * 2 + 1]);
258
+ .fields = (VMStateField[]) {
75
#endif
259
+ VMSTATE_UINT32(exti_imr, STM32F4xxExtiState),
76
}
260
+ VMSTATE_UINT32(exti_emr, STM32F4xxExtiState),
77
- __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
261
+ VMSTATE_UINT32(exti_rtsr, STM32F4xxExtiState),
78
- __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
262
+ VMSTATE_UINT32(exti_ftsr, STM32F4xxExtiState),
79
- __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
263
+ VMSTATE_UINT32(exti_swier, STM32F4xxExtiState),
80
- __put_user(sizeof(struct target_fpsimd_context),
264
+ VMSTATE_UINT32(exti_pr, STM32F4xxExtiState),
81
- &aux->fpsimd.head.size);
265
+ VMSTATE_END_OF_LIST()
82
-
266
+ }
83
- /* set the "end" magic */
267
+};
84
- __put_user(0, &aux->end.magic);
268
+
85
- __put_user(0, &aux->end.size);
269
+static void stm32f4xx_exti_class_init(ObjectClass *klass, void *data)
86
-
270
+{
87
- return 0;
271
+ DeviceClass *dc = DEVICE_CLASS(klass);
88
}
272
+
89
273
+ dc->reset = stm32f4xx_exti_reset;
90
-static int target_restore_sigframe(CPUARMState *env,
274
+ dc->vmsd = &vmstate_stm32f4xx_exti;
91
- struct target_rt_sigframe *sf)
275
+}
92
+static void target_setup_end_record(struct target_aarch64_ctx *end)
276
+
93
+{
277
+static const TypeInfo stm32f4xx_exti_info = {
94
+ __put_user(0, &end->magic);
278
+ .name = TYPE_STM32F4XX_EXTI,
95
+ __put_user(0, &end->size);
279
+ .parent = TYPE_SYS_BUS_DEVICE,
96
+}
280
+ .instance_size = sizeof(STM32F4xxExtiState),
97
+
281
+ .instance_init = stm32f4xx_exti_init,
98
+static void target_restore_general_frame(CPUARMState *env,
282
+ .class_init = stm32f4xx_exti_class_init,
99
+ struct target_rt_sigframe *sf)
283
+};
100
{
284
+
101
sigset_t set;
285
+static void stm32f4xx_exti_register_types(void)
102
- int i;
286
+{
103
- struct target_aux_context *aux =
287
+ type_register_static(&stm32f4xx_exti_info);
104
- (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
288
+}
105
- uint32_t magic, size, fpsr, fpcr;
289
+
106
uint64_t pstate;
290
+type_init(stm32f4xx_exti_register_types)
107
+ int i;
291
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
108
292
index XXXXXXX..XXXXXXX 100644
109
target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
293
--- a/hw/arm/Kconfig
110
set_sigmask(&set);
294
+++ b/hw/arm/Kconfig
111
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
295
@@ -XXX,XX +XXX,XX @@ config STM32F405_SOC
112
__get_user(env->pc, &sf->uc.tuc_mcontext.pc);
296
bool
113
__get_user(pstate, &sf->uc.tuc_mcontext.pstate);
297
select ARM_V7M
114
pstate_write(env, pstate);
298
select STM32F4XX_SYSCFG
115
+}
299
+ select STM32F4XX_EXTI
116
300
117
- __get_user(magic, &aux->fpsimd.head.magic);
301
config XLNX_ZYNQMP_ARM
118
- __get_user(size, &aux->fpsimd.head.size);
302
bool
119
+static void target_restore_fpsimd_record(CPUARMState *env,
303
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
120
+ struct target_fpsimd_context *fpsimd)
304
index XXXXXXX..XXXXXXX 100644
121
+{
305
--- a/hw/misc/Kconfig
122
+ uint32_t fpsr, fpcr;
306
+++ b/hw/misc/Kconfig
123
+ int i;
307
@@ -XXX,XX +XXX,XX @@ config STM32F2XX_SYSCFG
124
308
config STM32F4XX_SYSCFG
125
- if (magic != TARGET_FPSIMD_MAGIC
309
bool
126
- || size != sizeof(struct target_fpsimd_context)) {
310
127
- return 1;
311
+config STM32F4XX_EXTI
128
- }
312
+ bool
129
+ __get_user(fpsr, &fpsimd->fpsr);
313
+
130
+ vfp_set_fpsr(env, fpsr);
314
config MIPS_ITU
131
+ __get_user(fpcr, &fpsimd->fpcr);
315
bool
132
+ vfp_set_fpcr(env, fpcr);
316
133
317
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
134
for (i = 0; i < 32; i++) {
318
index XXXXXXX..XXXXXXX 100644
135
uint64_t *q = aa64_vfp_qreg(env, i);
319
--- a/hw/misc/trace-events
136
#ifdef TARGET_WORDS_BIGENDIAN
320
+++ b/hw/misc/trace-events
137
- __get_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
321
@@ -XXX,XX +XXX,XX @@ stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d"
138
- __get_user(q[1], &aux->fpsimd.vregs[i * 2]);
322
stm32f4xx_syscfg_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
139
+ __get_user(q[0], &fpsimd->vregs[i * 2 + 1]);
323
stm32f4xx_syscfg_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
140
+ __get_user(q[1], &fpsimd->vregs[i * 2]);
324
141
#else
325
+# stm32f4xx_exti
142
- __get_user(q[0], &aux->fpsimd.vregs[i * 2]);
326
+stm32f4xx_exti_set_irq(int irq, int leve) "Set EXTI: %d to %d"
143
- __get_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
327
+stm32f4xx_exti_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
144
+ __get_user(q[0], &fpsimd->vregs[i * 2]);
328
+stm32f4xx_exti_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
145
+ __get_user(q[1], &fpsimd->vregs[i * 2 + 1]);
329
+
146
#endif
330
# tz-mpc.c
147
}
331
tz_mpc_reg_read(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs read: offset 0x%x data 0x%" PRIx64 " size %u"
148
- __get_user(fpsr, &aux->fpsimd.fpsr);
332
tz_mpc_reg_write(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs write: offset 0x%x data 0x%" PRIx64 " size %u"
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
--
333
--
205
2.16.2
334
2.20.1
206
335
207
336
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Alistair Francis <alistair@alistair23.me>
2
2
3
The following interfaces are partially or fully emulated:
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
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>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
5
Message-id: 1d145c4c13e5fa140caf131232a6f524c88fcd72.1576658572.git.alistair@alistair23.me
31
[PMM: folded a couple of long lines]
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
---
7
---
34
hw/arm/Makefile.objs | 1 +
8
hw/arm/Makefile.objs | 1 +
35
include/hw/arm/fsl-imx7.h | 222 +++++++++++++++
9
include/hw/arm/stm32f405_soc.h | 73 ++++++++
36
hw/arm/fsl-imx7.c | 582 ++++++++++++++++++++++++++++++++++++++++
10
hw/arm/stm32f405_soc.c | 302 +++++++++++++++++++++++++++++++++
37
default-configs/arm-softmmu.mak | 1 +
11
MAINTAINERS | 8 +
38
4 files changed, 806 insertions(+)
12
4 files changed, 384 insertions(+)
39
create mode 100644 include/hw/arm/fsl-imx7.h
13
create mode 100644 include/hw/arm/stm32f405_soc.h
40
create mode 100644 hw/arm/fsl-imx7.c
14
create mode 100644 hw/arm/stm32f405_soc.c
41
15
42
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
16
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
43
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/Makefile.objs
18
--- a/hw/arm/Makefile.objs
45
+++ b/hw/arm/Makefile.objs
19
+++ b/hw/arm/Makefile.objs
46
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2.o
20
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_STRONGARM) += strongarm.o
47
obj-$(CONFIG_MPS2) += mps2-tz.o
21
obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
48
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
22
obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
49
obj-$(CONFIG_IOTKIT) += iotkit.o
23
obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
50
+obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o
24
+obj-$(CONFIG_STM32F405_SOC) += stm32f405_soc.o
51
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
25
obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o
26
obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o
27
obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
28
diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h
52
new file mode 100644
29
new file mode 100644
53
index XXXXXXX..XXXXXXX
30
index XXXXXXX..XXXXXXX
54
--- /dev/null
31
--- /dev/null
55
+++ b/include/hw/arm/fsl-imx7.h
32
+++ b/include/hw/arm/stm32f405_soc.h
56
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@
57
+/*
34
+/*
58
+ * Copyright (c) 2018, Impinj, Inc.
35
+ * STM32F405 SoC
59
+ *
36
+ *
60
+ * i.MX7 SoC definitions
37
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
61
+ *
38
+ *
62
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
39
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
63
+ *
40
+ * of this software and associated documentation files (the "Software"), to deal
64
+ * This program is free software; you can redistribute it and/or modify
41
+ * in the Software without restriction, including without limitation the rights
65
+ * it under the terms of the GNU General Public License as published by
42
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
66
+ * the Free Software Foundation; either version 2 of the License, or
43
+ * copies of the Software, and to permit persons to whom the Software is
67
+ * (at your option) any later version.
44
+ * furnished to do so, subject to the following conditions:
68
+ *
45
+ *
69
+ * This program is distributed in the hope that it will be useful,
46
+ * The above copyright notice and this permission notice shall be included in
70
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
47
+ * all copies or substantial portions of the Software.
71
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
48
+ *
72
+ * GNU General Public License for more details.
49
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
52
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55
+ * THE SOFTWARE.
73
+ */
56
+ */
74
+
57
+
75
+#ifndef FSL_IMX7_H
58
+#ifndef HW_ARM_STM32F405_SOC_H
76
+#define FSL_IMX7_H
59
+#define HW_ARM_STM32F405_SOC_H
77
+
60
+
78
+#include "hw/arm/arm.h"
61
+#include "hw/misc/stm32f4xx_syscfg.h"
79
+#include "hw/cpu/a15mpcore.h"
62
+#include "hw/timer/stm32f2xx_timer.h"
80
+#include "hw/intc/imx_gpcv2.h"
63
+#include "hw/char/stm32f2xx_usart.h"
81
+#include "hw/misc/imx7_ccm.h"
64
+#include "hw/adc/stm32f2xx_adc.h"
82
+#include "hw/misc/imx7_snvs.h"
65
+#include "hw/misc/stm32f4xx_exti.h"
83
+#include "hw/misc/imx7_gpr.h"
66
+#include "hw/or-irq.h"
84
+#include "hw/misc/imx6_src.h"
67
+#include "hw/ssi/stm32f2xx_spi.h"
85
+#include "hw/misc/imx2_wdt.h"
68
+#include "hw/arm/armv7m.h"
86
+#include "hw/gpio/imx_gpio.h"
69
+
87
+#include "hw/char/imx_serial.h"
70
+#define TYPE_STM32F405_SOC "stm32f405-soc"
88
+#include "hw/timer/imx_gpt.h"
71
+#define STM32F405_SOC(obj) \
89
+#include "hw/timer/imx_epit.h"
72
+ OBJECT_CHECK(STM32F405State, (obj), TYPE_STM32F405_SOC)
90
+#include "hw/i2c/imx_i2c.h"
73
+
91
+#include "hw/gpio/imx_gpio.h"
74
+#define STM_NUM_USARTS 7
92
+#include "hw/sd/sdhci.h"
75
+#define STM_NUM_TIMERS 4
93
+#include "hw/ssi/imx_spi.h"
76
+#define STM_NUM_ADCS 6
94
+#include "hw/net/imx_fec.h"
77
+#define STM_NUM_SPIS 6
95
+#include "hw/pci-host/designware.h"
78
+
96
+#include "hw/usb/chipidea.h"
79
+#define FLASH_BASE_ADDRESS 0x08000000
97
+#include "exec/memory.h"
80
+#define FLASH_SIZE (1024 * 1024)
98
+#include "cpu.h"
81
+#define SRAM_BASE_ADDRESS 0x20000000
99
+
82
+#define SRAM_SIZE (192 * 1024)
100
+#define TYPE_FSL_IMX7 "fsl,imx7"
83
+
101
+#define FSL_IMX7(obj) OBJECT_CHECK(FslIMX7State, (obj), TYPE_FSL_IMX7)
84
+typedef struct STM32F405State {
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 >*/
85
+ /*< private >*/
121
+ DeviceState parent_obj;
86
+ SysBusDevice parent_obj;
122
+
123
+ /*< public >*/
87
+ /*< public >*/
124
+ ARMCPU cpu[FSL_IMX7_NUM_CPUS];
88
+
125
+ A15MPPrivState a7mpcore;
89
+ char *cpu_type;
126
+ IMXGPTState gpt[FSL_IMX7_NUM_GPTS];
90
+
127
+ IMXGPIOState gpio[FSL_IMX7_NUM_GPIOS];
91
+ ARMv7MState armv7m;
128
+ IMX7CCMState ccm;
92
+
129
+ IMX7AnalogState analog;
93
+ STM32F4xxSyscfgState syscfg;
130
+ IMX7SNVSState snvs;
94
+ STM32F4xxExtiState exti;
131
+ IMXGPCv2State gpcv2;
95
+ STM32F2XXUsartState usart[STM_NUM_USARTS];
132
+ IMXSPIState spi[FSL_IMX7_NUM_ECSPIS];
96
+ STM32F2XXTimerState timer[STM_NUM_TIMERS];
133
+ IMXI2CState i2c[FSL_IMX7_NUM_I2CS];
97
+ qemu_or_irq adc_irqs;
134
+ IMXSerialState uart[FSL_IMX7_NUM_UARTS];
98
+ STM32F2XXADCState adc[STM_NUM_ADCS];
135
+ IMXFECState eth[FSL_IMX7_NUM_ETHS];
99
+ STM32F2XXSPIState spi[STM_NUM_SPIS];
136
+ SDHCIState usdhc[FSL_IMX7_NUM_USDHCS];
100
+
137
+ IMX2WdtState wdt[FSL_IMX7_NUM_WDTS];
101
+ MemoryRegion sram;
138
+ IMX7GPRState gpr;
102
+ MemoryRegion flash;
139
+ ChipideaState usb[FSL_IMX7_NUM_USBS];
103
+ MemoryRegion flash_alias;
140
+ DesignwarePCIEHost pcie;
104
+} STM32F405State;
141
+} FslIMX7State;
105
+
142
+
106
+#endif
143
+enum FslIMX7MemoryMap {
107
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
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
108
new file mode 100644
281
index XXXXXXX..XXXXXXX
109
index XXXXXXX..XXXXXXX
282
--- /dev/null
110
--- /dev/null
283
+++ b/hw/arm/fsl-imx7.c
111
+++ b/hw/arm/stm32f405_soc.c
284
@@ -XXX,XX +XXX,XX @@
112
@@ -XXX,XX +XXX,XX @@
285
+/*
113
+/*
286
+ * Copyright (c) 2018, Impinj, Inc.
114
+ * STM32F405 SoC
287
+ *
115
+ *
288
+ * i.MX7 SoC definitions
116
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
289
+ *
117
+ *
290
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
118
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
291
+ *
119
+ * of this software and associated documentation files (the "Software"), to deal
292
+ * Based on hw/arm/fsl-imx6.c
120
+ * in the Software without restriction, including without limitation the rights
293
+ *
121
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
294
+ * This program is free software; you can redistribute it and/or modify
122
+ * copies of the Software, and to permit persons to whom the Software is
295
+ * it under the terms of the GNU General Public License as published by
123
+ * furnished to do so, subject to the following conditions:
296
+ * the Free Software Foundation; either version 2 of the License, or
124
+ *
297
+ * (at your option) any later version.
125
+ * The above copyright notice and this permission notice shall be included in
298
+ *
126
+ * all copies or substantial portions of the Software.
299
+ * This program is distributed in the hope that it will be useful,
127
+ *
300
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
128
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
301
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
129
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
302
+ * GNU General Public License for more details.
130
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
131
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
132
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
133
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
134
+ * THE SOFTWARE.
303
+ */
135
+ */
304
+
136
+
305
+#include "qemu/osdep.h"
137
+#include "qemu/osdep.h"
306
+#include "qapi/error.h"
138
+#include "qapi/error.h"
307
+#include "qemu-common.h"
139
+#include "qemu-common.h"
308
+#include "hw/arm/fsl-imx7.h"
140
+#include "exec/address-spaces.h"
141
+#include "sysemu/sysemu.h"
142
+#include "hw/arm/stm32f405_soc.h"
309
+#include "hw/misc/unimp.h"
143
+#include "hw/misc/unimp.h"
310
+#include "sysemu/sysemu.h"
144
+
311
+#include "qemu/error-report.h"
145
+#define SYSCFG_ADD 0x40013800
312
+
146
+static const uint32_t usart_addr[] = { 0x40011000, 0x40004400, 0x40004800,
313
+#define NAME_SIZE 20
147
+ 0x40004C00, 0x40005000, 0x40011400,
314
+
148
+ 0x40007800, 0x40007C00 };
315
+static void fsl_imx7_init(Object *obj)
149
+/* At the moment only Timer 2 to 5 are modelled */
150
+static const uint32_t timer_addr[] = { 0x40000000, 0x40000400,
151
+ 0x40000800, 0x40000C00 };
152
+#define ADC_ADDR 0x40012000
153
+static const uint32_t spi_addr[] = { 0x40013000, 0x40003800, 0x40003C00,
154
+ 0x40013400, 0x40015000, 0x40015400 };
155
+#define EXTI_ADDR 0x40013C00
156
+
157
+#define SYSCFG_IRQ 71
158
+static const int usart_irq[] = { 37, 38, 39, 52, 53, 71, 82, 83 };
159
+static const int timer_irq[] = { 28, 29, 30, 50 };
160
+#define ADC_IRQ 18
161
+static const int spi_irq[] = { 35, 36, 51, 0, 0, 0 };
162
+static const int exti_irq[] = { 6, 7, 8, 9, 10, 23, 23, 23, 23, 23, 40,
163
+ 40, 40, 40, 40, 40} ;
164
+
165
+
166
+static void stm32f405_soc_initfn(Object *obj)
316
+{
167
+{
317
+ BusState *sysbus = sysbus_get_default();
168
+ STM32F405State *s = STM32F405_SOC(obj);
318
+ FslIMX7State *s = FSL_IMX7(obj);
319
+ char name[NAME_SIZE];
320
+ int i;
169
+ int i;
321
+
170
+
322
+ if (smp_cpus > FSL_IMX7_NUM_CPUS) {
171
+ sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
323
+ error_report("%s: Only %d CPUs are supported (%d requested)",
172
+ TYPE_ARMV7M);
324
+ TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus);
173
+
325
+ exit(1);
174
+ sysbus_init_child_obj(obj, "syscfg", &s->syscfg, sizeof(s->syscfg),
326
+ }
175
+ TYPE_STM32F4XX_SYSCFG);
327
+
176
+
328
+ for (i = 0; i < smp_cpus; i++) {
177
+ for (i = 0; i < STM_NUM_USARTS; i++) {
329
+ object_initialize(&s->cpu[i], sizeof(s->cpu[i]),
178
+ sysbus_init_child_obj(obj, "usart[*]", &s->usart[i],
330
+ ARM_CPU_TYPE_NAME("cortex-a7"));
179
+ sizeof(s->usart[i]), TYPE_STM32F2XX_USART);
331
+ snprintf(name, NAME_SIZE, "cpu%d", i);
180
+ }
332
+ object_property_add_child(obj, name, OBJECT(&s->cpu[i]),
181
+
333
+ &error_fatal);
182
+ for (i = 0; i < STM_NUM_TIMERS; i++) {
334
+ }
183
+ sysbus_init_child_obj(obj, "timer[*]", &s->timer[i],
335
+
184
+ sizeof(s->timer[i]), TYPE_STM32F2XX_TIMER);
336
+ /*
185
+ }
337
+ * A7MPCORE
186
+
338
+ */
187
+ for (i = 0; i < STM_NUM_ADCS; i++) {
339
+ object_initialize(&s->a7mpcore, sizeof(s->a7mpcore), TYPE_A15MPCORE_PRIV);
188
+ sysbus_init_child_obj(obj, "adc[*]", &s->adc[i], sizeof(s->adc[i]),
340
+ qdev_set_parent_bus(DEVICE(&s->a7mpcore), sysbus);
189
+ TYPE_STM32F2XX_ADC);
341
+ object_property_add_child(obj, "a7mpcore",
190
+ }
342
+ OBJECT(&s->a7mpcore), &error_fatal);
191
+
343
+
192
+ for (i = 0; i < STM_NUM_SPIS; i++) {
344
+ /*
193
+ sysbus_init_child_obj(obj, "spi[*]", &s->spi[i], sizeof(s->spi[i]),
345
+ * GPIOs 1 to 7
194
+ TYPE_STM32F2XX_SPI);
346
+ */
195
+ }
347
+ for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
196
+
348
+ object_initialize(&s->gpio[i], sizeof(s->gpio[i]),
197
+ sysbus_init_child_obj(obj, "exti", &s->exti, sizeof(s->exti),
349
+ TYPE_IMX_GPIO);
198
+ TYPE_STM32F4XX_EXTI);
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
+}
199
+}
475
+
200
+
476
+static void fsl_imx7_realize(DeviceState *dev, Error **errp)
201
+static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
477
+{
202
+{
478
+ FslIMX7State *s = FSL_IMX7(dev);
203
+ STM32F405State *s = STM32F405_SOC(dev_soc);
479
+ Object *o;
204
+ MemoryRegion *system_memory = get_system_memory();
205
+ DeviceState *dev, *armv7m;
206
+ SysBusDevice *busdev;
207
+ Error *err = NULL;
480
+ int i;
208
+ int i;
481
+ qemu_irq irq;
209
+
482
+ char name[NAME_SIZE];
210
+ memory_region_init_ram(&s->flash, NULL, "STM32F405.flash", FLASH_SIZE,
483
+
211
+ &err);
484
+ for (i = 0; i < smp_cpus; i++) {
212
+ if (err != NULL) {
485
+ o = OBJECT(&s->cpu[i]);
213
+ error_propagate(errp, err);
486
+
214
+ return;
487
+ object_property_set_int(o, QEMU_PSCI_CONDUIT_SMC,
215
+ }
488
+ "psci-conduit", &error_abort);
216
+ memory_region_init_alias(&s->flash_alias, NULL, "STM32F405.flash.alias",
489
+
217
+ &s->flash, 0, FLASH_SIZE);
490
+ /* On uniprocessor, the CBAR is set to 0 */
218
+
491
+ if (smp_cpus > 1) {
219
+ memory_region_set_readonly(&s->flash, true);
492
+ object_property_set_int(o, FSL_IMX7_A7MPCORE_ADDR,
220
+ memory_region_set_readonly(&s->flash_alias, true);
493
+ "reset-cbar", &error_abort);
221
+
222
+ memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash);
223
+ memory_region_add_subregion(system_memory, 0, &s->flash_alias);
224
+
225
+ memory_region_init_ram(&s->sram, NULL, "STM32F405.sram", SRAM_SIZE,
226
+ &err);
227
+ if (err != NULL) {
228
+ error_propagate(errp, err);
229
+ return;
230
+ }
231
+ memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, &s->sram);
232
+
233
+ armv7m = DEVICE(&s->armv7m);
234
+ qdev_prop_set_uint32(armv7m, "num-irq", 96);
235
+ qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
236
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
237
+ object_property_set_link(OBJECT(&s->armv7m), OBJECT(system_memory),
238
+ "memory", &error_abort);
239
+ object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
240
+ if (err != NULL) {
241
+ error_propagate(errp, err);
242
+ return;
243
+ }
244
+
245
+ /* System configuration controller */
246
+ dev = DEVICE(&s->syscfg);
247
+ object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
248
+ if (err != NULL) {
249
+ error_propagate(errp, err);
250
+ return;
251
+ }
252
+ busdev = SYS_BUS_DEVICE(dev);
253
+ sysbus_mmio_map(busdev, 0, SYSCFG_ADD);
254
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, SYSCFG_IRQ));
255
+
256
+ /* Attach UART (uses USART registers) and USART controllers */
257
+ for (i = 0; i < STM_NUM_USARTS; i++) {
258
+ dev = DEVICE(&(s->usart[i]));
259
+ qdev_prop_set_chr(dev, "chardev", serial_hd(i));
260
+ object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
261
+ if (err != NULL) {
262
+ error_propagate(errp, err);
263
+ return;
494
+ }
264
+ }
495
+
265
+ busdev = SYS_BUS_DEVICE(dev);
496
+ if (i) {
266
+ sysbus_mmio_map(busdev, 0, usart_addr[i]);
497
+ /* Secondary CPUs start in PSCI powered-down state */
267
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, usart_irq[i]));
498
+ object_property_set_bool(o, true,
268
+ }
499
+ "start-powered-off", &error_abort);
269
+
270
+ /* Timer 2 to 5 */
271
+ for (i = 0; i < STM_NUM_TIMERS; i++) {
272
+ dev = DEVICE(&(s->timer[i]));
273
+ qdev_prop_set_uint64(dev, "clock-frequency", 1000000000);
274
+ object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
275
+ if (err != NULL) {
276
+ error_propagate(errp, err);
277
+ return;
500
+ }
278
+ }
501
+
279
+ busdev = SYS_BUS_DEVICE(dev);
502
+ object_property_set_bool(o, true, "realized", &error_abort);
280
+ sysbus_mmio_map(busdev, 0, timer_addr[i]);
503
+ }
281
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, timer_irq[i]));
504
+
282
+ }
505
+ /*
283
+
506
+ * A7MPCORE
284
+ /* ADC device, the IRQs are ORed together */
507
+ */
285
+ object_initialize_child(OBJECT(s), "adc-orirq", &s->adc_irqs,
508
+ object_property_set_int(OBJECT(&s->a7mpcore), smp_cpus, "num-cpu",
286
+ sizeof(s->adc_irqs), TYPE_OR_IRQ,
509
+ &error_abort);
287
+ &err, NULL);
510
+ object_property_set_int(OBJECT(&s->a7mpcore),
288
+ if (err != NULL) {
511
+ FSL_IMX7_MAX_IRQ + GIC_INTERNAL,
289
+ error_propagate(errp, err);
512
+ "num-irq", &error_abort);
290
+ return;
513
+
291
+ }
514
+ object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized",
292
+ object_property_set_int(OBJECT(&s->adc_irqs), STM_NUM_ADCS,
515
+ &error_abort);
293
+ "num-lines", &err);
516
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX7_A7MPCORE_ADDR);
294
+ object_property_set_bool(OBJECT(&s->adc_irqs), true, "realized", &err);
517
+
295
+ if (err != NULL) {
518
+ for (i = 0; i < smp_cpus; i++) {
296
+ error_propagate(errp, err);
519
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
297
+ return;
520
+ DeviceState *d = DEVICE(qemu_get_cpu(i));
298
+ }
521
+
299
+ qdev_connect_gpio_out(DEVICE(&s->adc_irqs), 0,
522
+ irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
300
+ qdev_get_gpio_in(armv7m, ADC_IRQ));
523
+ sysbus_connect_irq(sbd, i, irq);
301
+
524
+ irq = qdev_get_gpio_in(d, ARM_CPU_FIQ);
302
+ dev = DEVICE(&(s->adc[i]));
525
+ sysbus_connect_irq(sbd, i + smp_cpus, irq);
303
+ object_property_set_bool(OBJECT(&s->adc[i]), true, "realized", &err);
526
+ }
304
+ if (err != NULL) {
527
+
305
+ error_propagate(errp, err);
528
+ /*
306
+ return;
529
+ * A7MPCORE DAP
307
+ }
530
+ */
308
+ busdev = SYS_BUS_DEVICE(dev);
531
+ create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
309
+ sysbus_mmio_map(busdev, 0, ADC_ADDR);
532
+ 0x100000);
310
+ sysbus_connect_irq(busdev, 0,
533
+
311
+ qdev_get_gpio_in(DEVICE(&s->adc_irqs), i));
534
+ /*
312
+
535
+ * GPT1, 2, 3, 4
313
+ /* SPI devices */
536
+ */
314
+ for (i = 0; i < STM_NUM_SPIS; i++) {
537
+ for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
315
+ dev = DEVICE(&(s->spi[i]));
538
+ static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
316
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &err);
539
+ FSL_IMX7_GPT1_ADDR,
317
+ if (err != NULL) {
540
+ FSL_IMX7_GPT2_ADDR,
318
+ error_propagate(errp, err);
541
+ FSL_IMX7_GPT3_ADDR,
319
+ return;
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
+ }
320
+ }
679
+
321
+ busdev = SYS_BUS_DEVICE(dev);
680
+ object_property_set_bool(OBJECT(&s->uart[i]), true, "realized",
322
+ sysbus_mmio_map(busdev, 0, spi_addr[i]);
681
+ &error_abort);
323
+ sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, spi_irq[i]));
682
+
324
+ }
683
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, FSL_IMX7_UARTn_ADDR[i]);
325
+
684
+
326
+ /* EXTI device */
685
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_UARTn_IRQ[i]);
327
+ dev = DEVICE(&s->exti);
686
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, irq);
328
+ object_property_set_bool(OBJECT(&s->exti), true, "realized", &err);
687
+ }
329
+ if (err != NULL) {
688
+
330
+ error_propagate(errp, err);
689
+ /*
331
+ return;
690
+ * Ethernet
332
+ }
691
+ */
333
+ busdev = SYS_BUS_DEVICE(dev);
692
+ for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
334
+ sysbus_mmio_map(busdev, 0, EXTI_ADDR);
693
+ static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = {
335
+ for (i = 0; i < 16; i++) {
694
+ FSL_IMX7_ENET1_ADDR,
336
+ sysbus_connect_irq(busdev, i, qdev_get_gpio_in(armv7m, exti_irq[i]));
695
+ FSL_IMX7_ENET2_ADDR,
337
+ }
696
+ };
338
+ for (i = 0; i < 16; i++) {
697
+
339
+ qdev_connect_gpio_out(DEVICE(&s->syscfg), i, qdev_get_gpio_in(dev, i));
698
+ object_property_set_uint(OBJECT(&s->eth[i]), FSL_IMX7_ETH_NUM_TX_RINGS,
340
+ }
699
+ "tx-ring-num", &error_abort);
341
+
700
+ qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
342
+ create_unimplemented_device("timer[7]", 0x40001400, 0x400);
701
+ object_property_set_bool(OBJECT(&s->eth[i]), true, "realized",
343
+ create_unimplemented_device("timer[12]", 0x40001800, 0x400);
702
+ &error_abort);
344
+ create_unimplemented_device("timer[6]", 0x40001000, 0x400);
703
+
345
+ create_unimplemented_device("timer[13]", 0x40001C00, 0x400);
704
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0, FSL_IMX7_ENETn_ADDR[i]);
346
+ create_unimplemented_device("timer[14]", 0x40002000, 0x400);
705
+
347
+ create_unimplemented_device("RTC and BKP", 0x40002800, 0x400);
706
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 0));
348
+ create_unimplemented_device("WWDG", 0x40002C00, 0x400);
707
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0, irq);
349
+ create_unimplemented_device("IWDG", 0x40003000, 0x400);
708
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 3));
350
+ create_unimplemented_device("I2S2ext", 0x40003000, 0x400);
709
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1, irq);
351
+ create_unimplemented_device("I2S3ext", 0x40004000, 0x400);
710
+ }
352
+ create_unimplemented_device("I2C1", 0x40005400, 0x400);
711
+
353
+ create_unimplemented_device("I2C2", 0x40005800, 0x400);
712
+ /*
354
+ create_unimplemented_device("I2C3", 0x40005C00, 0x400);
713
+ * USDHC
355
+ create_unimplemented_device("CAN1", 0x40006400, 0x400);
714
+ */
356
+ create_unimplemented_device("CAN2", 0x40006800, 0x400);
715
+ for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
357
+ create_unimplemented_device("PWR", 0x40007000, 0x400);
716
+ static const hwaddr FSL_IMX7_USDHCn_ADDR[FSL_IMX7_NUM_USDHCS] = {
358
+ create_unimplemented_device("DAC", 0x40007400, 0x400);
717
+ FSL_IMX7_USDHC1_ADDR,
359
+ create_unimplemented_device("timer[1]", 0x40010000, 0x400);
718
+ FSL_IMX7_USDHC2_ADDR,
360
+ create_unimplemented_device("timer[8]", 0x40010400, 0x400);
719
+ FSL_IMX7_USDHC3_ADDR,
361
+ create_unimplemented_device("SDIO", 0x40012C00, 0x400);
720
+ };
362
+ create_unimplemented_device("timer[9]", 0x40014000, 0x400);
721
+
363
+ create_unimplemented_device("timer[10]", 0x40014400, 0x400);
722
+ static const int FSL_IMX7_USDHCn_IRQ[FSL_IMX7_NUM_USDHCS] = {
364
+ create_unimplemented_device("timer[11]", 0x40014800, 0x400);
723
+ FSL_IMX7_USDHC1_IRQ,
365
+ create_unimplemented_device("GPIOA", 0x40020000, 0x400);
724
+ FSL_IMX7_USDHC2_IRQ,
366
+ create_unimplemented_device("GPIOB", 0x40020400, 0x400);
725
+ FSL_IMX7_USDHC3_IRQ,
367
+ create_unimplemented_device("GPIOC", 0x40020800, 0x400);
726
+ };
368
+ create_unimplemented_device("GPIOD", 0x40020C00, 0x400);
727
+
369
+ create_unimplemented_device("GPIOE", 0x40021000, 0x400);
728
+ object_property_set_bool(OBJECT(&s->usdhc[i]), true, "realized",
370
+ create_unimplemented_device("GPIOF", 0x40021400, 0x400);
729
+ &error_abort);
371
+ create_unimplemented_device("GPIOG", 0x40021800, 0x400);
730
+
372
+ create_unimplemented_device("GPIOH", 0x40021C00, 0x400);
731
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
373
+ create_unimplemented_device("GPIOI", 0x40022000, 0x400);
732
+ FSL_IMX7_USDHCn_ADDR[i]);
374
+ create_unimplemented_device("CRC", 0x40023000, 0x400);
733
+
375
+ create_unimplemented_device("RCC", 0x40023800, 0x400);
734
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USDHCn_IRQ[i]);
376
+ create_unimplemented_device("Flash Int", 0x40023C00, 0x400);
735
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, irq);
377
+ create_unimplemented_device("BKPSRAM", 0x40024000, 0x400);
736
+ }
378
+ create_unimplemented_device("DMA1", 0x40026000, 0x400);
737
+
379
+ create_unimplemented_device("DMA2", 0x40026400, 0x400);
738
+ /*
380
+ create_unimplemented_device("Ethernet", 0x40028000, 0x1400);
739
+ * SNVS
381
+ create_unimplemented_device("USB OTG HS", 0x40040000, 0x30000);
740
+ */
382
+ create_unimplemented_device("USB OTG FS", 0x50000000, 0x31000);
741
+ object_property_set_bool(OBJECT(&s->snvs), true, "realized", &error_abort);
383
+ create_unimplemented_device("DCMI", 0x50050000, 0x400);
742
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_ADDR);
384
+ create_unimplemented_device("RNG", 0x50060800, 0x400);
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
+}
385
+}
842
+
386
+
843
+static void fsl_imx7_class_init(ObjectClass *oc, void *data)
387
+static Property stm32f405_soc_properties[] = {
388
+ DEFINE_PROP_STRING("cpu-type", STM32F405State, cpu_type),
389
+ DEFINE_PROP_END_OF_LIST(),
390
+};
391
+
392
+static void stm32f405_soc_class_init(ObjectClass *klass, void *data)
844
+{
393
+{
845
+ DeviceClass *dc = DEVICE_CLASS(oc);
394
+ DeviceClass *dc = DEVICE_CLASS(klass);
846
+
395
+
847
+ dc->realize = fsl_imx7_realize;
396
+ dc->realize = stm32f405_soc_realize;
848
+
397
+ dc->props = stm32f405_soc_properties;
849
+ /* Reason: Uses serial_hds and nd_table in realize() directly */
398
+ /* No vmstate or reset required: device has no internal state */
850
+ dc->user_creatable = false;
851
+ dc->desc = "i.MX7 SOC";
852
+}
399
+}
853
+
400
+
854
+static const TypeInfo fsl_imx7_type_info = {
401
+static const TypeInfo stm32f405_soc_info = {
855
+ .name = TYPE_FSL_IMX7,
402
+ .name = TYPE_STM32F405_SOC,
856
+ .parent = TYPE_DEVICE,
403
+ .parent = TYPE_SYS_BUS_DEVICE,
857
+ .instance_size = sizeof(FslIMX7State),
404
+ .instance_size = sizeof(STM32F405State),
858
+ .instance_init = fsl_imx7_init,
405
+ .instance_init = stm32f405_soc_initfn,
859
+ .class_init = fsl_imx7_class_init,
406
+ .class_init = stm32f405_soc_class_init,
860
+};
407
+};
861
+
408
+
862
+static void fsl_imx7_register_types(void)
409
+static void stm32f405_soc_types(void)
863
+{
410
+{
864
+ type_register_static(&fsl_imx7_type_info);
411
+ type_register_static(&stm32f405_soc_info);
865
+}
412
+}
866
+type_init(fsl_imx7_register_types)
413
+
867
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
414
+type_init(stm32f405_soc_types)
415
diff --git a/MAINTAINERS b/MAINTAINERS
868
index XXXXXXX..XXXXXXX 100644
416
index XXXXXXX..XXXXXXX 100644
869
--- a/default-configs/arm-softmmu.mak
417
--- a/MAINTAINERS
870
+++ b/default-configs/arm-softmmu.mak
418
+++ b/MAINTAINERS
871
@@ -XXX,XX +XXX,XX @@ CONFIG_ALLWINNER_A10=y
419
@@ -XXX,XX +XXX,XX @@ F: hw/adc/*
872
CONFIG_FSL_IMX6=y
420
F: hw/ssi/stm32f2xx_spi.c
873
CONFIG_FSL_IMX31=y
421
F: include/hw/*/stm32*.h
874
CONFIG_FSL_IMX25=y
422
875
+CONFIG_FSL_IMX7=y
423
+STM32F405
876
424
+M: Alistair Francis <alistair@alistair23.me>
877
CONFIG_IMX_I2C=y
425
+M: Peter Maydell <peter.maydell@linaro.org>
878
426
+S: Maintained
427
+F: hw/arm/stm32f405_soc.c
428
+F: hw/misc/stm32f4xx_syscfg.c
429
+F: hw/misc/stm32f4xx_exti.c
430
+
431
Netduino 2
432
M: Alistair Francis <alistair@alistair23.me>
433
M: Peter Maydell <peter.maydell@linaro.org>
879
--
434
--
880
2.16.2
435
2.20.1
881
436
882
437
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Alistair Francis <alistair@alistair23.me>
2
2
3
Implement code needed to set up emulation of MCIMX7SABRE board from
3
Signed-off-by: Alistair Francis <alistair@alistair23.me>
4
NXP. For more info about the HW see:
5
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
8
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Cc: Jason Wang <jasowang@redhat.com>
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Cc: 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>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
5
Message-id: dad8d8d47f7625913e35e27a1c00f603a6b08f9a.1576658572.git.alistair@alistair23.me
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
7
---
20
hw/arm/Makefile.objs | 2 +-
8
hw/arm/Makefile.objs | 1 +
21
hw/arm/mcimx7d-sabre.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++
9
hw/arm/netduinoplus2.c | 52 ++++++++++++++++++++++++++++++++++++++++++
22
2 files changed, 91 insertions(+), 1 deletion(-)
10
MAINTAINERS | 6 +++++
23
create mode 100644 hw/arm/mcimx7d-sabre.c
11
3 files changed, 59 insertions(+)
12
create mode 100644 hw/arm/netduinoplus2.c
24
13
25
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
14
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
26
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/Makefile.objs
16
--- a/hw/arm/Makefile.objs
28
+++ b/hw/arm/Makefile.objs
17
+++ b/hw/arm/Makefile.objs
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2.o
18
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MAINSTONE) += mainstone.o
30
obj-$(CONFIG_MPS2) += mps2-tz.o
19
obj-$(CONFIG_MICROBIT) += microbit.o
31
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
20
obj-$(CONFIG_MUSICPAL) += musicpal.o
32
obj-$(CONFIG_IOTKIT) += iotkit.o
21
obj-$(CONFIG_NETDUINO2) += netduino2.o
33
-obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o
22
+obj-$(CONFIG_NETDUINOPLUS2) += netduinoplus2.o
34
+obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
23
obj-$(CONFIG_NSERIES) += nseries.o
35
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
24
obj-$(CONFIG_SX1) += omap_sx1.o
25
obj-$(CONFIG_CHEETAH) += palm.o
26
diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
36
new file mode 100644
27
new file mode 100644
37
index XXXXXXX..XXXXXXX
28
index XXXXXXX..XXXXXXX
38
--- /dev/null
29
--- /dev/null
39
+++ b/hw/arm/mcimx7d-sabre.c
30
+++ b/hw/arm/netduinoplus2.c
40
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
41
+/*
32
+/*
42
+ * Copyright (c) 2018, Impinj, Inc.
33
+ * Netduino Plus 2 Machine Model
43
+ *
34
+ *
44
+ * MCIMX7D_SABRE Board System emulation.
35
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
45
+ *
36
+ *
46
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
37
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
38
+ * of this software and associated documentation files (the "Software"), to deal
39
+ * in the Software without restriction, including without limitation the rights
40
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
41
+ * copies of the Software, and to permit persons to whom the Software is
42
+ * furnished to do so, subject to the following conditions:
47
+ *
43
+ *
48
+ * This code is licensed under the GPL, version 2 or later.
44
+ * The above copyright notice and this permission notice shall be included in
49
+ * See the file `COPYING' in the top level directory.
45
+ * all copies or substantial portions of the Software.
50
+ *
46
+ *
51
+ * It (partially) emulates a mcimx7d_sabre board, with a Freescale
47
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52
+ * i.MX7 SoC
48
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
50
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53
+ * THE SOFTWARE.
53
+ */
54
+ */
54
+
55
+
55
+#include "qemu/osdep.h"
56
+#include "qemu/osdep.h"
56
+#include "qapi/error.h"
57
+#include "qapi/error.h"
57
+#include "qemu-common.h"
58
+#include "hw/arm/fsl-imx7.h"
59
+#include "hw/boards.h"
58
+#include "hw/boards.h"
60
+#include "sysemu/sysemu.h"
59
+#include "hw/qdev-properties.h"
61
+#include "sysemu/device_tree.h"
62
+#include "qemu/error-report.h"
60
+#include "qemu/error-report.h"
63
+#include "sysemu/qtest.h"
61
+#include "hw/arm/stm32f405_soc.h"
64
+#include "net/net.h"
62
+#include "hw/arm/boot.h"
65
+
63
+
66
+typedef struct {
64
+static void netduinoplus2_init(MachineState *machine)
67
+ FslIMX7State soc;
65
+{
68
+ MemoryRegion ram;
66
+ DeviceState *dev;
69
+} MCIMX7Sabre;
70
+
67
+
71
+static void mcimx7d_sabre_init(MachineState *machine)
68
+ dev = qdev_create(NULL, TYPE_STM32F405_SOC);
72
+{
69
+ qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
73
+ static struct arm_boot_info boot_info;
70
+ object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
74
+ MCIMX7Sabre *s = g_new0(MCIMX7Sabre, 1);
75
+ Object *soc;
76
+ int i;
77
+
71
+
78
+ if (machine->ram_size > FSL_IMX7_MMDC_SIZE) {
72
+ armv7m_load_kernel(ARM_CPU(first_cpu),
79
+ error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
73
+ machine->kernel_filename,
80
+ machine->ram_size, FSL_IMX7_MMDC_SIZE);
74
+ FLASH_SIZE);
81
+ exit(1);
82
+ }
83
+
84
+ boot_info = (struct arm_boot_info) {
85
+ .loader_start = FSL_IMX7_MMDC_ADDR,
86
+ .board_id = -1,
87
+ .ram_size = machine->ram_size,
88
+ .kernel_filename = machine->kernel_filename,
89
+ .kernel_cmdline = machine->kernel_cmdline,
90
+ .initrd_filename = machine->initrd_filename,
91
+ .nb_cpus = smp_cpus,
92
+ };
93
+
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
+ }
118
+
119
+ if (!qtest_enabled()) {
120
+ arm_load_kernel(&s->soc.cpu[0], &boot_info);
121
+ }
122
+}
75
+}
123
+
76
+
124
+static void mcimx7d_sabre_machine_init(MachineClass *mc)
77
+static void netduinoplus2_machine_init(MachineClass *mc)
125
+{
78
+{
126
+ mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex A7)";
79
+ mc->desc = "Netduino Plus 2 Machine";
127
+ mc->init = mcimx7d_sabre_init;
80
+ mc->init = netduinoplus2_init;
128
+ mc->max_cpus = FSL_IMX7_NUM_CPUS;
129
+}
81
+}
130
+DEFINE_MACHINE("mcimx7d-sabre", mcimx7d_sabre_machine_init)
82
+
83
+DEFINE_MACHINE("netduinoplus2", netduinoplus2_machine_init)
84
diff --git a/MAINTAINERS b/MAINTAINERS
85
index XXXXXXX..XXXXXXX 100644
86
--- a/MAINTAINERS
87
+++ b/MAINTAINERS
88
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
89
S: Maintained
90
F: hw/arm/netduino2.c
91
92
+Netduino Plus 2
93
+M: Alistair Francis <alistair@alistair23.me>
94
+M: Peter Maydell <peter.maydell@linaro.org>
95
+S: Maintained
96
+F: hw/arm/netduinoplus2.c
97
+
98
SmartFusion2
99
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
100
M: Peter Maydell <peter.maydell@linaro.org>
131
--
101
--
132
2.16.2
102
2.20.1
133
103
134
104
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This test boots a Linux kernel on a CubieBoard and verify
4
the serial output is working.
5
6
The kernel image and DeviceTree blob are built by the Armbian
7
project (based on Debian):
8
https://docs.armbian.com/Developer-Guide_Build-Preparation/
9
10
The cpio image used comes from the linux-build-test project:
11
https://github.com/groeck/linux-build-test
12
13
If ARM is a target being built, "make check-acceptance" will
14
automatically include this test by the use of the "arch:arm" tags.
15
16
Alternatively, this test can be run using:
17
18
$ avocado --show=console run -t machine:cubieboard tests/acceptance/boot_linux_console.py
19
console: Uncompressing Linux... done, booting the kernel.
20
console: Booting Linux on physical CPU 0x0
21
console: Linux version 4.20.7-sunxi (root@armbian.com) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET 2019
22
console: CPU: ARMv7 Processor [410fc080] revision 0 (ARMv7), cr=50c5387d
23
console: CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
24
console: OF: fdt: Machine model: Cubietech Cubieboard
25
[...]
26
console: Boot successful.
27
console: cat /proc/cpuinfo
28
console: / # cat /proc/cpuinfo
29
console: processor : 0
30
console: model name : ARMv7 Processor rev 0 (v7l)
31
console: BogoMIPS : 832.51
32
[...]
33
console: Hardware : Allwinner sun4i/sun5i Families
34
console: Revision : 0000
35
console: Serial : 0000000000000000
36
console: cat /proc/iomem
37
console: / # cat /proc/iomem
38
console: 01c00000-01c0002f : system-control@1c00000
39
console: 01c02000-01c02fff : dma-controller@1c02000
40
console: 01c05000-01c05fff : spi@1c05000
41
console: 01c0b080-01c0b093 : mdio@1c0b080
42
console: 01c0c000-01c0cfff : lcd-controller@1c0c000
43
console: 01c0d000-01c0dfff : lcd-controller@1c0d000
44
console: 01c0f000-01c0ffff : mmc@1c0f000
45
[...]
46
PASS (54.35 s)
47
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
48
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
49
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
5
Message-id: 20180309153654.13518-8-f4bug@amsat.org
50
Tested-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
51
Message-id: 20191230110953.25496-2-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
52
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
53
---
8
hw/sd/sdhci.c | 4 ++--
54
tests/acceptance/boot_linux_console.py | 41 ++++++++++++++++++++++++++
9
1 file changed, 2 insertions(+), 2 deletions(-)
55
1 file changed, 41 insertions(+)
10
56
11
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
57
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
12
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/sdhci.c
59
--- a/tests/acceptance/boot_linux_console.py
14
+++ b/hw/sd/sdhci.c
60
+++ b/tests/acceptance/boot_linux_console.py
15
@@ -XXX,XX +XXX,XX @@ static void sdhci_read_block_from_card(SDHCIState *s)
61
@@ -XXX,XX +XXX,XX @@ class BootLinuxConsole(Test):
16
for (index = 0; index < blk_size; index++) {
62
self.wait_for_console_pattern('Boot successful.')
17
data = sdbus_read_data(&s->sdbus);
63
# TODO user command, for now the uart is stuck
18
if (!FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, EXECUTE_TUNING)) {
64
19
- /* Device is not in tunning */
65
+ def test_arm_cubieboard_initrd(self):
20
+ /* Device is not in tuning */
66
+ """
21
s->fifo_buffer[index] = data;
67
+ :avocado: tags=arch:arm
22
}
68
+ :avocado: tags=machine:cubieboard
23
}
69
+ """
24
70
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
25
if (FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, EXECUTE_TUNING)) {
71
+ 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
26
- /* Device is in tunning */
72
+ deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
27
+ /* Device is in tuning */
73
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
28
s->hostctl2 &= ~R_SDHC_HOSTCTL2_EXECUTE_TUNING_MASK;
74
+ kernel_path = self.extract_from_deb(deb_path,
29
s->hostctl2 |= R_SDHC_HOSTCTL2_SAMPLING_CLKSEL_MASK;
75
+ '/boot/vmlinuz-4.20.7-sunxi')
30
s->prnsts &= ~(SDHC_DAT_LINE_ACTIVE | SDHC_DOING_READ |
76
+ dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
77
+ dtb_path = self.extract_from_deb(deb_path, dtb_path)
78
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
79
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
80
+ 'arm/rootfs-armv5.cpio.gz')
81
+ initrd_hash = '2b50f1873e113523967806f4da2afe385462ff9b'
82
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
83
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
84
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
85
+
86
+ self.vm.set_console()
87
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
88
+ 'console=ttyS0,115200 '
89
+ 'usbcore.nousb '
90
+ 'panic=-1 noreboot')
91
+ self.vm.add_args('-kernel', kernel_path,
92
+ '-dtb', dtb_path,
93
+ '-initrd', initrd_path,
94
+ '-append', kernel_command_line,
95
+ '-no-reboot')
96
+ self.vm.launch()
97
+ self.wait_for_console_pattern('Boot successful.')
98
+
99
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
100
+ 'Allwinner sun4i/sun5i')
101
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
102
+ 'system-control@1c00000')
103
+ exec_command_and_wait_for_pattern(self, 'reboot',
104
+ 'reboot: Restarting system')
105
+
106
def test_s390x_s390_ccw_virtio(self):
107
"""
108
:avocado: tags=arch:s390x
31
--
109
--
32
2.16.2
110
2.20.1
33
111
34
112
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
From the "Physical Layer Simplified Specification Version 3.01":
3
The kernel image and DeviceTree blob are built by the Armbian
4
project (based on Debian):
5
https://docs.armbian.com/Developer-Guide_Build-Preparation/
4
6
5
A known data block ("Tuning block") can be used to tune sampling
7
The cpio image used comes from the linux-build-test project:
6
point for tuning required hosts. [...]
8
https://github.com/groeck/linux-build-test
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
9
14
[based on a patch from Alistair Francis <alistair.francis@xilinx.com>
10
If ARM is a target being built, "make check-acceptance" will
15
from qemu/xilinx tag xilinx-v2015.2]
11
automatically include this test by the use of the "arch:arm" tags.
12
13
Alternatively, this test can be run using:
14
15
$ avocado --show=console run -t machine:cubieboard tests/acceptance/boot_linux_console.py
16
console: Uncompressing Linux... done, booting the kernel.
17
console: Booting Linux on physical CPU 0x0
18
console: Linux version 4.20.7-sunxi (root@armbian.com) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #5.75 SMP Fri Feb 8 09:02:10 CET 2019
19
[...]
20
console: ahci-sunxi 1c18000.sata: Linked as a consumer to regulator.4
21
console: ahci-sunxi 1c18000.sata: controller can't do 64bit DMA, forcing 32bit
22
console: ahci-sunxi 1c18000.sata: AHCI 0001.0000 32 slots 1 ports 1.5 Gbps 0x1 impl platform mode
23
console: ahci-sunxi 1c18000.sata: flags: ncq only
24
console: scsi host0: ahci-sunxi
25
console: ata1: SATA max UDMA/133 mmio [mem 0x01c18000-0x01c18fff] port 0x100 irq 27
26
console: of_cfs_init
27
console: of_cfs_init: OK
28
console: vcc3v0: disabling
29
console: vcc5v0: disabling
30
console: usb1-vbus: disabling
31
console: usb2-vbus: disabling
32
console: ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
33
console: ata1.00: ATA-7: QEMU HARDDISK, 2.5+, max UDMA/100
34
console: ata1.00: 40960 sectors, multi 16: LBA48 NCQ (depth 32)
35
console: ata1.00: applying bridge limits
36
console: ata1.00: configured for UDMA/100
37
console: scsi 0:0:0:0: Direct-Access ATA QEMU HARDDISK 2.5+ PQ: 0 ANSI: 5
38
console: sd 0:0:0:0: Attached scsi generic sg0 type 0
39
console: sd 0:0:0:0: [sda] 40960 512-byte logical blocks: (21.0 MB/20.0 MiB)
40
console: sd 0:0:0:0: [sda] Write Protect is off
41
console: sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
42
console: sd 0:0:0:0: [sda] Attached SCSI disk
43
console: EXT4-fs (sda): mounting ext2 file system using the ext4 subsystem
44
console: EXT4-fs (sda): mounted filesystem without journal. Opts: (null)
45
console: VFS: Mounted root (ext2 filesystem) readonly on device 8:0.
46
[...]
47
console: cat /proc/partitions
48
console: / # cat /proc/partitions
49
console: major minor #blocks name
50
console: 1 0 4096 ram0
51
console: 1 1 4096 ram1
52
console: 1 2 4096 ram2
53
console: 1 3 4096 ram3
54
console: 8 0 20480 sda
55
console: reboot
56
console: / # reboot
57
[...]
58
console: sd 0:0:0:0: [sda] Synchronizing SCSI cache
59
console: reboot: Restarting system
60
PASS (48.39 s)
61
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
62
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
63
Message-id: 20191230110953.25496-3-f4bug@amsat.org
18
Message-id: 20180309153654.13518-5-f4bug@amsat.org
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
64
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
65
---
21
hw/sd/sd.c | 29 +++++++++++++++++++++++++++++
66
tests/acceptance/boot_linux_console.py | 44 ++++++++++++++++++++++++++
22
1 file changed, 29 insertions(+)
67
1 file changed, 44 insertions(+)
23
68
24
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
69
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
25
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/sd/sd.c
71
--- a/tests/acceptance/boot_linux_console.py
27
+++ b/hw/sd/sd.c
72
+++ b/tests/acceptance/boot_linux_console.py
28
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
73
@@ -XXX,XX +XXX,XX @@ class BootLinuxConsole(Test):
29
}
74
exec_command_and_wait_for_pattern(self, 'reboot',
30
break;
75
'reboot: Restarting system')
31
76
32
+ case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */
77
+ def test_arm_cubieboard_sata(self):
33
+ if (sd->state == sd_transfer_state) {
78
+ """
34
+ sd->state = sd_sendingdata_state;
79
+ :avocado: tags=arch:arm
35
+ sd->data_offset = 0;
80
+ :avocado: tags=machine:cubieboard
36
+ return sd_r1;
81
+ """
37
+ }
82
+ deb_url = ('https://apt.armbian.com/pool/main/l/'
38
+ break;
83
+ 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
84
+ deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
85
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
86
+ kernel_path = self.extract_from_deb(deb_path,
87
+ '/boot/vmlinuz-4.20.7-sunxi')
88
+ dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
89
+ dtb_path = self.extract_from_deb(deb_path, dtb_path)
90
+ rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
91
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
92
+ 'arm/rootfs-armv5.ext2.gz')
93
+ rootfs_hash = '093e89d2b4d982234bf528bc9fb2f2f17a9d1f93'
94
+ rootfs_path_gz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
95
+ rootfs_path = os.path.join(self.workdir, 'rootfs.cpio')
96
+ archive.gzip_uncompress(rootfs_path_gz, rootfs_path)
39
+
97
+
40
case 23: /* CMD23: SET_BLOCK_COUNT */
98
+ self.vm.set_console()
41
switch (sd->state) {
99
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
42
case sd_transfer_state:
100
+ 'console=ttyS0,115200 '
43
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
101
+ 'usbcore.nousb '
44
}
102
+ 'root=/dev/sda ro '
45
}
103
+ 'panic=-1 noreboot')
46
104
+ self.vm.add_args('-kernel', kernel_path,
47
+#define SD_TUNING_BLOCK_SIZE 64
105
+ '-dtb', dtb_path,
106
+ '-drive', 'if=none,format=raw,id=disk0,file='
107
+ + rootfs_path,
108
+ '-device', 'ide-hd,bus=ide.0,drive=disk0',
109
+ '-append', kernel_command_line,
110
+ '-no-reboot')
111
+ self.vm.launch()
112
+ self.wait_for_console_pattern('Boot successful.')
48
+
113
+
49
+static const uint8_t sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
114
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
50
+ /* See: Physical Layer Simplified Specification Version 3.01, Table 4-2 */
115
+ 'Allwinner sun4i/sun5i')
51
+ 0xff, 0x0f, 0xff, 0x00, 0x0f, 0xfc, 0xc3, 0xcc,
116
+ exec_command_and_wait_for_pattern(self, 'cat /proc/partitions',
52
+ 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
117
+ 'sda')
53
+ 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
118
+ exec_command_and_wait_for_pattern(self, 'reboot',
54
+ 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
119
+ 'reboot: Restarting system')
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
+
120
+
61
uint8_t sd_read_data(SDState *sd)
121
def test_s390x_s390_ccw_virtio(self):
62
{
122
"""
63
/* TODO: Append CRCs */
123
:avocado: tags=arch:s390x
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
--
124
--
79
2.16.2
125
2.20.1
80
126
81
127
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
After spending months studying all the different SD Specifications
3
These definitions are specific to the A10 SoC and don't need
4
from the SD Association, voluntarily add myself as maintainer
4
to be exported to the different Allwinner peripherals.
5
for the SD code.
6
5
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20191230110953.25496-4-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20180309153654.13518-9-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
MAINTAINERS | 8 ++++++++
11
include/hw/arm/allwinner-a10.h | 6 ------
13
1 file changed, 8 insertions(+)
12
hw/arm/allwinner-a10.c | 6 ++++++
13
2 files changed, 6 insertions(+), 6 deletions(-)
14
14
15
diff --git a/MAINTAINERS b/MAINTAINERS
15
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
17
--- a/include/hw/arm/allwinner-a10.h
18
+++ b/MAINTAINERS
18
+++ b/include/hw/arm/allwinner-a10.h
19
@@ -XXX,XX +XXX,XX @@ M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
19
@@ -XXX,XX +XXX,XX @@
20
S: Maintained
20
#include "target/arm/cpu.h"
21
F: hw/ssi/xilinx_*
21
22
22
23
+SD (Secure Card)
23
-#define AW_A10_PIC_REG_BASE 0x01c20400
24
+M: Philippe Mathieu-Daudé <f4bug@amsat.org>
24
-#define AW_A10_PIT_REG_BASE 0x01c20c00
25
+S: Odd Fixes
25
-#define AW_A10_UART0_REG_BASE 0x01c28000
26
+F: include/hw/sd/sd*
26
-#define AW_A10_EMAC_BASE 0x01c0b000
27
+F: hw/sd/core.c
27
-#define AW_A10_SATA_BASE 0x01c18000
28
+F: hw/sd/sd*
28
-
29
+F: tests/sd*
29
#define AW_A10_SDRAM_BASE 0x40000000
30
31
#define TYPE_AW_A10 "allwinner-a10"
32
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/allwinner-a10.c
35
+++ b/hw/arm/allwinner-a10.c
36
@@ -XXX,XX +XXX,XX @@
37
#include "hw/misc/unimp.h"
38
#include "sysemu/sysemu.h"
39
40
+#define AW_A10_PIC_REG_BASE 0x01c20400
41
+#define AW_A10_PIT_REG_BASE 0x01c20c00
42
+#define AW_A10_UART0_REG_BASE 0x01c28000
43
+#define AW_A10_EMAC_BASE 0x01c0b000
44
+#define AW_A10_SATA_BASE 0x01c18000
30
+
45
+
31
USB
46
static void aw_a10_init(Object *obj)
32
M: Gerd Hoffmann <kraxel@redhat.com>
47
{
33
S: Maintained
48
AwA10State *s = AW_A10(obj);
34
--
49
--
35
2.16.2
50
2.20.1
36
51
37
52
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
By calling qdev_pass_gpios() we don't need to hold a copy of the
4
IRQs from the INTC into the SoC state.
5
Instead of filling an array of qemu_irq and passing it around, we
6
can now directly call qdev_get_gpio_in() on the SoC.
7
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
9
Message-id: 20191230110953.25496-5-f4bug@amsat.org
5
Message-id: 20180309153654.13518-2-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
hw/sd/sd.c | 11 ++++++++---
13
include/hw/arm/allwinner-a10.h | 1 -
10
1 file changed, 8 insertions(+), 3 deletions(-)
14
hw/arm/allwinner-a10.c | 24 +++++++++++-------------
15
2 files changed, 11 insertions(+), 14 deletions(-)
11
16
12
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
17
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sd.c
19
--- a/include/hw/arm/allwinner-a10.h
15
+++ b/hw/sd/sd.c
20
+++ b/include/hw/arm/allwinner-a10.h
16
@@ -XXX,XX +XXX,XX @@ static void sd_lock_command(SDState *sd)
21
@@ -XXX,XX +XXX,XX @@ typedef struct AwA10State {
17
sd->card_status &= ~CARD_IS_LOCKED;
22
/*< public >*/
23
24
ARMCPU cpu;
25
- qemu_irq irq[AW_A10_PIC_INT_NR];
26
AwA10PITState timer;
27
AwA10PICState intc;
28
AwEmacState emac;
29
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/allwinner-a10.c
32
+++ b/hw/arm/allwinner-a10.c
33
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
34
{
35
AwA10State *s = AW_A10(dev);
36
SysBusDevice *sysbusdev;
37
- uint8_t i;
38
qemu_irq fiq, irq;
39
Error *err = NULL;
40
41
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
42
sysbus_mmio_map(sysbusdev, 0, AW_A10_PIC_REG_BASE);
43
sysbus_connect_irq(sysbusdev, 0, irq);
44
sysbus_connect_irq(sysbusdev, 1, fiq);
45
- for (i = 0; i < AW_A10_PIC_INT_NR; i++) {
46
- s->irq[i] = qdev_get_gpio_in(DEVICE(&s->intc), i);
47
- }
48
+ qdev_pass_gpios(DEVICE(&s->intc), dev, NULL);
49
50
object_property_set_bool(OBJECT(&s->timer), true, "realized", &err);
51
if (err != NULL) {
52
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
53
}
54
sysbusdev = SYS_BUS_DEVICE(&s->timer);
55
sysbus_mmio_map(sysbusdev, 0, AW_A10_PIT_REG_BASE);
56
- sysbus_connect_irq(sysbusdev, 0, s->irq[22]);
57
- sysbus_connect_irq(sysbusdev, 1, s->irq[23]);
58
- sysbus_connect_irq(sysbusdev, 2, s->irq[24]);
59
- sysbus_connect_irq(sysbusdev, 3, s->irq[25]);
60
- sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
61
- sysbus_connect_irq(sysbusdev, 5, s->irq[68]);
62
+ sysbus_connect_irq(sysbusdev, 0, qdev_get_gpio_in(dev, 22));
63
+ sysbus_connect_irq(sysbusdev, 1, qdev_get_gpio_in(dev, 23));
64
+ sysbus_connect_irq(sysbusdev, 2, qdev_get_gpio_in(dev, 24));
65
+ sysbus_connect_irq(sysbusdev, 3, qdev_get_gpio_in(dev, 25));
66
+ sysbus_connect_irq(sysbusdev, 4, qdev_get_gpio_in(dev, 67));
67
+ sysbus_connect_irq(sysbusdev, 5, qdev_get_gpio_in(dev, 68));
68
69
memory_region_init_ram(&s->sram_a, OBJECT(dev), "sram A", 48 * KiB,
70
&error_fatal);
71
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
72
}
73
sysbusdev = SYS_BUS_DEVICE(&s->emac);
74
sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE);
75
- sysbus_connect_irq(sysbusdev, 0, s->irq[55]);
76
+ sysbus_connect_irq(sysbusdev, 0, qdev_get_gpio_in(dev, 55));
77
78
object_property_set_bool(OBJECT(&s->sata), true, "realized", &err);
79
if (err) {
80
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
81
return;
82
}
83
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, AW_A10_SATA_BASE);
84
- sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, s->irq[56]);
85
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0, qdev_get_gpio_in(dev, 56));
86
87
/* FIXME use a qdev chardev prop instead of serial_hd() */
88
- serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s->irq[1],
89
+ serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2,
90
+ qdev_get_gpio_in(dev, 1),
91
115200, serial_hd(0), DEVICE_NATIVE_ENDIAN);
18
}
92
}
19
93
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
--
94
--
39
2.16.2
95
2.20.1
40
96
41
97
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
We won't reuse the CPU IRQ/FIQ variables. Simplify by calling
4
qdev_get_gpio_in() in place.
5
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20191230110953.25496-6-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180309153654.13518-4-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
hw/sd/sd.c | 14 ++++++++++----
11
hw/arm/allwinner-a10.c | 9 ++++-----
9
hw/sd/trace-events | 8 ++++----
12
1 file changed, 4 insertions(+), 5 deletions(-)
10
2 files changed, 14 insertions(+), 8 deletions(-)
11
13
12
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
14
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sd.c
16
--- a/hw/arm/allwinner-a10.c
15
+++ b/hw/sd/sd.c
17
+++ b/hw/arm/allwinner-a10.c
16
@@ -XXX,XX +XXX,XX @@ struct SDState {
18
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
17
qemu_irq readonly_cb;
19
{
18
qemu_irq inserted_cb;
20
AwA10State *s = AW_A10(dev);
19
QEMUTimer *ocr_power_timer;
21
SysBusDevice *sysbusdev;
20
+ const char *proto_name;
22
- qemu_irq fiq, irq;
21
bool enable;
23
Error *err = NULL;
22
uint8_t dat_lines;
24
23
bool cmd_line;
25
object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err);
24
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
26
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
25
* However there is no ACMD55, so we want to trace this particular case.
27
error_propagate(errp, err);
26
*/
28
return;
27
if (req.cmd != 55 || sd->expecting_acmd) {
28
- trace_sdcard_normal_command(sd_cmd_name(req.cmd), req.cmd,
29
+ trace_sdcard_normal_command(sd->proto_name,
30
+ sd_cmd_name(req.cmd), req.cmd,
31
req.arg, sd_state_name(sd->state));
32
}
29
}
33
30
- irq = qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ);
34
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
31
- fiq = qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ);
35
static sd_rsp_type_t sd_app_command(SDState *sd,
32
36
SDRequest req)
33
object_property_set_bool(OBJECT(&s->intc), true, "realized", &err);
37
{
34
if (err != NULL) {
38
- trace_sdcard_app_command(sd_acmd_name(req.cmd),
35
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
39
+ trace_sdcard_app_command(sd->proto_name, sd_acmd_name(req.cmd),
36
}
40
req.cmd, req.arg, sd_state_name(sd->state));
37
sysbusdev = SYS_BUS_DEVICE(&s->intc);
41
sd->card_status |= APP_CMD;
38
sysbus_mmio_map(sysbusdev, 0, AW_A10_PIC_REG_BASE);
42
switch (req.cmd) {
39
- sysbus_connect_irq(sysbusdev, 0, irq);
43
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
40
- sysbus_connect_irq(sysbusdev, 1, fiq);
44
if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
41
+ sysbus_connect_irq(sysbusdev, 0,
45
return;
42
+ qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
46
43
+ sysbus_connect_irq(sysbusdev, 1,
47
- trace_sdcard_write_data(sd_acmd_name(sd->current_cmd),
44
+ qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
48
+ trace_sdcard_write_data(sd->proto_name,
45
qdev_pass_gpios(DEVICE(&s->intc), dev, NULL);
49
+ sd_acmd_name(sd->current_cmd),
46
50
sd->current_cmd, value);
47
object_property_set_bool(OBJECT(&s->timer), true, "realized", &err);
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
--
48
--
99
2.16.2
49
2.20.1
100
50
101
51
diff view generated by jsdifflib
1
Add support for passing 'max' to -machine gic-version. By analogy
1
From: Masahiro Yamada <masahiroy@kernel.org>
2
with the -cpu max option, this picks the "best available" GIC version
3
whether you're using KVM or TCG, so it behaves like 'host' when
4
using KVM, and gives you GICv3 when using TCG.
5
2
6
Also like '-cpu host', using -machine gic-version=max' means there
3
According to the specification "Semihosting for AArch32 and Aarch64",
7
is no guarantee of migration compatibility between QEMU versions;
4
the SYS_OPEN operation should return:
8
in future 'max' might mean '4'.
9
5
6
- A nonzero handle if the call is successful
7
- -1 if the call is not successful
8
9
So, it should never return 0.
10
11
Prior to commit 35e9a0a8ce4b ("target/arm/arm-semi: Make semihosting
12
code hand out its own file descriptors"), the guest fd matched to the
13
host fd. It returned a nonzero handle on success since the fd 0 is
14
already used for stdin.
15
16
Now that the guest fd is the index of guestfd_array, it starts from 0.
17
18
I noticed this issue particularly because Trusted Firmware-A built with
19
PLAT=qemu is no longer working. Its io_semihosting driver only handles
20
a positive return value as a valid filehandle.
21
22
Basically, there are two ways to fix this:
23
24
- Use (guestfd - 1) as the index of guestfs_arrary. We need to insert
25
increment/decrement to convert the guestfd and the array index back
26
and forth.
27
28
- Keep using guestfd as the index of guestfs_array. The first entry
29
of guestfs_array is left unused.
30
31
I thought the latter is simpler. We end up with wasting a small piece
32
of memory for the unused first entry of guestfd_array, but this is
33
probably not a big deal.
34
35
Fixes: 35e9a0a8ce4b ("target/arm/arm-semi: Make semihosting code hand out its own file descriptors")
36
Cc: qemu-stable@nongnu.org
37
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
39
Message-id: 20200109041228.10131-1-masahiroy@kernel.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180308130626.12393-7-peter.maydell@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
---
41
---
14
hw/arm/virt.c | 29 +++++++++++++++++++----------
42
target/arm/arm-semi.c | 5 +++--
15
1 file changed, 19 insertions(+), 10 deletions(-)
43
1 file changed, 3 insertions(+), 2 deletions(-)
16
44
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
45
diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
18
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt.c
47
--- a/target/arm/arm-semi.c
20
+++ b/hw/arm/virt.c
48
+++ b/target/arm/arm-semi.c
21
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
49
@@ -XXX,XX +XXX,XX @@ static int alloc_guestfd(void)
22
/* We can probe only here because during property set
50
guestfd_array = g_array_new(FALSE, TRUE, sizeof(GuestFD));
23
* KVM is not available yet
24
*/
25
- if (!vms->gic_version) {
26
+ if (vms->gic_version <= 0) {
27
+ /* "host" or "max" */
28
if (!kvm_enabled()) {
29
- error_report("gic-version=host requires KVM");
30
- exit(1);
31
- }
32
-
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
}
51
}
53
52
54
@@ -XXX,XX +XXX,XX @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
53
- for (i = 0; i < guestfd_array->len; i++) {
55
vms->gic_version = 2;
54
+ /* SYS_OPEN should return nonzero handle on success. Start guestfd from 1 */
56
} else if (!strcmp(value, "host")) {
55
+ for (i = 1; i < guestfd_array->len; i++) {
57
vms->gic_version = 0; /* Will probe later */
56
GuestFD *gf = &g_array_index(guestfd_array, GuestFD, i);
58
+ } else if (!strcmp(value, "max")) {
57
59
+ vms->gic_version = -1; /* Will probe later */
58
if (gf->type == GuestFDUnused) {
60
} else {
59
@@ -XXX,XX +XXX,XX @@ static GuestFD *do_get_guestfd(int guestfd)
61
error_setg(errp, "Invalid gic-version value");
60
return NULL;
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
}
61
}
65
}
62
63
- if (guestfd < 0 || guestfd >= guestfd_array->len) {
64
+ if (guestfd <= 0 || guestfd >= guestfd_array->len) {
65
return NULL;
66
}
66
67
67
--
68
--
68
2.16.2
69
2.20.1
69
70
70
71
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Martin Kaiser <martin@kaiser.cx>
2
2
3
The SDBus will reuse these functions, so we put them in a new source file.
3
Add an emulation for the RNGC random number generator and the compatible
4
4
RNGB variant. These peripherals are included (at least) in imx25 and
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
imx35 chipsets.
6
Message-id: 20180309153654.13518-3-f4bug@amsat.org
6
7
The emulation supports the initial self test, reseeding the prng and
8
reading random numbers.
9
10
Signed-off-by: Martin Kaiser <martin@kaiser.cx>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/sd/Makefile.objs | 2 +-
14
hw/misc/Makefile.objs | 1 +
13
hw/sd/sdmmc-internal.h | 24 +++++++++++++++++
15
include/hw/arm/fsl-imx25.h | 5 +
14
hw/sd/sd.c | 13 +++++----
16
include/hw/misc/imx_rngc.h | 35 +++++
15
hw/sd/sdmmc-internal.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
17
hw/arm/fsl-imx25.c | 11 ++
16
hw/sd/trace-events | 8 +++---
18
hw/misc/imx_rngc.c | 278 +++++++++++++++++++++++++++++++++++++
17
5 files changed, 109 insertions(+), 10 deletions(-)
19
5 files changed, 330 insertions(+)
18
create mode 100644 hw/sd/sdmmc-internal.c
20
create mode 100644 include/hw/misc/imx_rngc.h
19
21
create mode 100644 hw/misc/imx_rngc.c
20
diff --git a/hw/sd/Makefile.objs b/hw/sd/Makefile.objs
22
23
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/sd/Makefile.objs
25
--- a/hw/misc/Makefile.objs
23
+++ b/hw/sd/Makefile.objs
26
+++ b/hw/misc/Makefile.objs
27
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_IMX) += imx7_ccm.o
28
common-obj-$(CONFIG_IMX) += imx2_wdt.o
29
common-obj-$(CONFIG_IMX) += imx7_snvs.o
30
common-obj-$(CONFIG_IMX) += imx7_gpr.o
31
+common-obj-$(CONFIG_IMX) += imx_rngc.o
32
common-obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
33
common-obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
34
common-obj-$(CONFIG_MAINSTONE) += mst_fpga.o
35
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/include/hw/arm/fsl-imx25.h
38
+++ b/include/hw/arm/fsl-imx25.h
24
@@ -XXX,XX +XXX,XX @@
39
@@ -XXX,XX +XXX,XX @@
25
common-obj-$(CONFIG_PL181) += pl181.o
40
#include "hw/timer/imx_gpt.h"
26
common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
41
#include "hw/timer/imx_epit.h"
27
-common-obj-$(CONFIG_SD) += sd.o core.o
42
#include "hw/net/imx_fec.h"
28
+common-obj-$(CONFIG_SD) += sd.o core.o sdmmc-internal.o
43
+#include "hw/misc/imx_rngc.h"
29
common-obj-$(CONFIG_SDHCI) += sdhci.o
44
#include "hw/i2c/imx_i2c.h"
30
45
#include "hw/gpio/imx_gpio.h"
31
obj-$(CONFIG_MILKYMIST) += milkymist-memcard.o
46
#include "exec/memory.h"
32
diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h
47
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
33
index XXXXXXX..XXXXXXX 100644
48
IMXGPTState gpt[FSL_IMX25_NUM_GPTS];
34
--- a/hw/sd/sdmmc-internal.h
49
IMXEPITState epit[FSL_IMX25_NUM_EPITS];
35
+++ b/hw/sd/sdmmc-internal.h
50
IMXFECState fec;
36
@@ -XXX,XX +XXX,XX @@
51
+ IMXRNGCState rngc;
37
52
IMXI2CState i2c[FSL_IMX25_NUM_I2CS];
38
#define SDMMC_CMD_MAX 64
53
IMXGPIOState gpio[FSL_IMX25_NUM_GPIOS];
39
54
MemoryRegion rom[2];
40
+/**
55
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
41
+ * sd_cmd_name:
56
#define FSL_IMX25_GPIO4_SIZE 0x4000
42
+ * @cmd: A SD "normal" command, up to SDMMC_CMD_MAX.
57
#define FSL_IMX25_GPIO3_ADDR 0x53FA4000
43
+ *
58
#define FSL_IMX25_GPIO3_SIZE 0x4000
44
+ * Returns a human-readable name describing the command.
59
+#define FSL_IMX25_RNGC_ADDR 0x53FB0000
45
+ * The return value is always a static string which does not need
60
+#define FSL_IMX25_RNGC_SIZE 0x4000
46
+ * to be freed after use.
61
#define FSL_IMX25_GPIO1_ADDR 0x53FCC000
47
+ *
62
#define FSL_IMX25_GPIO1_SIZE 0x4000
48
+ * Returns: The command name of @cmd or "UNKNOWN_CMD".
63
#define FSL_IMX25_GPIO2_ADDR 0x53FD0000
49
+ */
64
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
50
+const char *sd_cmd_name(uint8_t cmd);
65
#define FSL_IMX25_EPIT1_IRQ 28
51
+
66
#define FSL_IMX25_EPIT2_IRQ 27
52
+/**
67
#define FSL_IMX25_FEC_IRQ 57
53
+ * sd_acmd_name:
68
+#define FSL_IMX25_RNGC_IRQ 22
54
+ * @cmd: A SD "Application-Specific" command, up to SDMMC_CMD_MAX.
69
#define FSL_IMX25_I2C1_IRQ 3
55
+ *
70
#define FSL_IMX25_I2C2_IRQ 4
56
+ * Returns a human-readable name describing the application command.
71
#define FSL_IMX25_I2C3_IRQ 10
57
+ * The return value is always a static string which does not need
72
diff --git a/include/hw/misc/imx_rngc.h b/include/hw/misc/imx_rngc.h
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
73
new file mode 100644
112
index XXXXXXX..XXXXXXX
74
index XXXXXXX..XXXXXXX
113
--- /dev/null
75
--- /dev/null
114
+++ b/hw/sd/sdmmc-internal.c
76
+++ b/include/hw/misc/imx_rngc.h
115
@@ -XXX,XX +XXX,XX @@
77
@@ -XXX,XX +XXX,XX @@
116
+/*
78
+/*
117
+ * SD/MMC cards common helpers
79
+ * Freescale i.MX RNGC emulation
118
+ *
80
+ *
119
+ * Copyright (c) 2018 Philippe Mathieu-Daudé <f4bug@amsat.org>
81
+ * Copyright (C) 2020 Martin Kaiser <martin@kaiser.cx>
120
+ *
82
+ *
121
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
83
+ * 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.
84
+ * See the COPYING file in the top-level directory.
123
+ * SPDX-License-Identifier: GPL-2.0-or-later
124
+ */
85
+ */
125
+
86
+
87
+#ifndef IMX_RNGC_H
88
+#define IMX_RNGC_H
89
+
90
+#include "hw/sysbus.h"
91
+
92
+#define TYPE_IMX_RNGC "imx.rngc"
93
+#define IMX_RNGC(obj) OBJECT_CHECK(IMXRNGCState, (obj), TYPE_IMX_RNGC)
94
+
95
+typedef struct IMXRNGCState {
96
+ /*< private >*/
97
+ SysBusDevice parent_obj;
98
+
99
+ /*< public >*/
100
+ MemoryRegion iomem;
101
+
102
+ uint8_t op_self_test;
103
+ uint8_t op_seed;
104
+ uint8_t mask;
105
+ bool auto_seed;
106
+
107
+ QEMUBH *self_test_bh;
108
+ QEMUBH *seed_bh;
109
+ qemu_irq irq;
110
+} IMXRNGCState;
111
+
112
+#endif /* IMX_RNGC_H */
113
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/hw/arm/fsl-imx25.c
116
+++ b/hw/arm/fsl-imx25.c
117
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_init(Object *obj)
118
119
sysbus_init_child_obj(obj, "fec", &s->fec, sizeof(s->fec), TYPE_IMX_FEC);
120
121
+ sysbus_init_child_obj(obj, "rngc", &s->rngc, sizeof(s->rngc),
122
+ TYPE_IMX_RNGC);
123
+
124
for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
125
sysbus_init_child_obj(obj, "i2c[*]", &s->i2c[i], sizeof(s->i2c[i]),
126
TYPE_IMX_I2C);
127
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
128
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0,
129
qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_FEC_IRQ));
130
131
+ object_property_set_bool(OBJECT(&s->rngc), true, "realized", &err);
132
+ if (err) {
133
+ error_propagate(errp, err);
134
+ return;
135
+ }
136
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->rngc), 0, FSL_IMX25_RNGC_ADDR);
137
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->rngc), 0,
138
+ qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_RNGC_IRQ));
139
140
/* Initialize all I2C */
141
for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
142
diff --git a/hw/misc/imx_rngc.c b/hw/misc/imx_rngc.c
143
new file mode 100644
144
index XXXXXXX..XXXXXXX
145
--- /dev/null
146
+++ b/hw/misc/imx_rngc.c
147
@@ -XXX,XX +XXX,XX @@
148
+/*
149
+ * Freescale i.MX RNGC emulation
150
+ *
151
+ * Copyright (C) 2020 Martin Kaiser <martin@kaiser.cx>
152
+ *
153
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
154
+ * See the COPYING file in the top-level directory.
155
+ *
156
+ * This driver provides the minimum functionality to initialize and seed
157
+ * an rngc and to read random numbers. The rngb that is found in imx25
158
+ * chipsets is also supported.
159
+ */
160
+
126
+#include "qemu/osdep.h"
161
+#include "qemu/osdep.h"
127
+#include "sdmmc-internal.h"
162
+#include "qemu/main-loop.h"
128
+
163
+#include "qemu/module.h"
129
+const char *sd_cmd_name(uint8_t cmd)
164
+#include "qemu/log.h"
130
+{
165
+#include "qemu/guest-random.h"
131
+ static const char *cmd_abbrev[SDMMC_CMD_MAX] = {
166
+#include "hw/irq.h"
132
+ [0] = "GO_IDLE_STATE",
167
+#include "hw/misc/imx_rngc.h"
133
+ [2] = "ALL_SEND_CID", [3] = "SEND_RELATIVE_ADDR",
168
+#include "migration/vmstate.h"
134
+ [4] = "SET_DSR", [5] = "IO_SEND_OP_COND",
169
+
135
+ [6] = "SWITCH_FUNC", [7] = "SELECT/DESELECT_CARD",
170
+#define RNGC_NAME "i.MX RNGC"
136
+ [8] = "SEND_IF_COND", [9] = "SEND_CSD",
171
+
137
+ [10] = "SEND_CID", [11] = "VOLTAGE_SWITCH",
172
+#define RNGC_VER_ID 0x00
138
+ [12] = "STOP_TRANSMISSION", [13] = "SEND_STATUS",
173
+#define RNGC_COMMAND 0x04
139
+ [15] = "GO_INACTIVE_STATE",
174
+#define RNGC_CONTROL 0x08
140
+ [16] = "SET_BLOCKLEN", [17] = "READ_SINGLE_BLOCK",
175
+#define RNGC_STATUS 0x0C
141
+ [18] = "READ_MULTIPLE_BLOCK", [19] = "SEND_TUNING_BLOCK",
176
+#define RNGC_FIFO 0x14
142
+ [20] = "SPEED_CLASS_CONTROL", [21] = "DPS_spec",
177
+
143
+ [23] = "SET_BLOCK_COUNT",
178
+/* These version info are reported by the rngb in an imx258 chip. */
144
+ [24] = "WRITE_BLOCK", [25] = "WRITE_MULTIPLE_BLOCK",
179
+#define RNG_TYPE_RNGB 0x1
145
+ [26] = "MANUF_RSVD", [27] = "PROGRAM_CSD",
180
+#define V_MAJ 0x2
146
+ [28] = "SET_WRITE_PROT", [29] = "CLR_WRITE_PROT",
181
+#define V_MIN 0x40
147
+ [30] = "SEND_WRITE_PROT",
182
+
148
+ [32] = "ERASE_WR_BLK_START", [33] = "ERASE_WR_BLK_END",
183
+#define RNGC_CMD_BIT_SW_RST 0x40
149
+ [34] = "SW_FUNC_RSVD", [35] = "SW_FUNC_RSVD",
184
+#define RNGC_CMD_BIT_CLR_ERR 0x20
150
+ [36] = "SW_FUNC_RSVD", [37] = "SW_FUNC_RSVD",
185
+#define RNGC_CMD_BIT_CLR_INT 0x10
151
+ [38] = "ERASE",
186
+#define RNGC_CMD_BIT_SEED 0x02
152
+ [40] = "DPS_spec",
187
+#define RNGC_CMD_BIT_SELF_TEST 0x01
153
+ [42] = "LOCK_UNLOCK", [43] = "Q_MANAGEMENT",
188
+
154
+ [44] = "Q_TASK_INFO_A", [45] = "Q_TASK_INFO_B",
189
+#define RNGC_CTRL_BIT_MASK_ERR 0x40
155
+ [46] = "Q_RD_TASK", [47] = "Q_WR_TASK",
190
+#define RNGC_CTRL_BIT_MASK_DONE 0x20
156
+ [48] = "READ_EXTR_SINGLE", [49] = "WRITE_EXTR_SINGLE",
191
+#define RNGC_CTRL_BIT_AUTO_SEED 0x10
157
+ [50] = "SW_FUNC_RSVD",
192
+
158
+ [52] = "IO_RW_DIRECT", [53] = "IO_RW_EXTENDED",
193
+/* the current status for self-test and seed operations */
159
+ [54] = "SDIO_RSVD", [55] = "APP_CMD",
194
+#define OP_IDLE 0
160
+ [56] = "GEN_CMD", [57] = "SW_FUNC_RSVD",
195
+#define OP_RUN 1
161
+ [58] = "READ_EXTR_MULTI", [59] = "WRITE_EXTR_MULTI",
196
+#define OP_DONE 2
162
+ [60] = "MANUF_RSVD", [61] = "MANUF_RSVD",
197
+
163
+ [62] = "MANUF_RSVD", [63] = "MANUF_RSVD",
198
+static uint64_t imx_rngc_read(void *opaque, hwaddr offset, unsigned size)
164
+ };
199
+{
165
+ return cmd_abbrev[cmd] ? cmd_abbrev[cmd] : "UNKNOWN_CMD";
200
+ IMXRNGCState *s = IMX_RNGC(opaque);
166
+}
201
+ uint64_t val = 0;
167
+
202
+
168
+const char *sd_acmd_name(uint8_t cmd)
203
+ switch (offset) {
169
+{
204
+ case RNGC_VER_ID:
170
+ static const char *acmd_abbrev[SDMMC_CMD_MAX] = {
205
+ val |= RNG_TYPE_RNGB << 28 | V_MAJ << 8 | V_MIN;
171
+ [6] = "SET_BUS_WIDTH",
206
+ break;
172
+ [13] = "SD_STATUS",
207
+
173
+ [14] = "DPS_spec", [15] = "DPS_spec",
208
+ case RNGC_COMMAND:
174
+ [16] = "DPS_spec",
209
+ if (s->op_seed == OP_RUN) {
175
+ [18] = "SECU_spec",
210
+ val |= RNGC_CMD_BIT_SEED;
176
+ [22] = "SEND_NUM_WR_BLOCKS", [23] = "SET_WR_BLK_ERASE_COUNT",
211
+ }
177
+ [41] = "SD_SEND_OP_COND",
212
+ if (s->op_self_test == OP_RUN) {
178
+ [42] = "SET_CLR_CARD_DETECT",
213
+ val |= RNGC_CMD_BIT_SELF_TEST;
179
+ [51] = "SEND_SCR",
214
+ }
180
+ [52] = "SECU_spec", [53] = "SECU_spec",
215
+ break;
181
+ [54] = "SECU_spec",
216
+
182
+ [56] = "SECU_spec", [57] = "SECU_spec",
217
+ case RNGC_CONTROL:
183
+ [58] = "SECU_spec", [59] = "SECU_spec",
218
+ /*
184
+ };
219
+ * The CTL_ACC and VERIF_MODE bits are not supported yet.
185
+
220
+ * They read as 0.
186
+ return acmd_abbrev[cmd] ? acmd_abbrev[cmd] : "UNKNOWN_ACMD";
221
+ */
187
+}
222
+ val |= s->mask;
188
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
223
+ if (s->auto_seed) {
189
index XXXXXXX..XXXXXXX 100644
224
+ val |= RNGC_CTRL_BIT_AUTO_SEED;
190
--- a/hw/sd/trace-events
225
+ }
191
+++ b/hw/sd/trace-events
226
+ /*
192
@@ -XXX,XX +XXX,XX @@ sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of
227
+ * We don't have an internal fifo like the real hardware.
193
sdhci_capareg(const char *desc, uint16_t val) "%s: %u"
228
+ * There's no need for strategy to handle fifo underflows.
194
229
+ * We return the FIFO_UFLOW_RESPONSE bits as 0.
195
# hw/sd/sd.c
230
+ */
196
-sdcard_normal_command(uint8_t cmd, uint32_t arg, const char *state) "CMD%d arg 0x%08x (state %s)"
231
+ break;
197
-sdcard_app_command(uint8_t acmd, uint32_t arg) "ACMD%d arg 0x%08x"
232
+
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)"
233
+ case RNGC_STATUS:
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)"
234
+ /*
200
sdcard_response(const char *rspdesc, int rsplen) "%s (sz:%d)"
235
+ * We never report any statistics test or self-test errors or any
201
sdcard_powerup(void) ""
236
+ * other errors. STAT_TEST_PF, ST_PF and ERROR are always 0.
202
sdcard_inquiry_cmd41(void) ""
237
+ */
203
@@ -XXX,XX +XXX,XX @@ sdcard_lock(void) ""
238
+
204
sdcard_unlock(void) ""
239
+ /*
205
sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
240
+ * We don't have an internal fifo, see above. Therefore, we
206
sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
241
+ * report back the default fifo size (5 32-bit words) and
207
-sdcard_write_data(uint8_t cmd, uint8_t value) "CMD%02d value 0x%02x"
242
+ * indicate that our fifo is always full.
208
-sdcard_read_data(uint8_t cmd, int length) "CMD%02d len %d"
243
+ */
209
+sdcard_write_data(const char *cmd_desc, uint8_t cmd, uint8_t value) "%20s/ CMD%02d value 0x%02x"
244
+ val |= 5 << 12 | 5 << 8;
210
+sdcard_read_data(const char *cmd_desc, uint8_t cmd, int length) "%20s/ CMD%02d len %d"
245
+
211
sdcard_set_voltage(uint16_t millivolts) "%u mV"
246
+ /* We always have a new seed available. */
212
247
+ val |= 1 << 6;
213
# hw/sd/milkymist-memcard.c
248
+
249
+ if (s->op_seed == OP_DONE) {
250
+ val |= 1 << 5;
251
+ }
252
+ if (s->op_self_test == OP_DONE) {
253
+ val |= 1 << 4;
254
+ }
255
+ if (s->op_seed == OP_RUN || s->op_self_test == OP_RUN) {
256
+ /*
257
+ * We're busy if self-test is running or if we're
258
+ * seeding the prng.
259
+ */
260
+ val |= 1 << 1;
261
+ } else {
262
+ /*
263
+ * We're ready to provide secure random numbers whenever
264
+ * we're not busy.
265
+ */
266
+ val |= 1;
267
+ }
268
+ break;
269
+
270
+ case RNGC_FIFO:
271
+ qemu_guest_getrandom_nofail(&val, sizeof(val));
272
+ break;
273
+ }
274
+
275
+ return val;
276
+}
277
+
278
+static void imx_rngc_do_reset(IMXRNGCState *s)
279
+{
280
+ s->op_self_test = OP_IDLE;
281
+ s->op_seed = OP_IDLE;
282
+ s->mask = 0;
283
+ s->auto_seed = false;
284
+}
285
+
286
+static void imx_rngc_write(void *opaque, hwaddr offset, uint64_t value,
287
+ unsigned size)
288
+{
289
+ IMXRNGCState *s = IMX_RNGC(opaque);
290
+
291
+ switch (offset) {
292
+ case RNGC_COMMAND:
293
+ if (value & RNGC_CMD_BIT_SW_RST) {
294
+ imx_rngc_do_reset(s);
295
+ }
296
+
297
+ /*
298
+ * For now, both CLR_ERR and CLR_INT clear the interrupt. We
299
+ * don't report any errors yet.
300
+ */
301
+ if (value & (RNGC_CMD_BIT_CLR_ERR | RNGC_CMD_BIT_CLR_INT)) {
302
+ qemu_irq_lower(s->irq);
303
+ }
304
+
305
+ if (value & RNGC_CMD_BIT_SEED) {
306
+ s->op_seed = OP_RUN;
307
+ qemu_bh_schedule(s->seed_bh);
308
+ }
309
+
310
+ if (value & RNGC_CMD_BIT_SELF_TEST) {
311
+ s->op_self_test = OP_RUN;
312
+ qemu_bh_schedule(s->self_test_bh);
313
+ }
314
+ break;
315
+
316
+ case RNGC_CONTROL:
317
+ /*
318
+ * The CTL_ACC and VERIF_MODE bits are not supported yet.
319
+ * We ignore them if they're set by the caller.
320
+ */
321
+
322
+ if (value & RNGC_CTRL_BIT_MASK_ERR) {
323
+ s->mask |= RNGC_CTRL_BIT_MASK_ERR;
324
+ } else {
325
+ s->mask &= ~RNGC_CTRL_BIT_MASK_ERR;
326
+ }
327
+
328
+ if (value & RNGC_CTRL_BIT_MASK_DONE) {
329
+ s->mask |= RNGC_CTRL_BIT_MASK_DONE;
330
+ } else {
331
+ s->mask &= ~RNGC_CTRL_BIT_MASK_DONE;
332
+ }
333
+
334
+ if (value & RNGC_CTRL_BIT_AUTO_SEED) {
335
+ s->auto_seed = true;
336
+ } else {
337
+ s->auto_seed = false;
338
+ }
339
+ break;
340
+ }
341
+}
342
+
343
+static const MemoryRegionOps imx_rngc_ops = {
344
+ .read = imx_rngc_read,
345
+ .write = imx_rngc_write,
346
+ .endianness = DEVICE_NATIVE_ENDIAN,
347
+};
348
+
349
+static void imx_rngc_self_test(void *opaque)
350
+{
351
+ IMXRNGCState *s = IMX_RNGC(opaque);
352
+
353
+ s->op_self_test = OP_DONE;
354
+ if (!(s->mask & RNGC_CTRL_BIT_MASK_DONE)) {
355
+ qemu_irq_raise(s->irq);
356
+ }
357
+}
358
+
359
+static void imx_rngc_seed(void *opaque)
360
+{
361
+ IMXRNGCState *s = IMX_RNGC(opaque);
362
+
363
+ s->op_seed = OP_DONE;
364
+ if (!(s->mask & RNGC_CTRL_BIT_MASK_DONE)) {
365
+ qemu_irq_raise(s->irq);
366
+ }
367
+}
368
+
369
+static void imx_rngc_realize(DeviceState *dev, Error **errp)
370
+{
371
+ IMXRNGCState *s = IMX_RNGC(dev);
372
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
373
+
374
+ memory_region_init_io(&s->iomem, OBJECT(s), &imx_rngc_ops, s,
375
+ TYPE_IMX_RNGC, 0x1000);
376
+ sysbus_init_mmio(sbd, &s->iomem);
377
+
378
+ sysbus_init_irq(sbd, &s->irq);
379
+ s->self_test_bh = qemu_bh_new(imx_rngc_self_test, s);
380
+ s->seed_bh = qemu_bh_new(imx_rngc_seed, s);
381
+}
382
+
383
+static void imx_rngc_reset(DeviceState *dev)
384
+{
385
+ IMXRNGCState *s = IMX_RNGC(dev);
386
+
387
+ imx_rngc_do_reset(s);
388
+}
389
+
390
+static const VMStateDescription vmstate_imx_rngc = {
391
+ .name = RNGC_NAME,
392
+ .version_id = 1,
393
+ .minimum_version_id = 1,
394
+ .fields = (VMStateField[]) {
395
+ VMSTATE_UINT8(op_self_test, IMXRNGCState),
396
+ VMSTATE_UINT8(op_seed, IMXRNGCState),
397
+ VMSTATE_UINT8(mask, IMXRNGCState),
398
+ VMSTATE_BOOL(auto_seed, IMXRNGCState),
399
+ VMSTATE_END_OF_LIST()
400
+ }
401
+};
402
+
403
+static void imx_rngc_class_init(ObjectClass *klass, void *data)
404
+{
405
+ DeviceClass *dc = DEVICE_CLASS(klass);
406
+
407
+ dc->realize = imx_rngc_realize;
408
+ dc->reset = imx_rngc_reset;
409
+ dc->desc = RNGC_NAME,
410
+ dc->vmsd = &vmstate_imx_rngc;
411
+}
412
+
413
+static const TypeInfo imx_rngc_info = {
414
+ .name = TYPE_IMX_RNGC,
415
+ .parent = TYPE_SYS_BUS_DEVICE,
416
+ .instance_size = sizeof(IMXRNGCState),
417
+ .class_init = imx_rngc_class_init,
418
+};
419
+
420
+static void imx_rngc_register_types(void)
421
+{
422
+ type_register_static(&imx_rngc_info);
423
+}
424
+
425
+type_init(imx_rngc_register_types)
214
--
426
--
215
2.16.2
427
2.20.1
216
428
217
429
diff view generated by jsdifflib
1
From: Marc-André Lureau <marcandre.lureau@redhat.com>
1
From: Jeff Kubascik <jeff.kubascik@dornerworks.com>
2
2
3
Spotted by ASAN:
3
The wfi instruction can be configured to be trapped by a higher exception
4
QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 tests/boot-serial-test
4
level, such as the EL2 hypervisor. When the instruction is trapped, the
5
program counter should contain the address of the wfi instruction that
6
caused the exception. The program counter is adjusted for this in the wfi op
7
helper function.
5
8
6
Direct leak of 48 byte(s) in 1 object(s) allocated from:
9
However, this correction is done to env->pc, which only applies to AArch64
7
#0 0x7ff8a9b0ca38 in __interceptor_calloc (/lib64/libasan.so.4+0xdea38)
10
mode. For AArch32, the program counter is stored in env->regs[15]. This
8
#1 0x7ff8a8ea7f75 in g_malloc0 ../glib/gmem.c:124
11
adds an if-else statement to modify the correct program counter location
9
#2 0x55fef3d99129 in error_setv /home/elmarco/src/qemu/util/error.c:59
12
based on the the current CPU mode.
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
13
19
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
14
Signed-off-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
17
---
23
hw/arm/boot.c | 1 +
18
target/arm/op_helper.c | 7 ++++++-
24
1 file changed, 1 insertion(+)
19
1 file changed, 6 insertions(+), 1 deletion(-)
25
20
26
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
21
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
27
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/boot.c
23
--- a/target/arm/op_helper.c
29
+++ b/hw/arm/boot.c
24
+++ b/target/arm/op_helper.c
30
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
25
@@ -XXX,XX +XXX,XX @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
31
32
load_elf_hdr(info->kernel_filename, &elf_header, &elf_is64, &err);
33
if (err) {
34
+ error_free(err);
35
return ret;
36
}
26
}
37
27
28
if (target_el) {
29
- env->pc -= insn_len;
30
+ if (env->aarch64) {
31
+ env->pc -= insn_len;
32
+ } else {
33
+ env->regs[15] -= insn_len;
34
+ }
35
+
36
raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2),
37
target_el);
38
}
38
--
39
--
39
2.16.2
40
2.20.1
40
41
41
42
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jeff Kubascik <jeff.kubascik@dornerworks.com>
2
2
3
As an implementation choice, widening VL has zeroed the
3
The IAR0/IAR1 register is used to acknowledge an interrupt - a read of the
4
previously inaccessible portion of the sve registers.
4
register activates the highest priority pending interrupt and provides its
5
interrupt ID. Activating an interrupt can change the CPU's virtual interrupt
6
state - this change makes sure the virtual irq state is updated.
5
7
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Acked-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20200113154607.97032-1-jeff.kubascik@dornerworks.com
9
Message-id: 20180303143823.27055-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
linux-user/aarch64/target_syscall.h | 3 +++
13
hw/intc/arm_gicv3_cpuif.c | 3 +++
13
target/arm/cpu.h | 1 +
14
1 file changed, 3 insertions(+)
14
linux-user/syscall.c | 27 ++++++++++++++++++++++++
15
target/arm/cpu64.c | 41 +++++++++++++++++++++++++++++++++++++
16
4 files changed, 72 insertions(+)
17
15
18
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
16
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/aarch64/target_syscall.h
18
--- a/hw/intc/arm_gicv3_cpuif.c
21
+++ b/linux-user/aarch64/target_syscall.h
19
+++ b/hw/intc/arm_gicv3_cpuif.c
22
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
20
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri)
23
#define TARGET_MLOCKALL_MCL_CURRENT 1
21
24
#define TARGET_MLOCKALL_MCL_FUTURE 2
22
trace_gicv3_icv_iar_read(ri->crm == 8 ? 0 : 1,
25
23
gicv3_redist_affid(cs), intid);
26
+#define TARGET_PR_SVE_SET_VL 50
27
+#define TARGET_PR_SVE_GET_VL 51
28
+
24
+
29
#endif /* AARCH64_TARGET_SYSCALL_H */
25
+ gicv3_cpuif_virt_update(cs);
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
36
int aarch64_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
37
int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
38
+void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq);
39
#endif
40
41
target_ulong do_arm_semihosting(CPUARMState *env);
42
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/linux-user/syscall.c
45
+++ b/linux-user/syscall.c
46
@@ -XXX,XX +XXX,XX @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
47
break;
48
}
49
#endif
50
+#ifdef TARGET_AARCH64
51
+ case TARGET_PR_SVE_SET_VL:
52
+ /* We cannot support either PR_SVE_SET_VL_ONEXEC
53
+ or PR_SVE_VL_INHERIT. Therefore, anything above
54
+ ARM_MAX_VQ results in EINVAL. */
55
+ ret = -TARGET_EINVAL;
56
+ if (arm_feature(cpu_env, ARM_FEATURE_SVE)
57
+ && arg2 >= 0 && arg2 <= ARM_MAX_VQ * 16 && !(arg2 & 15)) {
58
+ CPUARMState *env = cpu_env;
59
+ int old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
60
+ int vq = MAX(arg2 / 16, 1);
61
+
26
+
62
+ if (vq < old_vq) {
27
return intid;
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
}
28
}
86
29
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
--
30
--
130
2.16.2
31
2.20.1
131
32
132
33
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
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The EXTRA record allows for additional space to be allocated
4
beyon what is currently reserved. Add code to emit and read
5
this record type.
6
7
Nothing uses extra space yet.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180303143823.27055-5-richard.henderson@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@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 | 74 +++++++++++++++++++++++++++++++++++++++++++++--------
16
1 file changed, 63 insertions(+), 11 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_fpsimd_context {
23
uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
24
};
25
26
+#define TARGET_EXTRA_MAGIC 0x45585401
27
+
28
+struct target_extra_context {
29
+ struct target_aarch64_ctx head;
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
--
165
2.16.2
166
167
diff view generated by jsdifflib
1
From: Marc-André Lureau <marcandre.lureau@redhat.com>
1
From: Jeff Kubascik <jeff.kubascik@dornerworks.com>
2
2
3
Spotted by ASAN:
3
The IL bit is set for 32-bit instructions, thus passing false
4
with the is_16bit parameter to syn_data_abort_with_iss() makes
5
a syn mask that always has the IL bit set.
4
6
5
elmarco@boraha:~/src/qemu/build (master *%)$ QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 tests/boot-serial-test
7
Pass is_16bit as true to make the initial syn mask have IL=0,
6
/aarch64/boot-serial/virt: ** (process:19740): DEBUG: 18:39:30.275: foo /tmp/qtest-boot-serial-cXaS94D
8
so that the final IL value comes from or'ing template_syn.
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
9
19
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
10
Cc: qemu-stable@nongnu.org
11
Fixes: aaa1f954d4ca ("target-arm: A64: Create Instruction Syndromes for Data Aborts")
12
Signed-off-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200117004618.2742-2-richard.henderson@linaro.org
15
[rth: Extracted this as a self-contained bug fix from a larger patch]
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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 | 3 ++-
20
target/arm/tlb_helper.c | 2 +-
24
1 file changed, 2 insertions(+), 1 deletion(-)
21
1 file changed, 1 insertion(+), 1 deletion(-)
25
22
26
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
23
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
27
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/boot.c
25
--- a/target/arm/tlb_helper.c
29
+++ b/hw/arm/boot.c
26
+++ b/target/arm/tlb_helper.c
30
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
27
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
28
syn = syn_data_abort_with_iss(same_el,
29
0, 0, 0, 0, 0,
30
ea, 0, s1ptw, is_write, fsc,
31
- false);
32
+ true);
33
/* Merge the runtime syndrome with the template syndrome. */
34
syn |= template_syn;
31
}
35
}
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
--
36
--
41
2.16.2
37
2.20.1
42
38
43
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Depending on the currently selected size of the SVE vector registers,
3
During the conversion to decodetree, the setting of
4
we can either store the data within the "standard" allocation, or we
4
ISSIs16Bit got lost. This causes the guest os to
5
may beedn to allocate additional space with an EXTRA record.
5
incorrectly adjust trapping memory operations.
6
6
7
Cc: qemu-stable@nongnu.org
8
Fixes: 46beb58efbb8a2a32 ("target/arm: Convert T16, load (literal)")
9
Reported-by: Jeff Kubascik <jeff.kubascik@dornerworks.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180303143823.27055-6-richard.henderson@linaro.org
11
Message-id: 20200117004618.2742-3-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
linux-user/signal.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++-----
15
target/arm/translate.c | 3 +++
13
1 file changed, 192 insertions(+), 18 deletions(-)
16
1 file changed, 3 insertions(+)
14
17
15
diff --git a/linux-user/signal.c b/linux-user/signal.c
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/signal.c
20
--- a/target/arm/translate.c
18
+++ b/linux-user/signal.c
21
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ struct target_extra_context {
22
@@ -XXX,XX +XXX,XX @@ static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
20
uint32_t reserved[3];
23
/* ISS not valid if writeback */
21
};
24
if (p && !w) {
22
25
ret = rd;
23
+#define TARGET_SVE_MAGIC 0x53564501
26
+ if (s->base.pc_next - s->pc_curr == 2) {
24
+
27
+ ret |= ISSIs16Bit;
25
+struct target_sve_context {
26
+ struct target_aarch64_ctx head;
27
+ uint16_t vl;
28
+ uint16_t reserved[3];
29
+ /* The actual SVE data immediately follows. It is layed out
30
+ * according to TARGET_SVE_SIG_{Z,P}REG_OFFSET, based off of
31
+ * the original struct pointer.
32
+ */
33
+};
34
+
35
+#define TARGET_SVE_VQ_BYTES 16
36
+
37
+#define TARGET_SVE_SIG_ZREG_SIZE(VQ) ((VQ) * TARGET_SVE_VQ_BYTES)
38
+#define TARGET_SVE_SIG_PREG_SIZE(VQ) ((VQ) * (TARGET_SVE_VQ_BYTES / 8))
39
+
40
+#define TARGET_SVE_SIG_REGS_OFFSET \
41
+ QEMU_ALIGN_UP(sizeof(struct target_sve_context), TARGET_SVE_VQ_BYTES)
42
+#define TARGET_SVE_SIG_ZREG_OFFSET(VQ, N) \
43
+ (TARGET_SVE_SIG_REGS_OFFSET + TARGET_SVE_SIG_ZREG_SIZE(VQ) * (N))
44
+#define TARGET_SVE_SIG_PREG_OFFSET(VQ, N) \
45
+ (TARGET_SVE_SIG_ZREG_OFFSET(VQ, 32) + TARGET_SVE_SIG_PREG_SIZE(VQ) * (N))
46
+#define TARGET_SVE_SIG_FFR_OFFSET(VQ) \
47
+ (TARGET_SVE_SIG_PREG_OFFSET(VQ, 16))
48
+#define TARGET_SVE_SIG_CONTEXT_SIZE(VQ) \
49
+ (TARGET_SVE_SIG_PREG_OFFSET(VQ, 17))
50
+
51
struct target_rt_sigframe {
52
struct target_siginfo info;
53
struct target_ucontext uc;
54
@@ -XXX,XX +XXX,XX @@ static void target_setup_end_record(struct target_aarch64_ctx *end)
55
__put_user(0, &end->size);
56
}
57
58
+static void target_setup_sve_record(struct target_sve_context *sve,
59
+ CPUARMState *env, int vq, int size)
60
+{
61
+ int i, j;
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
+ }
28
+ }
76
+ }
29
} else {
77
+ for (i = 0; i <= 16; ++i) {
30
ret = ISSInvalid;
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
{
89
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
90
}
31
}
91
}
92
93
+static void target_restore_sve_record(CPUARMState *env,
94
+ struct target_sve_context *sve, int vq)
95
+{
96
+ int i, j;
97
+
98
+ /* Note that SVE regs are stored as a byte stream, with each byte element
99
+ * at a subsequent address. This corresponds to a little-endian load
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
+ }
162
+
163
exit:
164
unlock_user(extra, extra_datap, 0);
165
return err;
166
}
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
--
32
--
306
2.16.2
33
2.20.1
307
34
308
35
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
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
Move the definition of the 'host' cpu type into cpu.c, where all the
2
other CPU types are defined. We can do this now we've decoupled it
3
from the KVM-specific host feature probing. This means we now create
4
the type unconditionally (assuming we were built with KVM support at
5
all), but if you try to use it without -enable-kvm this will end
6
up in the "host cpu probe failed and KVM not enabled" path in
7
arm_cpu_realizefn(), for an appropriate error message.
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: 20180308130626.12393-3-peter.maydell@linaro.org
13
---
14
target/arm/cpu.c | 24 ++++++++++++++++++++++++
15
target/arm/kvm.c | 19 -------------------
16
2 files changed, 24 insertions(+), 19 deletions(-)
17
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
21
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
23
#endif
24
}
25
26
+#ifdef CONFIG_KVM
27
+static void arm_host_initfn(Object *obj)
28
+{
29
+ ARMCPU *cpu = ARM_CPU(obj);
30
+
31
+ kvm_arm_set_cpu_features_from_host(cpu);
32
+}
33
+
34
+static const TypeInfo host_arm_cpu_type_info = {
35
+ .name = TYPE_ARM_HOST_CPU,
36
+#ifdef TARGET_AARCH64
37
+ .parent = TYPE_AARCH64_CPU,
38
+#else
39
+ .parent = TYPE_ARM_CPU,
40
+#endif
41
+ .instance_init = arm_host_initfn,
42
+};
43
+
44
+#endif
45
+
46
static void cpu_register(const ARMCPUInfo *info)
47
{
48
TypeInfo type_info = {
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
50
cpu_register(info);
51
info++;
52
}
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
--
98
2.16.2
99
100
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
Now we have a working '-cpu max', the linux-user-only
2
'any' CPU is pretty much the same thing, so implement it
3
that way.
4
1
5
For the moment we don't add any of the extra feature bits
6
to the system-emulation "max", because we don't set the
7
ID register bits we would need to to advertise those
8
features as present.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180308130626.12393-5-peter.maydell@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
---
15
target/arm/cpu.c | 52 +++++++++++++++++++++++++----------------------
16
target/arm/cpu64.c | 59 ++++++++++++++++++++++++++----------------------------
17
2 files changed, 56 insertions(+), 55 deletions(-)
18
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
24
ObjectClass *oc;
25
char *typename;
26
char **cpuname;
27
+ const char *cpunamestr;
28
29
cpuname = g_strsplit(cpu_model, ",", 1);
30
- typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpuname[0]);
31
+ cpunamestr = cpuname[0];
32
+#ifdef CONFIG_USER_ONLY
33
+ /* For backwards compatibility usermode emulation allows "-cpu any",
34
+ * which has the same semantics as "-cpu max".
35
+ */
36
+ if (!strcmp(cpunamestr, "any")) {
37
+ cpunamestr = "max";
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
-
55
#ifdef CONFIG_USER_ONLY
56
-static void arm_any_initfn(Object *obj)
57
-{
58
- ARMCPU *cpu = ARM_CPU(obj);
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
101
--- a/target/arm/cpu64.c
102
+++ b/target/arm/cpu64.c
103
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
104
kvm_arm_set_cpu_features_from_host(cpu);
105
} else {
106
aarch64_a57_initfn(obj);
107
- /* In future we might add feature bits here even if the
108
- * real-world A57 doesn't implement them.
109
+#ifdef CONFIG_USER_ONLY
110
+ /* We don't set these in system emulation mode for the moment,
111
+ * since we don't correctly set the ID registers to advertise them,
112
+ * and in some cases they're only available in AArch64 and not AArch32,
113
+ * whereas the architecture requires them to be present in both if
114
+ * present in either.
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
-
146
- set_feature(&cpu->env, ARM_FEATURE_V8);
147
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
148
- set_feature(&cpu->env, ARM_FEATURE_NEON);
149
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
150
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
151
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
152
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
153
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
154
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
155
- set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
156
- set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
157
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
158
- set_feature(&cpu->env, ARM_FEATURE_CRC);
159
- set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
160
- set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
161
- set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
162
- cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
163
- cpu->dcz_blocksize = 7; /* 512 bytes */
164
-}
165
-#endif
166
-
167
typedef struct ARMCPUInfo {
168
const char *name;
169
void (*initfn)(Object *obj);
170
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
171
{ .name = "cortex-a57", .initfn = aarch64_a57_initfn },
172
{ .name = "cortex-a53", .initfn = aarch64_a53_initfn },
173
{ .name = "max", .initfn = aarch64_max_initfn },
174
-#ifdef CONFIG_USER_ONLY
175
- { .name = "any", .initfn = aarch64_any_initfn },
176
-#endif
177
{ .name = NULL }
178
};
179
180
--
181
2.16.2
182
183
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