1
Arm pullreq for the 2.12 codefreeze...
1
Changes v1->v2 (fixing CI failures in v1, added a couple of
2
extra patches in an attempt to avoid having to do a last
3
minute arm pullreq next week):
4
* new patch to hopefully fix the build issue with the SVE/SME sysregs test
5
* dropped the IC IVAU test case patch
6
* new patch: fix over-length shift
7
* new patches: define neoverse-v1
2
8
3
thanks
9
thanks
4
-- PMM
10
-- PMM
5
11
6
The following changes since commit b39b61e410022f96ceb53d4381d25cba5126ac44:
12
The following changes since commit 2a6ae69154542caa91dd17c40fd3f5ffbec300de:
7
13
8
memory: fix flatview_access_valid RCU read lock/unlock imbalance (2018-03-09 15:55:20 +0000)
14
Merge tag 'pull-maintainer-ominbus-030723-1' of https://gitlab.com/stsquad/qemu into staging (2023-07-04 08:36:44 +0200)
9
15
10
are available in the Git repository at:
16
are available in the Git repository at:
11
17
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180309
18
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230706
13
19
14
for you to fetch changes up to 076a0fc32a73a9b960e0f73f04a531bc1bd94308:
20
for you to fetch changes up to c41077235168140cdd4a34fce9bd95c3d30efe9c:
15
21
16
MAINTAINERS: Add entries for SD (SDHCI, SDBus, SDCard) (2018-03-09 17:09:45 +0000)
22
target/arm: Avoid over-length shift in arm_cpu_sve_finalize() error case (2023-07-06 13:36:51 +0100)
17
23
18
----------------------------------------------------------------
24
----------------------------------------------------------------
19
target-arm queue:
25
target-arm queue:
20
* i.MX: Add i.MX7 SOC implementation and i.MX7 Sabre board
26
* Add raw_writes ops for register whose write induce TLB maintenance
21
* Report the correct core count in A53 L2CTLR on the ZynqMP board
27
* hw/arm/sbsa-ref: use XHCI to replace EHCI
22
* linux-user: preliminary SVE support work (signal handling)
28
* Avoid splitting Zregs across lines in dump
23
* hw/arm/boot: fix memory leak in case of error loading ELF file
29
* Dump ZA[] when active
24
* hw/arm/boot: avoid reading off end of buffer if passed very
30
* Fix SME full tile indexing
25
small image file
31
* Handle IC IVAU to improve compatibility with JITs
26
* hw/arm: Use more CONFIG switches for the object files
32
* xlnx-canfd-test: Fix code coverity issues
27
* target/arm: Add "-cpu max" support
33
* gdbstub: Guard M-profile code with CONFIG_TCG
28
* hw/arm/virt: Support -machine gic-version=max
34
* allwinner-sramc: Set class_size
29
* hw/sd: improve debug tracing
35
* target/xtensa: Assert that interrupt level is within bounds
30
* hw/sd: sdcard: Add the Tuning Command (CMD 19)
36
* Avoid over-length shift in arm_cpu_sve_finalize() error case
31
* MAINTAINERS: add Philippe as odd-fixes maintainer for SD
37
* Define new 'neoverse-v1' CPU type
32
38
33
----------------------------------------------------------------
39
----------------------------------------------------------------
34
Alistair Francis (2):
40
Akihiko Odaki (1):
35
target/arm: Add a core count property
41
hw: arm: allwinner-sramc: Set class_size
36
hw/arm: Set the core count for Xilinx's ZynqMP
37
42
38
Andrey Smirnov (3):
43
Eric Auger (1):
39
pci: Add support for Designware IP block
44
target/arm: Add raw_writes ops for register whose write induce TLB maintenance
40
i.MX: Add i.MX7 SOC implementation.
41
Implement support for i.MX7 Sabre board
42
45
43
Marc-André Lureau (2):
46
Fabiano Rosas (1):
44
arm: fix load ELF error leak
47
target/arm: gdbstub: Guard M-profile code with CONFIG_TCG
45
arm: avoid heap-buffer-overflow in load_aarch64_image
46
48
47
Peter Maydell (6):
49
John Högberg (1):
48
target/arm: Query host CPU features on-demand at instance init
50
target/arm: Handle IC IVAU to improve compatibility with JITs
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
51
55
Philippe Mathieu-Daudé (6):
52
Peter Maydell (5):
56
sdcard: Do not trace CMD55, except when we already expect an ACMD
53
tests/tcg/aarch64/sysregs.c: Use S syntax for id_aa64zfr0_el1 and id_aa64smfr0_el1
57
sdcard: Display command name when tracing CMD/ACMD
54
target/xtensa: Assert that interrupt level is within bounds
58
sdcard: Display which protocol is used when tracing (SD or SPI)
55
target/arm: Suppress more TCG unimplemented features in ID registers
59
sdcard: Add the Tuning Command (CMD19)
56
target/arm: Define neoverse-v1
60
sdhci: Fix a typo in comment
57
target/arm: Avoid over-length shift in arm_cpu_sve_finalize() error case
61
MAINTAINERS: Add entries for SD (SDHCI, SDBus, SDCard)
62
58
63
Richard Henderson (5):
59
Richard Henderson (3):
64
linux-user: Implement aarch64 PR_SVE_SET/GET_VL
60
target/arm: Avoid splitting Zregs across lines in dump
65
aarch64-linux-user: Split out helpers for guest signal handling
61
target/arm: Dump ZA[] when active
66
aarch64-linux-user: Remove struct target_aux_context
62
target/arm: Fix SME full tile indexing
67
aarch64-linux-user: Add support for EXTRA signal frame records
68
aarch64-linux-user: Add support for SVE signal frame records
69
63
70
Thomas Huth (1):
64
Vikram Garhwal (1):
71
hw/arm: Use more CONFIG switches for the object files
65
tests/qtest: xlnx-canfd-test: Fix code coverity issues
72
66
73
hw/arm/Makefile.objs | 31 +-
67
Yuquan Wang (1):
74
hw/pci-host/Makefile.objs | 2 +
68
hw/arm/sbsa-ref: use XHCI to replace EHCI
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
69
70
docs/system/arm/sbsa.rst | 5 +-
71
docs/system/arm/virt.rst | 1 +
72
hw/arm/sbsa-ref.c | 24 ++++---
73
hw/arm/virt.c | 1 +
74
hw/misc/allwinner-sramc.c | 1 +
75
target/arm/cpu.c | 98 +++++++++++++++++++++--------
76
target/arm/cpu64.c | 4 +-
77
target/arm/gdbstub.c | 4 ++
78
target/arm/helper.c | 70 +++++++++++++++++----
79
target/arm/tcg/cpu64.c | 128 ++++++++++++++++++++++++++++++++++++++
80
target/arm/tcg/translate-sme.c | 24 +++++--
81
target/xtensa/exc_helper.c | 3 +
82
tests/qtest/xlnx-canfd-test.c | 33 ++++------
83
tests/tcg/aarch64/sme-outprod1.c | 83 ++++++++++++++++++++++++
84
tests/tcg/aarch64/sysregs.c | 11 ++--
85
hw/arm/Kconfig | 2 +-
86
tests/tcg/aarch64/Makefile.target | 16 ++---
87
17 files changed, 415 insertions(+), 93 deletions(-)
88
create mode 100644 tests/tcg/aarch64/sme-outprod1.c
89
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
The cortex A53 TRM specifies that bits 24 and 25 of the L2CTLR register
3
Some registers whose 'cooked' writefns induce TLB maintenance do
4
specify the number of cores in the processor, not the total number of
4
not have raw_writefn ops defined. If only the writefn ops is set
5
cores in the system. To report this correctly on machines with multiple
5
(ie. no raw_writefn is provided), it is assumed the cooked also
6
CPU clusters (ARM's big.LITTLE or Xilinx's ZynqMP) we need to allow
6
work as the raw one. For those registers it is not obvious the
7
the machine to overwrite this value. To do this let's add an optional
7
tlb_flush works on KVM mode so better/safer setting the raw write.
8
property.
9
8
10
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Message-id: ef01d95c0759e88f47f22d11b14c91512a658b4f.1520018138.git.alistair.francis@xilinx.com
10
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
13
---
15
target/arm/cpu.h | 5 +++++
14
target/arm/helper.c | 23 +++++++++++++----------
16
target/arm/cpu.c | 6 ++++++
15
1 file changed, 13 insertions(+), 10 deletions(-)
17
target/arm/cpu64.c | 6 ++++--
18
3 files changed, 15 insertions(+), 2 deletions(-)
19
16
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
19
--- a/target/arm/helper.c
23
+++ b/target/arm/cpu.h
20
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
25
/* Uniprocessor system with MP extensions */
22
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
26
bool mp_is_up;
23
.access = PL1_RW, .accessfn = access_tvm_trvm,
27
24
.fgt = FGT_TTBR0_EL1,
28
+ /* Specify the number of cores in this CPU cluster. Used for the L2CTLR
25
- .writefn = vmsa_ttbr_write, .resetvalue = 0,
29
+ * register.
26
+ .writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
30
+ */
27
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
31
+ int32_t core_count;
28
offsetof(CPUARMState, cp15.ttbr0_ns) } },
32
+
29
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
33
/* The instance init functions for implementation-specific subclasses
30
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
34
* set these fields to specify the implementation-dependent values of
31
.access = PL1_RW, .accessfn = access_tvm_trvm,
35
* various constant registers and reset values of non-constant
32
.fgt = FGT_TTBR1_EL1,
36
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
33
- .writefn = vmsa_ttbr_write, .resetvalue = 0,
37
index XXXXXXX..XXXXXXX 100644
34
+ .writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
38
--- a/target/arm/cpu.c
35
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
39
+++ b/target/arm/cpu.c
36
offsetof(CPUARMState, cp15.ttbr1_ns) } },
40
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
37
{ .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
41
cs->num_ases = 1;
38
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
42
}
39
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
43
cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory);
40
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
44
+
41
offsetof(CPUARMState, cp15.ttbr0_ns) },
45
+ /* No core_count specified, default to smp_cpus. */
42
- .writefn = vmsa_ttbr_write, },
46
+ if (cpu->core_count == -1) {
43
+ .writefn = vmsa_ttbr_write, .raw_writefn = raw_write },
47
+ cpu->core_count = smp_cpus;
44
{ .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
48
+ }
45
.access = PL1_RW, .accessfn = access_tvm_trvm,
49
#endif
46
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
50
47
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
51
qemu_init_vcpu(cs);
48
offsetof(CPUARMState, cp15.ttbr1_ns) },
52
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_properties[] = {
49
- .writefn = vmsa_ttbr_write, },
53
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
50
+ .writefn = vmsa_ttbr_write, .raw_writefn = raw_write },
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
};
51
};
59
52
60
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
53
static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
61
index XXXXXXX..XXXXXXX 100644
54
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
62
--- a/target/arm/cpu64.c
55
.type = ARM_CP_IO,
63
+++ b/target/arm/cpu64.c
56
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
64
@@ -XXX,XX +XXX,XX @@ static inline void unset_feature(CPUARMState *env, int feature)
57
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
58
- .writefn = hcr_write },
59
+ .writefn = hcr_write, .raw_writefn = raw_write },
60
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
61
.type = ARM_CP_ALIAS | ARM_CP_IO,
62
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
64
{ .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
65
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
66
.access = PL2_RW, .writefn = vmsa_tcr_el12_write,
67
+ .raw_writefn = raw_write,
68
.fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) },
69
{ .name = "VTCR", .state = ARM_CP_STATE_AA32,
70
.cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
71
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
72
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
73
.access = PL2_RW, .accessfn = access_el3_aa32ns,
74
.fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2),
75
- .writefn = vttbr_write },
76
+ .writefn = vttbr_write, .raw_writefn = raw_write },
77
{ .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
78
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
79
- .access = PL2_RW, .writefn = vttbr_write,
80
+ .access = PL2_RW, .writefn = vttbr_write, .raw_writefn = raw_write,
81
.fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) },
82
{ .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
83
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
84
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
85
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
86
{ .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
87
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
88
- .access = PL2_RW, .resetvalue = 0, .writefn = vmsa_tcr_ttbr_el2_write,
89
+ .access = PL2_RW, .resetvalue = 0,
90
+ .writefn = vmsa_tcr_ttbr_el2_write, .raw_writefn = raw_write,
91
.fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
92
{ .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
93
.access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
94
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
95
{ .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
96
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
97
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
98
- .resetfn = scr_reset, .writefn = scr_write },
99
+ .resetfn = scr_reset, .writefn = scr_write, .raw_writefn = raw_write },
100
{ .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
101
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
102
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
103
.fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
104
- .writefn = scr_write },
105
+ .writefn = scr_write, .raw_writefn = raw_write },
106
{ .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64,
107
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1,
108
.access = PL3_RW, .resetvalue = 0,
109
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
110
{ .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
111
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 1,
112
.access = PL2_RW, .writefn = vmsa_tcr_ttbr_el2_write,
113
+ .raw_writefn = raw_write,
114
.fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el[2]) },
65
#ifndef CONFIG_USER_ONLY
115
#ifndef CONFIG_USER_ONLY
66
static uint64_t a57_a53_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
116
{ .name = "CNTHV_CVAL_EL2", .state = ARM_CP_STATE_AA64,
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
--
117
--
78
2.16.2
118
2.34.1
79
80
diff view generated by jsdifflib
Deleted patch
1
From: Alistair Francis <alistair.francis@xilinx.com>
2
1
3
Set the ARM CPU core count property for the A53's attached to the Xilnx
4
ZynqMP machine.
5
6
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: fe0dd90b85ac73f9fc9548c253bededa70a07006.1520018138.git.alistair.francis@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/xlnx-zynqmp.c | 2 ++
12
1 file changed, 2 insertions(+)
13
14
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-zynqmp.c
17
+++ b/hw/arm/xlnx-zynqmp.c
18
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
19
s->virt, "has_el2", NULL);
20
object_property_set_int(OBJECT(&s->apu_cpu[i]), GIC_BASE_ADDR,
21
"reset-cbar", &error_abort);
22
+ object_property_set_int(OBJECT(&s->apu_cpu[i]), num_apus,
23
+ "core-count", &error_abort);
24
object_property_set_bool(OBJECT(&s->apu_cpu[i]), true, "realized",
25
&err);
26
if (err) {
27
--
28
2.16.2
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Add code needed to get a functional PCI subsytem when using in
4
conjunction with upstream Linux guest (4.13+). Tested to work against
5
"e1000e" (network adapter, using MSI interrupts) as well as
6
"usb-ehci" (USB controller, using legacy PCI interrupts).
7
8
Based on "i.MX6 Applications Processor Reference Manual" (Document
9
Number: IMX6DQRM Rev. 4) as well as corresponding dirver in Linux
10
kernel (circa 4.13 - 4.16 found in drivers/pci/dwc/*)
11
12
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/pci-host/Makefile.objs | 2 +
17
include/hw/pci-host/designware.h | 102 ++++++
18
include/hw/pci/pci_ids.h | 2 +
19
hw/pci-host/designware.c | 754 +++++++++++++++++++++++++++++++++++++++
20
default-configs/arm-softmmu.mak | 1 +
21
5 files changed, 861 insertions(+)
22
create mode 100644 include/hw/pci-host/designware.h
23
create mode 100644 hw/pci-host/designware.c
24
25
diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/pci-host/Makefile.objs
28
+++ b/hw/pci-host/Makefile.objs
29
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_PCI_PIIX) += piix.o
30
common-obj-$(CONFIG_PCI_Q35) += q35.o
31
common-obj-$(CONFIG_PCI_GENERIC) += gpex.o
32
common-obj-$(CONFIG_PCI_XILINX) += xilinx-pcie.o
33
+
34
+common-obj-$(CONFIG_PCI_DESIGNWARE) += designware.o
35
diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/include/hw/pci-host/designware.h
40
@@ -XXX,XX +XXX,XX @@
41
+/*
42
+ * Copyright (c) 2017, Impinj, Inc.
43
+ *
44
+ * Designware PCIe IP block emulation
45
+ *
46
+ * This library is free software; you can redistribute it and/or
47
+ * modify it under the terms of the GNU Lesser General Public
48
+ * License as published by the Free Software Foundation; either
49
+ * version 2 of the License, or (at your option) any later version.
50
+ *
51
+ * This library is distributed in the hope that it will be useful,
52
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
53
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
54
+ * Lesser General Public License for more details.
55
+ *
56
+ * You should have received a copy of the GNU Lesser General Public
57
+ * License along with this library; if not, see
58
+ * <http://www.gnu.org/licenses/>.
59
+ */
60
+
61
+#ifndef DESIGNWARE_H
62
+#define DESIGNWARE_H
63
+
64
+#include "hw/hw.h"
65
+#include "hw/sysbus.h"
66
+#include "hw/pci/pci.h"
67
+#include "hw/pci/pci_bus.h"
68
+#include "hw/pci/pcie_host.h"
69
+#include "hw/pci/pci_bridge.h"
70
+
71
+#define TYPE_DESIGNWARE_PCIE_HOST "designware-pcie-host"
72
+#define DESIGNWARE_PCIE_HOST(obj) \
73
+ OBJECT_CHECK(DesignwarePCIEHost, (obj), TYPE_DESIGNWARE_PCIE_HOST)
74
+
75
+#define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root"
76
+#define DESIGNWARE_PCIE_ROOT(obj) \
77
+ OBJECT_CHECK(DesignwarePCIERoot, (obj), TYPE_DESIGNWARE_PCIE_ROOT)
78
+
79
+struct DesignwarePCIERoot;
80
+typedef struct DesignwarePCIERoot DesignwarePCIERoot;
81
+
82
+typedef struct DesignwarePCIEViewport {
83
+ DesignwarePCIERoot *root;
84
+
85
+ MemoryRegion cfg;
86
+ MemoryRegion mem;
87
+
88
+ uint64_t base;
89
+ uint64_t target;
90
+ uint32_t limit;
91
+ uint32_t cr[2];
92
+
93
+ bool inbound;
94
+} DesignwarePCIEViewport;
95
+
96
+typedef struct DesignwarePCIEMSIBank {
97
+ uint32_t enable;
98
+ uint32_t mask;
99
+ uint32_t status;
100
+} DesignwarePCIEMSIBank;
101
+
102
+typedef struct DesignwarePCIEMSI {
103
+ uint64_t base;
104
+ MemoryRegion iomem;
105
+
106
+#define DESIGNWARE_PCIE_NUM_MSI_BANKS 1
107
+
108
+ DesignwarePCIEMSIBank intr[DESIGNWARE_PCIE_NUM_MSI_BANKS];
109
+} DesignwarePCIEMSI;
110
+
111
+struct DesignwarePCIERoot {
112
+ PCIBridge parent_obj;
113
+
114
+ uint32_t atu_viewport;
115
+
116
+#define DESIGNWARE_PCIE_VIEWPORT_OUTBOUND 0
117
+#define DESIGNWARE_PCIE_VIEWPORT_INBOUND 1
118
+#define DESIGNWARE_PCIE_NUM_VIEWPORTS 4
119
+
120
+ DesignwarePCIEViewport viewports[2][DESIGNWARE_PCIE_NUM_VIEWPORTS];
121
+ DesignwarePCIEMSI msi;
122
+};
123
+
124
+typedef struct DesignwarePCIEHost {
125
+ PCIHostState parent_obj;
126
+
127
+ DesignwarePCIERoot root;
128
+
129
+ struct {
130
+ AddressSpace address_space;
131
+ MemoryRegion address_space_root;
132
+
133
+ MemoryRegion memory;
134
+ MemoryRegion io;
135
+
136
+ qemu_irq irqs[4];
137
+ } pci;
138
+
139
+ MemoryRegion mmio;
140
+} DesignwarePCIEHost;
141
+
142
+#endif /* DESIGNWARE_H */
143
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
144
index XXXXXXX..XXXXXXX 100644
145
--- a/include/hw/pci/pci_ids.h
146
+++ b/include/hw/pci/pci_ids.h
147
@@ -XXX,XX +XXX,XX @@
148
#define PCI_VENDOR_ID_VMWARE 0x15ad
149
#define PCI_DEVICE_ID_VMWARE_PVRDMA 0x0820
150
151
+#define PCI_VENDOR_ID_SYNOPSYS 0x16C3
152
+
153
#endif
154
diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c
155
new file mode 100644
156
index XXXXXXX..XXXXXXX
157
--- /dev/null
158
+++ b/hw/pci-host/designware.c
159
@@ -XXX,XX +XXX,XX @@
160
+/*
161
+ * Copyright (c) 2018, Impinj, Inc.
162
+ *
163
+ * Designware PCIe IP block emulation
164
+ *
165
+ * This library is free software; you can redistribute it and/or
166
+ * modify it under the terms of the GNU Lesser General Public
167
+ * License as published by the Free Software Foundation; either
168
+ * version 2 of the License, or (at your option) any later version.
169
+ *
170
+ * This library is distributed in the hope that it will be useful,
171
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
172
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
173
+ * Lesser General Public License for more details.
174
+ *
175
+ * You should have received a copy of the GNU Lesser General Public
176
+ * License along with this library; if not, see
177
+ * <http://www.gnu.org/licenses/>.
178
+ */
179
+
180
+#include "qemu/osdep.h"
181
+#include "qapi/error.h"
182
+#include "hw/pci/msi.h"
183
+#include "hw/pci/pci_bridge.h"
184
+#include "hw/pci/pci_host.h"
185
+#include "hw/pci/pcie_port.h"
186
+#include "hw/pci-host/designware.h"
187
+
188
+#define DESIGNWARE_PCIE_PORT_LINK_CONTROL 0x710
189
+#define DESIGNWARE_PCIE_PHY_DEBUG_R1 0x72C
190
+#define DESIGNWARE_PCIE_PHY_DEBUG_R1_XMLH_LINK_UP BIT(4)
191
+#define DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C
192
+#define DESIGNWARE_PCIE_PORT_LOGIC_SPEED_CHANGE BIT(17)
193
+#define DESIGNWARE_PCIE_MSI_ADDR_LO 0x820
194
+#define DESIGNWARE_PCIE_MSI_ADDR_HI 0x824
195
+#define DESIGNWARE_PCIE_MSI_INTR0_ENABLE 0x828
196
+#define DESIGNWARE_PCIE_MSI_INTR0_MASK 0x82C
197
+#define DESIGNWARE_PCIE_MSI_INTR0_STATUS 0x830
198
+#define DESIGNWARE_PCIE_ATU_VIEWPORT 0x900
199
+#define DESIGNWARE_PCIE_ATU_REGION_INBOUND BIT(31)
200
+#define DESIGNWARE_PCIE_ATU_CR1 0x904
201
+#define DESIGNWARE_PCIE_ATU_TYPE_MEM (0x0 << 0)
202
+#define DESIGNWARE_PCIE_ATU_CR2 0x908
203
+#define DESIGNWARE_PCIE_ATU_ENABLE BIT(31)
204
+#define DESIGNWARE_PCIE_ATU_LOWER_BASE 0x90C
205
+#define DESIGNWARE_PCIE_ATU_UPPER_BASE 0x910
206
+#define DESIGNWARE_PCIE_ATU_LIMIT 0x914
207
+#define DESIGNWARE_PCIE_ATU_LOWER_TARGET 0x918
208
+#define DESIGNWARE_PCIE_ATU_BUS(x) (((x) >> 24) & 0xff)
209
+#define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff)
210
+#define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C
211
+
212
+static DesignwarePCIEHost *
213
+designware_pcie_root_to_host(DesignwarePCIERoot *root)
214
+{
215
+ BusState *bus = qdev_get_parent_bus(DEVICE(root));
216
+ return DESIGNWARE_PCIE_HOST(bus->parent);
217
+}
218
+
219
+static void designware_pcie_root_msi_write(void *opaque, hwaddr addr,
220
+ uint64_t val, unsigned len)
221
+{
222
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(opaque);
223
+ DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
224
+
225
+ root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable;
226
+
227
+ if (root->msi.intr[0].status & ~root->msi.intr[0].mask) {
228
+ qemu_set_irq(host->pci.irqs[0], 1);
229
+ }
230
+}
231
+
232
+static const MemoryRegionOps designware_pci_host_msi_ops = {
233
+ .write = designware_pcie_root_msi_write,
234
+ .endianness = DEVICE_LITTLE_ENDIAN,
235
+ .valid = {
236
+ .min_access_size = 4,
237
+ .max_access_size = 4,
238
+ },
239
+};
240
+
241
+static void designware_pcie_root_update_msi_mapping(DesignwarePCIERoot *root)
242
+
243
+{
244
+ MemoryRegion *mem = &root->msi.iomem;
245
+ const uint64_t base = root->msi.base;
246
+ const bool enable = root->msi.intr[0].enable;
247
+
248
+ memory_region_set_address(mem, base);
249
+ memory_region_set_enabled(mem, enable);
250
+}
251
+
252
+static DesignwarePCIEViewport *
253
+designware_pcie_root_get_current_viewport(DesignwarePCIERoot *root)
254
+{
255
+ const unsigned int idx = root->atu_viewport & 0xF;
256
+ const unsigned int dir =
257
+ !!(root->atu_viewport & DESIGNWARE_PCIE_ATU_REGION_INBOUND);
258
+ return &root->viewports[dir][idx];
259
+}
260
+
261
+static uint32_t
262
+designware_pcie_root_config_read(PCIDevice *d, uint32_t address, int len)
263
+{
264
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(d);
265
+ DesignwarePCIEViewport *viewport =
266
+ designware_pcie_root_get_current_viewport(root);
267
+
268
+ uint32_t val;
269
+
270
+ switch (address) {
271
+ case DESIGNWARE_PCIE_PORT_LINK_CONTROL:
272
+ /*
273
+ * Linux guest uses this register only to configure number of
274
+ * PCIE lane (which in our case is irrelevant) and doesn't
275
+ * really care about the value it reads from this register
276
+ */
277
+ val = 0xDEADBEEF;
278
+ break;
279
+
280
+ case DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL:
281
+ /*
282
+ * To make sure that any code in guest waiting for speed
283
+ * change does not time out we always report
284
+ * PORT_LOGIC_SPEED_CHANGE as set
285
+ */
286
+ val = DESIGNWARE_PCIE_PORT_LOGIC_SPEED_CHANGE;
287
+ break;
288
+
289
+ case DESIGNWARE_PCIE_MSI_ADDR_LO:
290
+ val = root->msi.base;
291
+ break;
292
+
293
+ case DESIGNWARE_PCIE_MSI_ADDR_HI:
294
+ val = root->msi.base >> 32;
295
+ break;
296
+
297
+ case DESIGNWARE_PCIE_MSI_INTR0_ENABLE:
298
+ val = root->msi.intr[0].enable;
299
+ break;
300
+
301
+ case DESIGNWARE_PCIE_MSI_INTR0_MASK:
302
+ val = root->msi.intr[0].mask;
303
+ break;
304
+
305
+ case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
306
+ val = root->msi.intr[0].status;
307
+ break;
308
+
309
+ case DESIGNWARE_PCIE_PHY_DEBUG_R1:
310
+ val = DESIGNWARE_PCIE_PHY_DEBUG_R1_XMLH_LINK_UP;
311
+ break;
312
+
313
+ case DESIGNWARE_PCIE_ATU_VIEWPORT:
314
+ val = root->atu_viewport;
315
+ break;
316
+
317
+ case DESIGNWARE_PCIE_ATU_LOWER_BASE:
318
+ val = viewport->base;
319
+ break;
320
+
321
+ case DESIGNWARE_PCIE_ATU_UPPER_BASE:
322
+ val = viewport->base >> 32;
323
+ break;
324
+
325
+ case DESIGNWARE_PCIE_ATU_LOWER_TARGET:
326
+ val = viewport->target;
327
+ break;
328
+
329
+ case DESIGNWARE_PCIE_ATU_UPPER_TARGET:
330
+ val = viewport->target >> 32;
331
+ break;
332
+
333
+ case DESIGNWARE_PCIE_ATU_LIMIT:
334
+ val = viewport->limit;
335
+ break;
336
+
337
+ case DESIGNWARE_PCIE_ATU_CR1:
338
+ case DESIGNWARE_PCIE_ATU_CR2: /* FALLTHROUGH */
339
+ val = viewport->cr[(address - DESIGNWARE_PCIE_ATU_CR1) /
340
+ sizeof(uint32_t)];
341
+ break;
342
+
343
+ default:
344
+ val = pci_default_read_config(d, address, len);
345
+ break;
346
+ }
347
+
348
+ return val;
349
+}
350
+
351
+static uint64_t designware_pcie_root_data_access(void *opaque, hwaddr addr,
352
+ uint64_t *val, unsigned len)
353
+{
354
+ DesignwarePCIEViewport *viewport = opaque;
355
+ DesignwarePCIERoot *root = viewport->root;
356
+
357
+ const uint8_t busnum = DESIGNWARE_PCIE_ATU_BUS(viewport->target);
358
+ const uint8_t devfn = DESIGNWARE_PCIE_ATU_DEVFN(viewport->target);
359
+ PCIBus *pcibus = pci_get_bus(PCI_DEVICE(root));
360
+ PCIDevice *pcidev = pci_find_device(pcibus, busnum, devfn);
361
+
362
+ if (pcidev) {
363
+ addr &= pci_config_size(pcidev) - 1;
364
+
365
+ if (val) {
366
+ pci_host_config_write_common(pcidev, addr,
367
+ pci_config_size(pcidev),
368
+ *val, len);
369
+ } else {
370
+ return pci_host_config_read_common(pcidev, addr,
371
+ pci_config_size(pcidev),
372
+ len);
373
+ }
374
+ }
375
+
376
+ return UINT64_MAX;
377
+}
378
+
379
+static uint64_t designware_pcie_root_data_read(void *opaque, hwaddr addr,
380
+ unsigned len)
381
+{
382
+ return designware_pcie_root_data_access(opaque, addr, NULL, len);
383
+}
384
+
385
+static void designware_pcie_root_data_write(void *opaque, hwaddr addr,
386
+ uint64_t val, unsigned len)
387
+{
388
+ designware_pcie_root_data_access(opaque, addr, &val, len);
389
+}
390
+
391
+static const MemoryRegionOps designware_pci_host_conf_ops = {
392
+ .read = designware_pcie_root_data_read,
393
+ .write = designware_pcie_root_data_write,
394
+ .endianness = DEVICE_LITTLE_ENDIAN,
395
+ .valid = {
396
+ .min_access_size = 1,
397
+ .max_access_size = 4,
398
+ },
399
+};
400
+
401
+static void designware_pcie_update_viewport(DesignwarePCIERoot *root,
402
+ DesignwarePCIEViewport *viewport)
403
+{
404
+ const uint64_t target = viewport->target;
405
+ const uint64_t base = viewport->base;
406
+ const uint64_t size = (uint64_t)viewport->limit - base + 1;
407
+ const bool enabled = viewport->cr[1] & DESIGNWARE_PCIE_ATU_ENABLE;
408
+
409
+ MemoryRegion *current, *other;
410
+
411
+ if (viewport->cr[0] == DESIGNWARE_PCIE_ATU_TYPE_MEM) {
412
+ current = &viewport->mem;
413
+ other = &viewport->cfg;
414
+ memory_region_set_alias_offset(current, target);
415
+ } else {
416
+ current = &viewport->cfg;
417
+ other = &viewport->mem;
418
+ }
419
+
420
+ /*
421
+ * An outbound viewport can be reconfigure from being MEM to CFG,
422
+ * to account for that we disable the "other" memory region that
423
+ * becomes unused due to that fact.
424
+ */
425
+ memory_region_set_enabled(other, false);
426
+ if (enabled) {
427
+ memory_region_set_size(current, size);
428
+ memory_region_set_address(current, base);
429
+ }
430
+ memory_region_set_enabled(current, enabled);
431
+}
432
+
433
+static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address,
434
+ uint32_t val, int len)
435
+{
436
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(d);
437
+ DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
438
+ DesignwarePCIEViewport *viewport =
439
+ designware_pcie_root_get_current_viewport(root);
440
+
441
+ switch (address) {
442
+ case DESIGNWARE_PCIE_PORT_LINK_CONTROL:
443
+ case DESIGNWARE_PCIE_LINK_WIDTH_SPEED_CONTROL:
444
+ case DESIGNWARE_PCIE_PHY_DEBUG_R1:
445
+ /* No-op */
446
+ break;
447
+
448
+ case DESIGNWARE_PCIE_MSI_ADDR_LO:
449
+ root->msi.base &= 0xFFFFFFFF00000000ULL;
450
+ root->msi.base |= val;
451
+ break;
452
+
453
+ case DESIGNWARE_PCIE_MSI_ADDR_HI:
454
+ root->msi.base &= 0x00000000FFFFFFFFULL;
455
+ root->msi.base |= (uint64_t)val << 32;
456
+ break;
457
+
458
+ case DESIGNWARE_PCIE_MSI_INTR0_ENABLE: {
459
+ const bool update_msi_mapping = !root->msi.intr[0].enable ^ !!val;
460
+
461
+ root->msi.intr[0].enable = val;
462
+
463
+ if (update_msi_mapping) {
464
+ designware_pcie_root_update_msi_mapping(root);
465
+ }
466
+ break;
467
+ }
468
+
469
+ case DESIGNWARE_PCIE_MSI_INTR0_MASK:
470
+ root->msi.intr[0].mask = val;
471
+ break;
472
+
473
+ case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
474
+ root->msi.intr[0].status ^= val;
475
+ if (!root->msi.intr[0].status) {
476
+ qemu_set_irq(host->pci.irqs[0], 0);
477
+ }
478
+ break;
479
+
480
+ case DESIGNWARE_PCIE_ATU_VIEWPORT:
481
+ root->atu_viewport = val;
482
+ break;
483
+
484
+ case DESIGNWARE_PCIE_ATU_LOWER_BASE:
485
+ viewport->base &= 0xFFFFFFFF00000000ULL;
486
+ viewport->base |= val;
487
+ break;
488
+
489
+ case DESIGNWARE_PCIE_ATU_UPPER_BASE:
490
+ viewport->base &= 0x00000000FFFFFFFFULL;
491
+ viewport->base |= (uint64_t)val << 32;
492
+ break;
493
+
494
+ case DESIGNWARE_PCIE_ATU_LOWER_TARGET:
495
+ viewport->target &= 0xFFFFFFFF00000000ULL;
496
+ viewport->target |= val;
497
+ break;
498
+
499
+ case DESIGNWARE_PCIE_ATU_UPPER_TARGET:
500
+ viewport->target &= 0x00000000FFFFFFFFULL;
501
+ viewport->target |= val;
502
+ break;
503
+
504
+ case DESIGNWARE_PCIE_ATU_LIMIT:
505
+ viewport->limit = val;
506
+ break;
507
+
508
+ case DESIGNWARE_PCIE_ATU_CR1:
509
+ viewport->cr[0] = val;
510
+ break;
511
+ case DESIGNWARE_PCIE_ATU_CR2:
512
+ viewport->cr[1] = val;
513
+ designware_pcie_update_viewport(root, viewport);
514
+ break;
515
+
516
+ default:
517
+ pci_bridge_write_config(d, address, val, len);
518
+ break;
519
+ }
520
+}
521
+
522
+static char *designware_pcie_viewport_name(const char *direction,
523
+ unsigned int i,
524
+ const char *type)
525
+{
526
+ return g_strdup_printf("PCI %s Viewport %u [%s]",
527
+ direction, i, type);
528
+}
529
+
530
+static void designware_pcie_root_realize(PCIDevice *dev, Error **errp)
531
+{
532
+ DesignwarePCIERoot *root = DESIGNWARE_PCIE_ROOT(dev);
533
+ DesignwarePCIEHost *host = designware_pcie_root_to_host(root);
534
+ MemoryRegion *address_space = &host->pci.memory;
535
+ PCIBridge *br = PCI_BRIDGE(dev);
536
+ DesignwarePCIEViewport *viewport;
537
+ /*
538
+ * Dummy values used for initial configuration of MemoryRegions
539
+ * that belong to a given viewport
540
+ */
541
+ const hwaddr dummy_offset = 0;
542
+ const uint64_t dummy_size = 4;
543
+ size_t i;
544
+
545
+ br->bus_name = "dw-pcie";
546
+
547
+ pci_set_word(dev->config + PCI_COMMAND,
548
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
549
+
550
+ pci_config_set_interrupt_pin(dev->config, 1);
551
+ pci_bridge_initfn(dev, TYPE_PCIE_BUS);
552
+
553
+ pcie_port_init_reg(dev);
554
+
555
+ pcie_cap_init(dev, 0x70, PCI_EXP_TYPE_ROOT_PORT,
556
+ 0, &error_fatal);
557
+
558
+ msi_nonbroken = true;
559
+ msi_init(dev, 0x50, 32, true, true, &error_fatal);
560
+
561
+ for (i = 0; i < DESIGNWARE_PCIE_NUM_VIEWPORTS; i++) {
562
+ MemoryRegion *source, *destination, *mem;
563
+ const char *direction;
564
+ char *name;
565
+
566
+ viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][i];
567
+ viewport->inbound = true;
568
+ viewport->base = 0x0000000000000000ULL;
569
+ viewport->target = 0x0000000000000000ULL;
570
+ viewport->limit = UINT32_MAX;
571
+ viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM;
572
+
573
+ source = &host->pci.address_space_root;
574
+ destination = get_system_memory();
575
+ direction = "Inbound";
576
+
577
+ /*
578
+ * Configure MemoryRegion implementing PCI -> CPU memory
579
+ * access
580
+ */
581
+ mem = &viewport->mem;
582
+ name = designware_pcie_viewport_name(direction, i, "MEM");
583
+ memory_region_init_alias(mem, OBJECT(root), name, destination,
584
+ dummy_offset, dummy_size);
585
+ memory_region_add_subregion_overlap(source, dummy_offset, mem, -1);
586
+ memory_region_set_enabled(mem, false);
587
+ g_free(name);
588
+
589
+ viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_OUTBOUND][i];
590
+ viewport->root = root;
591
+ viewport->inbound = false;
592
+ viewport->base = 0x0000000000000000ULL;
593
+ viewport->target = 0x0000000000000000ULL;
594
+ viewport->limit = UINT32_MAX;
595
+ viewport->cr[0] = DESIGNWARE_PCIE_ATU_TYPE_MEM;
596
+
597
+ destination = &host->pci.memory;
598
+ direction = "Outbound";
599
+ source = get_system_memory();
600
+
601
+ /*
602
+ * Configure MemoryRegion implementing CPU -> PCI memory
603
+ * access
604
+ */
605
+ mem = &viewport->mem;
606
+ name = designware_pcie_viewport_name(direction, i, "MEM");
607
+ memory_region_init_alias(mem, OBJECT(root), name, destination,
608
+ dummy_offset, dummy_size);
609
+ memory_region_add_subregion(source, dummy_offset, mem);
610
+ memory_region_set_enabled(mem, false);
611
+ g_free(name);
612
+
613
+ /*
614
+ * Configure MemoryRegion implementing access to configuration
615
+ * space
616
+ */
617
+ mem = &viewport->cfg;
618
+ name = designware_pcie_viewport_name(direction, i, "CFG");
619
+ memory_region_init_io(&viewport->cfg, OBJECT(root),
620
+ &designware_pci_host_conf_ops,
621
+ viewport, name, dummy_size);
622
+ memory_region_add_subregion(source, dummy_offset, mem);
623
+ memory_region_set_enabled(mem, false);
624
+ g_free(name);
625
+ }
626
+
627
+ /*
628
+ * If no inbound iATU windows are configured, HW defaults to
629
+ * letting inbound TLPs to pass in. We emulate that by exlicitly
630
+ * configuring first inbound window to cover all of target's
631
+ * address space.
632
+ *
633
+ * NOTE: This will not work correctly for the case when first
634
+ * configured inbound window is window 0
635
+ */
636
+ viewport = &root->viewports[DESIGNWARE_PCIE_VIEWPORT_INBOUND][0];
637
+ viewport->cr[1] = DESIGNWARE_PCIE_ATU_ENABLE;
638
+ designware_pcie_update_viewport(root, viewport);
639
+
640
+ memory_region_init_io(&root->msi.iomem, OBJECT(root),
641
+ &designware_pci_host_msi_ops,
642
+ root, "pcie-msi", 0x4);
643
+ /*
644
+ * We initially place MSI interrupt I/O region a adress 0 and
645
+ * disable it. It'll be later moved to correct offset and enabled
646
+ * in designware_pcie_root_update_msi_mapping() as a part of
647
+ * initialization done by guest OS
648
+ */
649
+ memory_region_add_subregion(address_space, dummy_offset, &root->msi.iomem);
650
+ memory_region_set_enabled(&root->msi.iomem, false);
651
+}
652
+
653
+static void designware_pcie_set_irq(void *opaque, int irq_num, int level)
654
+{
655
+ DesignwarePCIEHost *host = DESIGNWARE_PCIE_HOST(opaque);
656
+
657
+ qemu_set_irq(host->pci.irqs[irq_num], level);
658
+}
659
+
660
+static const char *
661
+designware_pcie_host_root_bus_path(PCIHostState *host_bridge, PCIBus *rootbus)
662
+{
663
+ return "0000:00";
664
+}
665
+
666
+static const VMStateDescription vmstate_designware_pcie_msi_bank = {
667
+ .name = "designware-pcie-msi-bank",
668
+ .version_id = 1,
669
+ .minimum_version_id = 1,
670
+ .fields = (VMStateField[]) {
671
+ VMSTATE_UINT32(enable, DesignwarePCIEMSIBank),
672
+ VMSTATE_UINT32(mask, DesignwarePCIEMSIBank),
673
+ VMSTATE_UINT32(status, DesignwarePCIEMSIBank),
674
+ VMSTATE_END_OF_LIST()
675
+ }
676
+};
677
+
678
+static const VMStateDescription vmstate_designware_pcie_msi = {
679
+ .name = "designware-pcie-msi",
680
+ .version_id = 1,
681
+ .minimum_version_id = 1,
682
+ .fields = (VMStateField[]) {
683
+ VMSTATE_UINT64(base, DesignwarePCIEMSI),
684
+ VMSTATE_STRUCT_ARRAY(intr,
685
+ DesignwarePCIEMSI,
686
+ DESIGNWARE_PCIE_NUM_MSI_BANKS,
687
+ 1,
688
+ vmstate_designware_pcie_msi_bank,
689
+ DesignwarePCIEMSIBank),
690
+ VMSTATE_END_OF_LIST()
691
+ }
692
+};
693
+
694
+static const VMStateDescription vmstate_designware_pcie_viewport = {
695
+ .name = "designware-pcie-viewport",
696
+ .version_id = 1,
697
+ .minimum_version_id = 1,
698
+ .fields = (VMStateField[]) {
699
+ VMSTATE_UINT64(base, DesignwarePCIEViewport),
700
+ VMSTATE_UINT64(target, DesignwarePCIEViewport),
701
+ VMSTATE_UINT32(limit, DesignwarePCIEViewport),
702
+ VMSTATE_UINT32_ARRAY(cr, DesignwarePCIEViewport, 2),
703
+ VMSTATE_END_OF_LIST()
704
+ }
705
+};
706
+
707
+static const VMStateDescription vmstate_designware_pcie_root = {
708
+ .name = "designware-pcie-root",
709
+ .version_id = 1,
710
+ .minimum_version_id = 1,
711
+ .fields = (VMStateField[]) {
712
+ VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
713
+ VMSTATE_UINT32(atu_viewport, DesignwarePCIERoot),
714
+ VMSTATE_STRUCT_2DARRAY(viewports,
715
+ DesignwarePCIERoot,
716
+ 2,
717
+ DESIGNWARE_PCIE_NUM_VIEWPORTS,
718
+ 1,
719
+ vmstate_designware_pcie_viewport,
720
+ DesignwarePCIEViewport),
721
+ VMSTATE_STRUCT(msi,
722
+ DesignwarePCIERoot,
723
+ 1,
724
+ vmstate_designware_pcie_msi,
725
+ DesignwarePCIEMSI),
726
+ VMSTATE_END_OF_LIST()
727
+ }
728
+};
729
+
730
+static void designware_pcie_root_class_init(ObjectClass *klass, void *data)
731
+{
732
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
733
+ DeviceClass *dc = DEVICE_CLASS(klass);
734
+
735
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
736
+
737
+ k->vendor_id = PCI_VENDOR_ID_SYNOPSYS;
738
+ k->device_id = 0xABCD;
739
+ k->revision = 0;
740
+ k->class_id = PCI_CLASS_BRIDGE_PCI;
741
+ k->is_bridge = true;
742
+ k->exit = pci_bridge_exitfn;
743
+ k->realize = designware_pcie_root_realize;
744
+ k->config_read = designware_pcie_root_config_read;
745
+ k->config_write = designware_pcie_root_config_write;
746
+
747
+ dc->reset = pci_bridge_reset;
748
+ /*
749
+ * PCI-facing part of the host bridge, not usable without the
750
+ * host-facing part, which can't be device_add'ed, yet.
751
+ */
752
+ dc->user_creatable = false;
753
+ dc->vmsd = &vmstate_designware_pcie_root;
754
+}
755
+
756
+static uint64_t designware_pcie_host_mmio_read(void *opaque, hwaddr addr,
757
+ unsigned int size)
758
+{
759
+ PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
760
+ PCIDevice *device = pci_find_device(pci->bus, 0, 0);
761
+
762
+ return pci_host_config_read_common(device,
763
+ addr,
764
+ pci_config_size(device),
765
+ size);
766
+}
767
+
768
+static void designware_pcie_host_mmio_write(void *opaque, hwaddr addr,
769
+ uint64_t val, unsigned int size)
770
+{
771
+ PCIHostState *pci = PCI_HOST_BRIDGE(opaque);
772
+ PCIDevice *device = pci_find_device(pci->bus, 0, 0);
773
+
774
+ return pci_host_config_write_common(device,
775
+ addr,
776
+ pci_config_size(device),
777
+ val, size);
778
+}
779
+
780
+static const MemoryRegionOps designware_pci_mmio_ops = {
781
+ .read = designware_pcie_host_mmio_read,
782
+ .write = designware_pcie_host_mmio_write,
783
+ .endianness = DEVICE_LITTLE_ENDIAN,
784
+ .impl = {
785
+ /*
786
+ * Our device would not work correctly if the guest was doing
787
+ * unaligned access. This might not be a limitation on the real
788
+ * device but in practice there is no reason for a guest to access
789
+ * this device unaligned.
790
+ */
791
+ .min_access_size = 4,
792
+ .max_access_size = 4,
793
+ .unaligned = false,
794
+ },
795
+};
796
+
797
+static AddressSpace *designware_pcie_host_set_iommu(PCIBus *bus, void *opaque,
798
+ int devfn)
799
+{
800
+ DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(opaque);
801
+
802
+ return &s->pci.address_space;
803
+}
804
+
805
+static void designware_pcie_host_realize(DeviceState *dev, Error **errp)
806
+{
807
+ PCIHostState *pci = PCI_HOST_BRIDGE(dev);
808
+ DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(dev);
809
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
810
+ size_t i;
811
+
812
+ for (i = 0; i < ARRAY_SIZE(s->pci.irqs); i++) {
813
+ sysbus_init_irq(sbd, &s->pci.irqs[i]);
814
+ }
815
+
816
+ memory_region_init_io(&s->mmio,
817
+ OBJECT(s),
818
+ &designware_pci_mmio_ops,
819
+ s,
820
+ "pcie.reg", 4 * 1024);
821
+ sysbus_init_mmio(sbd, &s->mmio);
822
+
823
+ memory_region_init(&s->pci.io, OBJECT(s), "pcie-pio", 16);
824
+ memory_region_init(&s->pci.memory, OBJECT(s),
825
+ "pcie-bus-memory",
826
+ UINT64_MAX);
827
+
828
+ pci->bus = pci_register_root_bus(dev, "pcie",
829
+ designware_pcie_set_irq,
830
+ pci_swizzle_map_irq_fn,
831
+ s,
832
+ &s->pci.memory,
833
+ &s->pci.io,
834
+ 0, 4,
835
+ TYPE_PCIE_BUS);
836
+
837
+ memory_region_init(&s->pci.address_space_root,
838
+ OBJECT(s),
839
+ "pcie-bus-address-space-root",
840
+ UINT64_MAX);
841
+ memory_region_add_subregion(&s->pci.address_space_root,
842
+ 0x0, &s->pci.memory);
843
+ address_space_init(&s->pci.address_space,
844
+ &s->pci.address_space_root,
845
+ "pcie-bus-address-space");
846
+ pci_setup_iommu(pci->bus, designware_pcie_host_set_iommu, s);
847
+
848
+ qdev_set_parent_bus(DEVICE(&s->root), BUS(pci->bus));
849
+ qdev_init_nofail(DEVICE(&s->root));
850
+}
851
+
852
+static const VMStateDescription vmstate_designware_pcie_host = {
853
+ .name = "designware-pcie-host",
854
+ .version_id = 1,
855
+ .minimum_version_id = 1,
856
+ .fields = (VMStateField[]) {
857
+ VMSTATE_STRUCT(root,
858
+ DesignwarePCIEHost,
859
+ 1,
860
+ vmstate_designware_pcie_root,
861
+ DesignwarePCIERoot),
862
+ VMSTATE_END_OF_LIST()
863
+ }
864
+};
865
+
866
+static void designware_pcie_host_class_init(ObjectClass *klass, void *data)
867
+{
868
+ DeviceClass *dc = DEVICE_CLASS(klass);
869
+ PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
870
+
871
+ hc->root_bus_path = designware_pcie_host_root_bus_path;
872
+ dc->realize = designware_pcie_host_realize;
873
+ set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
874
+ dc->fw_name = "pci";
875
+ dc->vmsd = &vmstate_designware_pcie_host;
876
+}
877
+
878
+static void designware_pcie_host_init(Object *obj)
879
+{
880
+ DesignwarePCIEHost *s = DESIGNWARE_PCIE_HOST(obj);
881
+ DesignwarePCIERoot *root = &s->root;
882
+
883
+ object_initialize(root, sizeof(*root), TYPE_DESIGNWARE_PCIE_ROOT);
884
+ object_property_add_child(obj, "root", OBJECT(root), NULL);
885
+ qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
886
+ qdev_prop_set_bit(DEVICE(root), "multifunction", false);
887
+}
888
+
889
+static const TypeInfo designware_pcie_root_info = {
890
+ .name = TYPE_DESIGNWARE_PCIE_ROOT,
891
+ .parent = TYPE_PCI_BRIDGE,
892
+ .instance_size = sizeof(DesignwarePCIERoot),
893
+ .class_init = designware_pcie_root_class_init,
894
+ .interfaces = (InterfaceInfo[]) {
895
+ { INTERFACE_PCIE_DEVICE },
896
+ { }
897
+ },
898
+};
899
+
900
+static const TypeInfo designware_pcie_host_info = {
901
+ .name = TYPE_DESIGNWARE_PCIE_HOST,
902
+ .parent = TYPE_PCI_HOST_BRIDGE,
903
+ .instance_size = sizeof(DesignwarePCIEHost),
904
+ .instance_init = designware_pcie_host_init,
905
+ .class_init = designware_pcie_host_class_init,
906
+};
907
+
908
+static void designware_pcie_register(void)
909
+{
910
+ type_register_static(&designware_pcie_root_info);
911
+ type_register_static(&designware_pcie_host_info);
912
+}
913
+type_init(designware_pcie_register)
914
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
915
index XXXXXXX..XXXXXXX 100644
916
--- a/default-configs/arm-softmmu.mak
917
+++ b/default-configs/arm-softmmu.mak
918
@@ -XXX,XX +XXX,XX @@ CONFIG_GPIO_KEY=y
919
CONFIG_MSF2=y
920
CONFIG_FW_CFG_DMA=y
921
CONFIG_XILINX_AXI=y
922
+CONFIG_PCI_DESIGNWARE=y
923
--
924
2.16.2
925
926
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Yuquan Wang <wangyuquan1236@phytium.com.cn>
2
2
3
The EXTRA record allows for additional space to be allocated
3
The current sbsa-ref cannot use EHCI controller which is only
4
beyon what is currently reserved. Add code to emit and read
4
able to do 32-bit DMA, since sbsa-ref doesn't have RAM below 4GB.
5
this record type.
5
Hence, this uses XHCI to provide a usb controller with 64-bit
6
DMA capablity instead of EHCI.
6
7
7
Nothing uses extra space yet.
8
We bump the platform version to 0.3 with this change. Although the
9
hardware at the USB controller address changes, the firmware and
10
Linux can both cope with this -- on an older non-XHCI-aware
11
firmware/kernel setup the probe routine simply fails and the guest
12
proceeds without any USB. (This isn't a loss of functionality,
13
because the old USB controller never worked in the first place.) So
14
we can call this a backwards-compatible change and only bump the
15
minor version.
8
16
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Yuquan Wang <wangyuquan1236@phytium.com.cn>
10
Message-id: 20180303143823.27055-5-richard.henderson@linaro.org
18
Message-id: 20230621103847.447508-2-wangyuquan1236@phytium.com.cn
19
[PMM: tweaked commit message; add line to docs about what
20
changes in platform version 0.3]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
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>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
23
---
15
linux-user/signal.c | 74 +++++++++++++++++++++++++++++++++++++++++++++--------
24
docs/system/arm/sbsa.rst | 5 ++++-
16
1 file changed, 63 insertions(+), 11 deletions(-)
25
hw/arm/sbsa-ref.c | 23 +++++++++++++----------
26
hw/arm/Kconfig | 2 +-
27
3 files changed, 18 insertions(+), 12 deletions(-)
17
28
18
diff --git a/linux-user/signal.c b/linux-user/signal.c
29
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
19
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/signal.c
31
--- a/docs/system/arm/sbsa.rst
21
+++ b/linux-user/signal.c
32
+++ b/docs/system/arm/sbsa.rst
22
@@ -XXX,XX +XXX,XX @@ struct target_fpsimd_context {
33
@@ -XXX,XX +XXX,XX @@ The ``sbsa-ref`` board supports:
23
uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
34
- A configurable number of AArch64 CPUs
35
- GIC version 3
36
- System bus AHCI controller
37
- - System bus EHCI controller
38
+ - System bus XHCI controller
39
- CDROM and hard disc on AHCI bus
40
- E1000E ethernet card on PCIe bus
41
- Bochs display adapter on PCIe bus
42
@@ -XXX,XX +XXX,XX @@ Platform version changes:
43
44
0.2
45
GIC ITS information is present in devicetree.
46
+
47
+0.3
48
+ The USB controller is an XHCI device, not EHCI
49
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/sbsa-ref.c
52
+++ b/hw/arm/sbsa-ref.c
53
@@ -XXX,XX +XXX,XX @@
54
#include "hw/pci-host/gpex.h"
55
#include "hw/qdev-properties.h"
56
#include "hw/usb.h"
57
+#include "hw/usb/xhci.h"
58
#include "hw/char/pl011.h"
59
#include "hw/watchdog/sbsa_gwdt.h"
60
#include "net/net.h"
61
@@ -XXX,XX +XXX,XX @@ enum {
62
SBSA_SECURE_UART_MM,
63
SBSA_SECURE_MEM,
64
SBSA_AHCI,
65
- SBSA_EHCI,
66
+ SBSA_XHCI,
24
};
67
};
25
68
26
+#define TARGET_EXTRA_MAGIC 0x45585401
69
struct SBSAMachineState {
27
+
70
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
28
+struct target_extra_context {
71
[SBSA_SMMU] = { 0x60050000, 0x00020000 },
29
+ struct target_aarch64_ctx head;
72
/* Space here reserved for more SMMUs */
30
+ uint64_t datap; /* 16-byte aligned pointer to extra space cast to __u64 */
73
[SBSA_AHCI] = { 0x60100000, 0x00010000 },
31
+ uint32_t size; /* size in bytes of the extra space */
74
- [SBSA_EHCI] = { 0x60110000, 0x00010000 },
32
+ uint32_t reserved[3];
75
+ [SBSA_XHCI] = { 0x60110000, 0x00010000 },
33
+};
76
/* Space here reserved for other devices */
34
+
77
[SBSA_PCIE_PIO] = { 0x7fff0000, 0x00010000 },
35
struct target_rt_sigframe {
78
/* 32-bit address PCIE MMIO space */
36
struct target_siginfo info;
79
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
37
struct target_ucontext uc;
80
[SBSA_SECURE_UART] = 8,
38
@@ -XXX,XX +XXX,XX @@ static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
81
[SBSA_SECURE_UART_MM] = 9,
82
[SBSA_AHCI] = 10,
83
- [SBSA_EHCI] = 11,
84
+ [SBSA_XHCI] = 11,
85
[SBSA_SMMU] = 12, /* ... to 15 */
86
[SBSA_GWDT_WS0] = 16,
87
};
88
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
89
* fw compatibility.
90
*/
91
qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
92
- qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 2);
93
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 3);
94
95
if (ms->numa_state->have_numa_distance) {
96
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
97
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms)
39
}
98
}
40
}
99
}
41
100
42
+static void target_setup_extra_record(struct target_extra_context *extra,
101
-static void create_ehci(const SBSAMachineState *sms)
43
+ uint64_t datap, uint32_t extra_size)
102
+static void create_xhci(const SBSAMachineState *sms)
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
{
103
{
53
__put_user(0, &end->magic);
104
- hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
54
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
105
- int irq = sbsa_ref_irqmap[SBSA_EHCI];
55
static int target_restore_sigframe(CPUARMState *env,
106
+ hwaddr base = sbsa_ref_memmap[SBSA_XHCI].base;
56
struct target_rt_sigframe *sf)
107
+ int irq = sbsa_ref_irqmap[SBSA_XHCI];
57
{
108
+ DeviceState *dev = qdev_new(TYPE_XHCI_SYSBUS);
58
- struct target_aarch64_ctx *ctx;
109
59
+ struct target_aarch64_ctx *ctx, *extra = NULL;
110
- sysbus_create_simple("platform-ehci-usb", base,
60
struct target_fpsimd_context *fpsimd = NULL;
111
- qdev_get_gpio_in(sms->gic, irq));
61
+ uint64_t extra_datap = 0;
112
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
62
+ bool used_extra = false;
113
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
63
+ bool err = false;
114
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
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
}
115
}
137
116
138
static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
117
static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
139
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
118
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
140
CPUARMState *env)
119
141
{
120
create_ahci(sms);
142
int size = offsetof(struct target_rt_sigframe, uc.tuc_mcontext.__reserved);
121
143
- int fpsimd_ofs, end1_ofs, fr_ofs;
122
- create_ehci(sms);
144
+ int fpsimd_ofs, end1_ofs, fr_ofs, end2_ofs = 0;
123
+ create_xhci(sms);
145
+ int extra_ofs = 0, extra_base = 0, extra_size = 0;
124
146
struct target_rt_sigframe *frame;
125
create_pcie(sms);
147
struct target_rt_frame_record *fr;
126
148
abi_ulong frame_addr, return_addr;
127
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
149
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
128
index XXXXXXX..XXXXXXX 100644
150
129
--- a/hw/arm/Kconfig
151
target_setup_general_frame(frame, env, set);
130
+++ b/hw/arm/Kconfig
152
target_setup_fpsimd_record((void *)frame + fpsimd_ofs, env);
131
@@ -XXX,XX +XXX,XX @@ config SBSA_REF
153
+ if (extra_ofs) {
132
select PL011 # UART
154
+ target_setup_extra_record((void *)frame + extra_ofs,
133
select PL031 # RTC
155
+ frame_addr + extra_base, extra_size);
134
select PL061 # GPIO
156
+ }
135
- select USB_EHCI_SYSBUS
157
target_setup_end_record((void *)frame + end1_ofs);
136
+ select USB_XHCI_SYSBUS
158
+ if (end2_ofs) {
137
select WDT_SBSA
159
+ target_setup_end_record((void *)frame + end2_ofs);
138
select BOCHS_DISPLAY
160
+ }
139
161
162
/* Set up the stack frame for unwinding. */
163
fr = (void *)frame + fr_ofs;
164
--
140
--
165
2.16.2
141
2.34.1
166
167
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Some assemblers will complain about attempts to access
2
id_aa64zfr0_el1 and id_aa64smfr0_el1 by name if the test
3
binary isn't built for the right processor type:
2
4
3
After spending months studying all the different SD Specifications
5
/tmp/ccASXpLo.s:782: Error: selected processor does not support system register name 'id_aa64zfr0_el1'
4
from the SD Association, voluntarily add myself as maintainer
6
/tmp/ccASXpLo.s:829: Error: selected processor does not support system register name 'id_aa64smfr0_el1'
5
for the SD code.
6
7
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
However, these registers are in the ID space and are guaranteed to
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
read-as-zero on older CPUs, so the access is both safe and sensible.
9
Message-id: 20180309153654.13518-9-f4bug@amsat.org
10
Switch to using the S syntax, as we already do for ID_AA64ISAR2_EL1
11
and ID_AA64MMFR2_EL1. This allows us to drop the HAS_ARMV9_SME check
12
and the makefile machinery to adjust the CFLAGS for this test, so we
13
don't rely on having a sufficiently new compiler to be able to check
14
these registers.
15
16
This means we're actually testing the SME ID register: no released
17
GCC yet recognizes -march=armv9-a+sme, so that was always skipped.
18
It also avoids a future problem if we try to switch the "do we have
19
SME support in the toolchain" check from "in the compiler" to "in the
20
assembler" (at which point we would otherwise run into the above
21
errors).
22
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
24
---
12
MAINTAINERS | 8 ++++++++
25
tests/tcg/aarch64/sysregs.c | 11 +++++++----
13
1 file changed, 8 insertions(+)
26
tests/tcg/aarch64/Makefile.target | 7 +------
27
2 files changed, 8 insertions(+), 10 deletions(-)
14
28
15
diff --git a/MAINTAINERS b/MAINTAINERS
29
diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c
16
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
31
--- a/tests/tcg/aarch64/sysregs.c
18
+++ b/MAINTAINERS
32
+++ b/tests/tcg/aarch64/sysregs.c
19
@@ -XXX,XX +XXX,XX @@ M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
33
@@ -XXX,XX +XXX,XX @@
20
S: Maintained
34
/*
21
F: hw/ssi/xilinx_*
35
* Older assemblers don't recognize newer system register names,
22
36
* but we can still access them by the Sn_n_Cn_Cn_n syntax.
23
+SD (Secure Card)
37
+ * This also means we don't need to specifically request that the
24
+M: Philippe Mathieu-Daudé <f4bug@amsat.org>
38
+ * assembler enables whatever architectural features the ID registers
25
+S: Odd Fixes
39
+ * syntax might be gated behind.
26
+F: include/hw/sd/sd*
40
*/
27
+F: hw/sd/core.c
41
#define SYS_ID_AA64ISAR2_EL1 S3_0_C0_C6_2
28
+F: hw/sd/sd*
42
#define SYS_ID_AA64MMFR2_EL1 S3_0_C0_C7_2
29
+F: tests/sd*
43
+#define SYS_ID_AA64ZFR0_EL1 S3_0_C0_C4_4
30
+
44
+#define SYS_ID_AA64SMFR0_EL1 S3_0_C0_C4_5
31
USB
45
32
M: Gerd Hoffmann <kraxel@redhat.com>
46
int failed_bit_count;
33
S: Maintained
47
48
@@ -XXX,XX +XXX,XX @@ int main(void)
49
/* all hidden, DebugVer fixed to 0x6 (ARMv8 debug architecture) */
50
get_cpu_reg_check_mask(id_aa64dfr0_el1, _m(0000,0000,0000,0006));
51
get_cpu_reg_check_zero(id_aa64dfr1_el1);
52
- get_cpu_reg_check_mask(id_aa64zfr0_el1, _m(0ff0,ff0f,00ff,00ff));
53
-#ifdef HAS_ARMV9_SME
54
- get_cpu_reg_check_mask(id_aa64smfr0_el1, _m(80f1,00fd,0000,0000));
55
-#endif
56
+ get_cpu_reg_check_mask(SYS_ID_AA64ZFR0_EL1, _m(0ff0,ff0f,00ff,00ff));
57
+ get_cpu_reg_check_mask(SYS_ID_AA64SMFR0_EL1, _m(80f1,00fd,0000,0000));
58
59
get_cpu_reg_check_zero(id_aa64afr0_el1);
60
get_cpu_reg_check_zero(id_aa64afr1_el1);
61
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
62
index XXXXXXX..XXXXXXX 100644
63
--- a/tests/tcg/aarch64/Makefile.target
64
+++ b/tests/tcg/aarch64/Makefile.target
65
@@ -XXX,XX +XXX,XX @@ AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7
66
mte-%: CFLAGS += -march=armv8.5-a+memtag
67
endif
68
69
-ifneq ($(CROSS_CC_HAS_SVE),)
70
# System Registers Tests
71
AARCH64_TESTS += sysregs
72
-ifneq ($(CROSS_CC_HAS_ARMV9_SME),)
73
-sysregs: CFLAGS+=-march=armv9-a+sme -DHAS_ARMV9_SME
74
-else
75
-sysregs: CFLAGS+=-march=armv8.1-a+sve
76
-endif
77
78
+ifneq ($(CROSS_CC_HAS_SVE),)
79
# SVE ioctl test
80
AARCH64_TESTS += sve-ioctls
81
sve-ioctls: CFLAGS+=-march=armv8.1-a+sve
34
--
82
--
35
2.16.2
83
2.34.1
36
37
diff view generated by jsdifflib
1
Move the definition of the 'host' cpu type into cpu.c, where all the
1
From: Richard Henderson <richard.henderson@linaro.org>
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
2
3
Allow the line length to extend to 548 columns. While annoyingly wide,
4
it's still less confusing than the continuations we print. Also, the
5
default VL used by Linux (and max for A64FX) uses only 140 columns.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230622151201.1578522-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
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
---
11
---
14
target/arm/cpu.c | 24 ++++++++++++++++++++++++
12
target/arm/cpu.c | 36 ++++++++++++++----------------------
15
target/arm/kvm.c | 19 -------------------
13
1 file changed, 14 insertions(+), 22 deletions(-)
16
2 files changed, 24 insertions(+), 19 deletions(-)
17
14
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
17
--- a/target/arm/cpu.c
21
+++ b/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
19
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
23
#endif
20
ARMCPU *cpu = ARM_CPU(cs);
24
}
21
CPUARMState *env = &cpu->env;
25
22
uint32_t psr = pstate_read(env);
26
+#ifdef CONFIG_KVM
23
- int i;
27
+static void arm_host_initfn(Object *obj)
24
+ int i, j;
28
+{
25
int el = arm_current_el(env);
29
+ ARMCPU *cpu = ARM_CPU(obj);
26
const char *ns_status;
30
+
27
bool sve;
31
+ kvm_arm_set_cpu_features_from_host(cpu);
28
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
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
}
29
}
53
+
30
54
+#ifdef CONFIG_KVM
31
if (sve) {
55
+ type_register_static(&host_arm_cpu_type_info);
32
- int j, zcr_len = sve_vqm1_for_el(env, el);
56
+#endif
33
+ int zcr_len = sve_vqm1_for_el(env, el);
57
}
34
58
35
for (i = 0; i <= FFR_PRED_NUM; i++) {
59
type_init(arm_cpu_register_types)
36
bool eol;
60
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
61
index XXXXXXX..XXXXXXX 100644
38
}
62
--- a/target/arm/kvm.c
39
}
63
+++ b/target/arm/kvm.c
40
64
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
41
- for (i = 0; i < 32; i++) {
65
env->features = arm_host_cpu_features.features;
42
- if (zcr_len == 0) {
66
}
43
+ if (zcr_len == 0) {
67
44
+ /*
68
-static void kvm_arm_host_cpu_initfn(Object *obj)
45
+ * With vl=16, there are only 37 columns per register,
69
-{
46
+ * so output two registers per line.
70
- ARMCPU *cpu = ARM_CPU(obj);
47
+ */
71
-
48
+ for (i = 0; i < 32; i++) {
72
- kvm_arm_set_cpu_features_from_host(cpu);
49
qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
73
-}
50
i, env->vfp.zregs[i].d[1],
74
-
51
env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
75
-static const TypeInfo host_arm_cpu_type_info = {
52
- } else if (zcr_len == 1) {
76
- .name = TYPE_ARM_HOST_CPU,
53
- qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
77
-#ifdef TARGET_AARCH64
54
- ":%016" PRIx64 ":%016" PRIx64 "\n",
78
- .parent = TYPE_AARCH64_CPU,
55
- i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
79
-#else
56
- env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
80
- .parent = TYPE_ARM_CPU,
57
- } else {
81
-#endif
58
+ }
82
- .instance_init = kvm_arm_host_cpu_initfn,
59
+ } else {
83
-};
60
+ for (i = 0; i < 32; i++) {
84
-
61
+ qemu_fprintf(f, "Z%02d=", i);
85
int kvm_arch_init(MachineState *ms, KVMState *s)
62
for (j = zcr_len; j >= 0; j--) {
86
{
63
- bool odd = (zcr_len - j) % 2 != 0;
87
/* For ARM interrupt delivery is always asynchronous,
64
- if (j == zcr_len) {
88
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
65
- qemu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
89
66
- } else if (!odd) {
90
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
67
- if (j > 0) {
91
68
- qemu_fprintf(f, " [%x-%x]=", j, j - 1);
92
- type_register_static(&host_arm_cpu_type_info);
69
- } else {
93
-
70
- qemu_fprintf(f, " [%x]=", j);
94
return 0;
71
- }
95
}
72
- }
96
73
qemu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%s",
74
env->vfp.zregs[i].d[j * 2 + 1],
75
- env->vfp.zregs[i].d[j * 2],
76
- odd || j == 0 ? "\n" : ":");
77
+ env->vfp.zregs[i].d[j * 2 + 0],
78
+ j ? ":" : "\n");
79
}
80
}
81
}
97
--
82
--
98
2.16.2
83
2.34.1
99
100
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
Always print each matrix row whole, one per line, so that we
4
we can either store the data within the "standard" allocation, or we
4
get the entire matrix in the proper shape.
5
may beedn to allocate additional space with an EXTRA record.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180303143823.27055-6-richard.henderson@linaro.org
7
Message-id: 20230622151201.1578522-3-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
linux-user/signal.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++-----
11
target/arm/cpu.c | 18 ++++++++++++++++++
13
1 file changed, 192 insertions(+), 18 deletions(-)
12
1 file changed, 18 insertions(+)
14
13
15
diff --git a/linux-user/signal.c b/linux-user/signal.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/signal.c
16
--- a/target/arm/cpu.c
18
+++ b/linux-user/signal.c
17
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ struct target_extra_context {
18
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
20
uint32_t reserved[3];
19
i, q[1], q[0], (i & 1 ? "\n" : " "));
21
};
20
}
22
21
}
23
+#define TARGET_SVE_MAGIC 0x53564501
24
+
22
+
25
+struct target_sve_context {
23
+ if (cpu_isar_feature(aa64_sme, cpu) &&
26
+ struct target_aarch64_ctx head;
24
+ FIELD_EX64(env->svcr, SVCR, ZA) &&
27
+ uint16_t vl;
25
+ sme_exception_el(env, el) == 0) {
28
+ uint16_t reserved[3];
26
+ int zcr_len = sve_vqm1_for_el_sm(env, el, true);
29
+ /* The actual SVE data immediately follows. It is layed out
27
+ int svl = (zcr_len + 1) * 16;
30
+ * according to TARGET_SVE_SIG_{Z,P}REG_OFFSET, based off of
28
+ int svl_lg10 = svl < 100 ? 2 : 3;
31
+ * the original struct pointer.
32
+ */
33
+};
34
+
29
+
35
+#define TARGET_SVE_VQ_BYTES 16
30
+ for (i = 0; i < svl; i++) {
36
+
31
+ qemu_fprintf(f, "ZA[%0*d]=", svl_lg10, i);
37
+#define TARGET_SVE_SIG_ZREG_SIZE(VQ) ((VQ) * TARGET_SVE_VQ_BYTES)
32
+ for (j = zcr_len; j >= 0; --j) {
38
+#define TARGET_SVE_SIG_PREG_SIZE(VQ) ((VQ) * (TARGET_SVE_VQ_BYTES / 8))
33
+ qemu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%c",
39
+
34
+ env->zarray[i].d[2 * j + 1],
40
+#define TARGET_SVE_SIG_REGS_OFFSET \
35
+ env->zarray[i].d[2 * j],
41
+ QEMU_ALIGN_UP(sizeof(struct target_sve_context), TARGET_SVE_VQ_BYTES)
36
+ j ? ':' : '\n');
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
+ }
76
+ }
77
+ for (i = 0; i <= 16; ++i) {
78
+ uint16_t *p = (void *)sve + TARGET_SVE_SIG_PREG_OFFSET(vq, i);
79
+ for (j = 0; j < vq; ++j) {
80
+ uint64_t r = env->vfp.pregs[i].p[j >> 2];
81
+ __put_user_e(r >> ((j & 3) * 16), p + j, le);
82
+ }
83
+ }
84
+}
85
+
86
static void target_restore_general_frame(CPUARMState *env,
87
struct target_rt_sigframe *sf)
88
{
89
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
90
}
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
+ }
37
+ }
118
+ }
38
+ }
119
+ }
39
+ }
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
}
40
}
167
41
168
-static abi_ulong get_sigframe(struct target_sigaction *ka, CPUARMState *env)
42
#else
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
--
43
--
306
2.16.2
44
2.34.1
307
308
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The following interfaces are partially or fully emulated:
3
For the outer product set of insns, which take an entire matrix
4
tile as output, the argument is not a combined tile+column.
5
Therefore using get_tile_rowcol was incorrect, as we extracted
6
the tile number from itself.
4
7
5
* up to 2 Cortex A9 cores (SMP works with PSCI)
8
The test case relies only on assembler support for SME, since
6
* A7 MPCORE (identical to A15 MPCORE)
9
no release of GCC recognizes -march=armv9-a+sme yet.
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
10
27
Tested to boot and work with upstream Linux (4.13+) guest.
11
Cc: qemu-stable@nongnu.org
28
12
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1620
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20230622151201.1578522-5-richard.henderson@linaro.org
29
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
[PMM: dropped now-unneeded changes to sysregs CFLAGS]
31
[PMM: folded a couple of long lines]
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
---
18
---
34
hw/arm/Makefile.objs | 1 +
19
target/arm/tcg/translate-sme.c | 24 ++++++---
35
include/hw/arm/fsl-imx7.h | 222 +++++++++++++++
20
tests/tcg/aarch64/sme-outprod1.c | 83 +++++++++++++++++++++++++++++++
36
hw/arm/fsl-imx7.c | 582 ++++++++++++++++++++++++++++++++++++++++
21
tests/tcg/aarch64/Makefile.target | 7 ++-
37
default-configs/arm-softmmu.mak | 1 +
22
3 files changed, 107 insertions(+), 7 deletions(-)
38
4 files changed, 806 insertions(+)
23
create mode 100644 tests/tcg/aarch64/sme-outprod1.c
39
create mode 100644 include/hw/arm/fsl-imx7.h
40
create mode 100644 hw/arm/fsl-imx7.c
41
24
42
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
25
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
43
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/Makefile.objs
27
--- a/target/arm/tcg/translate-sme.c
45
+++ b/hw/arm/Makefile.objs
28
+++ b/target/arm/tcg/translate-sme.c
46
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2.o
29
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
47
obj-$(CONFIG_MPS2) += mps2-tz.o
30
return addr;
48
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
31
}
49
obj-$(CONFIG_IOTKIT) += iotkit.o
32
50
+obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o
33
+/*
51
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
34
+ * Resolve tile.size[0] to a host pointer.
35
+ * Used by e.g. outer product insns where we require the entire tile.
36
+ */
37
+static TCGv_ptr get_tile(DisasContext *s, int esz, int tile)
38
+{
39
+ TCGv_ptr addr = tcg_temp_new_ptr();
40
+ int offset;
41
+
42
+ offset = tile * sizeof(ARMVectorReg) + offsetof(CPUARMState, zarray);
43
+
44
+ tcg_gen_addi_ptr(addr, cpu_env, offset);
45
+ return addr;
46
+}
47
+
48
static bool trans_ZERO(DisasContext *s, arg_ZERO *a)
49
{
50
if (!dc_isar_feature(aa64_sme, s)) {
51
@@ -XXX,XX +XXX,XX @@ static bool do_adda(DisasContext *s, arg_adda *a, MemOp esz,
52
return true;
53
}
54
55
- /* Sum XZR+zad to find ZAd. */
56
- za = get_tile_rowcol(s, esz, 31, a->zad, false);
57
+ za = get_tile(s, esz, a->zad);
58
zn = vec_full_reg_ptr(s, a->zn);
59
pn = pred_full_reg_ptr(s, a->pn);
60
pm = pred_full_reg_ptr(s, a->pm);
61
@@ -XXX,XX +XXX,XX @@ static bool do_outprod(DisasContext *s, arg_op *a, MemOp esz,
62
return true;
63
}
64
65
- /* Sum XZR+zad to find ZAd. */
66
- za = get_tile_rowcol(s, esz, 31, a->zad, false);
67
+ za = get_tile(s, esz, a->zad);
68
zn = vec_full_reg_ptr(s, a->zn);
69
zm = vec_full_reg_ptr(s, a->zm);
70
pn = pred_full_reg_ptr(s, a->pn);
71
@@ -XXX,XX +XXX,XX @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
72
return true;
73
}
74
75
- /* Sum XZR+zad to find ZAd. */
76
- za = get_tile_rowcol(s, esz, 31, a->zad, false);
77
+ za = get_tile(s, esz, a->zad);
78
zn = vec_full_reg_ptr(s, a->zn);
79
zm = vec_full_reg_ptr(s, a->zm);
80
pn = pred_full_reg_ptr(s, a->pn);
81
diff --git a/tests/tcg/aarch64/sme-outprod1.c b/tests/tcg/aarch64/sme-outprod1.c
52
new file mode 100644
82
new file mode 100644
53
index XXXXXXX..XXXXXXX
83
index XXXXXXX..XXXXXXX
54
--- /dev/null
84
--- /dev/null
55
+++ b/include/hw/arm/fsl-imx7.h
85
+++ b/tests/tcg/aarch64/sme-outprod1.c
56
@@ -XXX,XX +XXX,XX @@
86
@@ -XXX,XX +XXX,XX @@
57
+/*
87
+/*
58
+ * Copyright (c) 2018, Impinj, Inc.
88
+ * SME outer product, 1 x 1.
59
+ *
89
+ * SPDX-License-Identifier: GPL-2.0-or-later
60
+ * i.MX7 SoC definitions
61
+ *
62
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
63
+ *
64
+ * This program is free software; you can redistribute it and/or modify
65
+ * it under the terms of the GNU General Public License as published by
66
+ * the Free Software Foundation; either version 2 of the License, or
67
+ * (at your option) any later version.
68
+ *
69
+ * This program is distributed in the hope that it will be useful,
70
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
71
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72
+ * GNU General Public License for more details.
73
+ */
90
+ */
74
+
91
+
75
+#ifndef FSL_IMX7_H
92
+#include <stdio.h>
76
+#define FSL_IMX7_H
77
+
93
+
78
+#include "hw/arm/arm.h"
94
+extern void foo(float *dst);
79
+#include "hw/cpu/a15mpcore.h"
80
+#include "hw/intc/imx_gpcv2.h"
81
+#include "hw/misc/imx7_ccm.h"
82
+#include "hw/misc/imx7_snvs.h"
83
+#include "hw/misc/imx7_gpr.h"
84
+#include "hw/misc/imx6_src.h"
85
+#include "hw/misc/imx2_wdt.h"
86
+#include "hw/gpio/imx_gpio.h"
87
+#include "hw/char/imx_serial.h"
88
+#include "hw/timer/imx_gpt.h"
89
+#include "hw/timer/imx_epit.h"
90
+#include "hw/i2c/imx_i2c.h"
91
+#include "hw/gpio/imx_gpio.h"
92
+#include "hw/sd/sdhci.h"
93
+#include "hw/ssi/imx_spi.h"
94
+#include "hw/net/imx_fec.h"
95
+#include "hw/pci-host/designware.h"
96
+#include "hw/usb/chipidea.h"
97
+#include "exec/memory.h"
98
+#include "cpu.h"
99
+
95
+
100
+#define TYPE_FSL_IMX7 "fsl,imx7"
96
+asm(
101
+#define FSL_IMX7(obj) OBJECT_CHECK(FslIMX7State, (obj), TYPE_FSL_IMX7)
97
+"    .arch_extension sme\n"
98
+"    .type foo, @function\n"
99
+"foo:\n"
100
+"    stp x29, x30, [sp, -80]!\n"
101
+"    mov x29, sp\n"
102
+"    stp d8, d9, [sp, 16]\n"
103
+"    stp d10, d11, [sp, 32]\n"
104
+"    stp d12, d13, [sp, 48]\n"
105
+"    stp d14, d15, [sp, 64]\n"
106
+"    smstart\n"
107
+"    ptrue p0.s, vl4\n"
108
+"    fmov z0.s, #1.0\n"
109
+/*
110
+ * An outer product of a vector of 1.0 by itself should be a matrix of 1.0.
111
+ * Note that we are using tile 1 here (za1.s) rather than tile 0.
112
+ */
113
+"    zero {za}\n"
114
+"    fmopa za1.s, p0/m, p0/m, z0.s, z0.s\n"
115
+/*
116
+ * Read the first 4x4 sub-matrix of elements from tile 1:
117
+ * Note that za1h should be interchangable here.
118
+ */
119
+"    mov w12, #0\n"
120
+"    mova z0.s, p0/m, za1v.s[w12, #0]\n"
121
+"    mova z1.s, p0/m, za1v.s[w12, #1]\n"
122
+"    mova z2.s, p0/m, za1v.s[w12, #2]\n"
123
+"    mova z3.s, p0/m, za1v.s[w12, #3]\n"
124
+/*
125
+ * And store them to the input pointer (dst in the C code):
126
+ */
127
+"    st1w {z0.s}, p0, [x0]\n"
128
+"    add x0, x0, #16\n"
129
+"    st1w {z1.s}, p0, [x0]\n"
130
+"    add x0, x0, #16\n"
131
+"    st1w {z2.s}, p0, [x0]\n"
132
+"    add x0, x0, #16\n"
133
+"    st1w {z3.s}, p0, [x0]\n"
134
+"    smstop\n"
135
+"    ldp d8, d9, [sp, 16]\n"
136
+"    ldp d10, d11, [sp, 32]\n"
137
+"    ldp d12, d13, [sp, 48]\n"
138
+"    ldp d14, d15, [sp, 64]\n"
139
+"    ldp x29, x30, [sp], 80\n"
140
+"    ret\n"
141
+"    .size foo, . - foo"
142
+);
102
+
143
+
103
+enum FslIMX7Configuration {
144
+int main()
104
+ FSL_IMX7_NUM_CPUS = 2,
145
+{
105
+ FSL_IMX7_NUM_UARTS = 7,
146
+ float dst[16];
106
+ FSL_IMX7_NUM_ETHS = 2,
147
+ int i, j;
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
+
148
+
119
+typedef struct FslIMX7State {
149
+ foo(dst);
120
+ /*< private >*/
121
+ DeviceState parent_obj;
122
+
150
+
123
+ /*< public >*/
151
+ for (i = 0; i < 16; i++) {
124
+ ARMCPU cpu[FSL_IMX7_NUM_CPUS];
152
+ if (dst[i] != 1.0f) {
125
+ A15MPPrivState a7mpcore;
153
+ break;
126
+ IMXGPTState gpt[FSL_IMX7_NUM_GPTS];
154
+ }
127
+ IMXGPIOState gpio[FSL_IMX7_NUM_GPIOS];
128
+ IMX7CCMState ccm;
129
+ IMX7AnalogState analog;
130
+ IMX7SNVSState snvs;
131
+ IMXGPCv2State gpcv2;
132
+ IMXSPIState spi[FSL_IMX7_NUM_ECSPIS];
133
+ IMXI2CState i2c[FSL_IMX7_NUM_I2CS];
134
+ IMXSerialState uart[FSL_IMX7_NUM_UARTS];
135
+ IMXFECState eth[FSL_IMX7_NUM_ETHS];
136
+ SDHCIState usdhc[FSL_IMX7_NUM_USDHCS];
137
+ IMX2WdtState wdt[FSL_IMX7_NUM_WDTS];
138
+ IMX7GPRState gpr;
139
+ ChipideaState usb[FSL_IMX7_NUM_USBS];
140
+ DesignwarePCIEHost pcie;
141
+} FslIMX7State;
142
+
143
+enum FslIMX7MemoryMap {
144
+ FSL_IMX7_MMDC_ADDR = 0x80000000,
145
+ FSL_IMX7_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL,
146
+
147
+ FSL_IMX7_GPIO1_ADDR = 0x30200000,
148
+ FSL_IMX7_GPIO2_ADDR = 0x30210000,
149
+ FSL_IMX7_GPIO3_ADDR = 0x30220000,
150
+ FSL_IMX7_GPIO4_ADDR = 0x30230000,
151
+ FSL_IMX7_GPIO5_ADDR = 0x30240000,
152
+ FSL_IMX7_GPIO6_ADDR = 0x30250000,
153
+ FSL_IMX7_GPIO7_ADDR = 0x30260000,
154
+
155
+ FSL_IMX7_IOMUXC_LPSR_GPR_ADDR = 0x30270000,
156
+
157
+ FSL_IMX7_WDOG1_ADDR = 0x30280000,
158
+ FSL_IMX7_WDOG2_ADDR = 0x30290000,
159
+ FSL_IMX7_WDOG3_ADDR = 0x302A0000,
160
+ FSL_IMX7_WDOG4_ADDR = 0x302B0000,
161
+
162
+ FSL_IMX7_IOMUXC_LPSR_ADDR = 0x302C0000,
163
+
164
+ FSL_IMX7_GPT1_ADDR = 0x302D0000,
165
+ FSL_IMX7_GPT2_ADDR = 0x302E0000,
166
+ FSL_IMX7_GPT3_ADDR = 0x302F0000,
167
+ FSL_IMX7_GPT4_ADDR = 0x30300000,
168
+
169
+ FSL_IMX7_IOMUXC_ADDR = 0x30330000,
170
+ FSL_IMX7_IOMUXC_GPR_ADDR = 0x30340000,
171
+ FSL_IMX7_IOMUXCn_SIZE = 0x1000,
172
+
173
+ FSL_IMX7_ANALOG_ADDR = 0x30360000,
174
+ FSL_IMX7_SNVS_ADDR = 0x30370000,
175
+ FSL_IMX7_CCM_ADDR = 0x30380000,
176
+
177
+ FSL_IMX7_SRC_ADDR = 0x30390000,
178
+ FSL_IMX7_SRC_SIZE = 0x1000,
179
+
180
+ FSL_IMX7_ADC1_ADDR = 0x30610000,
181
+ FSL_IMX7_ADC2_ADDR = 0x30620000,
182
+ FSL_IMX7_ADCn_SIZE = 0x1000,
183
+
184
+ FSL_IMX7_GPC_ADDR = 0x303A0000,
185
+
186
+ FSL_IMX7_I2C1_ADDR = 0x30A20000,
187
+ FSL_IMX7_I2C2_ADDR = 0x30A30000,
188
+ FSL_IMX7_I2C3_ADDR = 0x30A40000,
189
+ FSL_IMX7_I2C4_ADDR = 0x30A50000,
190
+
191
+ FSL_IMX7_ECSPI1_ADDR = 0x30820000,
192
+ FSL_IMX7_ECSPI2_ADDR = 0x30830000,
193
+ FSL_IMX7_ECSPI3_ADDR = 0x30840000,
194
+ FSL_IMX7_ECSPI4_ADDR = 0x30630000,
195
+
196
+ FSL_IMX7_LCDIF_ADDR = 0x30730000,
197
+ FSL_IMX7_LCDIF_SIZE = 0x1000,
198
+
199
+ FSL_IMX7_UART1_ADDR = 0x30860000,
200
+ /*
201
+ * Some versions of the reference manual claim that UART2 is @
202
+ * 0x30870000, but experiments with HW + DT files in upstream
203
+ * Linux kernel show that not to be true and that block is
204
+ * acutally located @ 0x30890000
205
+ */
206
+ FSL_IMX7_UART2_ADDR = 0x30890000,
207
+ FSL_IMX7_UART3_ADDR = 0x30880000,
208
+ FSL_IMX7_UART4_ADDR = 0x30A60000,
209
+ FSL_IMX7_UART5_ADDR = 0x30A70000,
210
+ FSL_IMX7_UART6_ADDR = 0x30A80000,
211
+ FSL_IMX7_UART7_ADDR = 0x30A90000,
212
+
213
+ FSL_IMX7_ENET1_ADDR = 0x30BE0000,
214
+ FSL_IMX7_ENET2_ADDR = 0x30BF0000,
215
+
216
+ FSL_IMX7_USB1_ADDR = 0x30B10000,
217
+ FSL_IMX7_USBMISC1_ADDR = 0x30B10200,
218
+ FSL_IMX7_USB2_ADDR = 0x30B20000,
219
+ FSL_IMX7_USBMISC2_ADDR = 0x30B20200,
220
+ FSL_IMX7_USB3_ADDR = 0x30B30000,
221
+ FSL_IMX7_USBMISC3_ADDR = 0x30B30200,
222
+ FSL_IMX7_USBMISCn_SIZE = 0x200,
223
+
224
+ FSL_IMX7_USDHC1_ADDR = 0x30B40000,
225
+ FSL_IMX7_USDHC2_ADDR = 0x30B50000,
226
+ FSL_IMX7_USDHC3_ADDR = 0x30B60000,
227
+
228
+ FSL_IMX7_SDMA_ADDR = 0x30BD0000,
229
+ FSL_IMX7_SDMA_SIZE = 0x1000,
230
+
231
+ FSL_IMX7_A7MPCORE_ADDR = 0x31000000,
232
+ FSL_IMX7_A7MPCORE_DAP_ADDR = 0x30000000,
233
+
234
+ FSL_IMX7_PCIE_REG_ADDR = 0x33800000,
235
+ FSL_IMX7_PCIE_REG_SIZE = 16 * 1024,
236
+
237
+ FSL_IMX7_GPR_ADDR = 0x30340000,
238
+};
239
+
240
+enum FslIMX7IRQs {
241
+ FSL_IMX7_USDHC1_IRQ = 22,
242
+ FSL_IMX7_USDHC2_IRQ = 23,
243
+ FSL_IMX7_USDHC3_IRQ = 24,
244
+
245
+ FSL_IMX7_UART1_IRQ = 26,
246
+ FSL_IMX7_UART2_IRQ = 27,
247
+ FSL_IMX7_UART3_IRQ = 28,
248
+ FSL_IMX7_UART4_IRQ = 29,
249
+ FSL_IMX7_UART5_IRQ = 30,
250
+ FSL_IMX7_UART6_IRQ = 16,
251
+
252
+ FSL_IMX7_ECSPI1_IRQ = 31,
253
+ FSL_IMX7_ECSPI2_IRQ = 32,
254
+ FSL_IMX7_ECSPI3_IRQ = 33,
255
+ FSL_IMX7_ECSPI4_IRQ = 34,
256
+
257
+ FSL_IMX7_I2C1_IRQ = 35,
258
+ FSL_IMX7_I2C2_IRQ = 36,
259
+ FSL_IMX7_I2C3_IRQ = 37,
260
+ FSL_IMX7_I2C4_IRQ = 38,
261
+
262
+ FSL_IMX7_USB1_IRQ = 43,
263
+ FSL_IMX7_USB2_IRQ = 42,
264
+ FSL_IMX7_USB3_IRQ = 40,
265
+
266
+ FSL_IMX7_PCI_INTA_IRQ = 122,
267
+ FSL_IMX7_PCI_INTB_IRQ = 123,
268
+ FSL_IMX7_PCI_INTC_IRQ = 124,
269
+ FSL_IMX7_PCI_INTD_IRQ = 125,
270
+
271
+ FSL_IMX7_UART7_IRQ = 126,
272
+
273
+#define FSL_IMX7_ENET_IRQ(i, n) ((n) + ((i) ? 100 : 118))
274
+
275
+ FSL_IMX7_MAX_IRQ = 128,
276
+};
277
+
278
+#endif /* FSL_IMX7_H */
279
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
280
new file mode 100644
281
index XXXXXXX..XXXXXXX
282
--- /dev/null
283
+++ b/hw/arm/fsl-imx7.c
284
@@ -XXX,XX +XXX,XX @@
285
+/*
286
+ * Copyright (c) 2018, Impinj, Inc.
287
+ *
288
+ * i.MX7 SoC definitions
289
+ *
290
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
291
+ *
292
+ * Based on hw/arm/fsl-imx6.c
293
+ *
294
+ * This program is free software; you can redistribute it and/or modify
295
+ * it under the terms of the GNU General Public License as published by
296
+ * the Free Software Foundation; either version 2 of the License, or
297
+ * (at your option) any later version.
298
+ *
299
+ * This program is distributed in the hope that it will be useful,
300
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
301
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
302
+ * GNU General Public License for more details.
303
+ */
304
+
305
+#include "qemu/osdep.h"
306
+#include "qapi/error.h"
307
+#include "qemu-common.h"
308
+#include "hw/arm/fsl-imx7.h"
309
+#include "hw/misc/unimp.h"
310
+#include "sysemu/sysemu.h"
311
+#include "qemu/error-report.h"
312
+
313
+#define NAME_SIZE 20
314
+
315
+static void fsl_imx7_init(Object *obj)
316
+{
317
+ BusState *sysbus = sysbus_get_default();
318
+ FslIMX7State *s = FSL_IMX7(obj);
319
+ char name[NAME_SIZE];
320
+ int i;
321
+
322
+ if (smp_cpus > FSL_IMX7_NUM_CPUS) {
323
+ error_report("%s: Only %d CPUs are supported (%d requested)",
324
+ TYPE_FSL_IMX7, FSL_IMX7_NUM_CPUS, smp_cpus);
325
+ exit(1);
326
+ }
155
+ }
327
+
156
+
328
+ for (i = 0; i < smp_cpus; i++) {
157
+ if (i == 16) {
329
+ object_initialize(&s->cpu[i], sizeof(s->cpu[i]),
158
+ return 0; /* success */
330
+ ARM_CPU_TYPE_NAME("cortex-a7"));
331
+ snprintf(name, NAME_SIZE, "cpu%d", i);
332
+ object_property_add_child(obj, name, OBJECT(&s->cpu[i]),
333
+ &error_fatal);
334
+ }
159
+ }
335
+
160
+
336
+ /*
161
+ /* failure */
337
+ * A7MPCORE
162
+ for (i = 0; i < 4; ++i) {
338
+ */
163
+ for (j = 0; j < 4; ++j) {
339
+ object_initialize(&s->a7mpcore, sizeof(s->a7mpcore), TYPE_A15MPCORE_PRIV);
164
+ printf("%f ", (double)dst[i * 4 + j]);
340
+ qdev_set_parent_bus(DEVICE(&s->a7mpcore), sysbus);
165
+ }
341
+ object_property_add_child(obj, "a7mpcore",
166
+ printf("\n");
342
+ OBJECT(&s->a7mpcore), &error_fatal);
167
+ }
168
+ return 1;
169
+}
170
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
171
index XXXXXXX..XXXXXXX 100644
172
--- a/tests/tcg/aarch64/Makefile.target
173
+++ b/tests/tcg/aarch64/Makefile.target
174
@@ -XXX,XX +XXX,XX @@ config-cc.mak: Makefile
175
     $(call cc-option,-march=armv8.5-a, CROSS_CC_HAS_ARMV8_5); \
176
     $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
177
     $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
178
-     $(call cc-option,-march=armv9-a+sme, CROSS_CC_HAS_ARMV9_SME)) 3> config-cc.mak
179
+     $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme, CROSS_AS_HAS_ARMV9_SME)) 3> config-cc.mak
180
-include config-cc.mak
181
182
ifneq ($(CROSS_CC_HAS_ARMV8_2),)
183
@@ -XXX,XX +XXX,XX @@ AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6 mte-7
184
mte-%: CFLAGS += -march=armv8.5-a+memtag
185
endif
186
187
+# SME Tests
188
+ifneq ($(CROSS_AS_HAS_ARMV9_SME),)
189
+AARCH64_TESTS += sme-outprod1
190
+endif
343
+
191
+
344
+ /*
192
# System Registers Tests
345
+ * GPIOs 1 to 7
193
AARCH64_TESTS += sysregs
346
+ */
347
+ for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
348
+ object_initialize(&s->gpio[i], sizeof(s->gpio[i]),
349
+ TYPE_IMX_GPIO);
350
+ qdev_set_parent_bus(DEVICE(&s->gpio[i]), sysbus);
351
+ snprintf(name, NAME_SIZE, "gpio%d", i);
352
+ object_property_add_child(obj, name,
353
+ OBJECT(&s->gpio[i]), &error_fatal);
354
+ }
355
+
356
+ /*
357
+ * GPT1, 2, 3, 4
358
+ */
359
+ for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
360
+ object_initialize(&s->gpt[i], sizeof(s->gpt[i]), TYPE_IMX7_GPT);
361
+ qdev_set_parent_bus(DEVICE(&s->gpt[i]), sysbus);
362
+ snprintf(name, NAME_SIZE, "gpt%d", i);
363
+ object_property_add_child(obj, name, OBJECT(&s->gpt[i]),
364
+ &error_fatal);
365
+ }
366
+
367
+ /*
368
+ * CCM
369
+ */
370
+ object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX7_CCM);
371
+ qdev_set_parent_bus(DEVICE(&s->ccm), sysbus);
372
+ object_property_add_child(obj, "ccm", OBJECT(&s->ccm), &error_fatal);
373
+
374
+ /*
375
+ * Analog
376
+ */
377
+ object_initialize(&s->analog, sizeof(s->analog), TYPE_IMX7_ANALOG);
378
+ qdev_set_parent_bus(DEVICE(&s->analog), sysbus);
379
+ object_property_add_child(obj, "analog", OBJECT(&s->analog), &error_fatal);
380
+
381
+ /*
382
+ * GPCv2
383
+ */
384
+ object_initialize(&s->gpcv2, sizeof(s->gpcv2), TYPE_IMX_GPCV2);
385
+ qdev_set_parent_bus(DEVICE(&s->gpcv2), sysbus);
386
+ object_property_add_child(obj, "gpcv2", OBJECT(&s->gpcv2), &error_fatal);
387
+
388
+ for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
389
+ object_initialize(&s->spi[i], sizeof(s->spi[i]), TYPE_IMX_SPI);
390
+ qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
391
+ snprintf(name, NAME_SIZE, "spi%d", i + 1);
392
+ object_property_add_child(obj, name, OBJECT(&s->spi[i]), NULL);
393
+ }
394
+
395
+
396
+ for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
397
+ object_initialize(&s->i2c[i], sizeof(s->i2c[i]), TYPE_IMX_I2C);
398
+ qdev_set_parent_bus(DEVICE(&s->i2c[i]), sysbus_get_default());
399
+ snprintf(name, NAME_SIZE, "i2c%d", i + 1);
400
+ object_property_add_child(obj, name, OBJECT(&s->i2c[i]), NULL);
401
+ }
402
+
403
+ /*
404
+ * UART
405
+ */
406
+ for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
407
+ object_initialize(&s->uart[i], sizeof(s->uart[i]), TYPE_IMX_SERIAL);
408
+ qdev_set_parent_bus(DEVICE(&s->uart[i]), sysbus);
409
+ snprintf(name, NAME_SIZE, "uart%d", i);
410
+ object_property_add_child(obj, name, OBJECT(&s->uart[i]),
411
+ &error_fatal);
412
+ }
413
+
414
+ /*
415
+ * Ethernet
416
+ */
417
+ for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
418
+ object_initialize(&s->eth[i], sizeof(s->eth[i]), TYPE_IMX_ENET);
419
+ qdev_set_parent_bus(DEVICE(&s->eth[i]), sysbus);
420
+ snprintf(name, NAME_SIZE, "eth%d", i);
421
+ object_property_add_child(obj, name, OBJECT(&s->eth[i]),
422
+ &error_fatal);
423
+ }
424
+
425
+ /*
426
+ * SDHCI
427
+ */
428
+ for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
429
+ object_initialize(&s->usdhc[i], sizeof(s->usdhc[i]),
430
+ TYPE_IMX_USDHC);
431
+ qdev_set_parent_bus(DEVICE(&s->usdhc[i]), sysbus);
432
+ snprintf(name, NAME_SIZE, "usdhc%d", i);
433
+ object_property_add_child(obj, name, OBJECT(&s->usdhc[i]),
434
+ &error_fatal);
435
+ }
436
+
437
+ /*
438
+ * SNVS
439
+ */
440
+ object_initialize(&s->snvs, sizeof(s->snvs), TYPE_IMX7_SNVS);
441
+ qdev_set_parent_bus(DEVICE(&s->snvs), sysbus);
442
+ object_property_add_child(obj, "snvs", OBJECT(&s->snvs), &error_fatal);
443
+
444
+ /*
445
+ * Watchdog
446
+ */
447
+ for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
448
+ object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_IMX2_WDT);
449
+ qdev_set_parent_bus(DEVICE(&s->wdt[i]), sysbus);
450
+ snprintf(name, NAME_SIZE, "wdt%d", i);
451
+ object_property_add_child(obj, name, OBJECT(&s->wdt[i]),
452
+ &error_fatal);
453
+ }
454
+
455
+ /*
456
+ * GPR
457
+ */
458
+ object_initialize(&s->gpr, sizeof(s->gpr), TYPE_IMX7_GPR);
459
+ qdev_set_parent_bus(DEVICE(&s->gpr), sysbus);
460
+ object_property_add_child(obj, "gpr", OBJECT(&s->gpr), &error_fatal);
461
+
462
+ object_initialize(&s->pcie, sizeof(s->pcie), TYPE_DESIGNWARE_PCIE_HOST);
463
+ qdev_set_parent_bus(DEVICE(&s->pcie), sysbus);
464
+ object_property_add_child(obj, "pcie", OBJECT(&s->pcie), &error_fatal);
465
+
466
+ for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
467
+ object_initialize(&s->usb[i],
468
+ sizeof(s->usb[i]), TYPE_CHIPIDEA);
469
+ qdev_set_parent_bus(DEVICE(&s->usb[i]), sysbus);
470
+ snprintf(name, NAME_SIZE, "usb%d", i);
471
+ object_property_add_child(obj, name,
472
+ OBJECT(&s->usb[i]), &error_fatal);
473
+ }
474
+}
475
+
476
+static void fsl_imx7_realize(DeviceState *dev, Error **errp)
477
+{
478
+ FslIMX7State *s = FSL_IMX7(dev);
479
+ Object *o;
480
+ int i;
481
+ qemu_irq irq;
482
+ char name[NAME_SIZE];
483
+
484
+ for (i = 0; i < smp_cpus; i++) {
485
+ o = OBJECT(&s->cpu[i]);
486
+
487
+ object_property_set_int(o, QEMU_PSCI_CONDUIT_SMC,
488
+ "psci-conduit", &error_abort);
489
+
490
+ /* On uniprocessor, the CBAR is set to 0 */
491
+ if (smp_cpus > 1) {
492
+ object_property_set_int(o, FSL_IMX7_A7MPCORE_ADDR,
493
+ "reset-cbar", &error_abort);
494
+ }
495
+
496
+ if (i) {
497
+ /* Secondary CPUs start in PSCI powered-down state */
498
+ object_property_set_bool(o, true,
499
+ "start-powered-off", &error_abort);
500
+ }
501
+
502
+ object_property_set_bool(o, true, "realized", &error_abort);
503
+ }
504
+
505
+ /*
506
+ * A7MPCORE
507
+ */
508
+ object_property_set_int(OBJECT(&s->a7mpcore), smp_cpus, "num-cpu",
509
+ &error_abort);
510
+ object_property_set_int(OBJECT(&s->a7mpcore),
511
+ FSL_IMX7_MAX_IRQ + GIC_INTERNAL,
512
+ "num-irq", &error_abort);
513
+
514
+ object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized",
515
+ &error_abort);
516
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX7_A7MPCORE_ADDR);
517
+
518
+ for (i = 0; i < smp_cpus; i++) {
519
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
520
+ DeviceState *d = DEVICE(qemu_get_cpu(i));
521
+
522
+ irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
523
+ sysbus_connect_irq(sbd, i, irq);
524
+ irq = qdev_get_gpio_in(d, ARM_CPU_FIQ);
525
+ sysbus_connect_irq(sbd, i + smp_cpus, irq);
526
+ }
527
+
528
+ /*
529
+ * A7MPCORE DAP
530
+ */
531
+ create_unimplemented_device("a7mpcore-dap", FSL_IMX7_A7MPCORE_DAP_ADDR,
532
+ 0x100000);
533
+
534
+ /*
535
+ * GPT1, 2, 3, 4
536
+ */
537
+ for (i = 0; i < FSL_IMX7_NUM_GPTS; i++) {
538
+ static const hwaddr FSL_IMX7_GPTn_ADDR[FSL_IMX7_NUM_GPTS] = {
539
+ FSL_IMX7_GPT1_ADDR,
540
+ FSL_IMX7_GPT2_ADDR,
541
+ FSL_IMX7_GPT3_ADDR,
542
+ FSL_IMX7_GPT4_ADDR,
543
+ };
544
+
545
+ s->gpt[i].ccm = IMX_CCM(&s->ccm);
546
+ object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized",
547
+ &error_abort);
548
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, FSL_IMX7_GPTn_ADDR[i]);
549
+ }
550
+
551
+ for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
552
+ static const hwaddr FSL_IMX7_GPIOn_ADDR[FSL_IMX7_NUM_GPIOS] = {
553
+ FSL_IMX7_GPIO1_ADDR,
554
+ FSL_IMX7_GPIO2_ADDR,
555
+ FSL_IMX7_GPIO3_ADDR,
556
+ FSL_IMX7_GPIO4_ADDR,
557
+ FSL_IMX7_GPIO5_ADDR,
558
+ FSL_IMX7_GPIO6_ADDR,
559
+ FSL_IMX7_GPIO7_ADDR,
560
+ };
561
+
562
+ object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized",
563
+ &error_abort);
564
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, FSL_IMX7_GPIOn_ADDR[i]);
565
+ }
566
+
567
+ /*
568
+ * IOMUXC and IOMUXC_LPSR
569
+ */
570
+ for (i = 0; i < FSL_IMX7_NUM_IOMUXCS; i++) {
571
+ static const hwaddr FSL_IMX7_IOMUXCn_ADDR[FSL_IMX7_NUM_IOMUXCS] = {
572
+ FSL_IMX7_IOMUXC_ADDR,
573
+ FSL_IMX7_IOMUXC_LPSR_ADDR,
574
+ };
575
+
576
+ snprintf(name, NAME_SIZE, "iomuxc%d", i);
577
+ create_unimplemented_device(name, FSL_IMX7_IOMUXCn_ADDR[i],
578
+ FSL_IMX7_IOMUXCn_SIZE);
579
+ }
580
+
581
+ /*
582
+ * CCM
583
+ */
584
+ object_property_set_bool(OBJECT(&s->ccm), true, "realized", &error_abort);
585
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX7_CCM_ADDR);
586
+
587
+ /*
588
+ * Analog
589
+ */
590
+ object_property_set_bool(OBJECT(&s->analog), true, "realized",
591
+ &error_abort);
592
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->analog), 0, FSL_IMX7_ANALOG_ADDR);
593
+
594
+ /*
595
+ * GPCv2
596
+ */
597
+ object_property_set_bool(OBJECT(&s->gpcv2), true,
598
+ "realized", &error_abort);
599
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX7_GPC_ADDR);
600
+
601
+ /* Initialize all ECSPI */
602
+ for (i = 0; i < FSL_IMX7_NUM_ECSPIS; i++) {
603
+ static const hwaddr FSL_IMX7_SPIn_ADDR[FSL_IMX7_NUM_ECSPIS] = {
604
+ FSL_IMX7_ECSPI1_ADDR,
605
+ FSL_IMX7_ECSPI2_ADDR,
606
+ FSL_IMX7_ECSPI3_ADDR,
607
+ FSL_IMX7_ECSPI4_ADDR,
608
+ };
609
+
610
+ static const hwaddr FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
611
+ FSL_IMX7_ECSPI1_IRQ,
612
+ FSL_IMX7_ECSPI2_IRQ,
613
+ FSL_IMX7_ECSPI3_IRQ,
614
+ FSL_IMX7_ECSPI4_IRQ,
615
+ };
616
+
617
+ /* Initialize the SPI */
618
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
619
+ &error_abort);
620
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
621
+ FSL_IMX7_SPIn_ADDR[i]);
622
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
623
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
624
+ FSL_IMX7_SPIn_IRQ[i]));
625
+ }
626
+
627
+ for (i = 0; i < FSL_IMX7_NUM_I2CS; i++) {
628
+ static const hwaddr FSL_IMX7_I2Cn_ADDR[FSL_IMX7_NUM_I2CS] = {
629
+ FSL_IMX7_I2C1_ADDR,
630
+ FSL_IMX7_I2C2_ADDR,
631
+ FSL_IMX7_I2C3_ADDR,
632
+ FSL_IMX7_I2C4_ADDR,
633
+ };
634
+
635
+ static const hwaddr FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
636
+ FSL_IMX7_I2C1_IRQ,
637
+ FSL_IMX7_I2C2_IRQ,
638
+ FSL_IMX7_I2C3_IRQ,
639
+ FSL_IMX7_I2C4_IRQ,
640
+ };
641
+
642
+ object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized",
643
+ &error_abort);
644
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX7_I2Cn_ADDR[i]);
645
+
646
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
647
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
648
+ FSL_IMX7_I2Cn_IRQ[i]));
649
+ }
650
+
651
+ /*
652
+ * UART
653
+ */
654
+ for (i = 0; i < FSL_IMX7_NUM_UARTS; i++) {
655
+ static const hwaddr FSL_IMX7_UARTn_ADDR[FSL_IMX7_NUM_UARTS] = {
656
+ FSL_IMX7_UART1_ADDR,
657
+ FSL_IMX7_UART2_ADDR,
658
+ FSL_IMX7_UART3_ADDR,
659
+ FSL_IMX7_UART4_ADDR,
660
+ FSL_IMX7_UART5_ADDR,
661
+ FSL_IMX7_UART6_ADDR,
662
+ FSL_IMX7_UART7_ADDR,
663
+ };
664
+
665
+ static const int FSL_IMX7_UARTn_IRQ[FSL_IMX7_NUM_UARTS] = {
666
+ FSL_IMX7_UART1_IRQ,
667
+ FSL_IMX7_UART2_IRQ,
668
+ FSL_IMX7_UART3_IRQ,
669
+ FSL_IMX7_UART4_IRQ,
670
+ FSL_IMX7_UART5_IRQ,
671
+ FSL_IMX7_UART6_IRQ,
672
+ FSL_IMX7_UART7_IRQ,
673
+ };
674
+
675
+
676
+ if (i < MAX_SERIAL_PORTS) {
677
+ qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hds[i]);
678
+ }
679
+
680
+ object_property_set_bool(OBJECT(&s->uart[i]), true, "realized",
681
+ &error_abort);
682
+
683
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, FSL_IMX7_UARTn_ADDR[i]);
684
+
685
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_UARTn_IRQ[i]);
686
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, irq);
687
+ }
688
+
689
+ /*
690
+ * Ethernet
691
+ */
692
+ for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
693
+ static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = {
694
+ FSL_IMX7_ENET1_ADDR,
695
+ FSL_IMX7_ENET2_ADDR,
696
+ };
697
+
698
+ object_property_set_uint(OBJECT(&s->eth[i]), FSL_IMX7_ETH_NUM_TX_RINGS,
699
+ "tx-ring-num", &error_abort);
700
+ qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
701
+ object_property_set_bool(OBJECT(&s->eth[i]), true, "realized",
702
+ &error_abort);
703
+
704
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0, FSL_IMX7_ENETn_ADDR[i]);
705
+
706
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 0));
707
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0, irq);
708
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_ENET_IRQ(i, 3));
709
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1, irq);
710
+ }
711
+
712
+ /*
713
+ * USDHC
714
+ */
715
+ for (i = 0; i < FSL_IMX7_NUM_USDHCS; i++) {
716
+ static const hwaddr FSL_IMX7_USDHCn_ADDR[FSL_IMX7_NUM_USDHCS] = {
717
+ FSL_IMX7_USDHC1_ADDR,
718
+ FSL_IMX7_USDHC2_ADDR,
719
+ FSL_IMX7_USDHC3_ADDR,
720
+ };
721
+
722
+ static const int FSL_IMX7_USDHCn_IRQ[FSL_IMX7_NUM_USDHCS] = {
723
+ FSL_IMX7_USDHC1_IRQ,
724
+ FSL_IMX7_USDHC2_IRQ,
725
+ FSL_IMX7_USDHC3_IRQ,
726
+ };
727
+
728
+ object_property_set_bool(OBJECT(&s->usdhc[i]), true, "realized",
729
+ &error_abort);
730
+
731
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
732
+ FSL_IMX7_USDHCn_ADDR[i]);
733
+
734
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USDHCn_IRQ[i]);
735
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, irq);
736
+ }
737
+
738
+ /*
739
+ * SNVS
740
+ */
741
+ object_property_set_bool(OBJECT(&s->snvs), true, "realized", &error_abort);
742
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX7_SNVS_ADDR);
743
+
744
+ /*
745
+ * SRC
746
+ */
747
+ create_unimplemented_device("sdma", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
748
+
749
+ /*
750
+ * Watchdog
751
+ */
752
+ for (i = 0; i < FSL_IMX7_NUM_WDTS; i++) {
753
+ static const hwaddr FSL_IMX7_WDOGn_ADDR[FSL_IMX7_NUM_WDTS] = {
754
+ FSL_IMX7_WDOG1_ADDR,
755
+ FSL_IMX7_WDOG2_ADDR,
756
+ FSL_IMX7_WDOG3_ADDR,
757
+ FSL_IMX7_WDOG4_ADDR,
758
+ };
759
+
760
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
761
+ &error_abort);
762
+
763
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, FSL_IMX7_WDOGn_ADDR[i]);
764
+ }
765
+
766
+ /*
767
+ * SDMA
768
+ */
769
+ create_unimplemented_device("sdma", FSL_IMX7_SDMA_ADDR, FSL_IMX7_SDMA_SIZE);
770
+
771
+
772
+ object_property_set_bool(OBJECT(&s->gpr), true, "realized",
773
+ &error_abort);
774
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX7_GPR_ADDR);
775
+
776
+ object_property_set_bool(OBJECT(&s->pcie), true,
777
+ "realized", &error_abort);
778
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
779
+
780
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ);
781
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
782
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ);
783
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
784
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ);
785
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
786
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_IRQ);
787
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
788
+
789
+
790
+ for (i = 0; i < FSL_IMX7_NUM_USBS; i++) {
791
+ static const hwaddr FSL_IMX7_USBMISCn_ADDR[FSL_IMX7_NUM_USBS] = {
792
+ FSL_IMX7_USBMISC1_ADDR,
793
+ FSL_IMX7_USBMISC2_ADDR,
794
+ FSL_IMX7_USBMISC3_ADDR,
795
+ };
796
+
797
+ static const hwaddr FSL_IMX7_USBn_ADDR[FSL_IMX7_NUM_USBS] = {
798
+ FSL_IMX7_USB1_ADDR,
799
+ FSL_IMX7_USB2_ADDR,
800
+ FSL_IMX7_USB3_ADDR,
801
+ };
802
+
803
+ static const hwaddr FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
804
+ FSL_IMX7_USB1_IRQ,
805
+ FSL_IMX7_USB2_IRQ,
806
+ FSL_IMX7_USB3_IRQ,
807
+ };
808
+
809
+ object_property_set_bool(OBJECT(&s->usb[i]), true, "realized",
810
+ &error_abort);
811
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0,
812
+ FSL_IMX7_USBn_ADDR[i]);
813
+
814
+ irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_USBn_IRQ[i]);
815
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0, irq);
816
+
817
+ snprintf(name, NAME_SIZE, "usbmisc%d", i);
818
+ create_unimplemented_device(name, FSL_IMX7_USBMISCn_ADDR[i],
819
+ FSL_IMX7_USBMISCn_SIZE);
820
+ }
821
+
822
+ /*
823
+ * ADCs
824
+ */
825
+ for (i = 0; i < FSL_IMX7_NUM_ADCS; i++) {
826
+ static const hwaddr FSL_IMX7_ADCn_ADDR[FSL_IMX7_NUM_ADCS] = {
827
+ FSL_IMX7_ADC1_ADDR,
828
+ FSL_IMX7_ADC2_ADDR,
829
+ };
830
+
831
+ snprintf(name, NAME_SIZE, "adc%d", i);
832
+ create_unimplemented_device(name, FSL_IMX7_ADCn_ADDR[i],
833
+ FSL_IMX7_ADCn_SIZE);
834
+ }
835
+
836
+ /*
837
+ * LCD
838
+ */
839
+ create_unimplemented_device("lcdif", FSL_IMX7_LCDIF_ADDR,
840
+ FSL_IMX7_LCDIF_SIZE);
841
+}
842
+
843
+static void fsl_imx7_class_init(ObjectClass *oc, void *data)
844
+{
845
+ DeviceClass *dc = DEVICE_CLASS(oc);
846
+
847
+ dc->realize = fsl_imx7_realize;
848
+
849
+ /* Reason: Uses serial_hds and nd_table in realize() directly */
850
+ dc->user_creatable = false;
851
+ dc->desc = "i.MX7 SOC";
852
+}
853
+
854
+static const TypeInfo fsl_imx7_type_info = {
855
+ .name = TYPE_FSL_IMX7,
856
+ .parent = TYPE_DEVICE,
857
+ .instance_size = sizeof(FslIMX7State),
858
+ .instance_init = fsl_imx7_init,
859
+ .class_init = fsl_imx7_class_init,
860
+};
861
+
862
+static void fsl_imx7_register_types(void)
863
+{
864
+ type_register_static(&fsl_imx7_type_info);
865
+}
866
+type_init(fsl_imx7_register_types)
867
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
868
index XXXXXXX..XXXXXXX 100644
869
--- a/default-configs/arm-softmmu.mak
870
+++ b/default-configs/arm-softmmu.mak
871
@@ -XXX,XX +XXX,XX @@ CONFIG_ALLWINNER_A10=y
872
CONFIG_FSL_IMX6=y
873
CONFIG_FSL_IMX31=y
874
CONFIG_FSL_IMX25=y
875
+CONFIG_FSL_IMX7=y
876
877
CONFIG_IMX_I2C=y
878
194
879
--
195
--
880
2.16.2
196
2.34.1
881
882
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Implement code needed to set up emulation of MCIMX7SABRE board from
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>
17
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
hw/arm/Makefile.objs | 2 +-
21
hw/arm/mcimx7d-sabre.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++
22
2 files changed, 91 insertions(+), 1 deletion(-)
23
create mode 100644 hw/arm/mcimx7d-sabre.c
24
25
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/Makefile.objs
28
+++ b/hw/arm/Makefile.objs
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2.o
30
obj-$(CONFIG_MPS2) += mps2-tz.o
31
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
32
obj-$(CONFIG_IOTKIT) += iotkit.o
33
-obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o
34
+obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
35
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--- /dev/null
39
+++ b/hw/arm/mcimx7d-sabre.c
40
@@ -XXX,XX +XXX,XX @@
41
+/*
42
+ * Copyright (c) 2018, Impinj, Inc.
43
+ *
44
+ * MCIMX7D_SABRE Board System emulation.
45
+ *
46
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
47
+ *
48
+ * This code is licensed under the GPL, version 2 or later.
49
+ * See the file `COPYING' in the top level directory.
50
+ *
51
+ * It (partially) emulates a mcimx7d_sabre board, with a Freescale
52
+ * i.MX7 SoC
53
+ */
54
+
55
+#include "qemu/osdep.h"
56
+#include "qapi/error.h"
57
+#include "qemu-common.h"
58
+#include "hw/arm/fsl-imx7.h"
59
+#include "hw/boards.h"
60
+#include "sysemu/sysemu.h"
61
+#include "sysemu/device_tree.h"
62
+#include "qemu/error-report.h"
63
+#include "sysemu/qtest.h"
64
+#include "net/net.h"
65
+
66
+typedef struct {
67
+ FslIMX7State soc;
68
+ MemoryRegion ram;
69
+} MCIMX7Sabre;
70
+
71
+static void mcimx7d_sabre_init(MachineState *machine)
72
+{
73
+ static struct arm_boot_info boot_info;
74
+ MCIMX7Sabre *s = g_new0(MCIMX7Sabre, 1);
75
+ Object *soc;
76
+ int i;
77
+
78
+ if (machine->ram_size > FSL_IMX7_MMDC_SIZE) {
79
+ error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
80
+ machine->ram_size, FSL_IMX7_MMDC_SIZE);
81
+ exit(1);
82
+ }
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
+}
123
+
124
+static void mcimx7d_sabre_machine_init(MachineClass *mc)
125
+{
126
+ mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex A7)";
127
+ mc->init = mcimx7d_sabre_init;
128
+ mc->max_cpus = FSL_IMX7_NUM_CPUS;
129
+}
130
+DEFINE_MACHINE("mcimx7d-sabre", mcimx7d_sabre_machine_init)
131
--
132
2.16.2
133
134
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
As an implementation choice, widening VL has zeroed the
4
previously inaccessible portion of the sve registers.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Acked-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180303143823.27055-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
linux-user/aarch64/target_syscall.h | 3 +++
13
target/arm/cpu.h | 1 +
14
linux-user/syscall.c | 27 ++++++++++++++++++++++++
15
target/arm/cpu64.c | 41 +++++++++++++++++++++++++++++++++++++
16
4 files changed, 72 insertions(+)
17
18
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/aarch64/target_syscall.h
21
+++ b/linux-user/aarch64/target_syscall.h
22
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
23
#define TARGET_MLOCKALL_MCL_CURRENT 1
24
#define TARGET_MLOCKALL_MCL_FUTURE 2
25
26
+#define TARGET_PR_SVE_SET_VL 50
27
+#define TARGET_PR_SVE_GET_VL 51
28
+
29
#endif /* AARCH64_TARGET_SYSCALL_H */
30
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.h
33
+++ b/target/arm/cpu.h
34
@@ -XXX,XX +XXX,XX @@ int arm_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
35
#ifdef TARGET_AARCH64
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
+
62
+ if (vq < old_vq) {
63
+ aarch64_sve_narrow_vq(env, vq);
64
+ }
65
+ env->vfp.zcr_el[1] = vq - 1;
66
+ ret = vq * 16;
67
+ }
68
+ break;
69
+ case TARGET_PR_SVE_GET_VL:
70
+ ret = -TARGET_EINVAL;
71
+ if (arm_feature(cpu_env, ARM_FEATURE_SVE)) {
72
+ CPUARMState *env = cpu_env;
73
+ ret = ((env->vfp.zcr_el[1] & 0xf) + 1) * 16;
74
+ }
75
+ break;
76
+#endif /* AARCH64 */
77
case PR_GET_SECCOMP:
78
case PR_SET_SECCOMP:
79
/* Disable seccomp to prevent the target disabling syscalls we
80
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/cpu64.c
83
+++ b/target/arm/cpu64.c
84
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_register_types(void)
85
}
86
87
type_init(aarch64_cpu_register_types)
88
+
89
+/* The manual says that when SVE is enabled and VQ is widened the
90
+ * implementation is allowed to zero the previously inaccessible
91
+ * portion of the registers. The corollary to that is that when
92
+ * SVE is enabled and VQ is narrowed we are also allowed to zero
93
+ * the now inaccessible portion of the registers.
94
+ *
95
+ * The intent of this is that no predicate bit beyond VQ is ever set.
96
+ * Which means that some operations on predicate registers themselves
97
+ * may operate on full uint64_t or even unrolled across the maximum
98
+ * uint64_t[4]. Performing 4 bits of host arithmetic unconditionally
99
+ * may well be cheaper than conditionals to restrict the operation
100
+ * to the relevant portion of a uint16_t[16].
101
+ *
102
+ * TODO: Need to call this for changes to the real system registers
103
+ * and EL state changes.
104
+ */
105
+void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
106
+{
107
+ int i, j;
108
+ uint64_t pmask;
109
+
110
+ assert(vq >= 1 && vq <= ARM_MAX_VQ);
111
+
112
+ /* Zap the high bits of the zregs. */
113
+ for (i = 0; i < 32; i++) {
114
+ memset(&env->vfp.zregs[i].d[2 * vq], 0, 16 * (ARM_MAX_VQ - vq));
115
+ }
116
+
117
+ /* Zap the high bits of the pregs and ffr. */
118
+ pmask = 0;
119
+ if (vq & 3) {
120
+ pmask = ~(-1ULL << (16 * (vq & 3)));
121
+ }
122
+ for (j = vq / 4; j < ARM_MAX_VQ / 4; j++) {
123
+ for (i = 0; i < 17; ++i) {
124
+ env->vfp.pregs[i].p[j] &= pmask;
125
+ }
126
+ pmask = 0;
127
+ }
128
+}
129
--
130
2.16.2
131
132
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Split out helpers from target_setup_frame and target_restore_sigframe
4
for dealing with general registers, fpsimd registers, and the end record.
5
6
When we add support for sve registers, the relative positions of
7
these will change.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180303143823.27055-3-richard.henderson@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
linux-user/signal.c | 120 ++++++++++++++++++++++++++++++----------------------
16
1 file changed, 69 insertions(+), 51 deletions(-)
17
18
diff --git a/linux-user/signal.c b/linux-user/signal.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/linux-user/signal.c
21
+++ b/linux-user/signal.c
22
@@ -XXX,XX +XXX,XX @@ struct target_rt_sigframe {
23
uint32_t tramp[2];
24
};
25
26
-static int target_setup_sigframe(struct target_rt_sigframe *sf,
27
- CPUARMState *env, target_sigset_t *set)
28
+static void target_setup_general_frame(struct target_rt_sigframe *sf,
29
+ CPUARMState *env, target_sigset_t *set)
30
{
31
int i;
32
- struct target_aux_context *aux =
33
- (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
34
35
- /* set up the stack frame for unwinding */
36
- __put_user(env->xregs[29], &sf->fp);
37
- __put_user(env->xregs[30], &sf->lr);
38
+ __put_user(0, &sf->uc.tuc_flags);
39
+ __put_user(0, &sf->uc.tuc_link);
40
+
41
+ __put_user(target_sigaltstack_used.ss_sp, &sf->uc.tuc_stack.ss_sp);
42
+ __put_user(sas_ss_flags(env->xregs[31]), &sf->uc.tuc_stack.ss_flags);
43
+ __put_user(target_sigaltstack_used.ss_size, &sf->uc.tuc_stack.ss_size);
44
45
for (i = 0; i < 31; i++) {
46
__put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
47
@@ -XXX,XX +XXX,XX @@ static int target_setup_sigframe(struct target_rt_sigframe *sf,
48
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
49
__put_user(set->sig[i], &sf->uc.tuc_sigmask.sig[i]);
50
}
51
+}
52
+
53
+static void target_setup_fpsimd_record(struct target_fpsimd_context *fpsimd,
54
+ CPUARMState *env)
55
+{
56
+ int i;
57
+
58
+ __put_user(TARGET_FPSIMD_MAGIC, &fpsimd->head.magic);
59
+ __put_user(sizeof(struct target_fpsimd_context), &fpsimd->head.size);
60
+ __put_user(vfp_get_fpsr(env), &fpsimd->fpsr);
61
+ __put_user(vfp_get_fpcr(env), &fpsimd->fpcr);
62
63
for (i = 0; i < 32; i++) {
64
uint64_t *q = aa64_vfp_qreg(env, i);
65
#ifdef TARGET_WORDS_BIGENDIAN
66
- __put_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
67
- __put_user(q[1], &aux->fpsimd.vregs[i * 2]);
68
+ __put_user(q[0], &fpsimd->vregs[i * 2 + 1]);
69
+ __put_user(q[1], &fpsimd->vregs[i * 2]);
70
#else
71
- __put_user(q[0], &aux->fpsimd.vregs[i * 2]);
72
- __put_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
73
+ __put_user(q[0], &fpsimd->vregs[i * 2]);
74
+ __put_user(q[1], &fpsimd->vregs[i * 2 + 1]);
75
#endif
76
}
77
- __put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
78
- __put_user(vfp_get_fpcr(env), &aux->fpsimd.fpcr);
79
- __put_user(TARGET_FPSIMD_MAGIC, &aux->fpsimd.head.magic);
80
- __put_user(sizeof(struct target_fpsimd_context),
81
- &aux->fpsimd.head.size);
82
-
83
- /* set the "end" magic */
84
- __put_user(0, &aux->end.magic);
85
- __put_user(0, &aux->end.size);
86
-
87
- return 0;
88
}
89
90
-static int target_restore_sigframe(CPUARMState *env,
91
- struct target_rt_sigframe *sf)
92
+static void target_setup_end_record(struct target_aarch64_ctx *end)
93
+{
94
+ __put_user(0, &end->magic);
95
+ __put_user(0, &end->size);
96
+}
97
+
98
+static void target_restore_general_frame(CPUARMState *env,
99
+ struct target_rt_sigframe *sf)
100
{
101
sigset_t set;
102
- int i;
103
- struct target_aux_context *aux =
104
- (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
105
- uint32_t magic, size, fpsr, fpcr;
106
uint64_t pstate;
107
+ int i;
108
109
target_to_host_sigset(&set, &sf->uc.tuc_sigmask);
110
set_sigmask(&set);
111
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
112
__get_user(env->pc, &sf->uc.tuc_mcontext.pc);
113
__get_user(pstate, &sf->uc.tuc_mcontext.pstate);
114
pstate_write(env, pstate);
115
+}
116
117
- __get_user(magic, &aux->fpsimd.head.magic);
118
- __get_user(size, &aux->fpsimd.head.size);
119
+static void target_restore_fpsimd_record(CPUARMState *env,
120
+ struct target_fpsimd_context *fpsimd)
121
+{
122
+ uint32_t fpsr, fpcr;
123
+ int i;
124
125
- if (magic != TARGET_FPSIMD_MAGIC
126
- || size != sizeof(struct target_fpsimd_context)) {
127
- return 1;
128
- }
129
+ __get_user(fpsr, &fpsimd->fpsr);
130
+ vfp_set_fpsr(env, fpsr);
131
+ __get_user(fpcr, &fpsimd->fpcr);
132
+ vfp_set_fpcr(env, fpcr);
133
134
for (i = 0; i < 32; i++) {
135
uint64_t *q = aa64_vfp_qreg(env, i);
136
#ifdef TARGET_WORDS_BIGENDIAN
137
- __get_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
138
- __get_user(q[1], &aux->fpsimd.vregs[i * 2]);
139
+ __get_user(q[0], &fpsimd->vregs[i * 2 + 1]);
140
+ __get_user(q[1], &fpsimd->vregs[i * 2]);
141
#else
142
- __get_user(q[0], &aux->fpsimd.vregs[i * 2]);
143
- __get_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
144
+ __get_user(q[0], &fpsimd->vregs[i * 2]);
145
+ __get_user(q[1], &fpsimd->vregs[i * 2 + 1]);
146
#endif
147
}
148
- __get_user(fpsr, &aux->fpsimd.fpsr);
149
- vfp_set_fpsr(env, fpsr);
150
- __get_user(fpcr, &aux->fpsimd.fpcr);
151
- vfp_set_fpcr(env, fpcr);
152
+}
153
154
+static int target_restore_sigframe(CPUARMState *env,
155
+ struct target_rt_sigframe *sf)
156
+{
157
+ struct target_aux_context *aux
158
+ = (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
159
+ uint32_t magic, size;
160
+
161
+ target_restore_general_frame(env, sf);
162
+
163
+ __get_user(magic, &aux->fpsimd.head.magic);
164
+ __get_user(size, &aux->fpsimd.head.size);
165
+ if (magic == TARGET_FPSIMD_MAGIC
166
+ && size == sizeof(struct target_fpsimd_context)) {
167
+ target_restore_fpsimd_record(env, &aux->fpsimd);
168
+ } else {
169
+ return 1;
170
+ }
171
return 0;
172
}
173
174
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
175
CPUARMState *env)
176
{
177
struct target_rt_sigframe *frame;
178
+ struct target_aux_context *aux;
179
abi_ulong frame_addr, return_addr;
180
181
frame_addr = get_sigframe(ka, env);
182
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
183
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
184
goto give_sigsegv;
185
}
186
+ aux = (struct target_aux_context *)frame->uc.tuc_mcontext.__reserved;
187
188
- __put_user(0, &frame->uc.tuc_flags);
189
- __put_user(0, &frame->uc.tuc_link);
190
+ target_setup_general_frame(frame, env, set);
191
+ target_setup_fpsimd_record(&aux->fpsimd, env);
192
+ target_setup_end_record(&aux->end);
193
194
- __put_user(target_sigaltstack_used.ss_sp,
195
- &frame->uc.tuc_stack.ss_sp);
196
- __put_user(sas_ss_flags(env->xregs[31]),
197
- &frame->uc.tuc_stack.ss_flags);
198
- __put_user(target_sigaltstack_used.ss_size,
199
- &frame->uc.tuc_stack.ss_size);
200
- target_setup_sigframe(frame, env, set);
201
if (ka->sa_flags & TARGET_SA_RESTORER) {
202
return_addr = ka->sa_restorer;
203
} else {
204
--
205
2.16.2
206
207
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This changes the qemu signal frame layout to be more like the kernel's,
4
in that the various records are dynamically allocated rather than fixed
5
in place by a structure.
6
7
For now, all of the allocation is out of uc.tuc_mcontext.__reserved,
8
so the allocation is actually trivial. That will change with SVE support.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20180303143823.27055-4-richard.henderson@linaro.org
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
linux-user/signal.c | 89 ++++++++++++++++++++++++++++++++++++-----------------
17
1 file changed, 61 insertions(+), 28 deletions(-)
18
19
diff --git a/linux-user/signal.c b/linux-user/signal.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/linux-user/signal.c
22
+++ b/linux-user/signal.c
23
@@ -XXX,XX +XXX,XX @@ struct target_fpsimd_context {
24
uint64_t vregs[32 * 2]; /* really uint128_t vregs[32] */
25
};
26
27
-/*
28
- * Auxiliary context saved in the sigcontext.__reserved array. Not exported to
29
- * user space as it will change with the addition of new context. User space
30
- * should check the magic/size information.
31
- */
32
-struct target_aux_context {
33
- struct target_fpsimd_context fpsimd;
34
- /* additional context to be added before "end" */
35
- struct target_aarch64_ctx end;
36
-};
37
-
38
struct target_rt_sigframe {
39
struct target_siginfo info;
40
struct target_ucontext uc;
41
+};
42
+
43
+struct target_rt_frame_record {
44
uint64_t fp;
45
uint64_t lr;
46
uint32_t tramp[2];
47
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
48
static int target_restore_sigframe(CPUARMState *env,
49
struct target_rt_sigframe *sf)
50
{
51
- struct target_aux_context *aux
52
- = (struct target_aux_context *)sf->uc.tuc_mcontext.__reserved;
53
- uint32_t magic, size;
54
+ struct target_aarch64_ctx *ctx;
55
+ struct target_fpsimd_context *fpsimd = NULL;
56
57
target_restore_general_frame(env, sf);
58
59
- __get_user(magic, &aux->fpsimd.head.magic);
60
- __get_user(size, &aux->fpsimd.head.size);
61
- if (magic == TARGET_FPSIMD_MAGIC
62
- && size == sizeof(struct target_fpsimd_context)) {
63
- target_restore_fpsimd_record(env, &aux->fpsimd);
64
- } else {
65
+ ctx = (struct target_aarch64_ctx *)sf->uc.tuc_mcontext.__reserved;
66
+ while (ctx) {
67
+ uint32_t magic, size;
68
+
69
+ __get_user(magic, &ctx->magic);
70
+ __get_user(size, &ctx->size);
71
+ switch (magic) {
72
+ case 0:
73
+ if (size != 0) {
74
+ return 1;
75
+ }
76
+ ctx = NULL;
77
+ continue;
78
+
79
+ case TARGET_FPSIMD_MAGIC:
80
+ if (fpsimd || size != sizeof(struct target_fpsimd_context)) {
81
+ return 1;
82
+ }
83
+ fpsimd = (struct target_fpsimd_context *)ctx;
84
+ break;
85
+
86
+ default:
87
+ /* Unknown record -- we certainly didn't generate it.
88
+ * Did we in fact get out of sync?
89
+ */
90
+ return 1;
91
+ }
92
+ ctx = (void *)ctx + size;
93
+ }
94
+
95
+ /* Require FPSIMD always. */
96
+ if (!fpsimd) {
97
return 1;
98
}
99
+ target_restore_fpsimd_record(env, fpsimd);
100
+
101
return 0;
102
}
103
104
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
105
target_siginfo_t *info, target_sigset_t *set,
106
CPUARMState *env)
107
{
108
+ int size = offsetof(struct target_rt_sigframe, uc.tuc_mcontext.__reserved);
109
+ int fpsimd_ofs, end1_ofs, fr_ofs;
110
struct target_rt_sigframe *frame;
111
- struct target_aux_context *aux;
112
+ struct target_rt_frame_record *fr;
113
abi_ulong frame_addr, return_addr;
114
115
+ fpsimd_ofs = size;
116
+ size += sizeof(struct target_fpsimd_context);
117
+ end1_ofs = size;
118
+ size += sizeof(struct target_aarch64_ctx);
119
+ fr_ofs = size;
120
+ size += sizeof(struct target_rt_frame_record);
121
+
122
frame_addr = get_sigframe(ka, env);
123
trace_user_setup_frame(env, frame_addr);
124
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
125
goto give_sigsegv;
126
}
127
- aux = (struct target_aux_context *)frame->uc.tuc_mcontext.__reserved;
128
129
target_setup_general_frame(frame, env, set);
130
- target_setup_fpsimd_record(&aux->fpsimd, env);
131
- target_setup_end_record(&aux->end);
132
+ target_setup_fpsimd_record((void *)frame + fpsimd_ofs, env);
133
+ target_setup_end_record((void *)frame + end1_ofs);
134
+
135
+ /* Set up the stack frame for unwinding. */
136
+ fr = (void *)frame + fr_ofs;
137
+ __put_user(env->xregs[29], &fr->fp);
138
+ __put_user(env->xregs[30], &fr->lr);
139
140
if (ka->sa_flags & TARGET_SA_RESTORER) {
141
return_addr = ka->sa_restorer;
142
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
143
* Since these are instructions they need to be put as little-endian
144
* regardless of target default or current CPU endianness.
145
*/
146
- __put_user_e(0xd2801168, &frame->tramp[0], le);
147
- __put_user_e(0xd4000001, &frame->tramp[1], le);
148
- return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
149
+ __put_user_e(0xd2801168, &fr->tramp[0], le);
150
+ __put_user_e(0xd4000001, &fr->tramp[1], le);
151
+ return_addr = frame_addr + fr_ofs
152
+ + offsetof(struct target_rt_frame_record, tramp);
153
}
154
env->xregs[0] = usig;
155
env->xregs[31] = frame_addr;
156
- env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp);
157
+ env->xregs[29] = frame_addr + fr_ofs;
158
env->pc = ka->_sa_handler;
159
env->xregs[30] = return_addr;
160
if (info) {
161
--
162
2.16.2
163
164
diff view generated by jsdifflib
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
1
Currently we query the host CPU features in the class init function
1
From: John Högberg <john.hogberg@ericsson.com>
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
2
8
Move the place where we store the information about the host CPU from
3
Unlike architectures with precise self-modifying code semantics
9
a class object to static variables in kvm.c, and then in the instance
4
(e.g. x86) ARM processors do not maintain coherency for instruction
10
init function call a new kvm_arm_set_cpu_features_from_host()
5
execution and memory, requiring an instruction synchronization
11
function which will query the host kernel if necessary and then
6
barrier on every core that will execute the new code, and on many
12
fill in the CPU instance fields.
7
models also the explicit use of cache management instructions.
13
8
14
This allows us to drop the special class struct and class init
9
While this is required to make JITs work on actual hardware, QEMU
15
function for TYPE_ARM_HOST_CPU entirely.
10
has gotten away with not handling this since it does not emulate
11
caches, and unconditionally invalidates code whenever the softmmu
12
or the user-mode page protection logic detects that code has been
13
modified.
16
14
17
We can't delay the probe until realize, because the ARM
15
Unfortunately the latter does not work in the face of dual-mapped
18
instance_post_init hook needs to look at the feature bits we
16
code (a common W^X workaround), where one page is executable and
19
set, so we need to do it in the initfn. This is safe because
17
the other is writable: user-mode has no way to connect one with the
20
the probing doesn't affect the actual VM state (it creates a
18
other as that is only known to the kernel and the emulated
21
separate scratch VM to do its testing), but the probe might fail.
19
application.
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
20
21
This commit works around the issue by telling software that
22
instruction cache invalidation is required by clearing the
23
CPR_EL0.DIC flag (regardless of whether the emulated processor
24
needs it), and then invalidating code in IC IVAU instructions.
25
26
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1034
27
28
Co-authored-by: Richard Henderson <richard.henderson@linaro.org>
29
Signed-off-by: John Högberg <john.hogberg@ericsson.com>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Message-id: 168778890374.24232.3402138851538068785-1@git.sr.ht
32
[PMM: removed unnecessary AArch64 feature check; moved
33
"clear CTR_EL1.DIC" code up a bit so it's not in the middle
34
of the vfp/neon related tests]
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
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
---
36
---
32
target/arm/cpu.h | 5 +++++
37
target/arm/cpu.c | 11 +++++++++++
33
target/arm/kvm_arm.h | 35 ++++++++++++++++++++++++-----------
38
target/arm/helper.c | 47 ++++++++++++++++++++++++++++++++++++++++++---
34
target/arm/cpu.c | 13 +++++++++++++
39
2 files changed, 55 insertions(+), 3 deletions(-)
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
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
41
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
122
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
123
--- a/target/arm/cpu.c
43
--- a/target/arm/cpu.c
124
+++ b/target/arm/cpu.c
44
+++ b/target/arm/cpu.c
125
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
45
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
126
int pagebits;
46
return;
127
Error *local_err = NULL;
47
}
128
48
129
+ /* If we needed to query the host kernel for the CPU features
49
+#ifdef CONFIG_USER_ONLY
130
+ * then it's possible that might have failed in the initfn, but
50
+ /*
131
+ * this is the first point where we can report it.
51
+ * User mode relies on IC IVAU instructions to catch modification of
52
+ * dual-mapped code.
53
+ *
54
+ * Clear CTR_EL0.DIC to ensure that software that honors these flags uses
55
+ * IC IVAU even if the emulated processor does not normally require it.
132
+ */
56
+ */
133
+ if (cpu->host_cpu_probe_failed) {
57
+ cpu->ctr = FIELD_DP64(cpu->ctr, CTR_EL0, DIC, 0);
134
+ if (!kvm_enabled()) {
58
+#endif
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
+
59
+
142
cpu_exec_realizefn(cs, &local_err);
60
if (arm_feature(env, ARM_FEATURE_AARCH64) &&
143
if (local_err != NULL) {
61
cpu->has_vfp != cpu->has_neon) {
144
error_propagate(errp, local_err);
62
/*
145
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
146
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/kvm.c
65
--- a/target/arm/helper.c
148
+++ b/target/arm/kvm.c
66
+++ b/target/arm/helper.c
149
@@ -XXX,XX +XXX,XX @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
67
@@ -XXX,XX +XXX,XX @@ static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
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
}
68
}
160
}
69
}
161
70
162
-static void kvm_arm_host_cpu_class_init(ObjectClass *oc, void *data)
71
+#ifdef CONFIG_USER_ONLY
163
+void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
72
+/*
164
{
73
+ * `IC IVAU` is handled to improve compatibility with JITs that dual-map their
165
- ARMHostCPUClass *ahcc = ARM_HOST_CPU_CLASS(oc);
74
+ * code to get around W^X restrictions, where one region is writable and the
166
+ CPUARMState *env = &cpu->env;
75
+ * other is executable.
167
76
+ *
168
- /* All we really need to set up for the 'host' CPU
77
+ * Since the executable region is never written to we cannot detect code
169
- * is the feature bits -- we rely on the fact that the
78
+ * changes when running in user mode, and rely on the emulated JIT telling us
170
- * various ID register values in ARMCPU are only used for
79
+ * that the code has changed by executing this instruction.
171
- * TCG CPUs.
80
+ */
172
- */
81
+static void ic_ivau_write(CPUARMState *env, const ARMCPRegInfo *ri,
173
- if (!kvm_arm_get_host_cpu_features(ahcc)) {
82
+ uint64_t value)
174
- fprintf(stderr, "Failed to retrieve host CPU features!\n");
83
+{
175
- abort();
84
+ uint64_t icache_line_mask, start_address, end_address;
176
+ if (!arm_host_cpu_features.dtb_compatible) {
85
+ const ARMCPU *cpu;
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
+
86
+
188
+ cpu->kvm_target = arm_host_cpu_features.target;
87
+ cpu = env_archcpu(env);
189
+ cpu->dtb_compatible = arm_host_cpu_features.dtb_compatible;
88
+
190
+ env->features = arm_host_cpu_features.features;
89
+ icache_line_mask = (4 << extract32(cpu->ctr, 0, 4)) - 1;
191
}
90
+ start_address = value & ~icache_line_mask;
192
91
+ end_address = value | icache_line_mask;
193
static void kvm_arm_host_cpu_initfn(Object *obj)
92
+
194
{
93
+ mmap_lock();
195
- ARMHostCPUClass *ahcc = ARM_HOST_CPU_GET_CLASS(obj);
94
+
196
ARMCPU *cpu = ARM_CPU(obj);
95
+ tb_invalidate_phys_range(start_address, end_address);
197
- CPUARMState *env = &cpu->env;
96
+
198
97
+ mmap_unlock();
199
- cpu->kvm_target = ahcc->target;
98
+}
200
- cpu->dtb_compatible = ahcc->dtb_compatible;
99
+#endif
201
- env->features = ahcc->features;
100
+
202
+ kvm_arm_set_cpu_features_from_host(cpu);
101
static const ARMCPRegInfo v8_cp_reginfo[] = {
203
}
102
/*
204
103
* Minimal set of EL0-visible registers. This will need to be expanded
205
static const TypeInfo host_arm_cpu_type_info = {
104
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
206
@@ -XXX,XX +XXX,XX @@ static const TypeInfo host_arm_cpu_type_info = {
105
{ .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
207
.parent = TYPE_ARM_CPU,
106
.opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
208
#endif
107
.access = PL1_R, .type = ARM_CP_CURRENTEL },
209
.instance_init = kvm_arm_host_cpu_initfn,
108
- /* Cache ops: all NOPs since we don't emulate caches */
210
- .class_init = kvm_arm_host_cpu_class_init,
109
+ /*
211
- .class_size = sizeof(ARMHostCPUClass),
110
+ * Instruction cache ops. All of these except `IC IVAU` NOP because we
212
};
111
+ * don't emulate caches.
213
112
+ */
214
int kvm_arch_init(MachineState *ms, KVMState *s)
113
{ .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
215
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
114
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
216
index XXXXXXX..XXXXXXX 100644
115
.access = PL1_W, .type = ARM_CP_NOP,
217
--- a/target/arm/kvm32.c
116
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
218
+++ b/target/arm/kvm32.c
117
.accessfn = access_tocu },
219
@@ -XXX,XX +XXX,XX @@ static inline void set_feature(uint64_t *features, int feature)
118
{ .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
220
*features |= 1ULL << feature;
119
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
221
}
120
- .access = PL0_W, .type = ARM_CP_NOP,
222
121
+ .access = PL0_W,
223
-bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
122
.fgt = FGT_ICIVAU,
224
+bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
123
- .accessfn = access_tocu },
225
{
124
+ .accessfn = access_tocu,
226
/* Identify the feature bits corresponding to the host CPU, and
125
+#ifdef CONFIG_USER_ONLY
227
* fill out the ARMHostCPUClass fields accordingly. To do this
126
+ .type = ARM_CP_NO_RAW,
228
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUClass *ahcc)
127
+ .writefn = ic_ivau_write
229
return false;
128
+#else
230
}
129
+ .type = ARM_CP_NOP
231
130
+#endif
232
- ahcc->target = init.target;
131
+ },
233
+ ahcf->target = init.target;
132
+ /* Cache ops: all NOPs since we don't emulate caches */
234
133
{ .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
235
/* This is not strictly blessed by the device tree binding docs yet,
134
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
236
* but in practice the kernel does not care about this string so
135
.access = PL1_W, .accessfn = aa64_cacheop_poc_access,
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
--
136
--
287
2.16.2
137
2.34.1
288
138
289
139
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Vikram Garhwal <vikram.garhwal@amd.com>
2
2
3
From the "Physical Layer Simplified Specification Version 3.01":
3
Following are done to fix the coverity issues:
4
1. Change read_data to fix the CID 1512899: Out-of-bounds access (OVERRUN)
5
2. Fix match_rx_tx_data to fix CID 1512900: Logically dead code (DEADCODE)
6
3. Replace rand() in generate_random_data() with g_rand_int()
4
7
5
A known data block ("Tuning block") can be used to tune sampling
8
Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
6
point for tuning required hosts. [...]
9
Message-id: 20230628202758.16398-1-vikram.garhwal@amd.com
7
This procedure gives the system optimal timing for each specific
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
14
[based on a patch from Alistair Francis <alistair.francis@xilinx.com>
15
from qemu/xilinx tag xilinx-v2015.2]
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
18
Message-id: 20180309153654.13518-5-f4bug@amsat.org
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
12
---
21
hw/sd/sd.c | 29 +++++++++++++++++++++++++++++
13
tests/qtest/xlnx-canfd-test.c | 33 +++++++++++----------------------
22
1 file changed, 29 insertions(+)
14
1 file changed, 11 insertions(+), 22 deletions(-)
23
15
24
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
16
diff --git a/tests/qtest/xlnx-canfd-test.c b/tests/qtest/xlnx-canfd-test.c
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/sd/sd.c
18
--- a/tests/qtest/xlnx-canfd-test.c
27
+++ b/hw/sd/sd.c
19
+++ b/tests/qtest/xlnx-canfd-test.c
28
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
20
@@ -XXX,XX +XXX,XX @@ static void generate_random_data(uint32_t *buf_tx, bool is_canfd_frame)
21
/* Generate random TX data for CANFD frame. */
22
if (is_canfd_frame) {
23
for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
24
- buf_tx[2 + i] = rand();
25
+ buf_tx[2 + i] = g_random_int();
29
}
26
}
30
break;
27
} else {
31
28
/* Generate random TX data for CAN frame. */
32
+ case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */
29
for (int i = 0; i < CAN_FRAME_SIZE - 2; i++) {
33
+ if (sd->state == sd_transfer_state) {
30
- buf_tx[2 + i] = rand();
34
+ sd->state = sd_sendingdata_state;
31
+ buf_tx[2 + i] = g_random_int();
35
+ sd->data_offset = 0;
32
}
36
+ return sd_r1;
37
+ }
38
+ break;
39
+
40
case 23: /* CMD23: SET_BLOCK_COUNT */
41
switch (sd->state) {
42
case sd_transfer_state:
43
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
44
}
33
}
45
}
34
}
46
35
47
+#define SD_TUNING_BLOCK_SIZE 64
36
-static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
48
+
37
+static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx,
49
+static const uint8_t sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
38
+ uint32_t frame_size)
50
+ /* See: Physical Layer Simplified Specification Version 3.01, Table 4-2 */
51
+ 0xff, 0x0f, 0xff, 0x00, 0x0f, 0xfc, 0xc3, 0xcc,
52
+ 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
53
+ 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
54
+ 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
55
+ 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
56
+ 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
57
+ 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
58
+ 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
59
+};
60
+
61
uint8_t sd_read_data(SDState *sd)
62
{
39
{
63
/* TODO: Append CRCs */
40
uint32_t int_status;
64
@@ -XXX,XX +XXX,XX @@ uint8_t sd_read_data(SDState *sd)
41
uint32_t fifo_status_reg_value;
42
/* At which RX FIFO the received data is stored. */
43
uint8_t store_ind = 0;
44
- bool is_canfd_frame = false;
45
46
/* Read the interrupt on CANFD rx. */
47
int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
48
@@ -XXX,XX +XXX,XX @@ static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
49
buf_rx[0] = qtest_readl(qts, can_base_addr + R_RX0_ID_OFFSET);
50
buf_rx[1] = qtest_readl(qts, can_base_addr + R_RX0_DLC_OFFSET);
51
52
- is_canfd_frame = (buf_rx[1] >> DLC_FD_BIT_SHIFT) & 1;
53
-
54
- if (is_canfd_frame) {
55
- for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
56
- buf_rx[i + 2] = qtest_readl(qts,
57
- can_base_addr + R_RX0_DATA1_OFFSET + 4 * i);
58
- }
59
- } else {
60
- buf_rx[2] = qtest_readl(qts, can_base_addr + R_RX0_DATA1_OFFSET);
61
- buf_rx[3] = qtest_readl(qts, can_base_addr + R_RX0_DATA2_OFFSET);
62
+ for (int i = 0; i < frame_size - 2; i++) {
63
+ buf_rx[i + 2] = qtest_readl(qts,
64
+ can_base_addr + R_RX0_DATA1_OFFSET + 4 * i);
65
}
66
67
/* Clear the RX interrupt. */
68
@@ -XXX,XX +XXX,XX @@ static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
69
g_assert_cmpint((buf_rx[size] & DLC_FD_BIT_MASK), ==,
70
(buf_tx[size] & DLC_FD_BIT_MASK));
71
} else {
72
- if (!is_canfd_frame && size == 4) {
73
- break;
74
- }
75
-
76
g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
65
}
77
}
66
break;
78
67
79
@@ -XXX,XX +XXX,XX @@ static void test_can_data_transfer(void)
68
+ case 19: /* CMD19: SEND_TUNING_BLOCK (SD) */
80
write_data(qts, CANFD0_BASE_ADDR, buf_tx, false);
69
+ if (sd->data_offset >= SD_TUNING_BLOCK_SIZE - 1) {
81
70
+ sd->state = sd_transfer_state;
82
send_data(qts, CANFD0_BASE_ADDR);
71
+ }
83
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
72
+ ret = sd_tuning_block_pattern[sd->data_offset++];
84
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CAN_FRAME_SIZE);
73
+ break;
85
match_rx_tx_data(buf_tx, buf_rx, false);
74
+
86
75
case 22:    /* ACMD22: SEND_NUM_WR_BLOCKS */
87
qtest_quit(qts);
76
ret = sd->data[sd->data_offset ++];
88
@@ -XXX,XX +XXX,XX @@ static void test_canfd_data_transfer(void)
77
89
write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
90
91
send_data(qts, CANFD0_BASE_ADDR);
92
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
93
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
94
match_rx_tx_data(buf_tx, buf_rx, true);
95
96
qtest_quit(qts);
97
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
98
write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
99
100
send_data(qts, CANFD0_BASE_ADDR);
101
- read_data(qts, CANFD0_BASE_ADDR, buf_rx);
102
+ read_data(qts, CANFD0_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
103
match_rx_tx_data(buf_tx, buf_rx, true);
104
105
generate_random_data(buf_tx, true);
106
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
107
write_data(qts, CANFD1_BASE_ADDR, buf_tx, true);
108
109
send_data(qts, CANFD1_BASE_ADDR);
110
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
111
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
112
match_rx_tx_data(buf_tx, buf_rx, true);
113
114
qtest_quit(qts);
78
--
115
--
79
2.16.2
116
2.34.1
80
81
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
This code is only relevant when TCG is present in the build. Building
4
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
4
with --disable-tcg --enable-xen on an x86 host we get:
5
Message-id: 20180309153654.13518-2-f4bug@amsat.org
5
6
$ ../configure --target-list=x86_64-softmmu,aarch64-softmmu --disable-tcg --enable-xen
7
$ make -j$(nproc)
8
...
9
libqemu-aarch64-softmmu.fa.p/target_arm_gdbstub.c.o: in function `m_sysreg_ptr':
10
../target/arm/gdbstub.c:358: undefined reference to `arm_v7m_get_sp_ptr'
11
../target/arm/gdbstub.c:361: undefined reference to `arm_v7m_get_sp_ptr'
12
13
libqemu-aarch64-softmmu.fa.p/target_arm_gdbstub.c.o: in function `arm_gdb_get_m_systemreg':
14
../target/arm/gdbstub.c:405: undefined reference to `arm_v7m_mrs_control'
15
16
Signed-off-by: Fabiano Rosas <farosas@suse.de>
17
Message-id: 20230628164821.16771-1-farosas@suse.de
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
20
---
9
hw/sd/sd.c | 11 ++++++++---
21
target/arm/gdbstub.c | 4 ++++
10
1 file changed, 8 insertions(+), 3 deletions(-)
22
1 file changed, 4 insertions(+)
11
23
12
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
24
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
13
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sd.c
26
--- a/target/arm/gdbstub.c
15
+++ b/hw/sd/sd.c
27
+++ b/target/arm/gdbstub.c
16
@@ -XXX,XX +XXX,XX @@ static void sd_lock_command(SDState *sd)
28
@@ -XXX,XX +XXX,XX @@ static int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg)
17
sd->card_status &= ~CARD_IS_LOCKED;
29
return cpu->dyn_sysreg_xml.num;
18
}
30
}
19
31
20
-static sd_rsp_type_t sd_normal_command(SDState *sd,
32
+#ifdef CONFIG_TCG
21
- SDRequest req)
33
typedef enum {
22
+static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
34
M_SYSREG_MSP,
35
M_SYSREG_PSP,
36
@@ -XXX,XX +XXX,XX @@ static int arm_gen_dynamic_m_secextreg_xml(CPUState *cs, int orig_base_reg)
37
return cpu->dyn_m_secextreg_xml.num;
38
}
39
#endif
40
+#endif /* CONFIG_TCG */
41
42
const char *arm_gdb_get_dynamic_xml(CPUState *cs, const char *xmlname)
23
{
43
{
24
uint32_t rca = 0x0000;
44
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
25
uint64_t addr = (sd->ocr & (1 << 30)) ? (uint64_t) req.arg << 9 : req.arg;
45
arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
26
46
"system-registers.xml", 0);
27
- trace_sdcard_normal_command(req.cmd, req.arg, sd_state_name(sd->state));
47
28
+ /* CMD55 precedes an ACMD, so we are not interested in tracing it.
48
+#ifdef CONFIG_TCG
29
+ * However there is no ACMD55, so we want to trace this particular case.
49
if (arm_feature(env, ARM_FEATURE_M) && tcg_enabled()) {
30
+ */
50
gdb_register_coprocessor(cs,
31
+ if (req.cmd != 55 || sd->expecting_acmd) {
51
arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg,
32
+ trace_sdcard_normal_command(req.cmd, req.arg,
52
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
33
+ sd_state_name(sd->state));
53
}
34
+ }
54
#endif
35
55
}
36
/* Not interpreting this as an app command */
56
+#endif /* CONFIG_TCG */
37
sd->card_status &= ~APP_CMD;
57
}
38
--
58
--
39
2.16.2
59
2.34.1
40
41
diff view generated by jsdifflib
1
From: Marc-André Lureau <marcandre.lureau@redhat.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
Spotted by ASAN:
3
AwSRAMCClass is larger than SysBusDeviceClass so the class size must be
4
QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 tests/boot-serial-test
4
advertised accordingly.
5
5
6
Direct leak of 48 byte(s) in 1 object(s) allocated from:
6
Fixes: 05def917e1 ("hw: arm: allwinner-sramc: Add SRAM Controller support for R40")
7
#0 0x7ff8a9b0ca38 in __interceptor_calloc (/lib64/libasan.so.4+0xdea38)
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
#1 0x7ff8a8ea7f75 in g_malloc0 ../glib/gmem.c:124
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
#2 0x55fef3d99129 in error_setv /home/elmarco/src/qemu/util/error.c:59
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
#3 0x55fef3d99738 in error_setg_internal /home/elmarco/src/qemu/util/error.c:95
10
Message-id: 20230628110905.38125-1-akihiko.odaki@daynix.com
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
19
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
12
---
23
hw/arm/boot.c | 1 +
13
hw/misc/allwinner-sramc.c | 1 +
24
1 file changed, 1 insertion(+)
14
1 file changed, 1 insertion(+)
25
15
26
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
16
diff --git a/hw/misc/allwinner-sramc.c b/hw/misc/allwinner-sramc.c
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/boot.c
18
--- a/hw/misc/allwinner-sramc.c
29
+++ b/hw/arm/boot.c
19
+++ b/hw/misc/allwinner-sramc.c
30
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry,
20
@@ -XXX,XX +XXX,XX @@ static const TypeInfo allwinner_sramc_info = {
31
21
.parent = TYPE_SYS_BUS_DEVICE,
32
load_elf_hdr(info->kernel_filename, &elf_header, &elf_is64, &err);
22
.instance_init = allwinner_sramc_init,
33
if (err) {
23
.instance_size = sizeof(AwSRAMCState),
34
+ error_free(err);
24
+ .class_size = sizeof(AwSRAMCClass),
35
return ret;
25
.class_init = allwinner_sramc_class_init,
36
}
26
};
37
27
38
--
28
--
39
2.16.2
29
2.34.1
40
30
41
31
diff view generated by jsdifflib
Deleted patch
1
From: Marc-André Lureau <marcandre.lureau@redhat.com>
2
1
3
Spotted by ASAN:
4
5
elmarco@boraha:~/src/qemu/build (master *%)$ QTEST_QEMU_BINARY=aarch64-softmmu/qemu-system-aarch64 tests/boot-serial-test
6
/aarch64/boot-serial/virt: ** (process:19740): DEBUG: 18:39:30.275: foo /tmp/qtest-boot-serial-cXaS94D
7
=================================================================
8
==19740==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000069648 at pc 0x7f1d2201cc54 bp 0x7fff331f6a40 sp 0x7fff331f61e8
9
READ of size 4 at 0x603000069648 thread T0
10
#0 0x7f1d2201cc53 (/lib64/libasan.so.4+0xafc53)
11
#1 0x55bc86685ee3 in load_aarch64_image /home/elmarco/src/qemu/hw/arm/boot.c:894
12
#2 0x55bc86687217 in arm_load_kernel_notify /home/elmarco/src/qemu/hw/arm/boot.c:1047
13
#3 0x55bc877363b5 in notifier_list_notify /home/elmarco/src/qemu/util/notify.c:40
14
#4 0x55bc869331ea in qemu_run_machine_init_done_notifiers /home/elmarco/src/qemu/vl.c:2716
15
#5 0x55bc8693bc39 in main /home/elmarco/src/qemu/vl.c:4679
16
#6 0x7f1d1652c009 in __libc_start_main (/lib64/libc.so.6+0x21009)
17
#7 0x55bc86255cc9 in _start (/home/elmarco/src/qemu/build/aarch64-softmmu/qemu-system-aarch64+0x1ae5cc9)
18
19
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/arm/boot.c | 3 ++-
24
1 file changed, 2 insertions(+), 1 deletion(-)
25
26
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/boot.c
29
+++ b/hw/arm/boot.c
30
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
31
}
32
33
/* check the arm64 magic header value -- very old kernels may not have it */
34
- if (memcmp(buffer + ARM64_MAGIC_OFFSET, "ARM\x64", 4) == 0) {
35
+ if (size > ARM64_MAGIC_OFFSET + 4 &&
36
+ memcmp(buffer + ARM64_MAGIC_OFFSET, "ARM\x64", 4) == 0) {
37
uint64_t hdrvals[2];
38
39
/* The arm64 Image header has text_offset and image_size fields at 8 and
40
--
41
2.16.2
42
43
diff view generated by jsdifflib
1
Add support for passing 'max' to -machine gic-version. By analogy
1
In handle_interrupt() we use level as an index into the interrupt_vector[]
2
with the -cpu max option, this picks the "best available" GIC version
2
array. This is safe because we have checked it against env->config->nlevel,
3
whether you're using KVM or TCG, so it behaves like 'host' when
3
but Coverity can't see that (and it is only true because each CPU config
4
using KVM, and gives you GICv3 when using TCG.
4
sets its XCHAL_NUM_INTLEVELS to something less than MAX_NLEVELS), so it
5
complains about a possible array overrun (CID 1507131)
5
6
6
Also like '-cpu host', using -machine gic-version=max' means there
7
Add an assert() which will make Coverity happy and catch the unlikely
7
is no guarantee of migration compatibility between QEMU versions;
8
case of a mis-set XCHAL_NUM_INTLEVELS in future.
8
in future 'max' might mean '4'.
9
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180308130626.12393-7-peter.maydell@linaro.org
11
Acked-by: Max Filippov <jcmvbkbc@gmail.com>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Message-id: 20230623154135.1930261-1-peter.maydell@linaro.org
13
---
13
---
14
hw/arm/virt.c | 29 +++++++++++++++++++----------
14
target/xtensa/exc_helper.c | 3 +++
15
1 file changed, 19 insertions(+), 10 deletions(-)
15
1 file changed, 3 insertions(+)
16
16
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
17
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt.c
19
--- a/target/xtensa/exc_helper.c
20
+++ b/hw/arm/virt.c
20
+++ b/target/xtensa/exc_helper.c
21
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
21
@@ -XXX,XX +XXX,XX @@ static void handle_interrupt(CPUXtensaState *env)
22
/* We can probe only here because during property set
22
CPUState *cs = env_cpu(env);
23
* KVM is not available yet
23
24
*/
24
if (level > 1) {
25
- if (!vms->gic_version) {
25
+ /* env->config->nlevel check should have ensured this */
26
+ if (vms->gic_version <= 0) {
26
+ assert(level < sizeof(env->config->interrupt_vector));
27
+ /* "host" or "max" */
27
+
28
if (!kvm_enabled()) {
28
env->sregs[EPC1 + level - 1] = env->pc;
29
- error_report("gic-version=host requires KVM");
29
env->sregs[EPS2 + level - 2] = env->sregs[PS];
30
- exit(1);
30
env->sregs[PS] =
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
}
53
54
@@ -XXX,XX +XXX,XX @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
55
vms->gic_version = 2;
56
} else if (!strcmp(value, "host")) {
57
vms->gic_version = 0; /* Will probe later */
58
+ } else if (!strcmp(value, "max")) {
59
+ vms->gic_version = -1; /* Will probe later */
60
} else {
61
error_setg(errp, "Invalid gic-version value");
62
- error_append_hint(errp, "Valid values are 3, 2, host.\n");
63
+ error_append_hint(errp, "Valid values are 3, 2, host, max.\n");
64
}
65
}
66
67
--
31
--
68
2.16.2
32
2.34.1
69
70
diff view generated by jsdifflib
1
Now we have a working '-cpu max', the linux-user-only
1
We already squash the ID register field for FEAT_SPE (the Statistical
2
'any' CPU is pretty much the same thing, so implement it
2
Profiling Extension) because TCG does not implement it and if we
3
that way.
3
advertise it to the guest the guest will crash trying to look at
4
non-existent system registers. Do the same for some other features
5
which a real hardware Neoverse-V1 implements but which TCG doesn't:
6
* FEAT_TRF (Self-hosted Trace Extension)
7
* Trace Macrocell system register access
8
* Memory mapped trace
9
* FEAT_AMU (Activity Monitors Extension)
10
* FEAT_MPAM (Memory Partitioning and Monitoring Extension)
11
* FEAT_NV (Nested Virtualization)
4
12
5
For the moment we don't add any of the extra feature bits
13
Most of these, like FEAT_SPE, are "introspection/trace" type features
6
to the system-emulation "max", because we don't set the
14
which QEMU is unlikely to ever implement. The odd-one-out here is
7
ID register bits we would need to to advertise those
15
FEAT_NV -- we could implement that and at some point we probably
8
features as present.
16
will.
9
17
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180308130626.12393-5-peter.maydell@linaro.org
19
Message-id: 20230704130647.2842917-2-peter.maydell@linaro.org
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
---
22
---
15
target/arm/cpu.c | 52 +++++++++++++++++++++++++----------------------
23
target/arm/cpu.c | 33 +++++++++++++++++++++++++++++----
16
target/arm/cpu64.c | 59 ++++++++++++++++++++++++++----------------------------
24
1 file changed, 29 insertions(+), 4 deletions(-)
17
2 files changed, 56 insertions(+), 55 deletions(-)
18
25
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
28
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
29
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
30
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
24
ObjectClass *oc;
31
25
char *typename;
32
if (tcg_enabled()) {
26
char **cpuname;
33
/*
27
+ const char *cpunamestr;
34
- * Don't report the Statistical Profiling Extension in the ID
28
35
- * registers, because TCG doesn't implement it yet (not even a
29
cpuname = g_strsplit(cpu_model, ",", 1);
36
- * minimal stub version) and guests will fall over when they
30
- typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpuname[0]);
37
- * try to access the non-existent system registers for it.
31
+ cpunamestr = cpuname[0];
38
+ * Don't report some architectural features in the ID registers
32
+#ifdef CONFIG_USER_ONLY
39
+ * where TCG does not yet implement it (not even a minimal
33
+ /* For backwards compatibility usermode emulation allows "-cpu any",
40
+ * stub version). This avoids guests falling over when they
34
+ * which has the same semantics as "-cpu max".
41
+ * try to access the non-existent system registers for them.
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
*/
42
*/
116
+ set_feature(&cpu->env, ARM_FEATURE_V8);
43
+ /* FEAT_SPE (Statistical Profiling Extension) */
117
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
44
cpu->isar.id_aa64dfr0 =
118
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
45
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMSVER, 0);
119
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
46
+ /* FEAT_TRF (Self-hosted Trace Extension) */
120
+ set_feature(&cpu->env, ARM_FEATURE_V8_AES);
47
+ cpu->isar.id_aa64dfr0 =
121
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
48
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEFILT, 0);
122
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
49
+ cpu->isar.id_dfr0 =
123
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
50
+ FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, TRACEFILT, 0);
124
+ set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
51
+ /* Trace Macrocell system register access */
125
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
52
+ cpu->isar.id_aa64dfr0 =
126
+ set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
53
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEVER, 0);
127
+ set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
54
+ cpu->isar.id_dfr0 =
128
+ set_feature(&cpu->env, ARM_FEATURE_CRC);
55
+ FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPTRC, 0);
129
+ set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
56
+ /* Memory mapped trace */
130
+ set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
57
+ cpu->isar.id_dfr0 =
131
+ set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
58
+ FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0);
132
+ /* For usermode -cpu max we can use a larger and more efficient DCZ
59
+ /* FEAT_AMU (Activity Monitors Extension) */
133
+ * blocksize since we don't have to follow what the hardware does.
60
+ cpu->isar.id_aa64pfr0 =
134
+ */
61
+ FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, AMU, 0);
135
+ cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
62
+ cpu->isar.id_pfr0 =
136
+ cpu->dcz_blocksize = 7; /* 512 bytes */
63
+ FIELD_DP32(cpu->isar.id_pfr0, ID_PFR0, AMU, 0);
137
+#endif
64
+ /* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
65
+ cpu->isar.id_aa64pfr0 =
66
+ FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0);
67
+ /* FEAT_NV (Nested Virtualization) */
68
+ cpu->isar.id_aa64mmfr2 =
69
+ FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 0);
138
}
70
}
139
}
71
140
72
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
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
--
73
--
181
2.16.2
74
2.34.1
182
75
183
76
diff view generated by jsdifflib
1
Allow the virt board to support '-cpu max' in the same way
1
Now that we have implemented support for FEAT_LSE2, we can define
2
it already handles '-cpu host'.
2
a CPU model for the Neoverse-V1, and enable it for the virt and
3
sbsa-ref boards.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180308130626.12393-6-peter.maydell@linaro.org
6
Message-id: 20230704130647.2842917-3-peter.maydell@linaro.org
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
---
9
hw/arm/virt.c | 1 +
10
docs/system/arm/virt.rst | 1 +
10
1 file changed, 1 insertion(+)
11
hw/arm/sbsa-ref.c | 1 +
11
12
hw/arm/virt.c | 1 +
13
target/arm/tcg/cpu64.c | 128 +++++++++++++++++++++++++++++++++++++++
14
4 files changed, 131 insertions(+)
15
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/virt.rst
19
+++ b/docs/system/arm/virt.rst
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
21
- ``a64fx`` (64-bit)
22
- ``host`` (with KVM only)
23
- ``neoverse-n1`` (64-bit)
24
+- ``neoverse-v1`` (64-bit)
25
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
26
27
Note that the default is ``cortex-a15``, so for an AArch64 guest you must
28
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/sbsa-ref.c
31
+++ b/hw/arm/sbsa-ref.c
32
@@ -XXX,XX +XXX,XX @@ static const char * const valid_cpus[] = {
33
ARM_CPU_TYPE_NAME("cortex-a57"),
34
ARM_CPU_TYPE_NAME("cortex-a72"),
35
ARM_CPU_TYPE_NAME("neoverse-n1"),
36
+ ARM_CPU_TYPE_NAME("neoverse-v1"),
37
ARM_CPU_TYPE_NAME("max"),
38
};
39
12
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
40
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
13
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/virt.c
42
--- a/hw/arm/virt.c
15
+++ b/hw/arm/virt.c
43
+++ b/hw/arm/virt.c
16
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
44
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
45
ARM_CPU_TYPE_NAME("cortex-a76"),
46
ARM_CPU_TYPE_NAME("a64fx"),
47
ARM_CPU_TYPE_NAME("neoverse-n1"),
48
+ ARM_CPU_TYPE_NAME("neoverse-v1"),
49
#endif
17
ARM_CPU_TYPE_NAME("cortex-a53"),
50
ARM_CPU_TYPE_NAME("cortex-a53"),
18
ARM_CPU_TYPE_NAME("cortex-a57"),
51
ARM_CPU_TYPE_NAME("cortex-a57"),
19
ARM_CPU_TYPE_NAME("host"),
52
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
20
+ ARM_CPU_TYPE_NAME("max"),
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/tcg/cpu64.c
55
+++ b/target/arm/tcg/cpu64.c
56
@@ -XXX,XX +XXX,XX @@ static void define_neoverse_n1_cp_reginfo(ARMCPU *cpu)
57
define_arm_cp_regs(cpu, neoverse_n1_cp_reginfo);
58
}
59
60
+static const ARMCPRegInfo neoverse_v1_cp_reginfo[] = {
61
+ { .name = "CPUECTLR2_EL1", .state = ARM_CP_STATE_AA64,
62
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 1, .opc2 = 5,
63
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
64
+ { .name = "CPUPPMCR_EL3", .state = ARM_CP_STATE_AA64,
65
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 0,
66
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
67
+ { .name = "CPUPPMCR2_EL3", .state = ARM_CP_STATE_AA64,
68
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 1,
69
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
70
+ { .name = "CPUPPMCR3_EL3", .state = ARM_CP_STATE_AA64,
71
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 2, .opc2 = 6,
72
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
73
+};
74
+
75
+static void define_neoverse_v1_cp_reginfo(ARMCPU *cpu)
76
+{
77
+ /*
78
+ * The Neoverse V1 has all of the Neoverse N1's IMPDEF
79
+ * registers and a few more of its own.
80
+ */
81
+ define_arm_cp_regs(cpu, neoverse_n1_cp_reginfo);
82
+ define_arm_cp_regs(cpu, neoverse_v1_cp_reginfo);
83
+}
84
+
85
static void aarch64_neoverse_n1_initfn(Object *obj)
86
{
87
ARMCPU *cpu = ARM_CPU(obj);
88
@@ -XXX,XX +XXX,XX @@ static void aarch64_neoverse_n1_initfn(Object *obj)
89
define_neoverse_n1_cp_reginfo(cpu);
90
}
91
92
+static void aarch64_neoverse_v1_initfn(Object *obj)
93
+{
94
+ ARMCPU *cpu = ARM_CPU(obj);
95
+
96
+ cpu->dtb_compatible = "arm,neoverse-v1";
97
+ set_feature(&cpu->env, ARM_FEATURE_V8);
98
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
99
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
100
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
101
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
102
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
103
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
104
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
105
+
106
+ /* Ordered by 3.2.4 AArch64 registers by functional group */
107
+ cpu->clidr = 0x82000023;
108
+ cpu->ctr = 0xb444c004; /* With DIC and IDC set */
109
+ cpu->dcz_blocksize = 4;
110
+ cpu->id_aa64afr0 = 0x00000000;
111
+ cpu->id_aa64afr1 = 0x00000000;
112
+ cpu->isar.id_aa64dfr0 = 0x000001f210305519ull;
113
+ cpu->isar.id_aa64dfr1 = 0x00000000;
114
+ cpu->isar.id_aa64isar0 = 0x1011111110212120ull; /* with FEAT_RNG */
115
+ cpu->isar.id_aa64isar1 = 0x0111000001211032ull;
116
+ cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
117
+ cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
118
+ cpu->isar.id_aa64mmfr2 = 0x0220011102101011ull;
119
+ cpu->isar.id_aa64pfr0 = 0x1101110120111112ull; /* GIC filled in later */
120
+ cpu->isar.id_aa64pfr1 = 0x0000000000000020ull;
121
+ cpu->id_afr0 = 0x00000000;
122
+ cpu->isar.id_dfr0 = 0x15011099;
123
+ cpu->isar.id_isar0 = 0x02101110;
124
+ cpu->isar.id_isar1 = 0x13112111;
125
+ cpu->isar.id_isar2 = 0x21232042;
126
+ cpu->isar.id_isar3 = 0x01112131;
127
+ cpu->isar.id_isar4 = 0x00010142;
128
+ cpu->isar.id_isar5 = 0x11011121;
129
+ cpu->isar.id_isar6 = 0x01100111;
130
+ cpu->isar.id_mmfr0 = 0x10201105;
131
+ cpu->isar.id_mmfr1 = 0x40000000;
132
+ cpu->isar.id_mmfr2 = 0x01260000;
133
+ cpu->isar.id_mmfr3 = 0x02122211;
134
+ cpu->isar.id_mmfr4 = 0x01021110;
135
+ cpu->isar.id_pfr0 = 0x21110131;
136
+ cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
137
+ cpu->isar.id_pfr2 = 0x00000011;
138
+ cpu->midr = 0x411FD402; /* r1p2 */
139
+ cpu->revidr = 0;
140
+
141
+ /*
142
+ * The Neoverse-V1 r1p2 TRM lists 32-bit format CCSIDR_EL1 values,
143
+ * but also says it implements CCIDX, which means they should be
144
+ * 64-bit format. So we here use values which are based on the textual
145
+ * information in chapter 2 of the TRM (and on the fact that
146
+ * sets * associativity * linesize == cachesize).
147
+ *
148
+ * The 64-bit CCSIDR_EL1 format is:
149
+ * [55:32] number of sets - 1
150
+ * [23:3] associativity - 1
151
+ * [2:0] log2(linesize) - 4
152
+ * so 0 == 16 bytes, 1 == 32 bytes, 2 == 64 bytes, etc
153
+ *
154
+ * L1: 4-way set associative 64-byte line size, total size 64K,
155
+ * so sets is 256.
156
+ *
157
+ * L2: 8-way set associative, 64 byte line size, either 512K or 1MB.
158
+ * We pick 1MB, so this has 2048 sets.
159
+ *
160
+ * L3: No L3 (this matches the CLIDR_EL1 value).
161
+ */
162
+ cpu->ccsidr[0] = 0x000000ff0000001aull; /* 64KB L1 dcache */
163
+ cpu->ccsidr[1] = 0x000000ff0000001aull; /* 64KB L1 icache */
164
+ cpu->ccsidr[2] = 0x000007ff0000003aull; /* 1MB L2 cache */
165
+
166
+ /* From 3.2.115 SCTLR_EL3 */
167
+ cpu->reset_sctlr = 0x30c50838;
168
+
169
+ /* From 3.4.8 ICC_CTLR_EL3 and 3.4.23 ICH_VTR_EL2 */
170
+ cpu->gic_num_lrs = 4;
171
+ cpu->gic_vpribits = 5;
172
+ cpu->gic_vprebits = 5;
173
+ cpu->gic_pribits = 5;
174
+
175
+ /* From 3.5.1 AdvSIMD AArch64 register summary */
176
+ cpu->isar.mvfr0 = 0x10110222;
177
+ cpu->isar.mvfr1 = 0x13211111;
178
+ cpu->isar.mvfr2 = 0x00000043;
179
+
180
+ /* From 3.7.5 ID_AA64ZFR0_EL1 */
181
+ cpu->isar.id_aa64zfr0 = 0x0000100000100000;
182
+ cpu->sve_vq.supported = (1 << 0) /* 128bit */
183
+ | (1 << 1); /* 256bit */
184
+
185
+ /* From 5.5.1 AArch64 PMU register summary */
186
+ cpu->isar.reset_pmcr_el0 = 0x41213000;
187
+
188
+ define_neoverse_v1_cp_reginfo(cpu);
189
+
190
+ aarch64_add_pauth_properties(obj);
191
+ aarch64_add_sve_properties(obj);
192
+}
193
+
194
/*
195
* -cpu max: a CPU with as many features enabled as our emulation supports.
196
* The version of '-cpu max' for qemu-system-arm is defined in cpu32.c;
197
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
198
{ .name = "cortex-a76", .initfn = aarch64_a76_initfn },
199
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
200
{ .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
201
+ { .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
21
};
202
};
22
203
23
static bool cpu_type_valid(const char *cpu)
204
static void aarch64_cpu_register_types(void)
24
--
205
--
25
2.16.2
206
2.34.1
26
207
27
208
diff view generated by jsdifflib
1
Add support for "-cpu max" for ARM guests. This CPU type behaves
1
If you build QEMU with the clang sanitizer enabled, you can see it
2
like "-cpu host" when KVM is enabled, and like a system CPU with
2
fire when running the arm-cpu-features test:
3
the maximum possible feature set otherwise. (Note that this means
3
4
it won't be migratable across versions, as we will likely add
4
$ QTEST_QEMU_BINARY=./build/arm-clang/qemu-system-aarch64 ./build/arm-clang/tests/qtest/arm-cpu-features
5
features to it in future.)
5
[...]
6
../../target/arm/cpu64.c:125:19: runtime error: shift exponent 64 is too large for 64-bit type 'unsigned long long'
7
[...]
8
9
This happens because the user can specify some incorrect SVE
10
properties that result in our calculating a max_vq of 0. We catch
11
this and error out, but before we do that we calculate
12
13
vq_mask = MAKE_64BIT_MASK(0, max_vq);$
14
15
and the MAKE_64BIT_MASK() call is only valid for lengths that are
16
greater than zero, so we hit the undefined behaviour.
17
18
Change the logic so that if max_vq is 0 we specifically set vq_mask
19
to 0 without going via MAKE_64BIT_MASK(). This lets us drop the
20
max_vq check from the error-exit logic, because if max_vq is 0 then
21
vq_map must now be 0.
22
23
The UB only happens in the case where the user passed us an incorrect
24
set of SVE properties, so it's not a big problem in practice.
6
25
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
27
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180308130626.12393-4-peter.maydell@linaro.org
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-id: 20230704154332.3014896-1-peter.maydell@linaro.org
10
---
30
---
11
target/arm/cpu-qom.h | 2 ++
31
target/arm/cpu64.c | 4 ++--
12
target/arm/cpu.c | 24 ++++++++++++++++++++++++
32
1 file changed, 2 insertions(+), 2 deletions(-)
13
target/arm/cpu64.c | 21 +++++++++++++++++++++
14
3 files changed, 47 insertions(+)
15
33
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
34
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
72
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/cpu64.c
36
--- a/target/arm/cpu64.c
74
+++ b/target/arm/cpu64.c
37
+++ b/target/arm/cpu64.c
75
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
76
#include "hw/arm/arm.h"
39
vq = ctz32(tmp) + 1;
77
#include "sysemu/sysemu.h"
40
78
#include "sysemu/kvm.h"
41
max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
79
+#include "kvm_arm.h"
42
- vq_mask = MAKE_64BIT_MASK(0, max_vq);
80
43
+ vq_mask = max_vq > 0 ? MAKE_64BIT_MASK(0, max_vq) : 0;
81
static inline void set_feature(CPUARMState *env, int feature)
44
vq_map = vq_supported & ~vq_init & vq_mask;
82
{
45
83
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
46
- if (max_vq == 0 || vq_map == 0) {
84
define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
47
+ if (vq_map == 0) {
85
}
48
error_setg(errp, "cannot disable sve%d", vq * 128);
86
49
error_append_hint(errp, "Disabling sve%d results in all "
87
+/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
50
"vector lengths being disabled.\n",
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
--
51
--
118
2.16.2
52
2.34.1
119
53
120
54
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
The SDBus will reuse these functions, so we put them in a new source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20180309153654.13518-3-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
[PMM: slight wordsmithing of comments, added note that string
9
returned does not need to be freed]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/sd/Makefile.objs | 2 +-
13
hw/sd/sdmmc-internal.h | 24 +++++++++++++++++
14
hw/sd/sd.c | 13 +++++----
15
hw/sd/sdmmc-internal.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
16
hw/sd/trace-events | 8 +++---
17
5 files changed, 109 insertions(+), 10 deletions(-)
18
create mode 100644 hw/sd/sdmmc-internal.c
19
20
diff --git a/hw/sd/Makefile.objs b/hw/sd/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/sd/Makefile.objs
23
+++ b/hw/sd/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@
25
common-obj-$(CONFIG_PL181) += pl181.o
26
common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
27
-common-obj-$(CONFIG_SD) += sd.o core.o
28
+common-obj-$(CONFIG_SD) += sd.o core.o sdmmc-internal.o
29
common-obj-$(CONFIG_SDHCI) += sdhci.o
30
31
obj-$(CONFIG_MILKYMIST) += milkymist-memcard.o
32
diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/sd/sdmmc-internal.h
35
+++ b/hw/sd/sdmmc-internal.h
36
@@ -XXX,XX +XXX,XX @@
37
38
#define SDMMC_CMD_MAX 64
39
40
+/**
41
+ * sd_cmd_name:
42
+ * @cmd: A SD "normal" command, up to SDMMC_CMD_MAX.
43
+ *
44
+ * Returns a human-readable name describing the command.
45
+ * The return value is always a static string which does not need
46
+ * to be freed after use.
47
+ *
48
+ * Returns: The command name of @cmd or "UNKNOWN_CMD".
49
+ */
50
+const char *sd_cmd_name(uint8_t cmd);
51
+
52
+/**
53
+ * sd_acmd_name:
54
+ * @cmd: A SD "Application-Specific" command, up to SDMMC_CMD_MAX.
55
+ *
56
+ * Returns a human-readable name describing the application command.
57
+ * The return value is always a static string which does not need
58
+ * to be freed after use.
59
+ *
60
+ * Returns: The application command name of @cmd or "UNKNOWN_ACMD".
61
+ */
62
+const char *sd_acmd_name(uint8_t cmd);
63
+
64
#endif
65
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/sd/sd.c
68
+++ b/hw/sd/sd.c
69
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
70
* However there is no ACMD55, so we want to trace this particular case.
71
*/
72
if (req.cmd != 55 || sd->expecting_acmd) {
73
- trace_sdcard_normal_command(req.cmd, req.arg,
74
- sd_state_name(sd->state));
75
+ trace_sdcard_normal_command(sd_cmd_name(req.cmd), req.cmd,
76
+ req.arg, sd_state_name(sd->state));
77
}
78
79
/* Not interpreting this as an app command */
80
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
81
static sd_rsp_type_t sd_app_command(SDState *sd,
82
SDRequest req)
83
{
84
- trace_sdcard_app_command(req.cmd, req.arg);
85
+ trace_sdcard_app_command(sd_acmd_name(req.cmd),
86
+ req.cmd, req.arg, sd_state_name(sd->state));
87
sd->card_status |= APP_CMD;
88
switch (req.cmd) {
89
case 6:    /* ACMD6: SET_BUS_WIDTH */
90
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
91
if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
92
return;
93
94
- trace_sdcard_write_data(sd->current_cmd, value);
95
+ trace_sdcard_write_data(sd_acmd_name(sd->current_cmd),
96
+ sd->current_cmd, value);
97
switch (sd->current_cmd) {
98
case 24:    /* CMD24: WRITE_SINGLE_BLOCK */
99
sd->data[sd->data_offset ++] = value;
100
@@ -XXX,XX +XXX,XX @@ uint8_t sd_read_data(SDState *sd)
101
102
io_len = (sd->ocr & (1 << 30)) ? 512 : sd->blk_len;
103
104
- trace_sdcard_read_data(sd->current_cmd, io_len);
105
+ trace_sdcard_read_data(sd_acmd_name(sd->current_cmd),
106
+ sd->current_cmd, io_len);
107
switch (sd->current_cmd) {
108
case 6:    /* CMD6: SWITCH_FUNCTION */
109
ret = sd->data[sd->data_offset ++];
110
diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
111
new file mode 100644
112
index XXXXXXX..XXXXXXX
113
--- /dev/null
114
+++ b/hw/sd/sdmmc-internal.c
115
@@ -XXX,XX +XXX,XX @@
116
+/*
117
+ * SD/MMC cards common helpers
118
+ *
119
+ * Copyright (c) 2018 Philippe Mathieu-Daudé <f4bug@amsat.org>
120
+ *
121
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
122
+ * See the COPYING file in the top-level directory.
123
+ * SPDX-License-Identifier: GPL-2.0-or-later
124
+ */
125
+
126
+#include "qemu/osdep.h"
127
+#include "sdmmc-internal.h"
128
+
129
+const char *sd_cmd_name(uint8_t cmd)
130
+{
131
+ static const char *cmd_abbrev[SDMMC_CMD_MAX] = {
132
+ [0] = "GO_IDLE_STATE",
133
+ [2] = "ALL_SEND_CID", [3] = "SEND_RELATIVE_ADDR",
134
+ [4] = "SET_DSR", [5] = "IO_SEND_OP_COND",
135
+ [6] = "SWITCH_FUNC", [7] = "SELECT/DESELECT_CARD",
136
+ [8] = "SEND_IF_COND", [9] = "SEND_CSD",
137
+ [10] = "SEND_CID", [11] = "VOLTAGE_SWITCH",
138
+ [12] = "STOP_TRANSMISSION", [13] = "SEND_STATUS",
139
+ [15] = "GO_INACTIVE_STATE",
140
+ [16] = "SET_BLOCKLEN", [17] = "READ_SINGLE_BLOCK",
141
+ [18] = "READ_MULTIPLE_BLOCK", [19] = "SEND_TUNING_BLOCK",
142
+ [20] = "SPEED_CLASS_CONTROL", [21] = "DPS_spec",
143
+ [23] = "SET_BLOCK_COUNT",
144
+ [24] = "WRITE_BLOCK", [25] = "WRITE_MULTIPLE_BLOCK",
145
+ [26] = "MANUF_RSVD", [27] = "PROGRAM_CSD",
146
+ [28] = "SET_WRITE_PROT", [29] = "CLR_WRITE_PROT",
147
+ [30] = "SEND_WRITE_PROT",
148
+ [32] = "ERASE_WR_BLK_START", [33] = "ERASE_WR_BLK_END",
149
+ [34] = "SW_FUNC_RSVD", [35] = "SW_FUNC_RSVD",
150
+ [36] = "SW_FUNC_RSVD", [37] = "SW_FUNC_RSVD",
151
+ [38] = "ERASE",
152
+ [40] = "DPS_spec",
153
+ [42] = "LOCK_UNLOCK", [43] = "Q_MANAGEMENT",
154
+ [44] = "Q_TASK_INFO_A", [45] = "Q_TASK_INFO_B",
155
+ [46] = "Q_RD_TASK", [47] = "Q_WR_TASK",
156
+ [48] = "READ_EXTR_SINGLE", [49] = "WRITE_EXTR_SINGLE",
157
+ [50] = "SW_FUNC_RSVD",
158
+ [52] = "IO_RW_DIRECT", [53] = "IO_RW_EXTENDED",
159
+ [54] = "SDIO_RSVD", [55] = "APP_CMD",
160
+ [56] = "GEN_CMD", [57] = "SW_FUNC_RSVD",
161
+ [58] = "READ_EXTR_MULTI", [59] = "WRITE_EXTR_MULTI",
162
+ [60] = "MANUF_RSVD", [61] = "MANUF_RSVD",
163
+ [62] = "MANUF_RSVD", [63] = "MANUF_RSVD",
164
+ };
165
+ return cmd_abbrev[cmd] ? cmd_abbrev[cmd] : "UNKNOWN_CMD";
166
+}
167
+
168
+const char *sd_acmd_name(uint8_t cmd)
169
+{
170
+ static const char *acmd_abbrev[SDMMC_CMD_MAX] = {
171
+ [6] = "SET_BUS_WIDTH",
172
+ [13] = "SD_STATUS",
173
+ [14] = "DPS_spec", [15] = "DPS_spec",
174
+ [16] = "DPS_spec",
175
+ [18] = "SECU_spec",
176
+ [22] = "SEND_NUM_WR_BLOCKS", [23] = "SET_WR_BLK_ERASE_COUNT",
177
+ [41] = "SD_SEND_OP_COND",
178
+ [42] = "SET_CLR_CARD_DETECT",
179
+ [51] = "SEND_SCR",
180
+ [52] = "SECU_spec", [53] = "SECU_spec",
181
+ [54] = "SECU_spec",
182
+ [56] = "SECU_spec", [57] = "SECU_spec",
183
+ [58] = "SECU_spec", [59] = "SECU_spec",
184
+ };
185
+
186
+ return acmd_abbrev[cmd] ? acmd_abbrev[cmd] : "UNKNOWN_ACMD";
187
+}
188
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
189
index XXXXXXX..XXXXXXX 100644
190
--- a/hw/sd/trace-events
191
+++ b/hw/sd/trace-events
192
@@ -XXX,XX +XXX,XX @@ sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of
193
sdhci_capareg(const char *desc, uint16_t val) "%s: %u"
194
195
# hw/sd/sd.c
196
-sdcard_normal_command(uint8_t cmd, uint32_t arg, const char *state) "CMD%d arg 0x%08x (state %s)"
197
-sdcard_app_command(uint8_t acmd, uint32_t arg) "ACMD%d arg 0x%08x"
198
+sdcard_normal_command(const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%20s/ CMD%02d arg 0x%08x (state %s)"
199
+sdcard_app_command(const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%23s/ACMD%02d arg 0x%08x (state %s)"
200
sdcard_response(const char *rspdesc, int rsplen) "%s (sz:%d)"
201
sdcard_powerup(void) ""
202
sdcard_inquiry_cmd41(void) ""
203
@@ -XXX,XX +XXX,XX @@ sdcard_lock(void) ""
204
sdcard_unlock(void) ""
205
sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
206
sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
207
-sdcard_write_data(uint8_t cmd, uint8_t value) "CMD%02d value 0x%02x"
208
-sdcard_read_data(uint8_t cmd, int length) "CMD%02d len %d"
209
+sdcard_write_data(const char *cmd_desc, uint8_t cmd, uint8_t value) "%20s/ CMD%02d value 0x%02x"
210
+sdcard_read_data(const char *cmd_desc, uint8_t cmd, int length) "%20s/ CMD%02d len %d"
211
sdcard_set_voltage(uint16_t millivolts) "%u mV"
212
213
# hw/sd/milkymist-memcard.c
214
--
215
2.16.2
216
217
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
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
---
8
hw/sd/sd.c | 14 ++++++++++----
9
hw/sd/trace-events | 8 ++++----
10
2 files changed, 14 insertions(+), 8 deletions(-)
11
12
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/sd.c
15
+++ b/hw/sd/sd.c
16
@@ -XXX,XX +XXX,XX @@ struct SDState {
17
qemu_irq readonly_cb;
18
qemu_irq inserted_cb;
19
QEMUTimer *ocr_power_timer;
20
+ const char *proto_name;
21
bool enable;
22
uint8_t dat_lines;
23
bool cmd_line;
24
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
25
* However there is no ACMD55, so we want to trace this particular case.
26
*/
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
}
33
34
@@ -XXX,XX +XXX,XX @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
35
static sd_rsp_type_t sd_app_command(SDState *sd,
36
SDRequest req)
37
{
38
- trace_sdcard_app_command(sd_acmd_name(req.cmd),
39
+ trace_sdcard_app_command(sd->proto_name, sd_acmd_name(req.cmd),
40
req.cmd, req.arg, sd_state_name(sd->state));
41
sd->card_status |= APP_CMD;
42
switch (req.cmd) {
43
@@ -XXX,XX +XXX,XX @@ void sd_write_data(SDState *sd, uint8_t value)
44
if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
45
return;
46
47
- trace_sdcard_write_data(sd_acmd_name(sd->current_cmd),
48
+ trace_sdcard_write_data(sd->proto_name,
49
+ sd_acmd_name(sd->current_cmd),
50
sd->current_cmd, value);
51
switch (sd->current_cmd) {
52
case 24:    /* CMD24: WRITE_SINGLE_BLOCK */
53
@@ -XXX,XX +XXX,XX @@ uint8_t sd_read_data(SDState *sd)
54
55
io_len = (sd->ocr & (1 << 30)) ? 512 : sd->blk_len;
56
57
- trace_sdcard_read_data(sd_acmd_name(sd->current_cmd),
58
+ trace_sdcard_read_data(sd->proto_name,
59
+ sd_acmd_name(sd->current_cmd),
60
sd->current_cmd, io_len);
61
switch (sd->current_cmd) {
62
case 6:    /* CMD6: SWITCH_FUNCTION */
63
@@ -XXX,XX +XXX,XX @@ static void sd_realize(DeviceState *dev, Error **errp)
64
SDState *sd = SD_CARD(dev);
65
int ret;
66
67
+ sd->proto_name = sd->spi ? "SPI" : "SD";
68
+
69
if (sd->blk && blk_is_read_only(sd->blk)) {
70
error_setg(errp, "Cannot use read-only drive as SD card");
71
return;
72
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/sd/trace-events
75
+++ b/hw/sd/trace-events
76
@@ -XXX,XX +XXX,XX @@ sdhci_write_dataport(uint16_t data_count) "write buffer filled with %u bytes of
77
sdhci_capareg(const char *desc, uint16_t val) "%s: %u"
78
79
# hw/sd/sd.c
80
-sdcard_normal_command(const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%20s/ CMD%02d arg 0x%08x (state %s)"
81
-sdcard_app_command(const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%23s/ACMD%02d arg 0x%08x (state %s)"
82
+sdcard_normal_command(const char *proto, const char *cmd_desc, uint8_t cmd, uint32_t arg, const char *state) "%s %20s/ CMD%02d arg 0x%08x (state %s)"
83
+sdcard_app_command(const char *proto, const char *acmd_desc, uint8_t acmd, uint32_t arg, const char *state) "%s %23s/ACMD%02d arg 0x%08x (state %s)"
84
sdcard_response(const char *rspdesc, int rsplen) "%s (sz:%d)"
85
sdcard_powerup(void) ""
86
sdcard_inquiry_cmd41(void) ""
87
@@ -XXX,XX +XXX,XX @@ sdcard_lock(void) ""
88
sdcard_unlock(void) ""
89
sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
90
sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
91
-sdcard_write_data(const char *cmd_desc, uint8_t cmd, uint8_t value) "%20s/ CMD%02d value 0x%02x"
92
-sdcard_read_data(const char *cmd_desc, uint8_t cmd, int length) "%20s/ CMD%02d len %d"
93
+sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint8_t value) "%s %20s/ CMD%02d value 0x%02x"
94
+sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, int length) "%s %20s/ CMD%02d len %d"
95
sdcard_set_voltage(uint16_t millivolts) "%u mV"
96
97
# hw/sd/milkymist-memcard.c
98
--
99
2.16.2
100
101
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180309153654.13518-8-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
hw/sd/sdhci.c | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
10
11
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/sdhci.c
14
+++ b/hw/sd/sdhci.c
15
@@ -XXX,XX +XXX,XX @@ static void sdhci_read_block_from_card(SDHCIState *s)
16
for (index = 0; index < blk_size; index++) {
17
data = sdbus_read_data(&s->sdbus);
18
if (!FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, EXECUTE_TUNING)) {
19
- /* Device is not in tunning */
20
+ /* Device is not in tuning */
21
s->fifo_buffer[index] = data;
22
}
23
}
24
25
if (FIELD_EX32(s->hostctl2, SDHC_HOSTCTL2, EXECUTE_TUNING)) {
26
- /* Device is in tunning */
27
+ /* Device is in tuning */
28
s->hostctl2 &= ~R_SDHC_HOSTCTL2_EXECUTE_TUNING_MASK;
29
s->hostctl2 |= R_SDHC_HOSTCTL2_SAMPLING_CLKSEL_MASK;
30
s->prnsts &= ~(SDHC_DAT_LINE_ACTIVE | SDHC_DOING_READ |
31
--
32
2.16.2
33
34
diff view generated by jsdifflib