1
Arm queue. I still have a lot of stuff in my to-review queue, so
1
Changes v1->v2 (fixing CI failures in v1, added a couple of
2
won't be long til the next one.
2
extra patches in an attempt to avoid having to do a last
3
3
minute arm pullreq next week):
4
I've thrown in a couple of minor non-arm patches (a xen code
4
* new patch to hopefully fix the build issue with the SVE/SME sysregs test
5
cleanup and a vl.c codestyle issue).
5
* dropped the IC IVAU test case patch
6
* new patch: fix over-length shift
7
* new patches: define neoverse-v1
6
8
7
thanks
9
thanks
8
-- PMM
10
-- PMM
9
11
10
The following changes since commit de44c044420d1139480fa50c2d5be19223391218:
12
The following changes since commit 2a6ae69154542caa91dd17c40fd3f5ffbec300de:
11
13
12
Merge remote-tracking branch 'remotes/stsquad/tags/pull-tcg-testing-revivial-210618-2' into staging (2018-06-22 10:57:47 +0100)
14
Merge tag 'pull-maintainer-ominbus-030723-1' of https://gitlab.com/stsquad/qemu into staging (2023-07-04 08:36:44 +0200)
13
15
14
are available in the Git repository at:
16
are available in the Git repository at:
15
17
16
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180622
18
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230706
17
19
18
for you to fetch changes up to 6dad8260e82b69bd278685ee25209f5824360455:
20
for you to fetch changes up to c41077235168140cdd4a34fce9bd95c3d30efe9c:
19
21
20
xen: Don't use memory_region_init_ram_nomigrate() in pci_assign_dev_load_option_rom() (2018-06-22 13:28:42 +0100)
22
target/arm: Avoid over-length shift in arm_cpu_sve_finalize() error case (2023-07-06 13:36:51 +0100)
21
23
22
----------------------------------------------------------------
24
----------------------------------------------------------------
23
target-arm queue:
25
target-arm queue:
24
* hw/intc/arm_gicv3: fix wrong values when reading IPRIORITYR
26
* Add raw_writes ops for register whose write induce TLB maintenance
25
* target/arm: fix read of freed memory in kvm_arm_machine_init_done()
27
* hw/arm/sbsa-ref: use XHCI to replace EHCI
26
* virt: support up to 512 CPUs
28
* Avoid splitting Zregs across lines in dump
27
* virt: support 256MB ECAM PCI region (for more PCI devices)
29
* Dump ZA[] when active
28
* xlnx-zynqmp: Use Cortex-R5F, not Cortex-R5
30
* Fix SME full tile indexing
29
* mps2-tz: Implement and use the TrustZone Memory Protection Controller
31
* Handle IC IVAU to improve compatibility with JITs
30
* target/arm: enforce alignment checking for v6M cores
32
* xlnx-canfd-test: Fix code coverity issues
31
* xen: Don't use memory_region_init_ram_nomigrate() in pci_assign_dev_load_option_rom()
33
* gdbstub: Guard M-profile code with CONFIG_TCG
32
* vl.c: Don't zero-initialize statics for serial_hds
34
* allwinner-sramc: Set class_size
35
* target/xtensa: Assert that interrupt level is within bounds
36
* Avoid over-length shift in arm_cpu_sve_finalize() error case
37
* Define new 'neoverse-v1' CPU type
33
38
34
----------------------------------------------------------------
39
----------------------------------------------------------------
35
Amol Surati (1):
40
Akihiko Odaki (1):
36
hw/intc/arm_gicv3: fix an extra left-shift when reading IPRIORITYR
41
hw: arm: allwinner-sramc: Set class_size
37
42
38
Edgar E. Iglesias (2):
43
Eric Auger (1):
39
target-arm: Add the Cortex-R5F
44
target/arm: Add raw_writes ops for register whose write induce TLB maintenance
40
xlnx-zynqmp: Swap Cortex-R5 for Cortex-R5F
41
45
42
Eric Auger (11):
46
Fabiano Rosas (1):
43
linux-headers: Update to kernel mainline commit b357bf602
47
target/arm: gdbstub: Guard M-profile code with CONFIG_TCG
44
target/arm: Allow KVM device address overwriting
45
hw/intc/arm_gicv3: Introduce redist-region-count array property
46
hw/intc/arm_gicv3_kvm: Get prepared to handle multiple redist regions
47
hw/arm/virt: GICv3 DT node with one or two redistributor regions
48
hw/arm/virt-acpi-build: Advertise one or two GICR structures
49
hw/arm/virt: Register two redistributor regions when necessary
50
hw/arm/virt: Add a new 256MB ECAM region
51
hw/arm/virt: Add virt-3.0 machine type
52
hw/arm/virt: Use 256MB ECAM region by default
53
hw/arm/virt: Increase max_cpus to 512
54
48
55
Julia Suvorova (3):
49
John Högberg (1):
56
target/arm: Minor cleanup for ARMv6-M 32-bit instructions
50
target/arm: Handle IC IVAU to improve compatibility with JITs
57
target/arm: Introduce ARM_FEATURE_M_MAIN
58
target/arm: Strict alignment for ARMv6-M and ARMv8-M Baseline
59
51
60
Peter Maydell (10):
52
Peter Maydell (5):
61
hw/misc/tz-mpc.c: Implement the Arm TrustZone Memory Protection Controller
53
tests/tcg/aarch64/sysregs.c: Use S syntax for id_aa64zfr0_el1 and id_aa64smfr0_el1
62
hw/misc/tz-mpc.c: Implement registers
54
target/xtensa: Assert that interrupt level is within bounds
63
hw/misc/tz-mpc.c: Implement correct blocked-access behaviour
55
target/arm: Suppress more TCG unimplemented features in ID registers
64
hw/misc/tz_mpc.c: Honour the BLK_LUT settings in translate
56
target/arm: Define neoverse-v1
65
hw/misc/iotkit-secctl.c: Implement SECMPCINTSTATUS
57
target/arm: Avoid over-length shift in arm_cpu_sve_finalize() error case
66
hw/arm/iotkit: Instantiate MPC
67
hw/arm/iotkit: Wire up MPC interrupt lines
68
hw/arm/mps2-tz.c: Instantiate MPCs
69
vl.c: Don't zero-initialize statics for serial_hds
70
xen: Don't use memory_region_init_ram_nomigrate() in pci_assign_dev_load_option_rom()
71
58
72
Zheng Xiang (1):
59
Richard Henderson (3):
73
target-arm: fix a segmentation fault due to illegal memory access
60
target/arm: Avoid splitting Zregs across lines in dump
61
target/arm: Dump ZA[] when active
62
target/arm: Fix SME full tile indexing
74
63
75
hw/misc/Makefile.objs | 1 +
64
Vikram Garhwal (1):
76
hw/xen/xen_pt.h | 2 +-
65
tests/qtest: xlnx-canfd-test: Fix code coverity issues
77
include/hw/arm/iotkit.h | 8 +
78
include/hw/arm/virt.h | 19 +
79
include/hw/intc/arm_gicv3_common.h | 8 +-
80
include/hw/misc/iotkit-secctl.h | 8 +
81
include/hw/misc/tz-mpc.h | 80 +++
82
include/standard-headers/linux/pci_regs.h | 8 +
83
include/standard-headers/linux/virtio_gpu.h | 1 +
84
include/standard-headers/linux/virtio_net.h | 3 +
85
linux-headers/asm-arm/kvm.h | 1 +
86
linux-headers/asm-arm/unistd-common.h | 1 +
87
linux-headers/asm-arm64/kvm.h | 1 +
88
linux-headers/asm-generic/unistd.h | 4 +-
89
linux-headers/asm-powerpc/unistd.h | 1 +
90
linux-headers/asm-x86/unistd_32.h | 2 +
91
linux-headers/asm-x86/unistd_64.h | 2 +
92
linux-headers/asm-x86/unistd_x32.h | 2 +
93
linux-headers/linux/kvm.h | 5 +-
94
linux-headers/linux/psp-sev.h | 12 +
95
target/arm/cpu.h | 1 +
96
target/arm/kvm_arm.h | 3 +-
97
hw/arm/iotkit.c | 112 +++-
98
hw/arm/mps2-tz.c | 71 ++-
99
hw/arm/virt-acpi-build.c | 30 +-
100
hw/arm/virt.c | 100 +++-
101
hw/arm/xlnx-zcu102.c | 2 +-
102
hw/arm/xlnx-zynqmp.c | 2 +-
103
hw/intc/arm_gic_kvm.c | 4 +-
104
hw/intc/arm_gicv3.c | 12 +-
105
hw/intc/arm_gicv3_common.c | 38 +-
106
hw/intc/arm_gicv3_dist.c | 3 +-
107
hw/intc/arm_gicv3_its_kvm.c | 2 +-
108
hw/intc/arm_gicv3_kvm.c | 44 +-
109
hw/intc/arm_gicv3_redist.c | 3 +-
110
hw/misc/iotkit-secctl.c | 38 +-
111
hw/misc/tz-mpc.c | 628 +++++++++++++++++++++
112
hw/xen/xen_pt_graphics.c | 2 +-
113
hw/xen/xen_pt_load_rom.c | 6 +-
114
target/arm/cpu.c | 12 +
115
target/arm/kvm.c | 11 +-
116
target/arm/translate.c | 45 +-
117
vl.c | 4 +-
118
MAINTAINERS | 2 +
119
default-configs/arm-softmmu.mak | 1 +
120
hw/misc/trace-events | 8 +
121
.../LICENSES/exceptions/Linux-syscall-note | 2 +-
122
linux-headers/LICENSES/preferred/GPL-2.0 | 6 +
123
48 files changed, 1250 insertions(+), 111 deletions(-)
124
create mode 100644 include/hw/misc/tz-mpc.h
125
create mode 100644 hw/misc/tz-mpc.c
126
66
67
Yuquan Wang (1):
68
hw/arm/sbsa-ref: use XHCI to replace EHCI
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
Deleted patch
1
From: Amol Surati <suratiamol@gmail.com>
2
1
3
When either GICD_IPRIORITYR or GICR_IPRIORITYR is read as a 32-bit
4
register, the post left-shift operator in the for loop causes an
5
extra shift after the least significant byte has been placed.
6
7
The 32-bit value actually returned is therefore the expected value
8
shifted left by 8 bits.
9
10
Signed-off-by: Amol Surati <suratiamol@gmail.com>
11
Message-id: 20180614054857.26248-1-suratiamol@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/intc/arm_gicv3_dist.c | 3 ++-
16
hw/intc/arm_gicv3_redist.c | 3 ++-
17
2 files changed, 4 insertions(+), 2 deletions(-)
18
19
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/intc/arm_gicv3_dist.c
22
+++ b/hw/intc/arm_gicv3_dist.c
23
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset,
24
int i, irq = offset - GICD_IPRIORITYR;
25
uint32_t value = 0;
26
27
- for (i = irq + 3; i >= irq; i--, value <<= 8) {
28
+ for (i = irq + 3; i >= irq; i--) {
29
+ value <<= 8;
30
value |= gicd_read_ipriorityr(s, attrs, i);
31
}
32
*data = value;
33
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/intc/arm_gicv3_redist.c
36
+++ b/hw/intc/arm_gicv3_redist.c
37
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset,
38
int i, irq = offset - GICR_IPRIORITYR;
39
uint32_t value = 0;
40
41
- for (i = irq + 3; i >= irq; i--, value <<= 8) {
42
+ for (i = irq + 3; i >= irq; i--) {
43
+ value <<= 8;
44
value |= gicr_read_ipriorityr(cs, attrs, i);
45
}
46
*data = value;
47
--
48
2.17.1
49
50
diff view generated by jsdifflib
Deleted patch
1
From: Julia Suvorova <jusual@mail.ru>
2
1
3
The arrays were made static, "if" was simplified because V7M and V8M
4
define V6 feature.
5
6
Signed-off-by: Julia Suvorova <jusual@mail.ru>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Message-id: 20180618214604.6777-1-jusual@mail.ru
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate.c | 27 +++++++++++++--------------
13
1 file changed, 13 insertions(+), 14 deletions(-)
14
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
18
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
20
!arm_dc_feature(s, ARM_FEATURE_V7)) {
21
int i;
22
bool found = false;
23
- const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
24
- 0xf3b08040 /* dsb */,
25
- 0xf3b08050 /* dmb */,
26
- 0xf3b08060 /* isb */,
27
- 0xf3e08000 /* mrs */,
28
- 0xf000d000 /* bl */};
29
- const uint32_t armv6m_mask[] = {0xffe0d000,
30
- 0xfff0d0f0,
31
- 0xfff0d0f0,
32
- 0xfff0d0f0,
33
- 0xffe0d000,
34
- 0xf800d000};
35
+ static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
36
+ 0xf3b08040 /* dsb */,
37
+ 0xf3b08050 /* dmb */,
38
+ 0xf3b08060 /* isb */,
39
+ 0xf3e08000 /* mrs */,
40
+ 0xf000d000 /* bl */};
41
+ static const uint32_t armv6m_mask[] = {0xffe0d000,
42
+ 0xfff0d0f0,
43
+ 0xfff0d0f0,
44
+ 0xfff0d0f0,
45
+ 0xffe0d000,
46
+ 0xf800d000};
47
48
for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
49
if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
50
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
51
break;
52
case 3: /* Special control operations. */
53
if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
54
- !(arm_dc_feature(s, ARM_FEATURE_V6) &&
55
- arm_dc_feature(s, ARM_FEATURE_M))) {
56
+ !arm_dc_feature(s, ARM_FEATURE_M)) {
57
goto illegal_op;
58
}
59
op = (insn >> 4) & 0xf;
60
--
61
2.17.1
62
63
diff view generated by jsdifflib
Deleted patch
1
From: Zheng Xiang <xiang.zheng@linaro.org>
2
1
3
The elements of kvm_devices_head list are freed in kvm_arm_machine_init_done(),
4
but we still access these illegal memory in kvm_arm_devlistener_del().
5
6
This will cause segment fault when booting guest with MALLOC_PERTURB_=1.
7
8
Signed-off-by: Zheng Xiang <xiang.zheng@linaro.org>
9
Message-id: 20180619075821.9884-1-zhengxiang9@huawei.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/kvm.c | 1 +
14
1 file changed, 1 insertion(+)
15
16
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/kvm.c
19
+++ b/target/arm/kvm.c
20
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_machine_init_done(Notifier *notifier, void *data)
21
kvm_arm_set_device_addr(kd);
22
}
23
memory_region_unref(kd->mr);
24
+ QSLIST_REMOVE_HEAD(&kvm_devices_head, entries);
25
g_free(kd);
26
}
27
memory_listener_unregister(&devlistener);
28
--
29
2.17.1
30
31
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
Update our kernel headers to mainline commit
3
Some registers whose 'cooked' writefns induce TLB maintenance do
4
b357bf6023a948cf6a9472f07a1b0caac0e4f8e8
4
not have raw_writefn ops defined. If only the writefn ops is set
5
("Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm")
5
(ie. no raw_writefn is provided), it is assumed the cooked also
6
work as the raw one. For those registers it is not obvious the
7
tlb_flush works on KVM mode so better/safer setting the raw write.
6
8
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 1529072910-16156-2-git-send-email-eric.auger@redhat.com
10
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
9
[PMM: clarified commit message]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
include/standard-headers/linux/pci_regs.h | 8 ++++++++
14
target/arm/helper.c | 23 +++++++++++++----------
13
include/standard-headers/linux/virtio_gpu.h | 1 +
15
1 file changed, 13 insertions(+), 10 deletions(-)
14
include/standard-headers/linux/virtio_net.h | 3 +++
15
linux-headers/asm-arm/kvm.h | 1 +
16
linux-headers/asm-arm/unistd-common.h | 1 +
17
linux-headers/asm-arm64/kvm.h | 1 +
18
linux-headers/asm-generic/unistd.h | 4 +++-
19
linux-headers/asm-powerpc/unistd.h | 1 +
20
linux-headers/asm-x86/unistd_32.h | 2 ++
21
linux-headers/asm-x86/unistd_64.h | 2 ++
22
linux-headers/asm-x86/unistd_x32.h | 2 ++
23
linux-headers/linux/kvm.h | 5 +++--
24
linux-headers/linux/psp-sev.h | 12 ++++++++++++
25
linux-headers/LICENSES/exceptions/Linux-syscall-note | 2 +-
26
linux-headers/LICENSES/preferred/GPL-2.0 | 6 ++++++
27
15 files changed, 47 insertions(+), 4 deletions(-)
28
16
29
diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/include/standard-headers/linux/pci_regs.h
19
--- a/target/arm/helper.c
32
+++ b/include/standard-headers/linux/pci_regs.h
20
+++ b/target/arm/helper.c
33
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
34
#define PCI_EXP_DEVCTL_READRQ_256B 0x1000 /* 256 Bytes */
22
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 0,
35
#define PCI_EXP_DEVCTL_READRQ_512B 0x2000 /* 512 Bytes */
23
.access = PL1_RW, .accessfn = access_tvm_trvm,
36
#define PCI_EXP_DEVCTL_READRQ_1024B 0x3000 /* 1024 Bytes */
24
.fgt = FGT_TTBR0_EL1,
37
+#define PCI_EXP_DEVCTL_READRQ_2048B 0x4000 /* 2048 Bytes */
25
- .writefn = vmsa_ttbr_write, .resetvalue = 0,
38
+#define PCI_EXP_DEVCTL_READRQ_4096B 0x5000 /* 4096 Bytes */
26
+ .writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
39
#define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */
27
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
40
#define PCI_EXP_DEVSTA        10    /* Device Status */
28
offsetof(CPUARMState, cp15.ttbr0_ns) } },
41
#define PCI_EXP_DEVSTA_CED    0x0001    /* Correctable Error Detected */
29
{ .name = "TTBR1_EL1", .state = ARM_CP_STATE_BOTH,
42
@@ -XXX,XX +XXX,XX @@
30
.opc0 = 3, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 1,
43
#define PCI_EXP_LNKCAP2_SLS_16_0GB    0x00000010 /* Supported Speed 16GT/s */
31
.access = PL1_RW, .accessfn = access_tvm_trvm,
44
#define PCI_EXP_LNKCAP2_CROSSLINK    0x00000100 /* Crosslink supported */
32
.fgt = FGT_TTBR1_EL1,
45
#define PCI_EXP_LNKCTL2        48    /* Link Control 2 */
33
- .writefn = vmsa_ttbr_write, .resetvalue = 0,
46
+#define PCI_EXP_LNKCTL2_TLS        0x000f
34
+ .writefn = vmsa_ttbr_write, .resetvalue = 0, .raw_writefn = raw_write,
47
+#define PCI_EXP_LNKCTL2_TLS_2_5GT    0x0001 /* Supported Speed 2.5GT/s */
35
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
48
+#define PCI_EXP_LNKCTL2_TLS_5_0GT    0x0002 /* Supported Speed 5GT/s */
36
offsetof(CPUARMState, cp15.ttbr1_ns) } },
49
+#define PCI_EXP_LNKCTL2_TLS_8_0GT    0x0003 /* Supported Speed 8GT/s */
37
{ .name = "TCR_EL1", .state = ARM_CP_STATE_AA64,
50
+#define PCI_EXP_LNKCTL2_TLS_16_0GT    0x0004 /* Supported Speed 16GT/s */
38
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lpae_cp_reginfo[] = {
51
#define PCI_EXP_LNKSTA2        50    /* Link Status 2 */
39
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
52
#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2    52    /* v2 endpoints with link end here */
40
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr0_s),
53
#define PCI_EXP_SLTCAP2        52    /* Slot Capabilities 2 */
41
offsetof(CPUARMState, cp15.ttbr0_ns) },
54
@@ -XXX,XX +XXX,XX @@
42
- .writefn = vmsa_ttbr_write, },
55
#define PCI_EXP_DPC_CAP_DL_ACTIVE    0x1000    /* ERR_COR signal on DL_Active supported */
43
+ .writefn = vmsa_ttbr_write, .raw_writefn = raw_write },
56
44
{ .name = "TTBR1", .cp = 15, .crm = 2, .opc1 = 1,
57
#define PCI_EXP_DPC_CTL            6    /* DPC control */
45
.access = PL1_RW, .accessfn = access_tvm_trvm,
58
+#define PCI_EXP_DPC_CTL_EN_FATAL     0x0001    /* Enable trigger on ERR_FATAL message */
46
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
59
#define PCI_EXP_DPC_CTL_EN_NONFATAL     0x0002    /* Enable trigger on ERR_NONFATAL message */
47
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ttbr1_s),
60
#define PCI_EXP_DPC_CTL_INT_EN     0x0008    /* DPC Interrupt Enable */
48
offsetof(CPUARMState, cp15.ttbr1_ns) },
61
49
- .writefn = vmsa_ttbr_write, },
62
diff --git a/include/standard-headers/linux/virtio_gpu.h b/include/standard-headers/linux/virtio_gpu.h
50
+ .writefn = vmsa_ttbr_write, .raw_writefn = raw_write },
63
index XXXXXXX..XXXXXXX 100644
64
--- a/include/standard-headers/linux/virtio_gpu.h
65
+++ b/include/standard-headers/linux/virtio_gpu.h
66
@@ -XXX,XX +XXX,XX @@ struct virtio_gpu_cmd_submit {
67
};
51
};
68
52
69
#define VIRTIO_GPU_CAPSET_VIRGL 1
53
static uint64_t aa64_fpcr_read(CPUARMState *env, const ARMCPRegInfo *ri)
70
+#define VIRTIO_GPU_CAPSET_VIRGL2 2
54
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
71
55
.type = ARM_CP_IO,
72
/* VIRTIO_GPU_CMD_GET_CAPSET_INFO */
56
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
73
struct virtio_gpu_get_capset_info {
57
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
74
diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h
58
- .writefn = hcr_write },
75
index XXXXXXX..XXXXXXX 100644
59
+ .writefn = hcr_write, .raw_writefn = raw_write },
76
--- a/include/standard-headers/linux/virtio_net.h
60
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
77
+++ b/include/standard-headers/linux/virtio_net.h
61
.type = ARM_CP_ALIAS | ARM_CP_IO,
78
@@ -XXX,XX +XXX,XX @@
62
.cp = 15, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
79
                     * Steering */
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
80
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23    /* Set MAC address */
64
{ .name = "TCR_EL2", .state = ARM_CP_STATE_BOTH,
81
65
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 2,
82
+#define VIRTIO_NET_F_STANDBY     62    /* Act as standby for another device
66
.access = PL2_RW, .writefn = vmsa_tcr_el12_write,
83
+                     * with the same MAC.
67
+ .raw_writefn = raw_write,
84
+                     */
68
.fieldoffset = offsetof(CPUARMState, cp15.tcr_el[2]) },
85
#define VIRTIO_NET_F_SPEED_DUPLEX 63    /* Device set linkspeed and duplex */
69
{ .name = "VTCR", .state = ARM_CP_STATE_AA32,
86
70
.cp = 15, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 2,
87
#ifndef VIRTIO_NET_NO_LEGACY
71
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
88
diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
72
.type = ARM_CP_64BIT | ARM_CP_ALIAS,
89
index XXXXXXX..XXXXXXX 100644
73
.access = PL2_RW, .accessfn = access_el3_aa32ns,
90
--- a/linux-headers/asm-arm/kvm.h
74
.fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2),
91
+++ b/linux-headers/asm-arm/kvm.h
75
- .writefn = vttbr_write },
92
@@ -XXX,XX +XXX,XX @@ struct kvm_regs {
76
+ .writefn = vttbr_write, .raw_writefn = raw_write },
93
#define KVM_VGIC_V3_ADDR_TYPE_DIST    2
77
{ .name = "VTTBR_EL2", .state = ARM_CP_STATE_AA64,
94
#define KVM_VGIC_V3_ADDR_TYPE_REDIST    3
78
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 1, .opc2 = 0,
95
#define KVM_VGIC_ITS_ADDR_TYPE        4
79
- .access = PL2_RW, .writefn = vttbr_write,
96
+#define KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION    5
80
+ .access = PL2_RW, .writefn = vttbr_write, .raw_writefn = raw_write,
97
81
.fieldoffset = offsetof(CPUARMState, cp15.vttbr_el2) },
98
#define KVM_VGIC_V3_DIST_SIZE        SZ_64K
82
{ .name = "SCTLR_EL2", .state = ARM_CP_STATE_BOTH,
99
#define KVM_VGIC_V3_REDIST_SIZE        (2 * SZ_64K)
83
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 0, .opc2 = 0,
100
diff --git a/linux-headers/asm-arm/unistd-common.h b/linux-headers/asm-arm/unistd-common.h
84
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
101
index XXXXXXX..XXXXXXX 100644
85
.fieldoffset = offsetof(CPUARMState, cp15.tpidr_el[2]) },
102
--- a/linux-headers/asm-arm/unistd-common.h
86
{ .name = "TTBR0_EL2", .state = ARM_CP_STATE_AA64,
103
+++ b/linux-headers/asm-arm/unistd-common.h
87
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
104
@@ -XXX,XX +XXX,XX @@
88
- .access = PL2_RW, .resetvalue = 0, .writefn = vmsa_tcr_ttbr_el2_write,
105
#define __NR_pkey_alloc (__NR_SYSCALL_BASE + 395)
89
+ .access = PL2_RW, .resetvalue = 0,
106
#define __NR_pkey_free (__NR_SYSCALL_BASE + 396)
90
+ .writefn = vmsa_tcr_ttbr_el2_write, .raw_writefn = raw_write,
107
#define __NR_statx (__NR_SYSCALL_BASE + 397)
91
.fieldoffset = offsetof(CPUARMState, cp15.ttbr0_el[2]) },
108
+#define __NR_rseq (__NR_SYSCALL_BASE + 398)
92
{ .name = "HTTBR", .cp = 15, .opc1 = 4, .crm = 2,
109
93
.access = PL2_RW, .type = ARM_CP_64BIT | ARM_CP_ALIAS,
110
#endif /* _ASM_ARM_UNISTD_COMMON_H */
94
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
111
diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
95
{ .name = "SCR_EL3", .state = ARM_CP_STATE_AA64,
112
index XXXXXXX..XXXXXXX 100644
96
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
113
--- a/linux-headers/asm-arm64/kvm.h
97
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
114
+++ b/linux-headers/asm-arm64/kvm.h
98
- .resetfn = scr_reset, .writefn = scr_write },
115
@@ -XXX,XX +XXX,XX @@ struct kvm_regs {
99
+ .resetfn = scr_reset, .writefn = scr_write, .raw_writefn = raw_write },
116
#define KVM_VGIC_V3_ADDR_TYPE_DIST    2
100
{ .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
117
#define KVM_VGIC_V3_ADDR_TYPE_REDIST    3
101
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
118
#define KVM_VGIC_ITS_ADDR_TYPE        4
102
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
119
+#define KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION    5
103
.fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
120
104
- .writefn = scr_write },
121
#define KVM_VGIC_V3_DIST_SIZE        SZ_64K
105
+ .writefn = scr_write, .raw_writefn = raw_write },
122
#define KVM_VGIC_V3_REDIST_SIZE        (2 * SZ_64K)
106
{ .name = "SDER32_EL3", .state = ARM_CP_STATE_AA64,
123
diff --git a/linux-headers/asm-generic/unistd.h b/linux-headers/asm-generic/unistd.h
107
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 1,
124
index XXXXXXX..XXXXXXX 100644
108
.access = PL3_RW, .resetvalue = 0,
125
--- a/linux-headers/asm-generic/unistd.h
109
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
126
+++ b/linux-headers/asm-generic/unistd.h
110
{ .name = "TTBR1_EL2", .state = ARM_CP_STATE_AA64,
127
@@ -XXX,XX +XXX,XX @@ __SYSCALL(__NR_pkey_alloc, sys_pkey_alloc)
111
.opc0 = 3, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 1,
128
__SYSCALL(__NR_pkey_free, sys_pkey_free)
112
.access = PL2_RW, .writefn = vmsa_tcr_ttbr_el2_write,
129
#define __NR_statx 291
113
+ .raw_writefn = raw_write,
130
__SYSCALL(__NR_statx, sys_statx)
114
.fieldoffset = offsetof(CPUARMState, cp15.ttbr1_el[2]) },
131
+#define __NR_io_pgetevents 292
115
#ifndef CONFIG_USER_ONLY
132
+__SC_COMP(__NR_io_pgetevents, sys_io_pgetevents, compat_sys_io_pgetevents)
116
{ .name = "CNTHV_CVAL_EL2", .state = ARM_CP_STATE_AA64,
133
134
#undef __NR_syscalls
135
-#define __NR_syscalls 292
136
+#define __NR_syscalls 293
137
138
/*
139
* 32 bit systems traditionally used different
140
diff --git a/linux-headers/asm-powerpc/unistd.h b/linux-headers/asm-powerpc/unistd.h
141
index XXXXXXX..XXXXXXX 100644
142
--- a/linux-headers/asm-powerpc/unistd.h
143
+++ b/linux-headers/asm-powerpc/unistd.h
144
@@ -XXX,XX +XXX,XX @@
145
#define __NR_pkey_alloc        384
146
#define __NR_pkey_free        385
147
#define __NR_pkey_mprotect    386
148
+#define __NR_rseq        387
149
150
#endif /* _ASM_POWERPC_UNISTD_H_ */
151
diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h
152
index XXXXXXX..XXXXXXX 100644
153
--- a/linux-headers/asm-x86/unistd_32.h
154
+++ b/linux-headers/asm-x86/unistd_32.h
155
@@ -XXX,XX +XXX,XX @@
156
#define __NR_pkey_free 382
157
#define __NR_statx 383
158
#define __NR_arch_prctl 384
159
+#define __NR_io_pgetevents 385
160
+#define __NR_rseq 386
161
162
#endif /* _ASM_X86_UNISTD_32_H */
163
diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h
164
index XXXXXXX..XXXXXXX 100644
165
--- a/linux-headers/asm-x86/unistd_64.h
166
+++ b/linux-headers/asm-x86/unistd_64.h
167
@@ -XXX,XX +XXX,XX @@
168
#define __NR_pkey_alloc 330
169
#define __NR_pkey_free 331
170
#define __NR_statx 332
171
+#define __NR_io_pgetevents 333
172
+#define __NR_rseq 334
173
174
#endif /* _ASM_X86_UNISTD_64_H */
175
diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h
176
index XXXXXXX..XXXXXXX 100644
177
--- a/linux-headers/asm-x86/unistd_x32.h
178
+++ b/linux-headers/asm-x86/unistd_x32.h
179
@@ -XXX,XX +XXX,XX @@
180
#define __NR_pkey_alloc (__X32_SYSCALL_BIT + 330)
181
#define __NR_pkey_free (__X32_SYSCALL_BIT + 331)
182
#define __NR_statx (__X32_SYSCALL_BIT + 332)
183
+#define __NR_io_pgetevents (__X32_SYSCALL_BIT + 333)
184
+#define __NR_rseq (__X32_SYSCALL_BIT + 334)
185
#define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512)
186
#define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513)
187
#define __NR_ioctl (__X32_SYSCALL_BIT + 514)
188
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
189
index XXXXXXX..XXXXXXX 100644
190
--- a/linux-headers/linux/kvm.h
191
+++ b/linux-headers/linux/kvm.h
192
@@ -XXX,XX +XXX,XX @@ struct kvm_ioeventfd {
193
};
194
195
#define KVM_X86_DISABLE_EXITS_MWAIT (1 << 0)
196
-#define KVM_X86_DISABLE_EXITS_HTL (1 << 1)
197
+#define KVM_X86_DISABLE_EXITS_HLT (1 << 1)
198
#define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2)
199
#define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \
200
- KVM_X86_DISABLE_EXITS_HTL | \
201
+ KVM_X86_DISABLE_EXITS_HLT | \
202
KVM_X86_DISABLE_EXITS_PAUSE)
203
204
/* for KVM_ENABLE_CAP */
205
@@ -XXX,XX +XXX,XX @@ struct kvm_ppc_resize_hpt {
206
#define KVM_CAP_S390_BPB 152
207
#define KVM_CAP_GET_MSR_FEATURES 153
208
#define KVM_CAP_HYPERV_EVENTFD 154
209
+#define KVM_CAP_HYPERV_TLBFLUSH 155
210
211
#ifdef KVM_CAP_IRQ_ROUTING
212
213
diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h
214
index XXXXXXX..XXXXXXX 100644
215
--- a/linux-headers/linux/psp-sev.h
216
+++ b/linux-headers/linux/psp-sev.h
217
@@ -XXX,XX +XXX,XX @@ enum {
218
    SEV_PDH_GEN,
219
    SEV_PDH_CERT_EXPORT,
220
    SEV_PEK_CERT_IMPORT,
221
+    SEV_GET_ID,
222
223
    SEV_MAX,
224
};
225
@@ -XXX,XX +XXX,XX @@ struct sev_user_data_pdh_cert_export {
226
    __u32 cert_chain_len;            /* In/Out */
227
} __attribute__((packed));
228
229
+/**
230
+ * struct sev_user_data_get_id - GET_ID command parameters
231
+ *
232
+ * @socket1: Buffer to pass unique ID of first socket
233
+ * @socket2: Buffer to pass unique ID of second socket
234
+ */
235
+struct sev_user_data_get_id {
236
+    __u8 socket1[64];            /* Out */
237
+    __u8 socket2[64];            /* Out */
238
+} __attribute__((packed));
239
+
240
/**
241
* struct sev_issue_cmd - SEV ioctl parameters
242
*
243
diff --git a/linux-headers/LICENSES/exceptions/Linux-syscall-note b/linux-headers/LICENSES/exceptions/Linux-syscall-note
244
index XXXXXXX..XXXXXXX 100644
245
--- a/linux-headers/LICENSES/exceptions/Linux-syscall-note
246
+++ b/linux-headers/LICENSES/exceptions/Linux-syscall-note
247
@@ -XXX,XX +XXX,XX @@
248
SPDX-Exception-Identifier: Linux-syscall-note
249
SPDX-URL: https://spdx.org/licenses/Linux-syscall-note.html
250
-SPDX-Licenses: GPL-2.0, GPL-2.0+, GPL-1.0+, LGPL-2.0, LGPL-2.0+, LGPL-2.1, LGPL-2.1+
251
+SPDX-Licenses: GPL-2.0, GPL-2.0+, GPL-1.0+, LGPL-2.0, LGPL-2.0+, LGPL-2.1, LGPL-2.1+, GPL-2.0-only, GPL-2.0-or-later
252
Usage-Guide:
253
This exception is used together with one of the above SPDX-Licenses
254
to mark user space API (uapi) header files so they can be included
255
diff --git a/linux-headers/LICENSES/preferred/GPL-2.0 b/linux-headers/LICENSES/preferred/GPL-2.0
256
index XXXXXXX..XXXXXXX 100644
257
--- a/linux-headers/LICENSES/preferred/GPL-2.0
258
+++ b/linux-headers/LICENSES/preferred/GPL-2.0
259
@@ -XXX,XX +XXX,XX @@
260
Valid-License-Identifier: GPL-2.0
261
+Valid-License-Identifier: GPL-2.0-only
262
Valid-License-Identifier: GPL-2.0+
263
+Valid-License-Identifier: GPL-2.0-or-later
264
SPDX-URL: https://spdx.org/licenses/GPL-2.0.html
265
Usage-Guide:
266
To use this license in source code, put one of the following SPDX
267
@@ -XXX,XX +XXX,XX @@ Usage-Guide:
268
guidelines in the licensing rules documentation.
269
For 'GNU General Public License (GPL) version 2 only' use:
270
SPDX-License-Identifier: GPL-2.0
271
+ or
272
+ SPDX-License-Identifier: GPL-2.0-only
273
For 'GNU General Public License (GPL) version 2 or any later version' use:
274
SPDX-License-Identifier: GPL-2.0+
275
+ or
276
+ SPDX-License-Identifier: GPL-2.0-or-later
277
License-Text:
278
279
         GNU GENERAL PUBLIC LICENSE
280
--
117
--
281
2.17.1
118
2.34.1
282
283
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
for KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION attribute, the attribute
4
data pointed to by kvm_device_attr.addr is a OR of the
5
redistributor region address and other fields such as the index
6
of the redistributor region and the number of redistributors the
7
region can contain.
8
9
The existing machine init done notifier framework sets the address
10
field to the actual address of the device and does not allow to OR
11
this value with other fields.
12
13
This patch extends the KVMDevice struct with a new kda_addr_ormask
14
member. Its value is passed at registration time and OR'ed with the
15
resolved address on kvm_arm_set_device_addr().
16
17
Signed-off-by: Eric Auger <eric.auger@redhat.com>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Message-id: 1529072910-16156-3-git-send-email-eric.auger@redhat.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
target/arm/kvm_arm.h | 3 ++-
23
hw/intc/arm_gic_kvm.c | 4 ++--
24
hw/intc/arm_gicv3_its_kvm.c | 2 +-
25
hw/intc/arm_gicv3_kvm.c | 4 ++--
26
target/arm/kvm.c | 10 +++++++++-
27
5 files changed, 16 insertions(+), 7 deletions(-)
28
29
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/kvm_arm.h
32
+++ b/target/arm/kvm_arm.h
33
@@ -XXX,XX +XXX,XX @@ int kvm_arm_vcpu_init(CPUState *cs);
34
* @group: device control API group for setting addresses
35
* @attr: device control API address type
36
* @dev_fd: device control device file descriptor (or -1 if not supported)
37
+ * @addr_ormask: value to be OR'ed with resolved address
38
*
39
* Remember the memory region @mr, and when it is mapped by the
40
* machine model, tell the kernel that base address using the
41
@@ -XXX,XX +XXX,XX @@ int kvm_arm_vcpu_init(CPUState *cs);
42
* address at the point where machine init is complete.
43
*/
44
void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
45
- uint64_t attr, int dev_fd);
46
+ uint64_t attr, int dev_fd, uint64_t addr_ormask);
47
48
/**
49
* kvm_arm_init_cpreg_list:
50
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/intc/arm_gic_kvm.c
53
+++ b/hw/intc/arm_gic_kvm.c
54
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
55
| KVM_VGIC_V2_ADDR_TYPE_DIST,
56
KVM_DEV_ARM_VGIC_GRP_ADDR,
57
KVM_VGIC_V2_ADDR_TYPE_DIST,
58
- s->dev_fd);
59
+ s->dev_fd, 0);
60
/* CPU interface for current core. Unlike arm_gic, we don't
61
* provide the "interface for core #N" memory regions, because
62
* cores with a VGIC don't have those.
63
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
64
| KVM_VGIC_V2_ADDR_TYPE_CPU,
65
KVM_DEV_ARM_VGIC_GRP_ADDR,
66
KVM_VGIC_V2_ADDR_TYPE_CPU,
67
- s->dev_fd);
68
+ s->dev_fd, 0);
69
70
if (kvm_has_gsi_routing()) {
71
/* set up irq routing */
72
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/intc/arm_gicv3_its_kvm.c
75
+++ b/hw/intc/arm_gicv3_its_kvm.c
76
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
77
78
/* register the base address */
79
kvm_arm_register_device(&s->iomem_its_cntrl, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
80
- KVM_VGIC_ITS_ADDR_TYPE, s->dev_fd);
81
+ KVM_VGIC_ITS_ADDR_TYPE, s->dev_fd, 0);
82
83
gicv3_its_init_mmio(s, NULL);
84
85
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/intc/arm_gicv3_kvm.c
88
+++ b/hw/intc/arm_gicv3_kvm.c
89
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
90
KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true, &error_abort);
91
92
kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
93
- KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd);
94
+ KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd, 0);
95
kvm_arm_register_device(&s->iomem_redist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
96
- KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd);
97
+ KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd, 0);
98
99
if (kvm_has_gsi_routing()) {
100
/* set up irq routing */
101
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/arm/kvm.c
104
+++ b/target/arm/kvm.c
105
@@ -XXX,XX +XXX,XX @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
106
* We use a MemoryListener to track mapping and unmapping of
107
* the regions during board creation, so the board models don't
108
* need to do anything special for the KVM case.
109
+ *
110
+ * Sometimes the address must be OR'ed with some other fields
111
+ * (for example for KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION).
112
+ * @kda_addr_ormask aims at storing the value of those fields.
113
*/
114
typedef struct KVMDevice {
115
struct kvm_arm_device_addr kda;
116
struct kvm_device_attr kdattr;
117
+ uint64_t kda_addr_ormask;
118
MemoryRegion *mr;
119
QSLIST_ENTRY(KVMDevice) entries;
120
int dev_fd;
121
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_set_device_addr(KVMDevice *kd)
122
*/
123
if (kd->dev_fd >= 0) {
124
uint64_t addr = kd->kda.addr;
125
+
126
+ addr |= kd->kda_addr_ormask;
127
attr->addr = (uintptr_t)&addr;
128
ret = kvm_device_ioctl(kd->dev_fd, KVM_SET_DEVICE_ATTR, attr);
129
} else {
130
@@ -XXX,XX +XXX,XX @@ static Notifier notify = {
131
};
132
133
void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
134
- uint64_t attr, int dev_fd)
135
+ uint64_t attr, int dev_fd, uint64_t addr_ormask)
136
{
137
KVMDevice *kd;
138
139
@@ -XXX,XX +XXX,XX @@ void kvm_arm_register_device(MemoryRegion *mr, uint64_t devid, uint64_t group,
140
kd->kdattr.group = group;
141
kd->kdattr.attr = attr;
142
kd->dev_fd = dev_fd;
143
+ kd->kda_addr_ormask = addr_ormask;
144
QSLIST_INSERT_HEAD(&kvm_devices_head, kd, entries);
145
memory_region_ref(kd->mr);
146
}
147
--
148
2.17.1
149
150
diff view generated by jsdifflib
1
The xen pci_assign_dev_load_option_rom() currently creates a RAM
1
From: Yuquan Wang <wangyuquan1236@phytium.com.cn>
2
memory region with memory_region_init_ram_nomigrate(), and then
3
manually registers it with vmstate_register_ram(). In fact for
4
its only callsite, the 'owner' pointer we use for the init call
5
and the '&dev->qdev' pointer we use for the vmstate_register_ram()
6
call refer to the same object. Simplify the function to only
7
take a pointer to the device once instead of twice, and use
8
memory_region_init_ram() which automatically does the vmstate
9
register for us.
10
2
11
Acked-by: Anthony PERARD <anthony.perard@citrix.com>
3
The current sbsa-ref cannot use EHCI controller which is only
4
able to do 32-bit DMA, since sbsa-ref doesn't have RAM below 4GB.
5
Hence, this uses XHCI to provide a usb controller with 64-bit
6
DMA capablity instead of EHCI.
7
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.
16
17
Signed-off-by: Yuquan Wang <wangyuquan1236@phytium.com.cn>
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]
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
23
---
14
hw/xen/xen_pt.h | 2 +-
24
docs/system/arm/sbsa.rst | 5 ++++-
15
hw/xen/xen_pt_graphics.c | 2 +-
25
hw/arm/sbsa-ref.c | 23 +++++++++++++----------
16
hw/xen/xen_pt_load_rom.c | 6 +++---
26
hw/arm/Kconfig | 2 +-
17
3 files changed, 5 insertions(+), 5 deletions(-)
27
3 files changed, 18 insertions(+), 12 deletions(-)
18
28
19
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
29
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
20
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/xen/xen_pt.h
31
--- a/docs/system/arm/sbsa.rst
22
+++ b/hw/xen/xen_pt.h
32
+++ b/docs/system/arm/sbsa.rst
23
@@ -XXX,XX +XXX,XX @@ static inline bool xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar)
33
@@ -XXX,XX +XXX,XX @@ The ``sbsa-ref`` board supports:
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,
67
};
68
69
struct SBSAMachineState {
70
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
71
[SBSA_SMMU] = { 0x60050000, 0x00020000 },
72
/* Space here reserved for more SMMUs */
73
[SBSA_AHCI] = { 0x60100000, 0x00010000 },
74
- [SBSA_EHCI] = { 0x60110000, 0x00010000 },
75
+ [SBSA_XHCI] = { 0x60110000, 0x00010000 },
76
/* Space here reserved for other devices */
77
[SBSA_PCIE_PIO] = { 0x7fff0000, 0x00010000 },
78
/* 32-bit address PCIE MMIO space */
79
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
80
[SBSA_SECURE_UART] = 8,
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)
98
}
24
}
99
}
25
100
26
extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
101
-static void create_ehci(const SBSAMachineState *sms)
27
- struct Object *owner, int *size,
102
+static void create_xhci(const SBSAMachineState *sms)
28
+ int *size,
103
{
29
unsigned int domain,
104
- hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
30
unsigned int bus, unsigned int slot,
105
- int irq = sbsa_ref_irqmap[SBSA_EHCI];
31
unsigned int function);
106
+ hwaddr base = sbsa_ref_memmap[SBSA_XHCI].base;
32
diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c
107
+ int irq = sbsa_ref_irqmap[SBSA_XHCI];
108
+ DeviceState *dev = qdev_new(TYPE_XHCI_SYSBUS);
109
110
- sysbus_create_simple("platform-ehci-usb", base,
111
- qdev_get_gpio_in(sms->gic, irq));
112
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
113
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
114
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
115
}
116
117
static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
118
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
119
120
create_ahci(sms);
121
122
- create_ehci(sms);
123
+ create_xhci(sms);
124
125
create_pcie(sms);
126
127
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
33
index XXXXXXX..XXXXXXX 100644
128
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/xen/xen_pt_graphics.c
129
--- a/hw/arm/Kconfig
35
+++ b/hw/xen/xen_pt_graphics.c
130
+++ b/hw/arm/Kconfig
36
@@ -XXX,XX +XXX,XX @@ int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)
131
@@ -XXX,XX +XXX,XX @@ config SBSA_REF
37
static void *get_vgabios(XenPCIPassthroughState *s, int *size,
132
select PL011 # UART
38
XenHostPCIDevice *dev)
133
select PL031 # RTC
39
{
134
select PL061 # GPIO
40
- return pci_assign_dev_load_option_rom(&s->dev, OBJECT(&s->dev), size,
135
- select USB_EHCI_SYSBUS
41
+ return pci_assign_dev_load_option_rom(&s->dev, size,
136
+ select USB_XHCI_SYSBUS
42
dev->domain, dev->bus,
137
select WDT_SBSA
43
dev->dev, dev->func);
138
select BOCHS_DISPLAY
44
}
45
diff --git a/hw/xen/xen_pt_load_rom.c b/hw/xen/xen_pt_load_rom.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/xen/xen_pt_load_rom.c
48
+++ b/hw/xen/xen_pt_load_rom.c
49
@@ -XXX,XX +XXX,XX @@
50
* load the corresponding ROM data to RAM. If an error occurs while loading an
51
* option ROM, we just ignore that option ROM and continue with the next one.
52
*/
53
-void *pci_assign_dev_load_option_rom(PCIDevice *dev, struct Object *owner,
54
+void *pci_assign_dev_load_option_rom(PCIDevice *dev,
55
int *size, unsigned int domain,
56
unsigned int bus, unsigned int slot,
57
unsigned int function)
58
@@ -XXX,XX +XXX,XX @@ void *pci_assign_dev_load_option_rom(PCIDevice *dev, struct Object *owner,
59
uint8_t val;
60
struct stat st;
61
void *ptr = NULL;
62
+ Object *owner = OBJECT(dev);
63
64
/* If loading ROM from file, pci handles it */
65
if (dev->romfile || !dev->rom_bar) {
66
@@ -XXX,XX +XXX,XX @@ void *pci_assign_dev_load_option_rom(PCIDevice *dev, struct Object *owner,
67
fseek(fp, 0, SEEK_SET);
68
69
snprintf(name, sizeof(name), "%s.rom", object_get_typename(owner));
70
- memory_region_init_ram_nomigrate(&dev->rom, owner, name, st.st_size, &error_abort);
71
- vmstate_register_ram(&dev->rom, &dev->qdev);
72
+ memory_region_init_ram(&dev->rom, owner, name, st.st_size, &error_abort);
73
ptr = memory_region_get_ram_ptr(&dev->rom);
74
memset(ptr, 0xff, st.st_size);
75
139
76
--
140
--
77
2.17.1
141
2.34.1
78
79
diff view generated by jsdifflib
1
checkpatch reminds us that statics shouldn't be zero-initialized:
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
ERROR: do not initialise statics to 0 or NULL
5
/tmp/ccASXpLo.s:782: Error: selected processor does not support system register name 'id_aa64zfr0_el1'
4
#35: FILE: vl.c:157:
6
/tmp/ccASXpLo.s:829: Error: selected processor does not support system register name 'id_aa64smfr0_el1'
5
+static int num_serial_hds = 0;
6
7
7
ERROR: do not initialise statics to 0 or NULL
8
However, these registers are in the ID space and are guaranteed to
8
#36: FILE: vl.c:158:
9
read-as-zero on older CPUs, so the access is both safe and sensible.
9
+static Chardev **serial_hds = NULL;
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.
10
15
11
I forgot to fix this in 6af2692e86f9fdfb3d; do so now.
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).
12
22
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Thomas Huth <thuth@redhat.com>
15
Message-id: 20180426140253.3918-1-peter.maydell@linaro.org
16
---
24
---
17
vl.c | 4 ++--
25
tests/tcg/aarch64/sysregs.c | 11 +++++++----
18
1 file changed, 2 insertions(+), 2 deletions(-)
26
tests/tcg/aarch64/Makefile.target | 7 +------
27
2 files changed, 8 insertions(+), 10 deletions(-)
19
28
20
diff --git a/vl.c b/vl.c
29
diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c
21
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
22
--- a/vl.c
31
--- a/tests/tcg/aarch64/sysregs.c
23
+++ b/vl.c
32
+++ b/tests/tcg/aarch64/sysregs.c
24
@@ -XXX,XX +XXX,XX @@ QEMUClockType rtc_clock;
33
@@ -XXX,XX +XXX,XX @@
25
int vga_interface_type = VGA_NONE;
34
/*
26
static DisplayOptions dpy;
35
* Older assemblers don't recognize newer system register names,
27
int no_frame;
36
* but we can still access them by the Sn_n_Cn_Cn_n syntax.
28
-static int num_serial_hds = 0;
37
+ * This also means we don't need to specifically request that the
29
-static Chardev **serial_hds = NULL;
38
+ * assembler enables whatever architectural features the ID registers
30
+static int num_serial_hds;
39
+ * syntax might be gated behind.
31
+static Chardev **serial_hds;
40
*/
32
Chardev *parallel_hds[MAX_PARALLEL_PORTS];
41
#define SYS_ID_AA64ISAR2_EL1 S3_0_C0_C6_2
33
Chardev *virtcon_hds[MAX_VIRTIO_CONSOLES];
42
#define SYS_ID_AA64MMFR2_EL1 S3_0_C0_C7_2
34
int win2k_install_hack = 0;
43
+#define SYS_ID_AA64ZFR0_EL1 S3_0_C0_C4_4
44
+#define SYS_ID_AA64SMFR0_EL1 S3_0_C0_C4_5
45
46
int failed_bit_count;
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
35
--
82
--
36
2.17.1
83
2.34.1
37
38
diff view generated by jsdifflib
1
From: Julia Suvorova <jusual@mail.ru>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This feature is intended to distinguish ARMv8-M variants: Baseline and
3
Allow the line length to extend to 548 columns. While annoyingly wide,
4
Mainline. ARMv7-M compatibility requires the Main Extension. ARMv6-M
4
it's still less confusing than the continuations we print. Also, the
5
compatibility is provided by all ARMv8-M implementations.
5
default VL used by Linux (and max for A64FX) uses only 140 columns.
6
6
7
Signed-off-by: Julia Suvorova <jusual@mail.ru>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180622080138.17702-2-jusual@mail.ru
8
Message-id: 20230622151201.1578522-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
target/arm/cpu.h | 1 +
12
target/arm/cpu.c | 36 ++++++++++++++----------------------
13
target/arm/cpu.c | 3 +++
13
1 file changed, 14 insertions(+), 22 deletions(-)
14
2 files changed, 4 insertions(+)
15
14
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ enum arm_features {
21
ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
22
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
23
ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */
24
+ ARM_FEATURE_M_MAIN, /* M profile Main Extension */
25
};
26
27
static inline int arm_feature(CPUARMState *env, int feature)
28
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
29
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.c
17
--- a/target/arm/cpu.c
31
+++ b/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
32
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
19
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
33
ARMCPU *cpu = ARM_CPU(obj);
20
ARMCPU *cpu = ARM_CPU(cs);
34
set_feature(&cpu->env, ARM_FEATURE_V7);
21
CPUARMState *env = &cpu->env;
35
set_feature(&cpu->env, ARM_FEATURE_M);
22
uint32_t psr = pstate_read(env);
36
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
23
- int i;
37
cpu->midr = 0x410fc231;
24
+ int i, j;
38
cpu->pmsav7_dregion = 8;
25
int el = arm_current_el(env);
39
cpu->id_pfr0 = 0x00000030;
26
const char *ns_status;
40
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
27
bool sve;
41
28
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
42
set_feature(&cpu->env, ARM_FEATURE_V7);
29
}
43
set_feature(&cpu->env, ARM_FEATURE_M);
30
44
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
31
if (sve) {
45
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
32
- int j, zcr_len = sve_vqm1_for_el(env, el);
46
cpu->midr = 0x410fc240; /* r0p0 */
33
+ int zcr_len = sve_vqm1_for_el(env, el);
47
cpu->pmsav7_dregion = 8;
34
48
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
35
for (i = 0; i <= FFR_PRED_NUM; i++) {
49
36
bool eol;
50
set_feature(&cpu->env, ARM_FEATURE_V8);
37
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
51
set_feature(&cpu->env, ARM_FEATURE_M);
38
}
52
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
39
}
53
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
40
54
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
41
- for (i = 0; i < 32; i++) {
55
cpu->midr = 0x410fd213; /* r0p3 */
42
- if (zcr_len == 0) {
43
+ if (zcr_len == 0) {
44
+ /*
45
+ * With vl=16, there are only 37 columns per register,
46
+ * so output two registers per line.
47
+ */
48
+ for (i = 0; i < 32; i++) {
49
qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
50
i, env->vfp.zregs[i].d[1],
51
env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
52
- } else if (zcr_len == 1) {
53
- qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
54
- ":%016" PRIx64 ":%016" PRIx64 "\n",
55
- i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
56
- env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
57
- } else {
58
+ }
59
+ } else {
60
+ for (i = 0; i < 32; i++) {
61
+ qemu_fprintf(f, "Z%02d=", i);
62
for (j = zcr_len; j >= 0; j--) {
63
- bool odd = (zcr_len - j) % 2 != 0;
64
- if (j == zcr_len) {
65
- qemu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
66
- } else if (!odd) {
67
- if (j > 0) {
68
- qemu_fprintf(f, " [%x-%x]=", j, j - 1);
69
- } else {
70
- qemu_fprintf(f, " [%x]=", j);
71
- }
72
- }
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
}
56
--
82
--
57
2.17.1
83
2.34.1
58
59
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add the Cortex-R5F with the optional FPU enabled.
3
Always print each matrix row whole, one per line, so that we
4
get the entire matrix in the proper shape.
4
5
5
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20230622151201.1578522-3-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20180529124707.3025-2-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/cpu.c | 9 +++++++++
11
target/arm/cpu.c | 18 ++++++++++++++++++
14
1 file changed, 9 insertions(+)
12
1 file changed, 18 insertions(+)
15
13
16
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.c
16
--- a/target/arm/cpu.c
19
+++ b/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
21
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
19
i, q[1], q[0], (i & 1 ? "\n" : " "));
20
}
21
}
22
+
23
+ if (cpu_isar_feature(aa64_sme, cpu) &&
24
+ FIELD_EX64(env->svcr, SVCR, ZA) &&
25
+ sme_exception_el(env, el) == 0) {
26
+ int zcr_len = sve_vqm1_for_el_sm(env, el, true);
27
+ int svl = (zcr_len + 1) * 16;
28
+ int svl_lg10 = svl < 100 ? 2 : 3;
29
+
30
+ for (i = 0; i < svl; i++) {
31
+ qemu_fprintf(f, "ZA[%0*d]=", svl_lg10, i);
32
+ for (j = zcr_len; j >= 0; --j) {
33
+ qemu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%c",
34
+ env->zarray[i].d[2 * j + 1],
35
+ env->zarray[i].d[2 * j],
36
+ j ? ':' : '\n');
37
+ }
38
+ }
39
+ }
22
}
40
}
23
41
24
+static void cortex_r5f_initfn(Object *obj)
42
#else
25
+{
26
+ ARMCPU *cpu = ARM_CPU(obj);
27
+
28
+ cortex_r5_initfn(obj);
29
+ set_feature(&cpu->env, ARM_FEATURE_VFP3);
30
+}
31
+
32
static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
33
{ .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0,
34
.access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
35
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
36
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
37
.class_init = arm_v7m_class_init },
38
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
39
+ { .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
40
{ .name = "cortex-a7", .initfn = cortex_a7_initfn },
41
{ .name = "cortex-a8", .initfn = cortex_a8_initfn },
42
{ .name = "cortex-a9", .initfn = cortex_a9_initfn },
43
--
43
--
44
2.17.1
44
2.34.1
45
46
diff view generated by jsdifflib
1
Implement the Arm TrustZone Memory Protection Controller, which sits
1
From: Richard Henderson <richard.henderson@linaro.org>
2
in front of RAM and allows secure software to configure it to either
3
pass through or reject transactions.
4
2
5
We implement the MPC as a QEMU IOMMU, which will direct transactions
3
For the outer product set of insns, which take an entire matrix
6
either through to the devices and memory behind it or to a special
4
tile as output, the argument is not a combined tile+column.
7
"never works" AddressSpace if they are blocked.
5
Therefore using get_tile_rowcol was incorrect, as we extracted
6
the tile number from itself.
8
7
9
This initial commit implements the skeleton of the device:
8
The test case relies only on assembler support for SME, since
10
* it always permits accesses
9
no release of GCC recognizes -march=armv9-a+sme yet.
11
* it doesn't implement most of the registers
12
* it doesn't implement the interrupt or other behaviour
13
for blocked transactions
14
10
11
Cc: qemu-stable@nongnu.org
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
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
[PMM: dropped now-unneeded changes to sysregs CFLAGS]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Reviewed-by: Eric Auger <eric.auger@redhat.com>
18
Message-id: 20180620132032.28865-2-peter.maydell@linaro.org
19
---
18
---
20
hw/misc/Makefile.objs | 1 +
19
target/arm/tcg/translate-sme.c | 24 ++++++---
21
include/hw/misc/tz-mpc.h | 70 ++++++
20
tests/tcg/aarch64/sme-outprod1.c | 83 +++++++++++++++++++++++++++++++
22
hw/misc/tz-mpc.c | 399 ++++++++++++++++++++++++++++++++
21
tests/tcg/aarch64/Makefile.target | 7 ++-
23
MAINTAINERS | 2 +
22
3 files changed, 107 insertions(+), 7 deletions(-)
24
default-configs/arm-softmmu.mak | 1 +
23
create mode 100644 tests/tcg/aarch64/sme-outprod1.c
25
hw/misc/trace-events | 7 +
26
6 files changed, 480 insertions(+)
27
create mode 100644 include/hw/misc/tz-mpc.h
28
create mode 100644 hw/misc/tz-mpc.c
29
24
30
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
25
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
31
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/misc/Makefile.objs
27
--- a/target/arm/tcg/translate-sme.c
33
+++ b/hw/misc/Makefile.objs
28
+++ b/target/arm/tcg/translate-sme.c
34
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MIPS_ITU) += mips_itu.o
29
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
35
obj-$(CONFIG_MPS2_FPGAIO) += mps2-fpgaio.o
30
return addr;
36
obj-$(CONFIG_MPS2_SCC) += mps2-scc.o
31
}
37
32
38
+obj-$(CONFIG_TZ_MPC) += tz-mpc.o
33
+/*
39
obj-$(CONFIG_TZ_PPC) += tz-ppc.o
34
+ * Resolve tile.size[0] to a host pointer.
40
obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
35
+ * Used by e.g. outer product insns where we require the entire tile.
41
36
+ */
42
diff --git a/include/hw/misc/tz-mpc.h b/include/hw/misc/tz-mpc.h
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
43
new file mode 100644
82
new file mode 100644
44
index XXXXXXX..XXXXXXX
83
index XXXXXXX..XXXXXXX
45
--- /dev/null
84
--- /dev/null
46
+++ b/include/hw/misc/tz-mpc.h
85
+++ b/tests/tcg/aarch64/sme-outprod1.c
47
@@ -XXX,XX +XXX,XX @@
86
@@ -XXX,XX +XXX,XX @@
48
+/*
87
+/*
49
+ * ARM AHB5 TrustZone Memory Protection Controller emulation
88
+ * SME outer product, 1 x 1.
50
+ *
89
+ * SPDX-License-Identifier: GPL-2.0-or-later
51
+ * Copyright (c) 2018 Linaro Limited
52
+ * Written by Peter Maydell
53
+ *
54
+ * This program is free software; you can redistribute it and/or modify
55
+ * it under the terms of the GNU General Public License version 2 or
56
+ * (at your option) any later version.
57
+ */
90
+ */
58
+
91
+
59
+/* This is a model of the TrustZone memory protection controller (MPC).
92
+#include <stdio.h>
60
+ * It is documented in the ARM CoreLink SIE-200 System IP for Embedded TRM
93
+
61
+ * (DDI 0571G):
94
+extern void foo(float *dst);
62
+ * https://developer.arm.com/products/architecture/m-profile/docs/ddi0571/g
95
+
63
+ *
96
+asm(
64
+ * The MPC sits in front of memory and allows secure software to
97
+"    .arch_extension sme\n"
65
+ * configure it to either pass through or reject transactions.
98
+"    .type foo, @function\n"
66
+ * Rejected transactions may be configured to either be aborted, or to
99
+"foo:\n"
67
+ * behave as RAZ/WI. An interrupt can be signalled for a rejected transaction.
100
+"    stp x29, x30, [sp, -80]!\n"
68
+ *
101
+"    mov x29, sp\n"
69
+ * The MPC has a register interface which the guest uses to configure it.
102
+"    stp d8, d9, [sp, 16]\n"
70
+ *
103
+"    stp d10, d11, [sp, 32]\n"
71
+ * QEMU interface:
104
+"    stp d12, d13, [sp, 48]\n"
72
+ * + sysbus MMIO region 0: MemoryRegion for the MPC's config registers
105
+"    stp d14, d15, [sp, 64]\n"
73
+ * + sysbus MMIO region 1: MemoryRegion for the upstream end of the MPC
106
+"    smstart\n"
74
+ * + Property "downstream": MemoryRegion defining the downstream memory
107
+"    ptrue p0.s, vl4\n"
75
+ * + Named GPIO output "irq": set for a transaction-failed interrupt
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.
76
+ */
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
+);
77
+
143
+
78
+#ifndef TZ_MPC_H
144
+int main()
79
+#define TZ_MPC_H
145
+{
146
+ float dst[16];
147
+ int i, j;
80
+
148
+
81
+#include "hw/sysbus.h"
149
+ foo(dst);
82
+
150
+
83
+#define TYPE_TZ_MPC "tz-mpc"
151
+ for (i = 0; i < 16; i++) {
84
+#define TZ_MPC(obj) OBJECT_CHECK(TZMPC, (obj), TYPE_TZ_MPC)
152
+ if (dst[i] != 1.0f) {
85
+
153
+ break;
86
+#define TZ_NUM_PORTS 16
154
+ }
87
+
88
+#define TYPE_TZ_MPC_IOMMU_MEMORY_REGION "tz-mpc-iommu-memory-region"
89
+
90
+typedef struct TZMPC TZMPC;
91
+
92
+struct TZMPC {
93
+ /*< private >*/
94
+ SysBusDevice parent_obj;
95
+
96
+ /*< public >*/
97
+
98
+ qemu_irq irq;
99
+
100
+ /* Properties */
101
+ MemoryRegion *downstream;
102
+
103
+ hwaddr blocksize;
104
+ uint32_t blk_max;
105
+
106
+ /* MemoryRegions exposed to user */
107
+ MemoryRegion regmr;
108
+ IOMMUMemoryRegion upstream;
109
+
110
+ /* MemoryRegion used internally */
111
+ MemoryRegion blocked_io;
112
+
113
+ AddressSpace downstream_as;
114
+ AddressSpace blocked_io_as;
115
+};
116
+
117
+#endif
118
diff --git a/hw/misc/tz-mpc.c b/hw/misc/tz-mpc.c
119
new file mode 100644
120
index XXXXXXX..XXXXXXX
121
--- /dev/null
122
+++ b/hw/misc/tz-mpc.c
123
@@ -XXX,XX +XXX,XX @@
124
+/*
125
+ * ARM AHB5 TrustZone Memory Protection Controller emulation
126
+ *
127
+ * Copyright (c) 2018 Linaro Limited
128
+ * Written by Peter Maydell
129
+ *
130
+ * This program is free software; you can redistribute it and/or modify
131
+ * it under the terms of the GNU General Public License version 2 or
132
+ * (at your option) any later version.
133
+ */
134
+
135
+#include "qemu/osdep.h"
136
+#include "qemu/log.h"
137
+#include "qapi/error.h"
138
+#include "trace.h"
139
+#include "hw/sysbus.h"
140
+#include "hw/registerfields.h"
141
+#include "hw/misc/tz-mpc.h"
142
+
143
+/* Our IOMMU has two IOMMU indexes, one for secure transactions and one for
144
+ * non-secure transactions.
145
+ */
146
+enum {
147
+ IOMMU_IDX_S,
148
+ IOMMU_IDX_NS,
149
+ IOMMU_NUM_INDEXES,
150
+};
151
+
152
+/* Config registers */
153
+REG32(CTRL, 0x00)
154
+REG32(BLK_MAX, 0x10)
155
+REG32(BLK_CFG, 0x14)
156
+REG32(BLK_IDX, 0x18)
157
+REG32(BLK_LUT, 0x1c)
158
+REG32(INT_STAT, 0x20)
159
+REG32(INT_CLEAR, 0x24)
160
+REG32(INT_EN, 0x28)
161
+REG32(INT_INFO1, 0x2c)
162
+REG32(INT_INFO2, 0x30)
163
+REG32(INT_SET, 0x34)
164
+REG32(PIDR4, 0xfd0)
165
+REG32(PIDR5, 0xfd4)
166
+REG32(PIDR6, 0xfd8)
167
+REG32(PIDR7, 0xfdc)
168
+REG32(PIDR0, 0xfe0)
169
+REG32(PIDR1, 0xfe4)
170
+REG32(PIDR2, 0xfe8)
171
+REG32(PIDR3, 0xfec)
172
+REG32(CIDR0, 0xff0)
173
+REG32(CIDR1, 0xff4)
174
+REG32(CIDR2, 0xff8)
175
+REG32(CIDR3, 0xffc)
176
+
177
+static const uint8_t tz_mpc_idregs[] = {
178
+ 0x04, 0x00, 0x00, 0x00,
179
+ 0x60, 0xb8, 0x1b, 0x00,
180
+ 0x0d, 0xf0, 0x05, 0xb1,
181
+};
182
+
183
+static MemTxResult tz_mpc_reg_read(void *opaque, hwaddr addr,
184
+ uint64_t *pdata,
185
+ unsigned size, MemTxAttrs attrs)
186
+{
187
+ uint64_t r;
188
+ uint32_t offset = addr & ~0x3;
189
+
190
+ if (!attrs.secure && offset < A_PIDR4) {
191
+ /* NS accesses can only see the ID registers */
192
+ qemu_log_mask(LOG_GUEST_ERROR,
193
+ "TZ MPC register read: NS access to offset 0x%x\n",
194
+ offset);
195
+ r = 0;
196
+ goto read_out;
197
+ }
155
+ }
198
+
156
+
199
+ switch (offset) {
157
+ if (i == 16) {
200
+ case A_PIDR4:
158
+ return 0; /* success */
201
+ case A_PIDR5:
202
+ case A_PIDR6:
203
+ case A_PIDR7:
204
+ case A_PIDR0:
205
+ case A_PIDR1:
206
+ case A_PIDR2:
207
+ case A_PIDR3:
208
+ case A_CIDR0:
209
+ case A_CIDR1:
210
+ case A_CIDR2:
211
+ case A_CIDR3:
212
+ r = tz_mpc_idregs[(offset - A_PIDR4) / 4];
213
+ break;
214
+ case A_INT_CLEAR:
215
+ case A_INT_SET:
216
+ qemu_log_mask(LOG_GUEST_ERROR,
217
+ "TZ MPC register read: write-only offset 0x%x\n",
218
+ offset);
219
+ r = 0;
220
+ break;
221
+ default:
222
+ qemu_log_mask(LOG_GUEST_ERROR,
223
+ "TZ MPC register read: bad offset 0x%x\n", offset);
224
+ r = 0;
225
+ break;
226
+ }
159
+ }
227
+
160
+
228
+ if (size != 4) {
161
+ /* failure */
229
+ /* None of our registers are read-sensitive (except BLK_LUT,
162
+ for (i = 0; i < 4; ++i) {
230
+ * which can special case the "size not 4" case), so just
163
+ for (j = 0; j < 4; ++j) {
231
+ * pull the right bytes out of the word read result.
164
+ printf("%f ", (double)dst[i * 4 + j]);
232
+ */
165
+ }
233
+ r = extract32(r, (addr & 3) * 8, size * 8);
166
+ printf("\n");
234
+ }
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
235
+
191
+
236
+read_out:
192
# System Registers Tests
237
+ trace_tz_mpc_reg_read(addr, r, size);
193
AARCH64_TESTS += sysregs
238
+ *pdata = r;
194
239
+ return MEMTX_OK;
240
+}
241
+
242
+static MemTxResult tz_mpc_reg_write(void *opaque, hwaddr addr,
243
+ uint64_t value,
244
+ unsigned size, MemTxAttrs attrs)
245
+{
246
+ uint32_t offset = addr & ~0x3;
247
+
248
+ trace_tz_mpc_reg_write(addr, value, size);
249
+
250
+ if (!attrs.secure && offset < A_PIDR4) {
251
+ /* NS accesses can only see the ID registers */
252
+ qemu_log_mask(LOG_GUEST_ERROR,
253
+ "TZ MPC register write: NS access to offset 0x%x\n",
254
+ offset);
255
+ return MEMTX_OK;
256
+ }
257
+
258
+ if (size != 4) {
259
+ /* Expand the byte or halfword write to a full word size.
260
+ * In most cases we can do this with zeroes; the exceptions
261
+ * are CTRL, BLK_IDX and BLK_LUT.
262
+ */
263
+ uint32_t oldval;
264
+
265
+ switch (offset) {
266
+ /* As we add support for registers which need expansions
267
+ * other than zeroes we'll fill in cases here.
268
+ */
269
+ default:
270
+ oldval = 0;
271
+ break;
272
+ }
273
+ value = deposit32(oldval, (addr & 3) * 8, size * 8, value);
274
+ }
275
+
276
+ switch (offset) {
277
+ case A_PIDR4:
278
+ case A_PIDR5:
279
+ case A_PIDR6:
280
+ case A_PIDR7:
281
+ case A_PIDR0:
282
+ case A_PIDR1:
283
+ case A_PIDR2:
284
+ case A_PIDR3:
285
+ case A_CIDR0:
286
+ case A_CIDR1:
287
+ case A_CIDR2:
288
+ case A_CIDR3:
289
+ qemu_log_mask(LOG_GUEST_ERROR,
290
+ "TZ MPC register write: read-only offset 0x%x\n", offset);
291
+ break;
292
+ default:
293
+ qemu_log_mask(LOG_GUEST_ERROR,
294
+ "TZ MPC register write: bad offset 0x%x\n", offset);
295
+ break;
296
+ }
297
+
298
+ return MEMTX_OK;
299
+}
300
+
301
+static const MemoryRegionOps tz_mpc_reg_ops = {
302
+ .read_with_attrs = tz_mpc_reg_read,
303
+ .write_with_attrs = tz_mpc_reg_write,
304
+ .endianness = DEVICE_LITTLE_ENDIAN,
305
+ .valid.min_access_size = 1,
306
+ .valid.max_access_size = 4,
307
+ .impl.min_access_size = 1,
308
+ .impl.max_access_size = 4,
309
+};
310
+
311
+/* Accesses only reach these read and write functions if the MPC is
312
+ * blocking them; non-blocked accesses go directly to the downstream
313
+ * memory region without passing through this code.
314
+ */
315
+static MemTxResult tz_mpc_mem_blocked_read(void *opaque, hwaddr addr,
316
+ uint64_t *pdata,
317
+ unsigned size, MemTxAttrs attrs)
318
+{
319
+ trace_tz_mpc_mem_blocked_read(addr, size, attrs.secure);
320
+
321
+ *pdata = 0;
322
+ return MEMTX_OK;
323
+}
324
+
325
+static MemTxResult tz_mpc_mem_blocked_write(void *opaque, hwaddr addr,
326
+ uint64_t value,
327
+ unsigned size, MemTxAttrs attrs)
328
+{
329
+ trace_tz_mpc_mem_blocked_write(addr, value, size, attrs.secure);
330
+
331
+ return MEMTX_OK;
332
+}
333
+
334
+static const MemoryRegionOps tz_mpc_mem_blocked_ops = {
335
+ .read_with_attrs = tz_mpc_mem_blocked_read,
336
+ .write_with_attrs = tz_mpc_mem_blocked_write,
337
+ .endianness = DEVICE_LITTLE_ENDIAN,
338
+ .valid.min_access_size = 1,
339
+ .valid.max_access_size = 8,
340
+ .impl.min_access_size = 1,
341
+ .impl.max_access_size = 8,
342
+};
343
+
344
+static IOMMUTLBEntry tz_mpc_translate(IOMMUMemoryRegion *iommu,
345
+ hwaddr addr, IOMMUAccessFlags flags,
346
+ int iommu_idx)
347
+{
348
+ TZMPC *s = TZ_MPC(container_of(iommu, TZMPC, upstream));
349
+ bool ok;
350
+
351
+ IOMMUTLBEntry ret = {
352
+ .iova = addr & ~(s->blocksize - 1),
353
+ .translated_addr = addr & ~(s->blocksize - 1),
354
+ .addr_mask = s->blocksize - 1,
355
+ .perm = IOMMU_RW,
356
+ };
357
+
358
+ /* Look at the per-block configuration for this address, and
359
+ * return a TLB entry directing the transaction at either
360
+ * downstream_as or blocked_io_as, as appropriate.
361
+ * For the moment, always permit accesses.
362
+ */
363
+ ok = true;
364
+
365
+ trace_tz_mpc_translate(addr, flags,
366
+ iommu_idx == IOMMU_IDX_S ? "S" : "NS",
367
+ ok ? "pass" : "block");
368
+
369
+ ret.target_as = ok ? &s->downstream_as : &s->blocked_io_as;
370
+ return ret;
371
+}
372
+
373
+static int tz_mpc_attrs_to_index(IOMMUMemoryRegion *iommu, MemTxAttrs attrs)
374
+{
375
+ /* We treat unspecified attributes like secure. Transactions with
376
+ * unspecified attributes come from places like
377
+ * cpu_physical_memory_write_rom() for initial image load, and we want
378
+ * those to pass through the from-reset "everything is secure" config.
379
+ * All the real during-emulation transactions from the CPU will
380
+ * specify attributes.
381
+ */
382
+ return (attrs.unspecified || attrs.secure) ? IOMMU_IDX_S : IOMMU_IDX_NS;
383
+}
384
+
385
+static int tz_mpc_num_indexes(IOMMUMemoryRegion *iommu)
386
+{
387
+ return IOMMU_NUM_INDEXES;
388
+}
389
+
390
+static void tz_mpc_reset(DeviceState *dev)
391
+{
392
+}
393
+
394
+static void tz_mpc_init(Object *obj)
395
+{
396
+ DeviceState *dev = DEVICE(obj);
397
+ TZMPC *s = TZ_MPC(obj);
398
+
399
+ qdev_init_gpio_out_named(dev, &s->irq, "irq", 1);
400
+}
401
+
402
+static void tz_mpc_realize(DeviceState *dev, Error **errp)
403
+{
404
+ Object *obj = OBJECT(dev);
405
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
406
+ TZMPC *s = TZ_MPC(dev);
407
+ uint64_t size;
408
+
409
+ /* We can't create the upstream end of the port until realize,
410
+ * as we don't know the size of the MR used as the downstream until then.
411
+ * We insist on having a downstream, to avoid complicating the code
412
+ * with handling the "don't know how big this is" case. It's easy
413
+ * enough for the user to create an unimplemented_device as downstream
414
+ * if they have nothing else to plug into this.
415
+ */
416
+ if (!s->downstream) {
417
+ error_setg(errp, "MPC 'downstream' link not set");
418
+ return;
419
+ }
420
+
421
+ size = memory_region_size(s->downstream);
422
+
423
+ memory_region_init_iommu(&s->upstream, sizeof(s->upstream),
424
+ TYPE_TZ_MPC_IOMMU_MEMORY_REGION,
425
+ obj, "tz-mpc-upstream", size);
426
+
427
+ /* In real hardware the block size is configurable. In QEMU we could
428
+ * make it configurable but will need it to be at least as big as the
429
+ * target page size so we can execute out of the resulting MRs. Guest
430
+ * software is supposed to check the block size using the BLK_CFG
431
+ * register, so make it fixed at the page size.
432
+ */
433
+ s->blocksize = memory_region_iommu_get_min_page_size(&s->upstream);
434
+ if (size % s->blocksize != 0) {
435
+ error_setg(errp,
436
+ "MPC 'downstream' size %" PRId64
437
+ " is not a multiple of %" HWADDR_PRIx " bytes",
438
+ size, s->blocksize);
439
+ object_unref(OBJECT(&s->upstream));
440
+ return;
441
+ }
442
+
443
+ /* BLK_MAX is the max value of BLK_IDX, which indexes an array of 32-bit
444
+ * words, each bit of which indicates one block.
445
+ */
446
+ s->blk_max = DIV_ROUND_UP(size / s->blocksize, 32);
447
+
448
+ memory_region_init_io(&s->regmr, obj, &tz_mpc_reg_ops,
449
+ s, "tz-mpc-regs", 0x1000);
450
+ sysbus_init_mmio(sbd, &s->regmr);
451
+
452
+ sysbus_init_mmio(sbd, MEMORY_REGION(&s->upstream));
453
+
454
+ /* This memory region is not exposed to users of this device as a
455
+ * sysbus MMIO region, but is instead used internally as something
456
+ * that our IOMMU translate function might direct accesses to.
457
+ */
458
+ memory_region_init_io(&s->blocked_io, obj, &tz_mpc_mem_blocked_ops,
459
+ s, "tz-mpc-blocked-io", size);
460
+
461
+ address_space_init(&s->downstream_as, s->downstream,
462
+ "tz-mpc-downstream");
463
+ address_space_init(&s->blocked_io_as, &s->blocked_io,
464
+ "tz-mpc-blocked-io");
465
+}
466
+
467
+static const VMStateDescription tz_mpc_vmstate = {
468
+ .name = "tz-mpc",
469
+ .version_id = 1,
470
+ .minimum_version_id = 1,
471
+ .fields = (VMStateField[]) {
472
+ VMSTATE_END_OF_LIST()
473
+ }
474
+};
475
+
476
+static Property tz_mpc_properties[] = {
477
+ DEFINE_PROP_LINK("downstream", TZMPC, downstream,
478
+ TYPE_MEMORY_REGION, MemoryRegion *),
479
+ DEFINE_PROP_END_OF_LIST(),
480
+};
481
+
482
+static void tz_mpc_class_init(ObjectClass *klass, void *data)
483
+{
484
+ DeviceClass *dc = DEVICE_CLASS(klass);
485
+
486
+ dc->realize = tz_mpc_realize;
487
+ dc->vmsd = &tz_mpc_vmstate;
488
+ dc->reset = tz_mpc_reset;
489
+ dc->props = tz_mpc_properties;
490
+}
491
+
492
+static const TypeInfo tz_mpc_info = {
493
+ .name = TYPE_TZ_MPC,
494
+ .parent = TYPE_SYS_BUS_DEVICE,
495
+ .instance_size = sizeof(TZMPC),
496
+ .instance_init = tz_mpc_init,
497
+ .class_init = tz_mpc_class_init,
498
+};
499
+
500
+static void tz_mpc_iommu_memory_region_class_init(ObjectClass *klass,
501
+ void *data)
502
+{
503
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
504
+
505
+ imrc->translate = tz_mpc_translate;
506
+ imrc->attrs_to_index = tz_mpc_attrs_to_index;
507
+ imrc->num_indexes = tz_mpc_num_indexes;
508
+}
509
+
510
+static const TypeInfo tz_mpc_iommu_memory_region_info = {
511
+ .name = TYPE_TZ_MPC_IOMMU_MEMORY_REGION,
512
+ .parent = TYPE_IOMMU_MEMORY_REGION,
513
+ .class_init = tz_mpc_iommu_memory_region_class_init,
514
+};
515
+
516
+static void tz_mpc_register_types(void)
517
+{
518
+ type_register_static(&tz_mpc_info);
519
+ type_register_static(&tz_mpc_iommu_memory_region_info);
520
+}
521
+
522
+type_init(tz_mpc_register_types);
523
diff --git a/MAINTAINERS b/MAINTAINERS
524
index XXXXXXX..XXXXXXX 100644
525
--- a/MAINTAINERS
526
+++ b/MAINTAINERS
527
@@ -XXX,XX +XXX,XX @@ F: hw/char/cmsdk-apb-uart.c
528
F: include/hw/char/cmsdk-apb-uart.h
529
F: hw/misc/tz-ppc.c
530
F: include/hw/misc/tz-ppc.h
531
+F: hw/misc/tz-mpc.c
532
+F: include/hw/misc/tz-mpc.h
533
534
ARM cores
535
M: Peter Maydell <peter.maydell@linaro.org>
536
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
537
index XXXXXXX..XXXXXXX 100644
538
--- a/default-configs/arm-softmmu.mak
539
+++ b/default-configs/arm-softmmu.mak
540
@@ -XXX,XX +XXX,XX @@ CONFIG_CMSDK_APB_UART=y
541
CONFIG_MPS2_FPGAIO=y
542
CONFIG_MPS2_SCC=y
543
544
+CONFIG_TZ_MPC=y
545
CONFIG_TZ_PPC=y
546
CONFIG_IOTKIT=y
547
CONFIG_IOTKIT_SECCTL=y
548
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
549
index XXXXXXX..XXXXXXX 100644
550
--- a/hw/misc/trace-events
551
+++ b/hw/misc/trace-events
552
@@ -XXX,XX +XXX,XX @@ mos6522_set_sr_int(void) "set sr_int"
553
mos6522_write(uint64_t addr, uint64_t val) "reg=0x%"PRIx64 " val=0x%"PRIx64
554
mos6522_read(uint64_t addr, unsigned val) "reg=0x%"PRIx64 " val=0x%x"
555
556
+# hw/misc/tz-mpc.c
557
+tz_mpc_reg_read(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs read: offset 0x%x data 0x%" PRIx64 " size %u"
558
+tz_mpc_reg_write(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs write: offset 0x%x data 0x%" PRIx64 " size %u"
559
+tz_mpc_mem_blocked_read(uint64_t addr, unsigned size, bool secure) "TZ MPC blocked read: offset 0x%" PRIx64 " size %u secure %d"
560
+tz_mpc_mem_blocked_write(uint64_t addr, uint64_t data, unsigned size, bool secure) "TZ MPC blocked write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
561
+tz_mpc_translate(uint64_t addr, int flags, const char *idx, const char *res) "TZ MPC translate: addr 0x%" PRIx64 " flags 0x%x iommu_idx %s: %s"
562
+
563
# hw/misc/tz-ppc.c
564
tz_ppc_reset(void) "TZ PPC: reset"
565
tz_ppc_cfg_nonsec(int n, int level) "TZ PPC: cfg_nonsec[%d] = %d"
566
--
195
--
567
2.17.1
196
2.34.1
568
569
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: John Högberg <john.hogberg@ericsson.com>
2
2
3
To prepare for multiple redistributor regions, we introduce
3
Unlike architectures with precise self-modifying code semantics
4
an array of uint32_t properties that stores the redistributor
4
(e.g. x86) ARM processors do not maintain coherency for instruction
5
count of each redistributor region.
5
execution and memory, requiring an instruction synchronization
6
barrier on every core that will execute the new code, and on many
7
models also the explicit use of cache management instructions.
6
8
7
Non accelerated VGICv3 only supports a single redistributor region.
9
While this is required to make JITs work on actual hardware, QEMU
8
The capacity of all redist regions is checked against the number of
10
has gotten away with not handling this since it does not emulate
9
vcpus.
11
caches, and unconditionally invalidates code whenever the softmmu
12
or the user-mode page protection logic detects that code has been
13
modified.
10
14
11
Machvirt is updated to set those properties, ie. a single
15
Unfortunately the latter does not work in the face of dual-mapped
12
redistributor region with count set to the number of vcpus
16
code (a common W^X workaround), where one page is executable and
13
capped by 123.
17
the other is writable: user-mode has no way to connect one with the
18
other as that is only known to the kernel and the emulated
19
application.
14
20
15
Signed-off-by: Eric Auger <eric.auger@redhat.com>
21
This commit works around the issue by telling software that
16
Reviewed-by: Andrew Jones <drjones@redhat.com>
22
instruction cache invalidation is required by clearing the
17
Message-id: 1529072910-16156-4-git-send-email-eric.auger@redhat.com
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]
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
36
---
20
include/hw/intc/arm_gicv3_common.h | 8 +++++--
37
target/arm/cpu.c | 11 +++++++++++
21
hw/arm/virt.c | 11 ++++++++-
38
target/arm/helper.c | 47 ++++++++++++++++++++++++++++++++++++++++++---
22
hw/intc/arm_gicv3.c | 12 +++++++++-
39
2 files changed, 55 insertions(+), 3 deletions(-)
23
hw/intc/arm_gicv3_common.c | 38 ++++++++++++++++++++++++++----
24
hw/intc/arm_gicv3_kvm.c | 9 +++++--
25
5 files changed, 67 insertions(+), 11 deletions(-)
26
40
27
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
41
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
28
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
29
--- a/include/hw/intc/arm_gicv3_common.h
43
--- a/target/arm/cpu.c
30
+++ b/include/hw/intc/arm_gicv3_common.h
44
+++ b/target/arm/cpu.c
31
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
32
#define GICV3_MAXIRQ 1020
33
#define GICV3_MAXSPI (GICV3_MAXIRQ - GIC_INTERNAL)
34
35
+#define GICV3_REDIST_SIZE 0x20000
36
+
37
/* Number of SGI target-list bits */
38
#define GICV3_TARGETLIST_BITS 16
39
40
@@ -XXX,XX +XXX,XX @@ struct GICv3State {
41
/*< public >*/
42
43
MemoryRegion iomem_dist; /* Distributor */
44
- MemoryRegion iomem_redist; /* Redistributors */
45
+ MemoryRegion *iomem_redist; /* Redistributor Regions */
46
+ uint32_t *redist_region_count; /* redistributor count within each region */
47
+ uint32_t nb_redist_regions; /* number of redist regions */
48
49
uint32_t num_cpu;
50
uint32_t num_irq;
51
@@ -XXX,XX +XXX,XX @@ typedef struct ARMGICv3CommonClass {
52
} ARMGICv3CommonClass;
53
54
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
55
- const MemoryRegionOps *ops);
56
+ const MemoryRegionOps *ops, Error **errp);
57
58
#endif
59
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/virt.c
62
+++ b/hw/arm/virt.c
63
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
64
if (!kvm_irqchip_in_kernel()) {
65
qdev_prop_set_bit(gicdev, "has-security-extensions", vms->secure);
66
}
67
+
68
+ if (type == 3) {
69
+ uint32_t redist0_capacity =
70
+ vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
71
+ uint32_t redist0_count = MIN(smp_cpus, redist0_capacity);
72
+
73
+ qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
74
+ qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
75
+ }
76
qdev_init_nofail(gicdev);
77
gicbusdev = SYS_BUS_DEVICE(gicdev);
78
sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base);
79
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
80
* many redistributors we can fit into the memory map.
81
*/
82
if (vms->gic_version == 3) {
83
- virt_max_cpus = vms->memmap[VIRT_GIC_REDIST].size / 0x20000;
84
+ virt_max_cpus = vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
85
} else {
86
virt_max_cpus = GIC_NCPU;
87
}
88
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/hw/intc/arm_gicv3.c
91
+++ b/hw/intc/arm_gicv3.c
92
@@ -XXX,XX +XXX,XX @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
93
return;
46
return;
94
}
47
}
95
48
96
- gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
49
+#ifdef CONFIG_USER_ONLY
97
+ if (s->nb_redist_regions != 1) {
50
+ /*
98
+ error_setg(errp, "VGICv3 redist region number(%d) not equal to 1",
51
+ * User mode relies on IC IVAU instructions to catch modification of
99
+ s->nb_redist_regions);
52
+ * dual-mapped code.
100
+ return;
53
+ *
101
+ }
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.
56
+ */
57
+ cpu->ctr = FIELD_DP64(cpu->ctr, CTR_EL0, DIC, 0);
58
+#endif
102
+
59
+
103
+ gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops, &local_err);
60
if (arm_feature(env, ARM_FEATURE_AARCH64) &&
104
+ if (local_err) {
61
cpu->has_vfp != cpu->has_neon) {
105
+ error_propagate(errp, local_err);
62
/*
106
+ return;
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
107
+ }
108
109
gicv3_init_cpuif(s);
110
}
111
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
112
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
113
--- a/hw/intc/arm_gicv3_common.c
65
--- a/target/arm/helper.c
114
+++ b/hw/intc/arm_gicv3_common.c
66
+++ b/target/arm/helper.c
115
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_gicv3 = {
67
@@ -XXX,XX +XXX,XX @@ static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
116
};
117
118
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
119
- const MemoryRegionOps *ops)
120
+ const MemoryRegionOps *ops, Error **errp)
121
{
122
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
123
+ int rdist_capacity = 0;
124
int i;
125
126
+ for (i = 0; i < s->nb_redist_regions; i++) {
127
+ rdist_capacity += s->redist_region_count[i];
128
+ }
129
+ if (rdist_capacity < s->num_cpu) {
130
+ error_setg(errp, "Capacity of the redist regions(%d) "
131
+ "is less than number of vcpus(%d)",
132
+ rdist_capacity, s->num_cpu);
133
+ return;
134
+ }
135
+
136
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
137
* GPIO array layout is thus:
138
* [0..N-1] spi
139
@@ -XXX,XX +XXX,XX @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
140
141
memory_region_init_io(&s->iomem_dist, OBJECT(s), ops, s,
142
"gicv3_dist", 0x10000);
143
- memory_region_init_io(&s->iomem_redist, OBJECT(s), ops ? &ops[1] : NULL, s,
144
- "gicv3_redist", 0x20000 * s->num_cpu);
145
-
146
sysbus_init_mmio(sbd, &s->iomem_dist);
147
- sysbus_init_mmio(sbd, &s->iomem_redist);
148
+
149
+ s->iomem_redist = g_new0(MemoryRegion, s->nb_redist_regions);
150
+ for (i = 0; i < s->nb_redist_regions; i++) {
151
+ char *name = g_strdup_printf("gicv3_redist_region[%d]", i);
152
+
153
+ memory_region_init_io(&s->iomem_redist[i], OBJECT(s),
154
+ ops ? &ops[1] : NULL, s, name,
155
+ s->redist_region_count[i] * GICV3_REDIST_SIZE);
156
+ sysbus_init_mmio(sbd, &s->iomem_redist[i]);
157
+ g_free(name);
158
+ }
159
}
160
161
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
162
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
163
}
68
}
164
}
69
}
165
70
166
+static void arm_gicv3_finalize(Object *obj)
71
+#ifdef CONFIG_USER_ONLY
72
+/*
73
+ * `IC IVAU` is handled to improve compatibility with JITs that dual-map their
74
+ * code to get around W^X restrictions, where one region is writable and the
75
+ * other is executable.
76
+ *
77
+ * Since the executable region is never written to we cannot detect code
78
+ * changes when running in user mode, and rely on the emulated JIT telling us
79
+ * that the code has changed by executing this instruction.
80
+ */
81
+static void ic_ivau_write(CPUARMState *env, const ARMCPRegInfo *ri,
82
+ uint64_t value)
167
+{
83
+{
168
+ GICv3State *s = ARM_GICV3_COMMON(obj);
84
+ uint64_t icache_line_mask, start_address, end_address;
85
+ const ARMCPU *cpu;
169
+
86
+
170
+ g_free(s->redist_region_count);
87
+ cpu = env_archcpu(env);
88
+
89
+ icache_line_mask = (4 << extract32(cpu->ctr, 0, 4)) - 1;
90
+ start_address = value & ~icache_line_mask;
91
+ end_address = value | icache_line_mask;
92
+
93
+ mmap_lock();
94
+
95
+ tb_invalidate_phys_range(start_address, end_address);
96
+
97
+ mmap_unlock();
171
+}
98
+}
99
+#endif
172
+
100
+
173
static void arm_gicv3_common_reset(DeviceState *dev)
101
static const ARMCPRegInfo v8_cp_reginfo[] = {
174
{
102
/*
175
GICv3State *s = ARM_GICV3_COMMON(dev);
103
* Minimal set of EL0-visible registers. This will need to be expanded
176
@@ -XXX,XX +XXX,XX @@ static Property arm_gicv3_common_properties[] = {
104
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
177
DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32),
105
{ .name = "CURRENTEL", .state = ARM_CP_STATE_AA64,
178
DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
106
.opc0 = 3, .opc1 = 0, .opc2 = 2, .crn = 4, .crm = 2,
179
DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
107
.access = PL1_R, .type = ARM_CP_CURRENTEL },
180
+ DEFINE_PROP_ARRAY("redist-region-count", GICv3State, nb_redist_regions,
108
- /* Cache ops: all NOPs since we don't emulate caches */
181
+ redist_region_count, qdev_prop_uint32, uint32_t),
109
+ /*
182
DEFINE_PROP_END_OF_LIST(),
110
+ * Instruction cache ops. All of these except `IC IVAU` NOP because we
183
};
111
+ * don't emulate caches.
184
112
+ */
185
@@ -XXX,XX +XXX,XX @@ static const TypeInfo arm_gicv3_common_type = {
113
{ .name = "IC_IALLUIS", .state = ARM_CP_STATE_AA64,
186
.instance_size = sizeof(GICv3State),
114
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
187
.class_size = sizeof(ARMGICv3CommonClass),
115
.access = PL1_W, .type = ARM_CP_NOP,
188
.class_init = arm_gicv3_common_class_init,
116
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
189
+ .instance_finalize = arm_gicv3_finalize,
117
.accessfn = access_tocu },
190
.abstract = true,
118
{ .name = "IC_IVAU", .state = ARM_CP_STATE_AA64,
191
.interfaces = (InterfaceInfo []) {
119
.opc0 = 1, .opc1 = 3, .crn = 7, .crm = 5, .opc2 = 1,
192
{ TYPE_ARM_LINUX_BOOT_IF },
120
- .access = PL0_W, .type = ARM_CP_NOP,
193
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
121
+ .access = PL0_W,
194
index XXXXXXX..XXXXXXX 100644
122
.fgt = FGT_ICIVAU,
195
--- a/hw/intc/arm_gicv3_kvm.c
123
- .accessfn = access_tocu },
196
+++ b/hw/intc/arm_gicv3_kvm.c
124
+ .accessfn = access_tocu,
197
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
125
+#ifdef CONFIG_USER_ONLY
198
return;
126
+ .type = ARM_CP_NO_RAW,
199
}
127
+ .writefn = ic_ivau_write
200
128
+#else
201
- gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL);
129
+ .type = ARM_CP_NOP
202
+ gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL, &local_err);
130
+#endif
203
+ if (local_err) {
131
+ },
204
+ error_propagate(errp, local_err);
132
+ /* Cache ops: all NOPs since we don't emulate caches */
205
+ return;
133
{ .name = "DC_IVAC", .state = ARM_CP_STATE_AA64,
206
+ }
134
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 6, .opc2 = 1,
207
135
.access = PL1_W, .accessfn = aa64_cacheop_poc_access,
208
for (i = 0; i < s->num_cpu; i++) {
209
ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
210
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
211
212
kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
213
KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd, 0);
214
- kvm_arm_register_device(&s->iomem_redist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
215
+ kvm_arm_register_device(&s->iomem_redist[0], -1,
216
+ KVM_DEV_ARM_VGIC_GRP_ADDR,
217
KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd, 0);
218
219
if (kvm_has_gsi_routing()) {
220
--
136
--
221
2.17.1
137
2.34.1
222
138
223
139
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
Let's check if KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION is supported.
4
If not, we check the number of redist region is equal to 1 and use the
5
legacy KVM_VGIC_V3_ADDR_TYPE_REDIST attribute. Otherwise we use
6
the new attribute and allow to register multiple regions to the
7
KVM device.
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Jones <drjones@redhat.com>
12
Message-id: 1529072910-16156-5-git-send-email-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/intc/arm_gicv3_kvm.c | 37 ++++++++++++++++++++++++++++++++++---
16
1 file changed, 34 insertions(+), 3 deletions(-)
17
18
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gicv3_kvm.c
21
+++ b/hw/intc/arm_gicv3_kvm.c
22
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
23
{
24
GICv3State *s = KVM_ARM_GICV3(dev);
25
KVMARMGICv3Class *kgc = KVM_ARM_GICV3_GET_CLASS(s);
26
+ bool multiple_redist_region_allowed;
27
Error *local_err = NULL;
28
int i;
29
30
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
31
return;
32
}
33
34
+ multiple_redist_region_allowed =
35
+ kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
36
+ KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION);
37
+
38
+ if (!multiple_redist_region_allowed && s->nb_redist_regions > 1) {
39
+ error_setg(errp, "Multiple VGICv3 redistributor regions are not "
40
+ "supported by this host kernel");
41
+ error_append_hint(errp, "A maximum of %d VCPUs can be used",
42
+ s->redist_region_count[0]);
43
+ return;
44
+ }
45
+
46
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
47
0, &s->num_irq, true, &error_abort);
48
49
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
50
51
kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
52
KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd, 0);
53
- kvm_arm_register_device(&s->iomem_redist[0], -1,
54
- KVM_DEV_ARM_VGIC_GRP_ADDR,
55
- KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd, 0);
56
+
57
+ if (!multiple_redist_region_allowed) {
58
+ kvm_arm_register_device(&s->iomem_redist[0], -1,
59
+ KVM_DEV_ARM_VGIC_GRP_ADDR,
60
+ KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd, 0);
61
+ } else {
62
+ /* we register regions in reverse order as "devices" are inserted at
63
+ * the head of a QSLIST and the list is then popped from the head
64
+ * onwards by kvm_arm_machine_init_done()
65
+ */
66
+ for (i = s->nb_redist_regions - 1; i >= 0; i--) {
67
+ /* Address mask made of the rdist region index and count */
68
+ uint64_t addr_ormask =
69
+ i | ((uint64_t)s->redist_region_count[i] << 52);
70
+
71
+ kvm_arm_register_device(&s->iomem_redist[i], -1,
72
+ KVM_DEV_ARM_VGIC_GRP_ADDR,
73
+ KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION,
74
+ s->dev_fd, addr_ormask);
75
+ }
76
+ }
77
78
if (kvm_has_gsi_routing()) {
79
/* set up irq routing */
80
--
81
2.17.1
82
83
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
This patch allows the creation of a GICv3 node with 1 or 2
4
redistributor regions depending on the number of smu_cpus.
5
The second redistributor region is located just after the
6
existing RAM region, at 256GB and contains up to up to 512 vcpus.
7
8
Please refer to kernel documentation for further node details:
9
Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt
10
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
Reviewed-by: Andrew Jones <drjones@redhat.com>
13
Message-id: 1529072910-16156-6-git-send-email-eric.auger@redhat.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/arm/virt.h | 14 ++++++++++++++
17
hw/arm/virt.c | 29 ++++++++++++++++++++++++-----
18
2 files changed, 38 insertions(+), 5 deletions(-)
19
20
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/virt.h
23
+++ b/include/hw/arm/virt.h
24
@@ -XXX,XX +XXX,XX @@
25
#include "qemu/notify.h"
26
#include "hw/boards.h"
27
#include "hw/arm/arm.h"
28
+#include "sysemu/kvm.h"
29
+#include "hw/intc/arm_gicv3_common.h"
30
31
#define NUM_GICV2M_SPIS 64
32
#define NUM_VIRTIO_TRANSPORTS 32
33
@@ -XXX,XX +XXX,XX @@ enum {
34
VIRT_GIC_V2M,
35
VIRT_GIC_ITS,
36
VIRT_GIC_REDIST,
37
+ VIRT_GIC_REDIST2,
38
VIRT_SMMU,
39
VIRT_UART,
40
VIRT_MMIO,
41
@@ -XXX,XX +XXX,XX @@ typedef struct {
42
43
void virt_acpi_setup(VirtMachineState *vms);
44
45
+/* Return the number of used redistributor regions */
46
+static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
47
+{
48
+ uint32_t redist0_capacity =
49
+ vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
50
+
51
+ assert(vms->gic_version == 3);
52
+
53
+ return vms->smp_cpus > redist0_capacity ? 2 : 1;
54
+}
55
+
56
#endif /* QEMU_ARM_VIRT_H */
57
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/virt.c
60
+++ b/hw/arm/virt.c
61
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
62
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
63
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
64
[VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
65
+ /* Additional 64 MB redist region (can contain up to 512 redistributors) */
66
+ [VIRT_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
67
/* Second PCIe window, 512GB wide at the 512GB boundary */
68
[VIRT_PCIE_MMIO_HIGH] = { 0x8000000000ULL, 0x8000000000ULL },
69
};
70
@@ -XXX,XX +XXX,XX @@ static void fdt_add_gic_node(VirtMachineState *vms)
71
qemu_fdt_setprop_cell(vms->fdt, "/intc", "#size-cells", 0x2);
72
qemu_fdt_setprop(vms->fdt, "/intc", "ranges", NULL, 0);
73
if (vms->gic_version == 3) {
74
+ int nb_redist_regions = virt_gicv3_redist_region_count(vms);
75
+
76
qemu_fdt_setprop_string(vms->fdt, "/intc", "compatible",
77
"arm,gic-v3");
78
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
79
- 2, vms->memmap[VIRT_GIC_DIST].base,
80
- 2, vms->memmap[VIRT_GIC_DIST].size,
81
- 2, vms->memmap[VIRT_GIC_REDIST].base,
82
- 2, vms->memmap[VIRT_GIC_REDIST].size);
83
+
84
+ qemu_fdt_setprop_cell(vms->fdt, "/intc",
85
+ "#redistributor-regions", nb_redist_regions);
86
+
87
+ if (nb_redist_regions == 1) {
88
+ qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
89
+ 2, vms->memmap[VIRT_GIC_DIST].base,
90
+ 2, vms->memmap[VIRT_GIC_DIST].size,
91
+ 2, vms->memmap[VIRT_GIC_REDIST].base,
92
+ 2, vms->memmap[VIRT_GIC_REDIST].size);
93
+ } else {
94
+ qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
95
+ 2, vms->memmap[VIRT_GIC_DIST].base,
96
+ 2, vms->memmap[VIRT_GIC_DIST].size,
97
+ 2, vms->memmap[VIRT_GIC_REDIST].base,
98
+ 2, vms->memmap[VIRT_GIC_REDIST].size,
99
+ 2, vms->memmap[VIRT_GIC_REDIST2].base,
100
+ 2, vms->memmap[VIRT_GIC_REDIST2].size);
101
+ }
102
+
103
if (vms->virt) {
104
qemu_fdt_setprop_cells(vms->fdt, "/intc", "interrupts",
105
GIC_FDT_IRQ_TYPE_PPI, ARCH_GICV3_MAINT_IRQ,
106
--
107
2.17.1
108
109
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
Depending on the number of smp_cpus we now register one or two
4
GICR structures.
5
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Andrew Jones <drjones@redhat.com>
8
Message-id: 1529072910-16156-7-git-send-email-eric.auger@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/virt-acpi-build.c | 9 +++++++++
12
1 file changed, 9 insertions(+)
13
14
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/virt-acpi-build.c
17
+++ b/hw/arm/virt-acpi-build.c
18
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
19
20
if (vms->gic_version == 3) {
21
AcpiMadtGenericTranslator *gic_its;
22
+ int nb_redist_regions = virt_gicv3_redist_region_count(vms);
23
AcpiMadtGenericRedistributor *gicr = acpi_data_push(table_data,
24
sizeof *gicr);
25
26
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
27
gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST].base);
28
gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST].size);
29
30
+ if (nb_redist_regions == 2) {
31
+ gicr = acpi_data_push(table_data, sizeof(*gicr));
32
+ gicr->type = ACPI_APIC_GENERIC_REDISTRIBUTOR;
33
+ gicr->length = sizeof(*gicr);
34
+ gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST2].base);
35
+ gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST2].size);
36
+ }
37
+
38
if (its_class_name() && !vmc->no_its) {
39
gic_its = acpi_data_push(table_data, sizeof *gic_its);
40
gic_its->type = ACPI_APIC_GENERIC_TRANSLATOR;
41
--
42
2.17.1
43
44
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
With a VGICv3 KVM device, if the number of vcpus exceeds the
4
capacity of the legacy redistributor region (123 redistributors),
5
we now attempt to register a second redistributor region. Up to
6
512 redistributors can fit in this latter on top of the 123 allowed
7
by the legacy redistributor region.
8
9
Registering this second redistributor region is possible if the
10
host kernel supports the following VGICv3 KVM device group/attribute:
11
KVM_DEV_ARM_VGIC_GRP_ADDR/KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION.
12
13
In case the host kernel does not support the registration of several
14
redistributor regions and the requested number of vcpus exceeds the
15
capacity of the legacy redistributor region, the GICv3 device
16
initialization fails with a proper error message and qemu exits.
17
18
At the moment the max number of vcpus still is capped by the
19
virt machine class max_cpus.
20
21
Signed-off-by: Eric Auger <eric.auger@redhat.com>
22
Reviewed-by: Andrew Jones <drjones@redhat.com>
23
Message-id: 1529072910-16156-8-git-send-email-eric.auger@redhat.com
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
26
hw/arm/virt.c | 18 +++++++++++++++++-
27
1 file changed, 17 insertions(+), 1 deletion(-)
28
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/virt.c
32
+++ b/hw/arm/virt.c
33
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
34
SysBusDevice *gicbusdev;
35
const char *gictype;
36
int type = vms->gic_version, i;
37
+ uint32_t nb_redist_regions = 0;
38
39
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
40
41
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
42
vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
43
uint32_t redist0_count = MIN(smp_cpus, redist0_capacity);
44
45
- qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
46
+ nb_redist_regions = virt_gicv3_redist_region_count(vms);
47
+
48
+ qdev_prop_set_uint32(gicdev, "len-redist-region-count",
49
+ nb_redist_regions);
50
qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
51
+
52
+ if (nb_redist_regions == 2) {
53
+ uint32_t redist1_capacity =
54
+ vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
55
+
56
+ qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
57
+ MIN(smp_cpus - redist0_count, redist1_capacity));
58
+ }
59
}
60
qdev_init_nofail(gicdev);
61
gicbusdev = SYS_BUS_DEVICE(gicdev);
62
sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base);
63
if (type == 3) {
64
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
65
+ if (nb_redist_regions == 2) {
66
+ sysbus_mmio_map(gicbusdev, 2, vms->memmap[VIRT_GIC_REDIST2].base);
67
+ }
68
} else {
69
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_CPU].base);
70
}
71
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
72
*/
73
if (vms->gic_version == 3) {
74
virt_max_cpus = vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
75
+ virt_max_cpus += vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
76
} else {
77
virt_max_cpus = GIC_NCPU;
78
}
79
--
80
2.17.1
81
82
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
This patch defines a new ECAM region located after the 256GB limit.
4
5
The virt machine state is augmented with a new highmem_ecam field
6
which guards the usage of this new ECAM region instead of the legacy
7
16MB one. With the highmem ECAM region, up to 256 PCIe buses can be
8
used.
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
12
Reviewed-by: Andrew Jones <drjones@redhat.com>
13
Message-id: 1529072910-16156-9-git-send-email-eric.auger@redhat.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/arm/virt.h | 4 ++++
17
hw/arm/virt-acpi-build.c | 21 +++++++++++++--------
18
hw/arm/virt.c | 12 ++++++++----
19
3 files changed, 25 insertions(+), 12 deletions(-)
20
21
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/virt.h
24
+++ b/include/hw/arm/virt.h
25
@@ -XXX,XX +XXX,XX @@ enum {
26
VIRT_PCIE_MMIO,
27
VIRT_PCIE_PIO,
28
VIRT_PCIE_ECAM,
29
+ VIRT_PCIE_ECAM_HIGH,
30
VIRT_PLATFORM_BUS,
31
VIRT_PCIE_MMIO_HIGH,
32
VIRT_GPIO,
33
@@ -XXX,XX +XXX,XX @@ typedef struct {
34
FWCfgState *fw_cfg;
35
bool secure;
36
bool highmem;
37
+ bool highmem_ecam;
38
bool its;
39
bool virt;
40
int32_t gic_version;
41
@@ -XXX,XX +XXX,XX @@ typedef struct {
42
int psci_conduit;
43
} VirtMachineState;
44
45
+#define VIRT_ECAM_ID(high) (high ? VIRT_PCIE_ECAM_HIGH : VIRT_PCIE_ECAM)
46
+
47
#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
48
#define VIRT_MACHINE(obj) \
49
OBJECT_CHECK(VirtMachineState, (obj), TYPE_VIRT_MACHINE)
50
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/virt-acpi-build.c
53
+++ b/hw/arm/virt-acpi-build.c
54
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_virtio(Aml *scope,
55
}
56
57
static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
58
- uint32_t irq, bool use_highmem)
59
+ uint32_t irq, bool use_highmem, bool highmem_ecam)
60
{
61
+ int ecam_id = VIRT_ECAM_ID(highmem_ecam);
62
Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf;
63
int i, bus_no;
64
hwaddr base_mmio = memmap[VIRT_PCIE_MMIO].base;
65
hwaddr size_mmio = memmap[VIRT_PCIE_MMIO].size;
66
hwaddr base_pio = memmap[VIRT_PCIE_PIO].base;
67
hwaddr size_pio = memmap[VIRT_PCIE_PIO].size;
68
- hwaddr base_ecam = memmap[VIRT_PCIE_ECAM].base;
69
- hwaddr size_ecam = memmap[VIRT_PCIE_ECAM].size;
70
+ hwaddr base_ecam = memmap[ecam_id].base;
71
+ hwaddr size_ecam = memmap[ecam_id].size;
72
int nr_pcie_buses = size_ecam / PCIE_MMCFG_SIZE_MIN;
73
74
Aml *dev = aml_device("%s", "PCI0");
75
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
76
aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
77
78
/* Declare the PCI Routing Table. */
79
- Aml *rt_pkg = aml_package(nr_pcie_buses * PCI_NUM_PINS);
80
+ Aml *rt_pkg = aml_varpackage(nr_pcie_buses * PCI_NUM_PINS);
81
for (bus_no = 0; bus_no < nr_pcie_buses; bus_no++) {
82
for (i = 0; i < PCI_NUM_PINS; i++) {
83
int gsi = (i + bus_no) % PCI_NUM_PINS;
84
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
85
Aml *dev_res0 = aml_device("%s", "RES0");
86
aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02")));
87
crs = aml_resource_template();
88
- aml_append(crs, aml_memory32_fixed(base_ecam, size_ecam, AML_READ_WRITE));
89
+ aml_append(crs,
90
+ aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
91
+ AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000, base_ecam,
92
+ base_ecam + size_ecam - 1, 0x0000, size_ecam));
93
aml_append(dev_res0, aml_name_decl("_CRS", crs));
94
aml_append(dev, dev_res0);
95
aml_append(scope, dev);
96
@@ -XXX,XX +XXX,XX @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
97
{
98
AcpiTableMcfg *mcfg;
99
const MemMapEntry *memmap = vms->memmap;
100
+ int ecam_id = VIRT_ECAM_ID(vms->highmem_ecam);
101
int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
102
int mcfg_start = table_data->len;
103
104
mcfg = acpi_data_push(table_data, len);
105
- mcfg->allocation[0].address = cpu_to_le64(memmap[VIRT_PCIE_ECAM].base);
106
+ mcfg->allocation[0].address = cpu_to_le64(memmap[ecam_id].base);
107
108
/* Only a single allocation so no need to play with segments */
109
mcfg->allocation[0].pci_segment = cpu_to_le16(0);
110
mcfg->allocation[0].start_bus_number = 0;
111
- mcfg->allocation[0].end_bus_number = (memmap[VIRT_PCIE_ECAM].size
112
+ mcfg->allocation[0].end_bus_number = (memmap[ecam_id].size
113
/ PCIE_MMCFG_SIZE_MIN) - 1;
114
115
build_header(linker, table_data, (void *)(table_data->data + mcfg_start),
116
@@ -XXX,XX +XXX,XX @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
117
acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
118
(irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
119
acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
120
- vms->highmem);
121
+ vms->highmem, vms->highmem_ecam);
122
acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
123
(irqmap[VIRT_GPIO] + ARM_SPI_BASE));
124
acpi_dsdt_add_power_button(scope);
125
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/hw/arm/virt.c
128
+++ b/hw/arm/virt.c
129
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
130
[VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
131
/* Additional 64 MB redist region (can contain up to 512 redistributors) */
132
[VIRT_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
133
+ [VIRT_PCIE_ECAM_HIGH] = { 0x4010000000ULL, 0x10000000 },
134
/* Second PCIe window, 512GB wide at the 512GB boundary */
135
[VIRT_PCIE_MMIO_HIGH] = { 0x8000000000ULL, 0x8000000000ULL },
136
};
137
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
138
hwaddr size_mmio_high = vms->memmap[VIRT_PCIE_MMIO_HIGH].size;
139
hwaddr base_pio = vms->memmap[VIRT_PCIE_PIO].base;
140
hwaddr size_pio = vms->memmap[VIRT_PCIE_PIO].size;
141
- hwaddr base_ecam = vms->memmap[VIRT_PCIE_ECAM].base;
142
- hwaddr size_ecam = vms->memmap[VIRT_PCIE_ECAM].size;
143
+ hwaddr base_ecam, size_ecam;
144
hwaddr base = base_mmio;
145
- int nr_pcie_buses = size_ecam / PCIE_MMCFG_SIZE_MIN;
146
+ int nr_pcie_buses;
147
int irq = vms->irqmap[VIRT_PCIE];
148
MemoryRegion *mmio_alias;
149
MemoryRegion *mmio_reg;
150
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
151
MemoryRegion *ecam_reg;
152
DeviceState *dev;
153
char *nodename;
154
- int i;
155
+ int i, ecam_id;
156
PCIHostState *pci;
157
158
dev = qdev_create(NULL, TYPE_GPEX_HOST);
159
qdev_init_nofail(dev);
160
161
+ ecam_id = VIRT_ECAM_ID(vms->highmem_ecam);
162
+ base_ecam = vms->memmap[ecam_id].base;
163
+ size_ecam = vms->memmap[ecam_id].size;
164
+ nr_pcie_buses = size_ecam / PCIE_MMCFG_SIZE_MIN;
165
/* Map only the first size_ecam bytes of ECAM space */
166
ecam_alias = g_new0(MemoryRegion, 1);
167
ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
168
--
169
2.17.1
170
171
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
Add virt-3.0 machine type.
4
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
7
Reviewed-by: Andrew Jones <drjones@redhat.com>
8
Message-id: 1529072910-16156-10-git-send-email-eric.auger@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/virt.c | 15 +++++++++++++--
12
1 file changed, 13 insertions(+), 2 deletions(-)
13
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/virt.c
17
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@ type_init(machvirt_machine_init);
19
#define VIRT_COMPAT_2_12 \
20
HW_COMPAT_2_12
21
22
-static void virt_2_12_instance_init(Object *obj)
23
+static void virt_3_0_instance_init(Object *obj)
24
{
25
VirtMachineState *vms = VIRT_MACHINE(obj);
26
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
27
@@ -XXX,XX +XXX,XX @@ static void virt_2_12_instance_init(Object *obj)
28
vms->irqmap = a15irqmap;
29
}
30
31
+static void virt_machine_3_0_options(MachineClass *mc)
32
+{
33
+}
34
+DEFINE_VIRT_MACHINE_AS_LATEST(3, 0)
35
+
36
+static void virt_2_12_instance_init(Object *obj)
37
+{
38
+ virt_3_0_instance_init(obj);
39
+}
40
+
41
static void virt_machine_2_12_options(MachineClass *mc)
42
{
43
+ virt_machine_3_0_options(mc);
44
SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_12);
45
}
46
-DEFINE_VIRT_MACHINE_AS_LATEST(2, 12)
47
+DEFINE_VIRT_MACHINE(2, 12)
48
49
#define VIRT_COMPAT_2_11 \
50
HW_COMPAT_2_11
51
--
52
2.17.1
53
54
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
With this patch, virt-3.0 machine uses a new 256MB ECAM region
4
by default instead of the legacy 16MB one, if highmem is set
5
(LPAE supported by the guest) and (!firmware_loaded || aarch64).
6
7
Indeed aarch32 mode FW may not support this high ECAM region.
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
11
Reviewed-by: Andrew Jones <drjones@redhat.com>
12
Message-id: 1529072910-16156-11-git-send-email-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/hw/arm/virt.h | 1 +
16
hw/arm/virt.c | 10 ++++++++++
17
2 files changed, 11 insertions(+)
18
19
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/arm/virt.h
22
+++ b/include/hw/arm/virt.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
24
bool no_pmu;
25
bool claim_edge_triggered_timers;
26
bool smbios_old_sys_ver;
27
+ bool no_highmem_ecam;
28
} VirtMachineClass;
29
30
typedef struct {
31
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/virt.c
34
+++ b/hw/arm/virt.c
35
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
36
int n, virt_max_cpus;
37
MemoryRegion *ram = g_new(MemoryRegion, 1);
38
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
39
+ bool aarch64 = true;
40
41
/* We can probe only here because during property set
42
* KVM is not available yet
43
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
44
numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpuobj),
45
&error_fatal);
46
47
+ aarch64 &= object_property_get_bool(cpuobj, "aarch64", NULL);
48
+
49
if (!vms->secure) {
50
object_property_set_bool(cpuobj, false, "has_el3", NULL);
51
}
52
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
53
create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
54
}
55
56
+ vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
57
+
58
create_rtc(vms, pic);
59
60
create_pcie(vms, pic);
61
@@ -XXX,XX +XXX,XX @@ static void virt_3_0_instance_init(Object *obj)
62
"Set GIC version. "
63
"Valid values are 2, 3 and host", NULL);
64
65
+ vms->highmem_ecam = !vmc->no_highmem_ecam;
66
+
67
if (vmc->no_its) {
68
vms->its = false;
69
} else {
70
@@ -XXX,XX +XXX,XX @@ static void virt_2_12_instance_init(Object *obj)
71
72
static void virt_machine_2_12_options(MachineClass *mc)
73
{
74
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
75
+
76
virt_machine_3_0_options(mc);
77
SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_12);
78
+ vmc->no_highmem_ecam = true;
79
}
80
DEFINE_VIRT_MACHINE(2, 12)
81
82
--
83
2.17.1
84
85
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
virt 3.0 now allows up to 512 vcpus whereas for earlier machine
4
types, max_cpus was set to 255 and any attempt to start the
5
machine with vcpus > 255 was rejected at a very early stage,
6
in vl.c/main level.
7
8
512 is the max supported by KVM. Anyway the actual vcpu count
9
that can be achieved depends on other parameters such as the
10
acceleration mode, the vgic version, the host kernel version.
11
Those are discovered later on.
12
13
Signed-off-by: Eric Auger <eric.auger@redhat.com>
14
Reviewed-by: Andrew Jones <drjones@redhat.com>
15
Message-id: 1529072910-16156-12-git-send-email-eric.auger@redhat.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
hw/arm/virt.c | 7 ++++---
19
1 file changed, 4 insertions(+), 3 deletions(-)
20
21
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/virt.c
24
+++ b/hw/arm/virt.c
25
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
26
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
27
28
mc->init = machvirt_init;
29
- /* Start max_cpus at the maximum QEMU supports. We'll further restrict
30
- * it later in machvirt_init, where we have more information about the
31
+ /* Start with max_cpus set to 512, which is the maximum supported by KVM.
32
+ * The value may be reduced later when we have more information about the
33
* configuration of the particular instance.
34
*/
35
- mc->max_cpus = 255;
36
+ mc->max_cpus = 512;
37
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC);
38
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE);
39
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
40
@@ -XXX,XX +XXX,XX @@ static void virt_machine_2_12_options(MachineClass *mc)
41
virt_machine_3_0_options(mc);
42
SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_12);
43
vmc->no_highmem_ecam = true;
44
+ mc->max_cpus = 255;
45
}
46
DEFINE_VIRT_MACHINE(2, 12)
47
48
--
49
2.17.1
50
51
diff view generated by jsdifflib
1
The interrupt outputs from the MPC in the IoTKit and the expansion
1
From: Vikram Garhwal <vikram.garhwal@amd.com>
2
MPCs in the board must be wired up to the security controller, and
3
also all ORed together to produce a single line to the NVIC.
4
2
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()
7
8
Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
9
Message-id: 20230628202758.16398-1-vikram.garhwal@amd.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180620132032.28865-8-peter.maydell@linaro.org
8
---
12
---
9
include/hw/arm/iotkit.h | 6 ++++
13
tests/qtest/xlnx-canfd-test.c | 33 +++++++++++----------------------
10
hw/arm/iotkit.c | 74 +++++++++++++++++++++++++++++++++++++++++
14
1 file changed, 11 insertions(+), 22 deletions(-)
11
2 files changed, 80 insertions(+)
12
15
13
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
16
diff --git a/tests/qtest/xlnx-canfd-test.c b/tests/qtest/xlnx-canfd-test.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/iotkit.h
18
--- a/tests/qtest/xlnx-canfd-test.c
16
+++ b/include/hw/arm/iotkit.h
19
+++ b/tests/qtest/xlnx-canfd-test.c
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void generate_random_data(uint32_t *buf_tx, bool is_canfd_frame)
18
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable
21
/* Generate random TX data for CANFD frame. */
19
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear
22
if (is_canfd_frame) {
20
* + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status
23
for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
21
+ * Controlling each of the 16 expansion MPCs which a system using the IoTKit
24
- buf_tx[2 + i] = rand();
22
+ * might provide:
25
+ buf_tx[2 + i] = g_random_int();
23
+ * + named GPIO inputs mpcexp_status[0..15]
26
}
24
*/
27
} else {
25
28
/* Generate random TX data for CAN frame. */
26
#ifndef IOTKIT_H
29
for (int i = 0; i < CAN_FRAME_SIZE - 2; i++) {
27
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
30
- buf_tx[2 + i] = rand();
28
qemu_or_irq ppc_irq_orgate;
31
+ buf_tx[2 + i] = g_random_int();
29
SplitIRQ sec_resp_splitter;
32
}
30
SplitIRQ ppc_irq_splitter[NUM_PPCS];
33
}
31
+ SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
32
+ qemu_or_irq mpc_irq_orgate;
33
34
UnimplementedDeviceState dualtimer;
35
UnimplementedDeviceState s32ktimer;
36
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
37
qemu_irq nsc_cfg_in;
38
39
qemu_irq irq_status_in[NUM_EXTERNAL_PPCS];
40
+ qemu_irq mpcexp_status_in[IOTS_NUM_EXP_MPC];
41
42
uint32_t nsccfg;
43
44
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/iotkit.c
47
+++ b/hw/arm/iotkit.c
48
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
49
init_sysbus_child(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
50
TYPE_TZ_PPC);
51
init_sysbus_child(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
52
+ object_initialize(&s->mpc_irq_orgate, sizeof(s->mpc_irq_orgate),
53
+ TYPE_OR_IRQ);
54
+ object_property_add_child(obj, "mpc-irq-orgate",
55
+ OBJECT(&s->mpc_irq_orgate), &error_abort);
56
+ for (i = 0; i < ARRAY_SIZE(s->mpc_irq_splitter); i++) {
57
+ char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
58
+ SplitIRQ *splitter = &s->mpc_irq_splitter[i];
59
+
60
+ object_initialize(splitter, sizeof(*splitter), TYPE_SPLIT_IRQ);
61
+ object_property_add_child(obj, name, OBJECT(splitter), &error_abort);
62
+ g_free(name);
63
+ }
64
init_sysbus_child(obj, "timer0", &s->timer0, sizeof(s->timer0),
65
TYPE_CMSDK_APB_TIMER);
66
init_sysbus_child(obj, "timer1", &s->timer1, sizeof(s->timer1),
67
@@ -XXX,XX +XXX,XX @@ static void iotkit_exp_irq(void *opaque, int n, int level)
68
qemu_set_irq(s->exp_irqs[n], level);
69
}
34
}
70
35
71
+static void iotkit_mpcexp_status(void *opaque, int n, int level)
36
-static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
72
+{
37
+static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx,
73
+ IoTKit *s = IOTKIT(opaque);
38
+ uint32_t frame_size)
74
+ qemu_set_irq(s->mpcexp_status_in[n], level);
75
+}
76
+
77
static void iotkit_realize(DeviceState *dev, Error **errp)
78
{
39
{
79
IoTKit *s = IOTKIT(dev);
40
uint32_t int_status;
80
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
41
uint32_t fifo_status_reg_value;
81
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
42
/* At which RX FIFO the received data is stored. */
82
0));
43
uint8_t store_ind = 0;
83
44
- bool is_canfd_frame = false;
84
+ /* We must OR together lines from the MPC splitters to go to the NVIC */
45
85
+ object_property_set_int(OBJECT(&s->mpc_irq_orgate),
46
/* Read the interrupt on CANFD rx. */
86
+ IOTS_NUM_EXP_MPC + IOTS_NUM_MPC, "num-lines", &err);
47
int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
87
+ if (err) {
48
@@ -XXX,XX +XXX,XX @@ static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
88
+ error_propagate(errp, err);
49
buf_rx[0] = qtest_readl(qts, can_base_addr + R_RX0_ID_OFFSET);
89
+ return;
50
buf_rx[1] = qtest_readl(qts, can_base_addr + R_RX0_DLC_OFFSET);
90
+ }
51
91
+ object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
52
- is_canfd_frame = (buf_rx[1] >> DLC_FD_BIT_SHIFT) & 1;
92
+ "realized", &err);
53
-
93
+ if (err) {
54
- if (is_canfd_frame) {
94
+ error_propagate(errp, err);
55
- for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
95
+ return;
56
- buf_rx[i + 2] = qtest_readl(qts,
96
+ }
57
- can_base_addr + R_RX0_DATA1_OFFSET + 4 * i);
97
+ qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
58
- }
98
+ qdev_get_gpio_in(DEVICE(&s->armv7m), 9));
59
- } else {
99
+
60
- buf_rx[2] = qtest_readl(qts, can_base_addr + R_RX0_DATA1_OFFSET);
100
/* Devices behind APB PPC0:
61
- buf_rx[3] = qtest_readl(qts, can_base_addr + R_RX0_DATA2_OFFSET);
101
* 0x40000000: timer0
62
+ for (int i = 0; i < frame_size - 2; i++) {
102
* 0x40001000: timer1
63
+ buf_rx[i + 2] = qtest_readl(qts,
103
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
64
+ can_base_addr + R_RX0_DATA1_OFFSET + 4 * i);
104
g_free(gpioname);
105
}
65
}
106
66
107
+ /* Wire up the splitters for the MPC IRQs */
67
/* Clear the RX interrupt. */
108
+ for (i = 0; i < IOTS_NUM_EXP_MPC + IOTS_NUM_MPC; i++) {
68
@@ -XXX,XX +XXX,XX @@ static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
109
+ SplitIRQ *splitter = &s->mpc_irq_splitter[i];
69
g_assert_cmpint((buf_rx[size] & DLC_FD_BIT_MASK), ==,
110
+ DeviceState *dev_splitter = DEVICE(splitter);
70
(buf_tx[size] & DLC_FD_BIT_MASK));
111
+
71
} else {
112
+ object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
72
- if (!is_canfd_frame && size == 4) {
113
+ if (err) {
73
- break;
114
+ error_propagate(errp, err);
74
- }
115
+ return;
75
-
116
+ }
76
g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
117
+ object_property_set_bool(OBJECT(splitter), true, "realized", &err);
77
}
118
+ if (err) {
78
119
+ error_propagate(errp, err);
79
@@ -XXX,XX +XXX,XX @@ static void test_can_data_transfer(void)
120
+ return;
80
write_data(qts, CANFD0_BASE_ADDR, buf_tx, false);
121
+ }
81
122
+
82
send_data(qts, CANFD0_BASE_ADDR);
123
+ if (i < IOTS_NUM_EXP_MPC) {
83
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
124
+ /* Splitter input is from GPIO input line */
84
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CAN_FRAME_SIZE);
125
+ s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
85
match_rx_tx_data(buf_tx, buf_rx, false);
126
+ qdev_connect_gpio_out(dev_splitter, 0,
86
127
+ qdev_get_gpio_in_named(dev_secctl,
87
qtest_quit(qts);
128
+ "mpcexp_status", i));
88
@@ -XXX,XX +XXX,XX @@ static void test_canfd_data_transfer(void)
129
+ } else {
89
write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
130
+ /* Splitter input is from our own MPC */
90
131
+ qdev_connect_gpio_out_named(DEVICE(&s->mpc), "irq", 0,
91
send_data(qts, CANFD0_BASE_ADDR);
132
+ qdev_get_gpio_in(dev_splitter, 0));
92
- read_data(qts, CANFD1_BASE_ADDR, buf_rx);
133
+ qdev_connect_gpio_out(dev_splitter, 0,
93
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
134
+ qdev_get_gpio_in_named(dev_secctl,
94
match_rx_tx_data(buf_tx, buf_rx, true);
135
+ "mpc_status", 0));
95
136
+ }
96
qtest_quit(qts);
137
+
97
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
138
+ qdev_connect_gpio_out(dev_splitter, 1,
98
write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
139
+ qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
99
140
+ }
100
send_data(qts, CANFD0_BASE_ADDR);
141
+ /* Create GPIO inputs which will pass the line state for our
101
- read_data(qts, CANFD0_BASE_ADDR, buf_rx);
142
+ * mpcexp_irq inputs to the correct splitter devices.
102
+ read_data(qts, CANFD0_BASE_ADDR, buf_rx, CANFD_FRAME_SIZE);
143
+ */
103
match_rx_tx_data(buf_tx, buf_rx, true);
144
+ qdev_init_gpio_in_named(dev, iotkit_mpcexp_status, "mpcexp_status",
104
145
+ IOTS_NUM_EXP_MPC);
105
generate_random_data(buf_tx, true);
146
+
106
@@ -XXX,XX +XXX,XX @@ static void test_can_loopback(void)
147
iotkit_forward_sec_resp_cfg(s);
107
write_data(qts, CANFD1_BASE_ADDR, buf_tx, true);
148
108
149
system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
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);
150
--
115
--
151
2.17.1
116
2.34.1
152
153
diff view generated by jsdifflib
1
From: Julia Suvorova <jusual@mail.ru>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Unlike ARMv7-M, ARMv6-M and ARMv8-M Baseline only supports naturally
3
This code is only relevant when TCG is present in the build. Building
4
aligned memory accesses for load/store instructions.
4
with --disable-tcg --enable-xen on an x86 host we get:
5
5
6
Signed-off-by: Julia Suvorova <jusual@mail.ru>
6
$ ../configure --target-list=x86_64-softmmu,aarch64-softmmu --disable-tcg --enable-xen
7
Message-id: 20180622080138.17702-3-jusual@mail.ru
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
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
20
---
11
target/arm/translate.c | 18 ++++++++++++++++--
21
target/arm/gdbstub.c | 4 ++++
12
1 file changed, 16 insertions(+), 2 deletions(-)
22
1 file changed, 4 insertions(+)
13
23
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
24
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
26
--- a/target/arm/gdbstub.c
17
+++ b/target/arm/translate.c
27
+++ b/target/arm/gdbstub.c
18
@@ -XXX,XX +XXX,XX @@ static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
28
@@ -XXX,XX +XXX,XX @@ static int arm_gen_dynamic_sysreg_xml(CPUState *cs, int base_reg)
19
static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
29
return cpu->dyn_sysreg_xml.num;
20
int index, TCGMemOp opc)
30
}
31
32
+#ifdef CONFIG_TCG
33
typedef enum {
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)
21
{
43
{
22
- TCGv addr = gen_aa32_addr(s, a32, opc);
44
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
23
+ TCGv addr;
45
arm_gen_dynamic_sysreg_xml(cs, cs->gdb_num_regs),
24
+
46
"system-registers.xml", 0);
25
+ if (arm_dc_feature(s, ARM_FEATURE_M) &&
47
26
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
48
+#ifdef CONFIG_TCG
27
+ opc |= MO_ALIGN;
49
if (arm_feature(env, ARM_FEATURE_M) && tcg_enabled()) {
28
+ }
50
gdb_register_coprocessor(cs,
29
+
51
arm_gdb_get_m_systemreg, arm_gdb_set_m_systemreg,
30
+ addr = gen_aa32_addr(s, a32, opc);
52
@@ -XXX,XX +XXX,XX @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
31
tcg_gen_qemu_ld_i32(val, addr, index, opc);
53
}
32
tcg_temp_free(addr);
54
#endif
33
}
55
}
34
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
56
+#endif /* CONFIG_TCG */
35
static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
36
int index, TCGMemOp opc)
37
{
38
- TCGv addr = gen_aa32_addr(s, a32, opc);
39
+ TCGv addr;
40
+
41
+ if (arm_dc_feature(s, ARM_FEATURE_M) &&
42
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
43
+ opc |= MO_ALIGN;
44
+ }
45
+
46
+ addr = gen_aa32_addr(s, a32, opc);
47
tcg_gen_qemu_st_i32(val, addr, index, opc);
48
tcg_temp_free(addr);
49
}
57
}
50
--
58
--
51
2.17.1
59
2.34.1
52
53
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
The ZynqMP has Cortex-R5Fs with the optional FPU enabled.
3
AwSRAMCClass is larger than SysBusDeviceClass so the class size must be
4
advertised accordingly.
4
5
5
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
6
Fixes: 05def917e1 ("hw: arm: allwinner-sramc: Add SRAM Controller support for R40")
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20230628110905.38125-1-akihiko.odaki@daynix.com
10
Message-id: 20180529124707.3025-3-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
hw/arm/xlnx-zcu102.c | 2 +-
13
hw/misc/allwinner-sramc.c | 1 +
14
hw/arm/xlnx-zynqmp.c | 2 +-
14
1 file changed, 1 insertion(+)
15
2 files changed, 2 insertions(+), 2 deletions(-)
16
15
17
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
16
diff --git a/hw/misc/allwinner-sramc.c b/hw/misc/allwinner-sramc.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/xlnx-zcu102.c
18
--- a/hw/misc/allwinner-sramc.c
20
+++ b/hw/arm/xlnx-zcu102.c
19
+++ b/hw/misc/allwinner-sramc.c
21
@@ -XXX,XX +XXX,XX @@ static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
20
@@ -XXX,XX +XXX,XX @@ static const TypeInfo allwinner_sramc_info = {
22
{
21
.parent = TYPE_SYS_BUS_DEVICE,
23
MachineClass *mc = MACHINE_CLASS(oc);
22
.instance_init = allwinner_sramc_init,
24
23
.instance_size = sizeof(AwSRAMCState),
25
- mc->desc = "Xilinx ZynqMP ZCU102 board with 4xA53s and 2xR5s based on " \
24
+ .class_size = sizeof(AwSRAMCClass),
26
+ mc->desc = "Xilinx ZynqMP ZCU102 board with 4xA53s and 2xR5Fs based on " \
25
.class_init = allwinner_sramc_class_init,
27
"the value of smp";
26
};
28
mc->init = xlnx_zcu102_init;
29
mc->block_default_type = IF_IDE;
30
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/xlnx-zynqmp.c
33
+++ b/hw/arm/xlnx-zynqmp.c
34
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_rpu(XlnxZynqMPState *s, const char *boot_cpu,
35
char *name;
36
37
object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
38
- "cortex-r5-" TYPE_ARM_CPU);
39
+ "cortex-r5f-" TYPE_ARM_CPU);
40
object_property_add_child(OBJECT(s), "rpu-cpu[*]",
41
OBJECT(&s->rpu_cpu[i]), &error_abort);
42
27
43
--
28
--
44
2.17.1
29
2.34.1
45
30
46
31
diff view generated by jsdifflib
1
Instantiate and wire up the Memory Protection Controllers
1
In handle_interrupt() we use level as an index into the interrupt_vector[]
2
in the MPS2 board itself.
2
array. This is safe because we have checked it against env->config->nlevel,
3
but Coverity can't see that (and it is only true because each CPU config
4
sets its XCHAL_NUM_INTLEVELS to something less than MAX_NLEVELS), so it
5
complains about a possible array overrun (CID 1507131)
6
7
Add an assert() which will make Coverity happy and catch the unlikely
8
case of a mis-set XCHAL_NUM_INTLEVELS in future.
3
9
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Acked-by: Max Filippov <jcmvbkbc@gmail.com>
6
Message-id: 20180620132032.28865-9-peter.maydell@linaro.org
12
Message-id: 20230623154135.1930261-1-peter.maydell@linaro.org
7
---
13
---
8
hw/arm/mps2-tz.c | 71 ++++++++++++++++++++++++++++++------------------
14
target/xtensa/exc_helper.c | 3 +++
9
1 file changed, 44 insertions(+), 27 deletions(-)
15
1 file changed, 3 insertions(+)
10
16
11
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
diff --git a/target/xtensa/exc_helper.c b/target/xtensa/exc_helper.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2-tz.c
19
--- a/target/xtensa/exc_helper.c
14
+++ b/hw/arm/mps2-tz.c
20
+++ b/target/xtensa/exc_helper.c
15
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void handle_interrupt(CPUXtensaState *env)
16
#include "hw/timer/cmsdk-apb-timer.h"
22
CPUState *cs = env_cpu(env);
17
#include "hw/misc/mps2-scc.h"
23
18
#include "hw/misc/mps2-fpgaio.h"
24
if (level > 1) {
19
+#include "hw/misc/tz-mpc.h"
25
+ /* env->config->nlevel check should have ensured this */
20
#include "hw/arm/iotkit.h"
26
+ assert(level < sizeof(env->config->interrupt_vector));
21
#include "hw/devices.h"
22
#include "net/net.h"
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
24
25
IoTKit iotkit;
26
MemoryRegion psram;
27
- MemoryRegion ssram1;
28
+ MemoryRegion ssram[3];
29
MemoryRegion ssram1_m;
30
- MemoryRegion ssram23;
31
MPS2SCC scc;
32
MPS2FPGAIO fpgaio;
33
TZPPC ppc[5];
34
- UnimplementedDeviceState ssram_mpc[3];
35
+ TZMPC ssram_mpc[3];
36
UnimplementedDeviceState spi[5];
37
UnimplementedDeviceState i2c[4];
38
UnimplementedDeviceState i2s_audio;
39
@@ -XXX,XX +XXX,XX @@ typedef struct {
40
/* Main SYSCLK frequency in Hz */
41
#define SYSCLK_FRQ 20000000
42
43
-/* Initialize the auxiliary RAM region @mr and map it into
44
- * the memory map at @base.
45
- */
46
-static void make_ram(MemoryRegion *mr, const char *name,
47
- hwaddr base, hwaddr size)
48
-{
49
- memory_region_init_ram(mr, NULL, name, size, &error_fatal);
50
- memory_region_add_subregion(get_system_memory(), base, mr);
51
-}
52
-
53
/* Create an alias of an entire original MemoryRegion @orig
54
* located at @base in the memory map.
55
*/
56
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
57
return sysbus_mmio_get_region(s, 0);
58
}
59
60
+static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
61
+ const char *name, hwaddr size)
62
+{
63
+ TZMPC *mpc = opaque;
64
+ int i = mpc - &mms->ssram_mpc[0];
65
+ MemoryRegion *ssram = &mms->ssram[i];
66
+ MemoryRegion *upstream;
67
+ char *mpcname = g_strdup_printf("%s-mpc", name);
68
+ static uint32_t ramsize[] = { 0x00400000, 0x00200000, 0x00200000 };
69
+ static uint32_t rambase[] = { 0x00000000, 0x28000000, 0x28200000 };
70
+
27
+
71
+ memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);
28
env->sregs[EPC1 + level - 1] = env->pc;
72
+
29
env->sregs[EPS2 + level - 2] = env->sregs[PS];
73
+ init_sysbus_child(OBJECT(mms), mpcname, mpc,
30
env->sregs[PS] =
74
+ sizeof(mms->ssram_mpc[0]), TYPE_TZ_MPC);
75
+ object_property_set_link(OBJECT(mpc), OBJECT(ssram),
76
+ "downstream", &error_fatal);
77
+ object_property_set_bool(OBJECT(mpc), true, "realized", &error_fatal);
78
+ /* Map the upstream end of the MPC into system memory */
79
+ upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
80
+ memory_region_add_subregion(get_system_memory(), rambase[i], upstream);
81
+ /* and connect its interrupt to the IoTKit */
82
+ qdev_connect_gpio_out_named(DEVICE(mpc), "irq", 0,
83
+ qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
84
+ "mpcexp_status", i));
85
+
86
+ /* The first SSRAM is a special case as it has an alias; accesses to
87
+ * the alias region at 0x00400000 must also go to the MPC upstream.
88
+ */
89
+ if (i == 0) {
90
+ make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", upstream, 0x00400000);
91
+ }
92
+
93
+ g_free(mpcname);
94
+ /* Return the register interface MR for our caller to map behind the PPC */
95
+ return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
96
+}
97
+
98
static void mps2tz_common_init(MachineState *machine)
99
{
100
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
101
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
102
NULL, "mps.ram", 0x01000000);
103
memory_region_add_subregion(system_memory, 0x80000000, &mms->psram);
104
105
- /* The SSRAM memories should all be behind Memory Protection Controllers,
106
- * but we don't implement that yet.
107
- */
108
- make_ram(&mms->ssram1, "mps.ssram1", 0x00000000, 0x00400000);
109
- make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x00400000);
110
-
111
- make_ram(&mms->ssram23, "mps.ssram23", 0x28000000, 0x00400000);
112
-
113
/* The overflow IRQs for all UARTs are ORed together.
114
* Tx, Rx and "combined" IRQs are sent to the NVIC separately.
115
* Create the OR gate for this.
116
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
117
const PPCInfo ppcs[] = { {
118
.name = "apb_ppcexp0",
119
.ports = {
120
- { "ssram-mpc0", make_unimp_dev, &mms->ssram_mpc[0],
121
- 0x58007000, 0x1000 },
122
- { "ssram-mpc1", make_unimp_dev, &mms->ssram_mpc[1],
123
- 0x58008000, 0x1000 },
124
- { "ssram-mpc2", make_unimp_dev, &mms->ssram_mpc[2],
125
- 0x58009000, 0x1000 },
126
+ { "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
127
+ { "ssram-1", make_mpc, &mms->ssram_mpc[1], 0x58008000, 0x1000 },
128
+ { "ssram-2", make_mpc, &mms->ssram_mpc[2], 0x58009000, 0x1000 },
129
},
130
}, {
131
.name = "apb_ppcexp1",
132
--
31
--
133
2.17.1
32
2.34.1
134
135
diff view generated by jsdifflib
1
Implement the missing registers for the TZ MPC.
1
We already squash the ID register field for FEAT_SPE (the Statistical
2
Profiling Extension) because TCG does not implement it and if we
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)
12
13
Most of these, like FEAT_SPE, are "introspection/trace" type features
14
which QEMU is unlikely to ever implement. The odd-one-out here is
15
FEAT_NV -- we could implement that and at some point we probably
16
will.
2
17
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Eric Auger <eric.auger@redhat.com>
19
Message-id: 20230704130647.2842917-2-peter.maydell@linaro.org
5
Message-id: 20180620132032.28865-3-peter.maydell@linaro.org
20
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
---
22
---
7
include/hw/misc/tz-mpc.h | 10 +++
23
target/arm/cpu.c | 33 +++++++++++++++++++++++++++++----
8
hw/misc/tz-mpc.c | 140 ++++++++++++++++++++++++++++++++++++++-
24
1 file changed, 29 insertions(+), 4 deletions(-)
9
2 files changed, 147 insertions(+), 3 deletions(-)
10
25
11
diff --git a/include/hw/misc/tz-mpc.h b/include/hw/misc/tz-mpc.h
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
13
--- a/include/hw/misc/tz-mpc.h
28
--- a/target/arm/cpu.c
14
+++ b/include/hw/misc/tz-mpc.h
29
+++ b/target/arm/cpu.c
15
@@ -XXX,XX +XXX,XX @@ struct TZMPC {
30
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
16
31
17
/*< public >*/
32
if (tcg_enabled()) {
18
33
/*
19
+ /* State */
34
- * Don't report the Statistical Profiling Extension in the ID
20
+ uint32_t ctrl;
35
- * registers, because TCG doesn't implement it yet (not even a
21
+ uint32_t blk_idx;
36
- * minimal stub version) and guests will fall over when they
22
+ uint32_t int_stat;
37
- * try to access the non-existent system registers for it.
23
+ uint32_t int_en;
38
+ * Don't report some architectural features in the ID registers
24
+ uint32_t int_info1;
39
+ * where TCG does not yet implement it (not even a minimal
25
+ uint32_t int_info2;
40
+ * stub version). This avoids guests falling over when they
26
+
41
+ * try to access the non-existent system registers for them.
27
+ uint32_t *blk_lut;
42
*/
28
+
43
+ /* FEAT_SPE (Statistical Profiling Extension) */
29
qemu_irq irq;
44
cpu->isar.id_aa64dfr0 =
30
45
FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMSVER, 0);
31
/* Properties */
46
+ /* FEAT_TRF (Self-hosted Trace Extension) */
32
diff --git a/hw/misc/tz-mpc.c b/hw/misc/tz-mpc.c
47
+ cpu->isar.id_aa64dfr0 =
33
index XXXXXXX..XXXXXXX 100644
48
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEFILT, 0);
34
--- a/hw/misc/tz-mpc.c
49
+ cpu->isar.id_dfr0 =
35
+++ b/hw/misc/tz-mpc.c
50
+ FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, TRACEFILT, 0);
36
@@ -XXX,XX +XXX,XX @@ enum {
51
+ /* Trace Macrocell system register access */
37
52
+ cpu->isar.id_aa64dfr0 =
38
/* Config registers */
53
+ FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, TRACEVER, 0);
39
REG32(CTRL, 0x00)
54
+ cpu->isar.id_dfr0 =
40
+ FIELD(CTRL, SEC_RESP, 4, 1)
55
+ FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPTRC, 0);
41
+ FIELD(CTRL, AUTOINC, 8, 1)
56
+ /* Memory mapped trace */
42
+ FIELD(CTRL, LOCKDOWN, 31, 1)
57
+ cpu->isar.id_dfr0 =
43
REG32(BLK_MAX, 0x10)
58
+ FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, MMAPTRC, 0);
44
REG32(BLK_CFG, 0x14)
59
+ /* FEAT_AMU (Activity Monitors Extension) */
45
REG32(BLK_IDX, 0x18)
60
+ cpu->isar.id_aa64pfr0 =
46
REG32(BLK_LUT, 0x1c)
61
+ FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, AMU, 0);
47
REG32(INT_STAT, 0x20)
62
+ cpu->isar.id_pfr0 =
48
+ FIELD(INT_STAT, IRQ, 0, 1)
63
+ FIELD_DP32(cpu->isar.id_pfr0, ID_PFR0, AMU, 0);
49
REG32(INT_CLEAR, 0x24)
64
+ /* FEAT_MPAM (Memory Partitioning and Monitoring Extension) */
50
+ FIELD(INT_CLEAR, IRQ, 0, 1)
65
+ cpu->isar.id_aa64pfr0 =
51
REG32(INT_EN, 0x28)
66
+ FIELD_DP64(cpu->isar.id_aa64pfr0, ID_AA64PFR0, MPAM, 0);
52
+ FIELD(INT_EN, IRQ, 0, 1)
67
+ /* FEAT_NV (Nested Virtualization) */
53
REG32(INT_INFO1, 0x2c)
68
+ cpu->isar.id_aa64mmfr2 =
54
REG32(INT_INFO2, 0x30)
69
+ FIELD_DP64(cpu->isar.id_aa64mmfr2, ID_AA64MMFR2, NV, 0);
55
REG32(INT_SET, 0x34)
56
+ FIELD(INT_SET, IRQ, 0, 1)
57
REG32(PIDR4, 0xfd0)
58
REG32(PIDR5, 0xfd4)
59
REG32(PIDR6, 0xfd8)
60
@@ -XXX,XX +XXX,XX @@ static const uint8_t tz_mpc_idregs[] = {
61
0x0d, 0xf0, 0x05, 0xb1,
62
};
63
64
+static void tz_mpc_irq_update(TZMPC *s)
65
+{
66
+ qemu_set_irq(s->irq, s->int_stat && s->int_en);
67
+}
68
+
69
+static void tz_mpc_autoinc_idx(TZMPC *s, unsigned access_size)
70
+{
71
+ /* Auto-increment BLK_IDX if necessary */
72
+ if (access_size == 4 && (s->ctrl & R_CTRL_AUTOINC_MASK)) {
73
+ s->blk_idx++;
74
+ s->blk_idx %= s->blk_max;
75
+ }
76
+}
77
+
78
static MemTxResult tz_mpc_reg_read(void *opaque, hwaddr addr,
79
uint64_t *pdata,
80
unsigned size, MemTxAttrs attrs)
81
{
82
+ TZMPC *s = TZ_MPC(opaque);
83
uint64_t r;
84
uint32_t offset = addr & ~0x3;
85
86
@@ -XXX,XX +XXX,XX @@ static MemTxResult tz_mpc_reg_read(void *opaque, hwaddr addr,
87
}
70
}
88
71
89
switch (offset) {
72
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
90
+ case A_CTRL:
91
+ r = s->ctrl;
92
+ break;
93
+ case A_BLK_MAX:
94
+ r = s->blk_max;
95
+ break;
96
+ case A_BLK_CFG:
97
+ /* We are never in "init in progress state", so this just indicates
98
+ * the block size. s->blocksize == (1 << BLK_CFG + 5), so
99
+ * BLK_CFG == ctz32(s->blocksize) - 5
100
+ */
101
+ r = ctz32(s->blocksize) - 5;
102
+ break;
103
+ case A_BLK_IDX:
104
+ r = s->blk_idx;
105
+ break;
106
+ case A_BLK_LUT:
107
+ r = s->blk_lut[s->blk_idx];
108
+ tz_mpc_autoinc_idx(s, size);
109
+ break;
110
+ case A_INT_STAT:
111
+ r = s->int_stat;
112
+ break;
113
+ case A_INT_EN:
114
+ r = s->int_en;
115
+ break;
116
+ case A_INT_INFO1:
117
+ r = s->int_info1;
118
+ break;
119
+ case A_INT_INFO2:
120
+ r = s->int_info2;
121
+ break;
122
case A_PIDR4:
123
case A_PIDR5:
124
case A_PIDR6:
125
@@ -XXX,XX +XXX,XX @@ static MemTxResult tz_mpc_reg_write(void *opaque, hwaddr addr,
126
uint64_t value,
127
unsigned size, MemTxAttrs attrs)
128
{
129
+ TZMPC *s = TZ_MPC(opaque);
130
uint32_t offset = addr & ~0x3;
131
132
trace_tz_mpc_reg_write(addr, value, size);
133
@@ -XXX,XX +XXX,XX @@ static MemTxResult tz_mpc_reg_write(void *opaque, hwaddr addr,
134
uint32_t oldval;
135
136
switch (offset) {
137
- /* As we add support for registers which need expansions
138
- * other than zeroes we'll fill in cases here.
139
- */
140
+ case A_CTRL:
141
+ oldval = s->ctrl;
142
+ break;
143
+ case A_BLK_IDX:
144
+ oldval = s->blk_idx;
145
+ break;
146
+ case A_BLK_LUT:
147
+ oldval = s->blk_lut[s->blk_idx];
148
+ break;
149
default:
150
oldval = 0;
151
break;
152
@@ -XXX,XX +XXX,XX @@ static MemTxResult tz_mpc_reg_write(void *opaque, hwaddr addr,
153
value = deposit32(oldval, (addr & 3) * 8, size * 8, value);
154
}
155
156
+ if ((s->ctrl & R_CTRL_LOCKDOWN_MASK) &&
157
+ (offset == A_CTRL || offset == A_BLK_LUT || offset == A_INT_EN)) {
158
+ /* Lockdown mode makes these three registers read-only, and
159
+ * the only way out of it is to reset the device.
160
+ */
161
+ qemu_log_mask(LOG_GUEST_ERROR, "TZ MPC register write to offset 0x%x "
162
+ "while MPC is in lockdown mode\n", offset);
163
+ return MEMTX_OK;
164
+ }
165
+
166
switch (offset) {
167
+ case A_CTRL:
168
+ /* We don't implement the 'data gating' feature so all other bits
169
+ * are reserved and we make them RAZ/WI.
170
+ */
171
+ s->ctrl = value & (R_CTRL_SEC_RESP_MASK |
172
+ R_CTRL_AUTOINC_MASK |
173
+ R_CTRL_LOCKDOWN_MASK);
174
+ break;
175
+ case A_BLK_IDX:
176
+ s->blk_idx = value % s->blk_max;
177
+ break;
178
+ case A_BLK_LUT:
179
+ s->blk_lut[s->blk_idx] = value;
180
+ tz_mpc_autoinc_idx(s, size);
181
+ break;
182
+ case A_INT_CLEAR:
183
+ if (value & R_INT_CLEAR_IRQ_MASK) {
184
+ s->int_stat = 0;
185
+ tz_mpc_irq_update(s);
186
+ }
187
+ break;
188
+ case A_INT_EN:
189
+ s->int_en = value & R_INT_EN_IRQ_MASK;
190
+ tz_mpc_irq_update(s);
191
+ break;
192
+ case A_INT_SET:
193
+ if (value & R_INT_SET_IRQ_MASK) {
194
+ s->int_stat = R_INT_STAT_IRQ_MASK;
195
+ tz_mpc_irq_update(s);
196
+ }
197
+ break;
198
case A_PIDR4:
199
case A_PIDR5:
200
case A_PIDR6:
201
@@ -XXX,XX +XXX,XX @@ static int tz_mpc_num_indexes(IOMMUMemoryRegion *iommu)
202
203
static void tz_mpc_reset(DeviceState *dev)
204
{
205
+ TZMPC *s = TZ_MPC(dev);
206
+
207
+ s->ctrl = 0x00000100;
208
+ s->blk_idx = 0;
209
+ s->int_stat = 0;
210
+ s->int_en = 1;
211
+ s->int_info1 = 0;
212
+ s->int_info2 = 0;
213
+
214
+ memset(s->blk_lut, 0, s->blk_max * sizeof(uint32_t));
215
}
216
217
static void tz_mpc_init(Object *obj)
218
@@ -XXX,XX +XXX,XX @@ static void tz_mpc_realize(DeviceState *dev, Error **errp)
219
"tz-mpc-downstream");
220
address_space_init(&s->blocked_io_as, &s->blocked_io,
221
"tz-mpc-blocked-io");
222
+
223
+ s->blk_lut = g_new(uint32_t, s->blk_max);
224
+}
225
+
226
+static int tz_mpc_post_load(void *opaque, int version_id)
227
+{
228
+ TZMPC *s = TZ_MPC(opaque);
229
+
230
+ /* Check the incoming data doesn't point blk_idx off the end of blk_lut. */
231
+ if (s->blk_idx >= s->blk_max) {
232
+ return -1;
233
+ }
234
+ return 0;
235
}
236
237
static const VMStateDescription tz_mpc_vmstate = {
238
.name = "tz-mpc",
239
.version_id = 1,
240
.minimum_version_id = 1,
241
+ .post_load = tz_mpc_post_load,
242
.fields = (VMStateField[]) {
243
+ VMSTATE_UINT32(ctrl, TZMPC),
244
+ VMSTATE_UINT32(blk_idx, TZMPC),
245
+ VMSTATE_UINT32(int_stat, TZMPC),
246
+ VMSTATE_UINT32(int_en, TZMPC),
247
+ VMSTATE_UINT32(int_info1, TZMPC),
248
+ VMSTATE_UINT32(int_info2, TZMPC),
249
+ VMSTATE_VARRAY_UINT32(blk_lut, TZMPC, blk_max,
250
+ 0, vmstate_info_uint32, uint32_t),
251
VMSTATE_END_OF_LIST()
252
}
253
};
254
--
73
--
255
2.17.1
74
2.34.1
256
75
257
76
diff view generated by jsdifflib
Deleted patch
1
The MPC is guest-configurable for whether blocked accesses:
2
* should be RAZ/WI or cause a bus error
3
* should generate an interrupt or not
4
1
5
Implement this behaviour in the blocked-access handlers.
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Message-id: 20180620132032.28865-4-peter.maydell@linaro.org
10
---
11
hw/misc/tz-mpc.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++--
12
1 file changed, 48 insertions(+), 2 deletions(-)
13
14
diff --git a/hw/misc/tz-mpc.c b/hw/misc/tz-mpc.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/misc/tz-mpc.c
17
+++ b/hw/misc/tz-mpc.c
18
@@ -XXX,XX +XXX,XX @@ REG32(INT_EN, 0x28)
19
FIELD(INT_EN, IRQ, 0, 1)
20
REG32(INT_INFO1, 0x2c)
21
REG32(INT_INFO2, 0x30)
22
+ FIELD(INT_INFO2, HMASTER, 0, 16)
23
+ FIELD(INT_INFO2, HNONSEC, 16, 1)
24
+ FIELD(INT_INFO2, CFG_NS, 17, 1)
25
REG32(INT_SET, 0x34)
26
FIELD(INT_SET, IRQ, 0, 1)
27
REG32(PIDR4, 0xfd0)
28
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps tz_mpc_reg_ops = {
29
.impl.max_access_size = 4,
30
};
31
32
+static inline bool tz_mpc_cfg_ns(TZMPC *s, hwaddr addr)
33
+{
34
+ /* Return the cfg_ns bit from the LUT for the specified address */
35
+ hwaddr blknum = addr / s->blocksize;
36
+ hwaddr blkword = blknum / 32;
37
+ uint32_t blkbit = 1U << (blknum % 32);
38
+
39
+ /* This would imply the address was larger than the size we
40
+ * defined this memory region to be, so it can't happen.
41
+ */
42
+ assert(blkword < s->blk_max);
43
+ return s->blk_lut[blkword] & blkbit;
44
+}
45
+
46
+static MemTxResult tz_mpc_handle_block(TZMPC *s, hwaddr addr, MemTxAttrs attrs)
47
+{
48
+ /* Handle a blocked transaction: raise IRQ, capture info, etc */
49
+ if (!s->int_stat) {
50
+ /* First blocked transfer: capture information into INT_INFO1 and
51
+ * INT_INFO2. Subsequent transfers are still blocked but don't
52
+ * capture information until the guest clears the interrupt.
53
+ */
54
+
55
+ s->int_info1 = addr;
56
+ s->int_info2 = 0;
57
+ s->int_info2 = FIELD_DP32(s->int_info2, INT_INFO2, HMASTER,
58
+ attrs.requester_id & 0xffff);
59
+ s->int_info2 = FIELD_DP32(s->int_info2, INT_INFO2, HNONSEC,
60
+ ~attrs.secure);
61
+ s->int_info2 = FIELD_DP32(s->int_info2, INT_INFO2, CFG_NS,
62
+ tz_mpc_cfg_ns(s, addr));
63
+ s->int_stat |= R_INT_STAT_IRQ_MASK;
64
+ tz_mpc_irq_update(s);
65
+ }
66
+
67
+ /* Generate bus error if desired; otherwise RAZ/WI */
68
+ return (s->ctrl & R_CTRL_SEC_RESP_MASK) ? MEMTX_ERROR : MEMTX_OK;
69
+}
70
+
71
/* Accesses only reach these read and write functions if the MPC is
72
* blocking them; non-blocked accesses go directly to the downstream
73
* memory region without passing through this code.
74
@@ -XXX,XX +XXX,XX @@ static MemTxResult tz_mpc_mem_blocked_read(void *opaque, hwaddr addr,
75
uint64_t *pdata,
76
unsigned size, MemTxAttrs attrs)
77
{
78
+ TZMPC *s = TZ_MPC(opaque);
79
+
80
trace_tz_mpc_mem_blocked_read(addr, size, attrs.secure);
81
82
*pdata = 0;
83
- return MEMTX_OK;
84
+ return tz_mpc_handle_block(s, addr, attrs);
85
}
86
87
static MemTxResult tz_mpc_mem_blocked_write(void *opaque, hwaddr addr,
88
uint64_t value,
89
unsigned size, MemTxAttrs attrs)
90
{
91
+ TZMPC *s = TZ_MPC(opaque);
92
+
93
trace_tz_mpc_mem_blocked_write(addr, value, size, attrs.secure);
94
95
- return MEMTX_OK;
96
+ return tz_mpc_handle_block(s, addr, attrs);
97
}
98
99
static const MemoryRegionOps tz_mpc_mem_blocked_ops = {
100
--
101
2.17.1
102
103
diff view generated by jsdifflib
Deleted patch
1
The final part of the Memory Protection Controller we need to
2
implement is actually using the BLK_LUT data programmed by the
3
guest to determine whether to block the transaction or not.
4
1
5
Since this means we now change transaction mappings when
6
the guest writes to BLK_LUT, we must also call the IOMMU
7
notifiers at that point.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Message-id: 20180620132032.28865-5-peter.maydell@linaro.org
12
---
13
hw/misc/tz-mpc.c | 53 ++++++++++++++++++++++++++++++++++++++++++--
14
hw/misc/trace-events | 1 +
15
2 files changed, 52 insertions(+), 2 deletions(-)
16
17
diff --git a/hw/misc/tz-mpc.c b/hw/misc/tz-mpc.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/misc/tz-mpc.c
20
+++ b/hw/misc/tz-mpc.c
21
@@ -XXX,XX +XXX,XX @@ static void tz_mpc_irq_update(TZMPC *s)
22
qemu_set_irq(s->irq, s->int_stat && s->int_en);
23
}
24
25
+static void tz_mpc_iommu_notify(TZMPC *s, uint32_t lutidx,
26
+ uint32_t oldlut, uint32_t newlut)
27
+{
28
+ /* Called when the LUT word at lutidx has changed from oldlut to newlut;
29
+ * must call the IOMMU notifiers for the changed blocks.
30
+ */
31
+ IOMMUTLBEntry entry = {
32
+ .addr_mask = s->blocksize - 1,
33
+ };
34
+ hwaddr addr = lutidx * s->blocksize * 32;
35
+ int i;
36
+
37
+ for (i = 0; i < 32; i++, addr += s->blocksize) {
38
+ bool block_is_ns;
39
+
40
+ if (!((oldlut ^ newlut) & (1 << i))) {
41
+ continue;
42
+ }
43
+ /* This changes the mappings for both the S and the NS space,
44
+ * so we need to do four notifies: an UNMAP then a MAP for each.
45
+ */
46
+ block_is_ns = newlut & (1 << i);
47
+
48
+ trace_tz_mpc_iommu_notify(addr);
49
+ entry.iova = addr;
50
+ entry.translated_addr = addr;
51
+
52
+ entry.perm = IOMMU_NONE;
53
+ memory_region_notify_iommu(&s->upstream, IOMMU_IDX_S, entry);
54
+ memory_region_notify_iommu(&s->upstream, IOMMU_IDX_NS, entry);
55
+
56
+ entry.perm = IOMMU_RW;
57
+ if (block_is_ns) {
58
+ entry.target_as = &s->blocked_io_as;
59
+ } else {
60
+ entry.target_as = &s->downstream_as;
61
+ }
62
+ memory_region_notify_iommu(&s->upstream, IOMMU_IDX_S, entry);
63
+ if (block_is_ns) {
64
+ entry.target_as = &s->downstream_as;
65
+ } else {
66
+ entry.target_as = &s->blocked_io_as;
67
+ }
68
+ memory_region_notify_iommu(&s->upstream, IOMMU_IDX_NS, entry);
69
+ }
70
+}
71
+
72
static void tz_mpc_autoinc_idx(TZMPC *s, unsigned access_size)
73
{
74
/* Auto-increment BLK_IDX if necessary */
75
@@ -XXX,XX +XXX,XX @@ static MemTxResult tz_mpc_reg_write(void *opaque, hwaddr addr,
76
s->blk_idx = value % s->blk_max;
77
break;
78
case A_BLK_LUT:
79
+ tz_mpc_iommu_notify(s, s->blk_idx, s->blk_lut[s->blk_idx], value);
80
s->blk_lut[s->blk_idx] = value;
81
tz_mpc_autoinc_idx(s, size);
82
break;
83
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry tz_mpc_translate(IOMMUMemoryRegion *iommu,
84
/* Look at the per-block configuration for this address, and
85
* return a TLB entry directing the transaction at either
86
* downstream_as or blocked_io_as, as appropriate.
87
- * For the moment, always permit accesses.
88
+ * If the LUT cfg_ns bit is 1, only non-secure transactions
89
+ * may pass. If the bit is 0, only secure transactions may pass.
90
*/
91
- ok = true;
92
+ ok = tz_mpc_cfg_ns(s, addr) == (iommu_idx == IOMMU_IDX_NS);
93
94
trace_tz_mpc_translate(addr, flags,
95
iommu_idx == IOMMU_IDX_S ? "S" : "NS",
96
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
97
index XXXXXXX..XXXXXXX 100644
98
--- a/hw/misc/trace-events
99
+++ b/hw/misc/trace-events
100
@@ -XXX,XX +XXX,XX @@ tz_mpc_reg_write(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs wri
101
tz_mpc_mem_blocked_read(uint64_t addr, unsigned size, bool secure) "TZ MPC blocked read: offset 0x%" PRIx64 " size %u secure %d"
102
tz_mpc_mem_blocked_write(uint64_t addr, uint64_t data, unsigned size, bool secure) "TZ MPC blocked write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d"
103
tz_mpc_translate(uint64_t addr, int flags, const char *idx, const char *res) "TZ MPC translate: addr 0x%" PRIx64 " flags 0x%x iommu_idx %s: %s"
104
+tz_mpc_iommu_notify(uint64_t addr) "TZ MPC iommu: notifying UNMAP/MAP for 0x%" PRIx64
105
106
# hw/misc/tz-ppc.c
107
tz_ppc_reset(void) "TZ PPC: reset"
108
--
109
2.17.1
110
111
diff view generated by jsdifflib
1
Implement the SECMPCINTSTATUS register. This is the only register
1
Now that we have implemented support for FEAT_LSE2, we can define
2
in the security controller that deals with Memory Protection
2
a CPU model for the Neoverse-V1, and enable it for the virt and
3
Controllers, and it simply provides a read-only view of the
3
sbsa-ref boards.
4
interrupt lines from the various MPCs in the system.
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180620132032.28865-6-peter.maydell@linaro.org
6
Message-id: 20230704130647.2842917-3-peter.maydell@linaro.org
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
---
9
---
9
include/hw/misc/iotkit-secctl.h | 8 +++++++
10
docs/system/arm/virt.rst | 1 +
10
hw/misc/iotkit-secctl.c | 38 +++++++++++++++++++++++++++++++--
11
hw/arm/sbsa-ref.c | 1 +
11
2 files changed, 44 insertions(+), 2 deletions(-)
12
hw/arm/virt.c | 1 +
12
13
target/arm/tcg/cpu64.c | 128 +++++++++++++++++++++++++++++++++++++++
13
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
14
4 files changed, 131 insertions(+)
14
index XXXXXXX..XXXXXXX 100644
15
15
--- a/include/hw/misc/iotkit-secctl.h
16
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
16
+++ b/include/hw/misc/iotkit-secctl.h
17
index XXXXXXX..XXXXXXX 100644
17
@@ -XXX,XX +XXX,XX @@
18
--- a/docs/system/arm/virt.rst
18
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable
19
+++ b/docs/system/arm/virt.rst
19
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear
20
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
20
* + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status
21
- ``a64fx`` (64-bit)
21
+ * Controlling the MPC in the IoTKit:
22
- ``host`` (with KVM only)
22
+ * + named GPIO input mpc_status
23
- ``neoverse-n1`` (64-bit)
23
+ * Controlling each of the 16 expansion MPCs which a system using the IoTKit
24
+- ``neoverse-v1`` (64-bit)
24
+ * might provide:
25
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
25
+ * + named GPIO inputs mpcexp_status[0..15]
26
26
*/
27
Note that the default is ``cortex-a15``, so for an AArch64 guest you must
27
28
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
28
#ifndef IOTKIT_SECCTL_H
29
index XXXXXXX..XXXXXXX 100644
29
@@ -XXX,XX +XXX,XX @@
30
--- a/hw/arm/sbsa-ref.c
30
#define IOTS_NUM_APB_PPC 2
31
+++ b/hw/arm/sbsa-ref.c
31
#define IOTS_NUM_APB_EXP_PPC 4
32
@@ -XXX,XX +XXX,XX @@ static const char * const valid_cpus[] = {
32
#define IOTS_NUM_AHB_EXP_PPC 4
33
ARM_CPU_TYPE_NAME("cortex-a57"),
33
+#define IOTS_NUM_EXP_MPC 16
34
ARM_CPU_TYPE_NAME("cortex-a72"),
34
+#define IOTS_NUM_MPC 1
35
ARM_CPU_TYPE_NAME("neoverse-n1"),
35
36
+ ARM_CPU_TYPE_NAME("neoverse-v1"),
36
typedef struct IoTKitSecCtl IoTKitSecCtl;
37
ARM_CPU_TYPE_NAME("max"),
37
38
};
38
@@ -XXX,XX +XXX,XX @@ struct IoTKitSecCtl {
39
39
uint32_t secrespcfg;
40
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
40
uint32_t nsccfg;
41
index XXXXXXX..XXXXXXX 100644
41
uint32_t brginten;
42
--- a/hw/arm/virt.c
42
+ uint32_t mpcintstatus;
43
+++ b/hw/arm/virt.c
43
44
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
44
IoTKitSecCtlPPC apb[IOTS_NUM_APB_PPC];
45
ARM_CPU_TYPE_NAME("cortex-a76"),
45
IoTKitSecCtlPPC apbexp[IOTS_NUM_APB_EXP_PPC];
46
ARM_CPU_TYPE_NAME("a64fx"),
46
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
47
ARM_CPU_TYPE_NAME("neoverse-n1"),
47
index XXXXXXX..XXXXXXX 100644
48
+ ARM_CPU_TYPE_NAME("neoverse-v1"),
48
--- a/hw/misc/iotkit-secctl.c
49
#endif
49
+++ b/hw/misc/iotkit-secctl.c
50
ARM_CPU_TYPE_NAME("cortex-a53"),
50
@@ -XXX,XX +XXX,XX @@ static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
51
ARM_CPU_TYPE_NAME("cortex-a57"),
51
case A_NSCCFG:
52
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
52
r = s->nsccfg;
53
index XXXXXXX..XXXXXXX 100644
53
break;
54
--- a/target/arm/tcg/cpu64.c
54
+ case A_SECMPCINTSTATUS:
55
+++ b/target/arm/tcg/cpu64.c
55
+ r = s->mpcintstatus;
56
@@ -XXX,XX +XXX,XX @@ static void define_neoverse_n1_cp_reginfo(ARMCPU *cpu)
56
+ break;
57
define_arm_cp_regs(cpu, neoverse_n1_cp_reginfo);
57
case A_SECPPCINTSTAT:
58
r = s->secppcintstat;
59
break;
60
@@ -XXX,XX +XXX,XX @@ static MemTxResult iotkit_secctl_s_read(void *opaque, hwaddr addr,
61
case A_APBSPPPCEXP3:
62
r = s->apbexp[offset_to_ppc_idx(offset)].sp;
63
break;
64
- case A_SECMPCINTSTATUS:
65
case A_SECMSCINTSTAT:
66
case A_SECMSCINTEN:
67
case A_NSMSCEXP:
68
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_reset(DeviceState *dev)
69
foreach_ppc(s, iotkit_secctl_reset_ppc);
70
}
58
}
71
59
72
+static void iotkit_secctl_mpc_status(void *opaque, int n, int level)
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)
73
+{
76
+{
74
+ IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
77
+ /*
75
+
78
+ * The Neoverse V1 has all of the Neoverse N1's IMPDEF
76
+ s->mpcintstatus = deposit32(s->mpcintstatus, 0, 1, !!level);
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);
77
+}
83
+}
78
+
84
+
79
+static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
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)
80
+{
93
+{
81
+ IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
94
+ ARMCPU *cpu = ARM_CPU(obj);
82
+
95
+
83
+ s->mpcintstatus = deposit32(s->mpcintstatus, n + 16, 1, !!level);
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);
84
+}
192
+}
85
+
193
+
86
static void iotkit_secctl_ppc_irqstatus(void *opaque, int n, int level)
194
/*
87
{
195
* -cpu max: a CPU with as many features enabled as our emulation supports.
88
IoTKitSecCtlPPC *ppc = opaque;
196
* The version of '-cpu max' for qemu-system-arm is defined in cpu32.c;
89
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_init(Object *obj)
197
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
90
qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
198
{ .name = "cortex-a76", .initfn = aarch64_a76_initfn },
91
qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1);
199
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
92
200
{ .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
93
+ qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status", 1);
201
+ { .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
94
+ qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
95
+ "mpcexp_status", IOTS_NUM_EXP_MPC);
96
+
97
memory_region_init_io(&s->s_regs, obj, &iotkit_secctl_s_ops,
98
s, "iotkit-secctl-s-regs", 0x1000);
99
memory_region_init_io(&s->ns_regs, obj, &iotkit_secctl_ns_ops,
100
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_secctl_ppc_vmstate = {
101
}
102
};
202
};
103
203
104
+static const VMStateDescription iotkit_secctl_mpcintstatus_vmstate = {
204
static void aarch64_cpu_register_types(void)
105
+ .name = "iotkit-secctl-mpcintstatus",
106
+ .version_id = 1,
107
+ .minimum_version_id = 1,
108
+ .fields = (VMStateField[]) {
109
+ VMSTATE_UINT32(mpcintstatus, IoTKitSecCtl),
110
+ VMSTATE_END_OF_LIST()
111
+ }
112
+};
113
+
114
static const VMStateDescription iotkit_secctl_vmstate = {
115
.name = "iotkit-secctl",
116
.version_id = 1,
117
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_secctl_vmstate = {
118
VMSTATE_STRUCT_ARRAY(ahbexp, IoTKitSecCtl, IOTS_NUM_AHB_EXP_PPC, 1,
119
iotkit_secctl_ppc_vmstate, IoTKitSecCtlPPC),
120
VMSTATE_END_OF_LIST()
121
- }
122
+ },
123
+ .subsections = (const VMStateDescription*[]) {
124
+ &iotkit_secctl_mpcintstatus_vmstate,
125
+ NULL
126
+ },
127
};
128
129
static void iotkit_secctl_class_init(ObjectClass *klass, void *data)
130
--
205
--
131
2.17.1
206
2.34.1
132
207
133
208
diff view generated by jsdifflib
1
Wire up the one MPC that is part of the IoTKit itself. For the
1
If you build QEMU with the clang sanitizer enabled, you can see it
2
moment we don't wire up its interrupt line.
2
fire when running the arm-cpu-features test:
3
4
$ QTEST_QEMU_BINARY=./build/arm-clang/qemu-system-aarch64 ./build/arm-clang/tests/qtest/arm-cpu-features
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.
3
25
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
27
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180620132032.28865-7-peter.maydell@linaro.org
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-id: 20230704154332.3014896-1-peter.maydell@linaro.org
7
---
30
---
8
include/hw/arm/iotkit.h | 2 ++
31
target/arm/cpu64.c | 4 ++--
9
hw/arm/iotkit.c | 38 +++++++++++++++++++++++++++-----------
32
1 file changed, 2 insertions(+), 2 deletions(-)
10
2 files changed, 29 insertions(+), 11 deletions(-)
11
33
12
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
34
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
13
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/iotkit.h
36
--- a/target/arm/cpu64.c
15
+++ b/include/hw/arm/iotkit.h
37
+++ b/target/arm/cpu64.c
16
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
17
#include "hw/arm/armv7m.h"
39
vq = ctz32(tmp) + 1;
18
#include "hw/misc/iotkit-secctl.h"
40
19
#include "hw/misc/tz-ppc.h"
41
max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
20
+#include "hw/misc/tz-mpc.h"
42
- vq_mask = MAKE_64BIT_MASK(0, max_vq);
21
#include "hw/timer/cmsdk-apb-timer.h"
43
+ vq_mask = max_vq > 0 ? MAKE_64BIT_MASK(0, max_vq) : 0;
22
#include "hw/misc/unimp.h"
44
vq_map = vq_supported & ~vq_init & vq_mask;
23
#include "hw/or-irq.h"
45
24
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
46
- if (max_vq == 0 || vq_map == 0) {
25
IoTKitSecCtl secctl;
47
+ if (vq_map == 0) {
26
TZPPC apb_ppc0;
48
error_setg(errp, "cannot disable sve%d", vq * 128);
27
TZPPC apb_ppc1;
49
error_append_hint(errp, "Disabling sve%d results in all "
28
+ TZMPC mpc;
50
"vector lengths being disabled.\n",
29
CMSDKAPBTIMER timer0;
30
CMSDKAPBTIMER timer1;
31
qemu_or_irq ppc_irq_orgate;
32
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/iotkit.c
35
+++ b/hw/arm/iotkit.c
36
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
37
TYPE_TZ_PPC);
38
init_sysbus_child(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
39
TYPE_TZ_PPC);
40
+ init_sysbus_child(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
41
init_sysbus_child(obj, "timer0", &s->timer0, sizeof(s->timer0),
42
TYPE_CMSDK_APB_TIMER);
43
init_sysbus_child(obj, "timer1", &s->timer1, sizeof(s->timer1),
44
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
45
*/
46
make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000);
47
48
- /* This RAM should be behind a Memory Protection Controller, but we
49
- * don't implement that yet.
50
- */
51
- memory_region_init_ram(&s->sram0, NULL, "iotkit.sram0", 0x00008000, &err);
52
- if (err) {
53
- error_propagate(errp, err);
54
- return;
55
- }
56
- memory_region_add_subregion(&s->container, 0x20000000, &s->sram0);
57
58
/* Security controller */
59
object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
60
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
61
qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
62
qdev_get_gpio_in(dev_splitter, 0));
63
64
+ /* This RAM lives behind the Memory Protection Controller */
65
+ memory_region_init_ram(&s->sram0, NULL, "iotkit.sram0", 0x00008000, &err);
66
+ if (err) {
67
+ error_propagate(errp, err);
68
+ return;
69
+ }
70
+ object_property_set_link(OBJECT(&s->mpc), OBJECT(&s->sram0),
71
+ "downstream", &err);
72
+ if (err) {
73
+ error_propagate(errp, err);
74
+ return;
75
+ }
76
+ object_property_set_bool(OBJECT(&s->mpc), true, "realized", &err);
77
+ if (err) {
78
+ error_propagate(errp, err);
79
+ return;
80
+ }
81
+ /* Map the upstream end of the MPC into the right place... */
82
+ memory_region_add_subregion(&s->container, 0x20000000,
83
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
84
+ 1));
85
+ /* ...and its register interface */
86
+ memory_region_add_subregion(&s->container, 0x50083000,
87
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
88
+ 0));
89
+
90
/* Devices behind APB PPC0:
91
* 0x40000000: timer0
92
* 0x40001000: timer1
93
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
94
create_unimplemented_device("NS watchdog", 0x40081000, 0x1000);
95
create_unimplemented_device("S watchdog", 0x50081000, 0x1000);
96
97
- create_unimplemented_device("SRAM0 MPC", 0x50083000, 0x1000);
98
-
99
for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
100
Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
101
102
--
51
--
103
2.17.1
52
2.34.1
104
53
105
54
diff view generated by jsdifflib