1
Arm patches for rc3 : just a handful of bug fixes.
1
Hi; some minor changes for 6.2, which I think can be classified
2
as bug fixes and are OK for this point in the release cycle.
3
(Wouldn't be the end of the world if they slipped to 7.0.)
2
4
3
thanks
4
-- PMM
5
-- PMM
5
6
7
The following changes since commit 42f6c9179be4401974dd3a75ee72defd16b5092d:
6
8
7
The following changes since commit 4ecc984210ca1bf508a96a550ec8a93a5f833f6c:
9
Merge tag 'pull-ppc-20211112' of https://github.com/legoater/qemu into staging (2021-11-12 12:28:25 +0100)
8
9
Merge remote-tracking branch 'remotes/palmer/tags/riscv-for-master-4.2-rc3' into staging (2019-11-26 12:36:40 +0000)
10
10
11
are available in the Git repository at:
11
are available in the Git repository at:
12
12
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191126
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211115-1
14
14
15
for you to fetch changes up to 6a4ef4e5d1084ce41fafa7d470a644b0fd3d9317:
15
for you to fetch changes up to 1adf528ec3bdf62ea3b580b7ad562534a3676ff5:
16
16
17
target/arm: Honor HCR_EL2.TID3 trapping requirements (2019-11-26 13:55:37 +0000)
17
hw/rtc/pl031: Send RTC_CHANGE QMP event (2021-11-15 18:53:00 +0000)
18
18
19
----------------------------------------------------------------
19
----------------------------------------------------------------
20
target-arm queue:
20
target-arm queue:
21
* handle FTYPE flag correctly in v7M exception return
21
* Support multiple redistributor regions for TCG GICv3
22
for v7M CPUs with an FPU (v8M CPUs were already correct)
22
* Send RTC_CHANGE QMP event from pl031
23
* versal: Add the CRP as unimplemented
24
* Fix ISR_EL1 tracking when executing at EL2
25
* Honor HCR_EL2.TID3 trapping requirements
26
23
27
----------------------------------------------------------------
24
----------------------------------------------------------------
28
Edgar E. Iglesias (1):
25
Eric Auger (1):
29
hw/arm: versal: Add the CRP as unimplemented
26
hw/rtc/pl031: Send RTC_CHANGE QMP event
30
27
31
Jean-Hugues Deschênes (1):
28
Peter Maydell (3):
32
target/arm: Fix handling of cortex-m FTYPE flag in EXCRET
29
hw/intc/arm_gicv3: Move checking of redist-region-count to arm_gicv3_common_realize
30
hw/intc/arm_gicv3: Set GICR_TYPER.Last correctly when nb_redist_regions > 1
31
hw/intc/arm_gicv3: Support multiple redistributor regions
33
32
34
Marc Zyngier (2):
33
include/hw/intc/arm_gicv3_common.h | 14 ++++++++--
35
target/arm: Fix ISR_EL1 tracking when executing at EL2
34
hw/intc/arm_gicv3.c | 12 +-------
36
target/arm: Honor HCR_EL2.TID3 trapping requirements
35
hw/intc/arm_gicv3_common.c | 56 ++++++++++++++++++++++++--------------
36
hw/intc/arm_gicv3_kvm.c | 10 ++-----
37
hw/intc/arm_gicv3_redist.c | 40 +++++++++++++++------------
38
hw/rtc/pl031.c | 10 ++++++-
39
hw/rtc/meson.build | 2 +-
40
7 files changed, 83 insertions(+), 61 deletions(-)
37
41
38
include/hw/arm/xlnx-versal.h | 3 ++
39
hw/arm/xlnx-versal.c | 2 ++
40
target/arm/helper.c | 83 ++++++++++++++++++++++++++++++++++++++++++--
41
target/arm/m_helper.c | 7 ++--
42
4 files changed, 89 insertions(+), 6 deletions(-)
43
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
The GICv3 devices have an array property redist-region-count.
2
Currently we check this for errors (bad values) in
3
gicv3_init_irqs_and_mmio(), just before we use it. Move this error
4
checking to the arm_gicv3_common_realize() function, where we
5
sanity-check all of the other base-class properties. (This will
6
always be before gicv3_init_irqs_and_mmio() is called, because
7
that function is called in the subclass realize methods, after
8
they have called the parent-class realize.)
2
9
3
HCR_EL2.TID3 mandates that access from EL1 to a long list of id
10
The motivation for this refactor is:
4
registers traps to EL2, and QEMU has so far ignored this requirement.
11
* we would like to use the redist_region_count[] values in
12
arm_gicv3_common_realize() in a subsequent patch, so we need
13
to have already done the sanity-checking first
14
* this removes the only use of the Error** argument to
15
gicv3_init_irqs_and_mmio(), so we can remove some error-handling
16
boilerplate
5
17
6
This breaks (among other things) KVM guests that have PtrAuth enabled,
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
while the hypervisor doesn't want to expose the feature to its guest.
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
To achieve this, KVM traps the ID registers (ID_AA64ISAR1_EL1 in this
20
---
9
case), and masks out the unsupported feature.
21
include/hw/intc/arm_gicv3_common.h | 2 +-
22
hw/intc/arm_gicv3.c | 6 +-----
23
hw/intc/arm_gicv3_common.c | 26 +++++++++++++-------------
24
hw/intc/arm_gicv3_kvm.c | 6 +-----
25
4 files changed, 16 insertions(+), 24 deletions(-)
10
26
11
QEMU not honoring the trap request means that the guest observes
27
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
12
that the feature is present in the HW, starts using it, and dies
13
a horrible death when KVM injects an UNDEF, because the feature
14
*really* isn't supported.
15
16
Do the right thing by trapping to EL2 if HCR_EL2.TID3 is set.
17
18
Note that this change does not include trapping of the MVFR
19
registers from AArch32 (they are accessed via the VMRS
20
instruction and need to be handled in a different way).
21
22
Reported-by: Will Deacon <will@kernel.org>
23
Signed-off-by: Marc Zyngier <maz@kernel.org>
24
Tested-by: Will Deacon <will@kernel.org>
25
Message-id: 20191123115618.29230-1-maz@kernel.org
26
[PMM: added missing accessfn line for ID_AA4PFR2_EL1_RESERVED;
27
changed names of access functions to include _tid3]
28
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
---
31
target/arm/helper.c | 76 +++++++++++++++++++++++++++++++++++++++++++++
32
1 file changed, 76 insertions(+)
33
34
diff --git a/target/arm/helper.c b/target/arm/helper.c
35
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/helper.c
29
--- a/include/hw/intc/arm_gicv3_common.h
37
+++ b/target/arm/helper.c
30
+++ b/include/hw/intc/arm_gicv3_common.h
38
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo predinv_reginfo[] = {
31
@@ -XXX,XX +XXX,XX @@ struct ARMGICv3CommonClass {
39
REGINFO_SENTINEL
40
};
32
};
41
33
42
+static CPAccessResult access_aa64_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
34
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
43
+ bool isread)
35
- const MemoryRegionOps *ops, Error **errp);
44
+{
36
+ const MemoryRegionOps *ops);
45
+ if ((arm_current_el(env) < 2) && (arm_hcr_el2_eff(env) & HCR_TID3)) {
37
46
+ return CP_ACCESS_TRAP_EL2;
38
#endif
39
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/arm_gicv3.c
42
+++ b/hw/intc/arm_gicv3.c
43
@@ -XXX,XX +XXX,XX @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
44
return;
45
}
46
47
- gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops, &local_err);
48
- if (local_err) {
49
- error_propagate(errp, local_err);
50
- return;
51
- }
52
+ gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
53
54
gicv3_init_cpuif(s);
55
}
56
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/intc/arm_gicv3_common.c
59
+++ b/hw/intc/arm_gicv3_common.c
60
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_gicv3 = {
61
};
62
63
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
64
- const MemoryRegionOps *ops, Error **errp)
65
+ const MemoryRegionOps *ops)
66
{
67
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
68
- int rdist_capacity = 0;
69
int i;
70
71
- for (i = 0; i < s->nb_redist_regions; i++) {
72
- rdist_capacity += s->redist_region_count[i];
73
- }
74
- if (rdist_capacity < s->num_cpu) {
75
- error_setg(errp, "Capacity of the redist regions(%d) "
76
- "is less than number of vcpus(%d)",
77
- rdist_capacity, s->num_cpu);
78
- return;
79
- }
80
-
81
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
82
* GPIO array layout is thus:
83
* [0..N-1] spi
84
@@ -XXX,XX +XXX,XX @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
85
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
86
{
87
GICv3State *s = ARM_GICV3_COMMON(dev);
88
- int i;
89
+ int i, rdist_capacity;
90
91
/* revision property is actually reserved and currently used only in order
92
* to keep the interface compatible with GICv2 code, avoiding extra
93
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
94
return;
95
}
96
97
+ rdist_capacity = 0;
98
+ for (i = 0; i < s->nb_redist_regions; i++) {
99
+ rdist_capacity += s->redist_region_count[i];
100
+ }
101
+ if (rdist_capacity < s->num_cpu) {
102
+ error_setg(errp, "Capacity of the redist regions(%d) "
103
+ "is less than number of vcpus(%d)",
104
+ rdist_capacity, s->num_cpu);
105
+ return;
47
+ }
106
+ }
48
+
107
+
49
+ return CP_ACCESS_OK;
108
s->cpu = g_new0(GICv3CPUState, s->num_cpu);
50
+}
109
51
+
110
for (i = 0; i < s->num_cpu; i++) {
52
+static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
111
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
53
+ bool isread)
112
index XXXXXXX..XXXXXXX 100644
54
+{
113
--- a/hw/intc/arm_gicv3_kvm.c
55
+ if (arm_feature(env, ARM_FEATURE_V8)) {
114
+++ b/hw/intc/arm_gicv3_kvm.c
56
+ return access_aa64_tid3(env, ri, isread);
115
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
57
+ }
116
return;
58
+
117
}
59
+ return CP_ACCESS_OK;
118
60
+}
119
- gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL, &local_err);
61
+
120
- if (local_err) {
62
void register_cp_regs_for_features(ARMCPU *cpu)
121
- error_propagate(errp, local_err);
63
{
122
- return;
64
/* Register all the coprocessor registers based on feature bits */
123
- }
65
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
124
+ gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL);
66
{ .name = "ID_PFR0", .state = ARM_CP_STATE_BOTH,
125
67
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 0,
126
for (i = 0; i < s->num_cpu; i++) {
68
.access = PL1_R, .type = ARM_CP_CONST,
127
ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
69
+ .accessfn = access_aa32_tid3,
70
.resetvalue = cpu->id_pfr0 },
71
/* ID_PFR1 is not a plain ARM_CP_CONST because we don't know
72
* the value of the GIC field until after we define these regs.
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
74
{ .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH,
75
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1,
76
.access = PL1_R, .type = ARM_CP_NO_RAW,
77
+ .accessfn = access_aa32_tid3,
78
.readfn = id_pfr1_read,
79
.writefn = arm_cp_write_ignore },
80
{ .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH,
81
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
82
.access = PL1_R, .type = ARM_CP_CONST,
83
+ .accessfn = access_aa32_tid3,
84
.resetvalue = cpu->id_dfr0 },
85
{ .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
86
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
87
.access = PL1_R, .type = ARM_CP_CONST,
88
+ .accessfn = access_aa32_tid3,
89
.resetvalue = cpu->id_afr0 },
90
{ .name = "ID_MMFR0", .state = ARM_CP_STATE_BOTH,
91
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 4,
92
.access = PL1_R, .type = ARM_CP_CONST,
93
+ .accessfn = access_aa32_tid3,
94
.resetvalue = cpu->id_mmfr0 },
95
{ .name = "ID_MMFR1", .state = ARM_CP_STATE_BOTH,
96
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 5,
97
.access = PL1_R, .type = ARM_CP_CONST,
98
+ .accessfn = access_aa32_tid3,
99
.resetvalue = cpu->id_mmfr1 },
100
{ .name = "ID_MMFR2", .state = ARM_CP_STATE_BOTH,
101
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 6,
102
.access = PL1_R, .type = ARM_CP_CONST,
103
+ .accessfn = access_aa32_tid3,
104
.resetvalue = cpu->id_mmfr2 },
105
{ .name = "ID_MMFR3", .state = ARM_CP_STATE_BOTH,
106
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 7,
107
.access = PL1_R, .type = ARM_CP_CONST,
108
+ .accessfn = access_aa32_tid3,
109
.resetvalue = cpu->id_mmfr3 },
110
{ .name = "ID_ISAR0", .state = ARM_CP_STATE_BOTH,
111
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 0,
112
.access = PL1_R, .type = ARM_CP_CONST,
113
+ .accessfn = access_aa32_tid3,
114
.resetvalue = cpu->isar.id_isar0 },
115
{ .name = "ID_ISAR1", .state = ARM_CP_STATE_BOTH,
116
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 1,
117
.access = PL1_R, .type = ARM_CP_CONST,
118
+ .accessfn = access_aa32_tid3,
119
.resetvalue = cpu->isar.id_isar1 },
120
{ .name = "ID_ISAR2", .state = ARM_CP_STATE_BOTH,
121
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 2,
122
.access = PL1_R, .type = ARM_CP_CONST,
123
+ .accessfn = access_aa32_tid3,
124
.resetvalue = cpu->isar.id_isar2 },
125
{ .name = "ID_ISAR3", .state = ARM_CP_STATE_BOTH,
126
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 3,
127
.access = PL1_R, .type = ARM_CP_CONST,
128
+ .accessfn = access_aa32_tid3,
129
.resetvalue = cpu->isar.id_isar3 },
130
{ .name = "ID_ISAR4", .state = ARM_CP_STATE_BOTH,
131
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 4,
132
.access = PL1_R, .type = ARM_CP_CONST,
133
+ .accessfn = access_aa32_tid3,
134
.resetvalue = cpu->isar.id_isar4 },
135
{ .name = "ID_ISAR5", .state = ARM_CP_STATE_BOTH,
136
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 5,
137
.access = PL1_R, .type = ARM_CP_CONST,
138
+ .accessfn = access_aa32_tid3,
139
.resetvalue = cpu->isar.id_isar5 },
140
{ .name = "ID_MMFR4", .state = ARM_CP_STATE_BOTH,
141
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
142
.access = PL1_R, .type = ARM_CP_CONST,
143
+ .accessfn = access_aa32_tid3,
144
.resetvalue = cpu->id_mmfr4 },
145
{ .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
146
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
147
.access = PL1_R, .type = ARM_CP_CONST,
148
+ .accessfn = access_aa32_tid3,
149
.resetvalue = cpu->isar.id_isar6 },
150
REGINFO_SENTINEL
151
};
152
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
153
{ .name = "ID_AA64PFR0_EL1", .state = ARM_CP_STATE_AA64,
154
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 0,
155
.access = PL1_R, .type = ARM_CP_NO_RAW,
156
+ .accessfn = access_aa64_tid3,
157
.readfn = id_aa64pfr0_read,
158
.writefn = arm_cp_write_ignore },
159
{ .name = "ID_AA64PFR1_EL1", .state = ARM_CP_STATE_AA64,
160
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 1,
161
.access = PL1_R, .type = ARM_CP_CONST,
162
+ .accessfn = access_aa64_tid3,
163
.resetvalue = cpu->isar.id_aa64pfr1},
164
{ .name = "ID_AA64PFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
165
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 2,
166
.access = PL1_R, .type = ARM_CP_CONST,
167
+ .accessfn = access_aa64_tid3,
168
.resetvalue = 0 },
169
{ .name = "ID_AA64PFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
170
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 3,
171
.access = PL1_R, .type = ARM_CP_CONST,
172
+ .accessfn = access_aa64_tid3,
173
.resetvalue = 0 },
174
{ .name = "ID_AA64ZFR0_EL1", .state = ARM_CP_STATE_AA64,
175
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4,
176
.access = PL1_R, .type = ARM_CP_CONST,
177
+ .accessfn = access_aa64_tid3,
178
/* At present, only SVEver == 0 is defined anyway. */
179
.resetvalue = 0 },
180
{ .name = "ID_AA64PFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
181
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
182
.access = PL1_R, .type = ARM_CP_CONST,
183
+ .accessfn = access_aa64_tid3,
184
.resetvalue = 0 },
185
{ .name = "ID_AA64PFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
186
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 6,
187
.access = PL1_R, .type = ARM_CP_CONST,
188
+ .accessfn = access_aa64_tid3,
189
.resetvalue = 0 },
190
{ .name = "ID_AA64PFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
191
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 7,
192
.access = PL1_R, .type = ARM_CP_CONST,
193
+ .accessfn = access_aa64_tid3,
194
.resetvalue = 0 },
195
{ .name = "ID_AA64DFR0_EL1", .state = ARM_CP_STATE_AA64,
196
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
197
.access = PL1_R, .type = ARM_CP_CONST,
198
+ .accessfn = access_aa64_tid3,
199
.resetvalue = cpu->id_aa64dfr0 },
200
{ .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
201
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
202
.access = PL1_R, .type = ARM_CP_CONST,
203
+ .accessfn = access_aa64_tid3,
204
.resetvalue = cpu->id_aa64dfr1 },
205
{ .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
206
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
207
.access = PL1_R, .type = ARM_CP_CONST,
208
+ .accessfn = access_aa64_tid3,
209
.resetvalue = 0 },
210
{ .name = "ID_AA64DFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
211
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 3,
212
.access = PL1_R, .type = ARM_CP_CONST,
213
+ .accessfn = access_aa64_tid3,
214
.resetvalue = 0 },
215
{ .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64,
216
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4,
217
.access = PL1_R, .type = ARM_CP_CONST,
218
+ .accessfn = access_aa64_tid3,
219
.resetvalue = cpu->id_aa64afr0 },
220
{ .name = "ID_AA64AFR1_EL1", .state = ARM_CP_STATE_AA64,
221
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 5,
222
.access = PL1_R, .type = ARM_CP_CONST,
223
+ .accessfn = access_aa64_tid3,
224
.resetvalue = cpu->id_aa64afr1 },
225
{ .name = "ID_AA64AFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
226
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 6,
227
.access = PL1_R, .type = ARM_CP_CONST,
228
+ .accessfn = access_aa64_tid3,
229
.resetvalue = 0 },
230
{ .name = "ID_AA64AFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
231
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 7,
232
.access = PL1_R, .type = ARM_CP_CONST,
233
+ .accessfn = access_aa64_tid3,
234
.resetvalue = 0 },
235
{ .name = "ID_AA64ISAR0_EL1", .state = ARM_CP_STATE_AA64,
236
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 0,
237
.access = PL1_R, .type = ARM_CP_CONST,
238
+ .accessfn = access_aa64_tid3,
239
.resetvalue = cpu->isar.id_aa64isar0 },
240
{ .name = "ID_AA64ISAR1_EL1", .state = ARM_CP_STATE_AA64,
241
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 1,
242
.access = PL1_R, .type = ARM_CP_CONST,
243
+ .accessfn = access_aa64_tid3,
244
.resetvalue = cpu->isar.id_aa64isar1 },
245
{ .name = "ID_AA64ISAR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
246
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 2,
247
.access = PL1_R, .type = ARM_CP_CONST,
248
+ .accessfn = access_aa64_tid3,
249
.resetvalue = 0 },
250
{ .name = "ID_AA64ISAR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
251
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 3,
252
.access = PL1_R, .type = ARM_CP_CONST,
253
+ .accessfn = access_aa64_tid3,
254
.resetvalue = 0 },
255
{ .name = "ID_AA64ISAR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
256
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 4,
257
.access = PL1_R, .type = ARM_CP_CONST,
258
+ .accessfn = access_aa64_tid3,
259
.resetvalue = 0 },
260
{ .name = "ID_AA64ISAR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
261
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 5,
262
.access = PL1_R, .type = ARM_CP_CONST,
263
+ .accessfn = access_aa64_tid3,
264
.resetvalue = 0 },
265
{ .name = "ID_AA64ISAR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
266
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 6,
267
.access = PL1_R, .type = ARM_CP_CONST,
268
+ .accessfn = access_aa64_tid3,
269
.resetvalue = 0 },
270
{ .name = "ID_AA64ISAR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
271
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 6, .opc2 = 7,
272
.access = PL1_R, .type = ARM_CP_CONST,
273
+ .accessfn = access_aa64_tid3,
274
.resetvalue = 0 },
275
{ .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
276
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
277
.access = PL1_R, .type = ARM_CP_CONST,
278
+ .accessfn = access_aa64_tid3,
279
.resetvalue = cpu->isar.id_aa64mmfr0 },
280
{ .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
281
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
282
.access = PL1_R, .type = ARM_CP_CONST,
283
+ .accessfn = access_aa64_tid3,
284
.resetvalue = cpu->isar.id_aa64mmfr1 },
285
{ .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
286
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
287
.access = PL1_R, .type = ARM_CP_CONST,
288
+ .accessfn = access_aa64_tid3,
289
.resetvalue = 0 },
290
{ .name = "ID_AA64MMFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
291
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 3,
292
.access = PL1_R, .type = ARM_CP_CONST,
293
+ .accessfn = access_aa64_tid3,
294
.resetvalue = 0 },
295
{ .name = "ID_AA64MMFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
296
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 4,
297
.access = PL1_R, .type = ARM_CP_CONST,
298
+ .accessfn = access_aa64_tid3,
299
.resetvalue = 0 },
300
{ .name = "ID_AA64MMFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
301
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 5,
302
.access = PL1_R, .type = ARM_CP_CONST,
303
+ .accessfn = access_aa64_tid3,
304
.resetvalue = 0 },
305
{ .name = "ID_AA64MMFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
306
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 6,
307
.access = PL1_R, .type = ARM_CP_CONST,
308
+ .accessfn = access_aa64_tid3,
309
.resetvalue = 0 },
310
{ .name = "ID_AA64MMFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
311
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 7,
312
.access = PL1_R, .type = ARM_CP_CONST,
313
+ .accessfn = access_aa64_tid3,
314
.resetvalue = 0 },
315
{ .name = "MVFR0_EL1", .state = ARM_CP_STATE_AA64,
316
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,
317
.access = PL1_R, .type = ARM_CP_CONST,
318
+ .accessfn = access_aa64_tid3,
319
.resetvalue = cpu->isar.mvfr0 },
320
{ .name = "MVFR1_EL1", .state = ARM_CP_STATE_AA64,
321
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1,
322
.access = PL1_R, .type = ARM_CP_CONST,
323
+ .accessfn = access_aa64_tid3,
324
.resetvalue = cpu->isar.mvfr1 },
325
{ .name = "MVFR2_EL1", .state = ARM_CP_STATE_AA64,
326
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
327
.access = PL1_R, .type = ARM_CP_CONST,
328
+ .accessfn = access_aa64_tid3,
329
.resetvalue = cpu->isar.mvfr2 },
330
{ .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
331
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,
332
.access = PL1_R, .type = ARM_CP_CONST,
333
+ .accessfn = access_aa64_tid3,
334
.resetvalue = 0 },
335
{ .name = "MVFR4_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
336
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 4,
337
.access = PL1_R, .type = ARM_CP_CONST,
338
+ .accessfn = access_aa64_tid3,
339
.resetvalue = 0 },
340
{ .name = "MVFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
341
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
342
.access = PL1_R, .type = ARM_CP_CONST,
343
+ .accessfn = access_aa64_tid3,
344
.resetvalue = 0 },
345
{ .name = "MVFR6_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
346
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
347
.access = PL1_R, .type = ARM_CP_CONST,
348
+ .accessfn = access_aa64_tid3,
349
.resetvalue = 0 },
350
{ .name = "MVFR7_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
351
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
352
.access = PL1_R, .type = ARM_CP_CONST,
353
+ .accessfn = access_aa64_tid3,
354
.resetvalue = 0 },
355
{ .name = "PMCEID0", .state = ARM_CP_STATE_AA32,
356
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6,
357
--
128
--
358
2.20.1
129
2.25.1
359
130
360
131
diff view generated by jsdifflib
1
From: Jean-Hugues Deschênes <Jean-Hugues.Deschenes@ossiaco.com>
1
The 'Last' bit in the GICR_TYPER GICv3 redistributor register is
2
supposed to be set to 1 if this is the last redistributor in a series
3
of contiguous redistributor pages. Currently we set Last only for
4
the redistributor for CPU (num_cpu - 1). This only works if there is
5
a single redistributor region; if there are multiple redistributor
6
regions then we need to set the Last bit for the last redistributor
7
in each region.
2
8
3
According to the PushStack() pseudocode in the armv7m RM,
9
This doesn't cause any problems currently because only the KVM GICv3
4
bit 4 of the LR should be set to NOT(CONTROL.PFCA) when
10
supports multiple redistributor regions, and it ignores the value in
5
an FPU is present. Current implementation is doing it for
11
GICv3State::gicr_typer. But we need to fix this before we can enable
6
armv8, but not for armv7. This patch makes the existing
12
support for multiple regions in the emulated GICv3.
7
logic applicable to both code paths.
8
13
9
Signed-off-by: Jean-Hugues Deschenes <jean-hugues.deschenes@ossiaco.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
---
16
---
13
target/arm/m_helper.c | 7 +++----
17
hw/intc/arm_gicv3_common.c | 17 ++++++++++++-----
14
1 file changed, 3 insertions(+), 4 deletions(-)
18
1 file changed, 12 insertions(+), 5 deletions(-)
15
19
16
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
20
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/m_helper.c
22
--- a/hw/intc/arm_gicv3_common.c
19
+++ b/target/arm/m_helper.c
23
+++ b/hw/intc/arm_gicv3_common.c
20
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
24
@@ -XXX,XX +XXX,XX @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
21
if (env->v7m.secure) {
25
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
22
lr |= R_V7M_EXCRET_S_MASK;
26
{
23
}
27
GICv3State *s = ARM_GICV3_COMMON(dev);
24
- if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
28
- int i, rdist_capacity;
25
- lr |= R_V7M_EXCRET_FTYPE_MASK;
29
+ int i, rdist_capacity, cpuidx;
26
- }
30
27
} else {
31
/* revision property is actually reserved and currently used only in order
28
lr = R_V7M_EXCRET_RES1_MASK |
32
* to keep the interface compatible with GICv2 code, avoiding extra
29
R_V7M_EXCRET_S_MASK |
33
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
30
R_V7M_EXCRET_DCRS_MASK |
34
for (i = 0; i < s->num_cpu; i++) {
31
- R_V7M_EXCRET_FTYPE_MASK |
35
CPUState *cpu = qemu_get_cpu(i);
32
R_V7M_EXCRET_ES_MASK;
36
uint64_t cpu_affid;
33
if (env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSEL_MASK) {
37
- int last;
34
lr |= R_V7M_EXCRET_SPSEL_MASK;
38
39
s->cpu[i].cpu = cpu;
40
s->cpu[i].gic = s;
41
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
42
* PLPIS == 0 (physical LPIs not supported)
43
*/
44
cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL);
45
- last = (i == s->num_cpu - 1);
46
47
/* The CPU mp-affinity property is in MPIDR register format; squash
48
* the affinity bytes into 32 bits as the GICR_TYPER has them.
49
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
50
(cpu_affid & 0xFFFFFF);
51
s->cpu[i].gicr_typer = (cpu_affid << 32) |
52
(1 << 24) |
53
- (i << 8) |
54
- (last << 4);
55
+ (i << 8);
56
57
if (s->lpi_enable) {
58
s->cpu[i].gicr_typer |= GICR_TYPER_PLPIS;
35
}
59
}
36
}
60
}
37
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
61
+
38
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
62
+ /*
63
+ * Now go through and set GICR_TYPER.Last for the final
64
+ * redistributor in each region.
65
+ */
66
+ cpuidx = 0;
67
+ for (i = 0; i < s->nb_redist_regions; i++) {
68
+ cpuidx += s->redist_region_count[i];
69
+ s->cpu[cpuidx - 1].gicr_typer |= GICR_TYPER_LAST;
39
+ }
70
+ }
40
if (!arm_v7m_is_handler_mode(env)) {
71
}
41
lr |= R_V7M_EXCRET_MODE_MASK;
72
42
}
73
static void arm_gicv3_finalize(Object *obj)
43
--
74
--
44
2.20.1
75
2.25.1
45
76
46
77
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
Our GICv3 QOM interface includes an array property
2
2
redist-region-count which allows board models to specify that the
3
The ARMv8 ARM states when executing at EL2, EL3 or Secure EL1,
3
registributor registers are not in a single contiguous range, but
4
ISR_EL1 shows the pending status of the physical IRQ, FIQ, or
4
split into multiple pieces. We implemented this for KVM, but
5
SError interrupts.
5
currently the TCG GICv3 model insists that there is only one region.
6
6
You can see the limit being hit with a setup like:
7
Unfortunately, QEMU's implementation only considers the HCR_EL2
7
qemu-system-aarch64 -machine virt,gic-version=3 -smp 124
8
bits, and ignores the current exception level. This means a hypervisor
8
9
trying to look at its own interrupt state actually sees the guest
9
Add support for split regions to the TCG GICv3. To do this we switch
10
state, which is unexpected and breaks KVM as of Linux 5.3.
10
from allocating a simple array of MemoryRegions to an array of
11
11
GICv3RedistRegion structs so that we can use the GICv3RedistRegion as
12
Instead, check for the running EL and return the physical bits
12
the opaque pointer in the MemoryRegion read/write callbacks. Each
13
if not running in a virtualized context.
13
GICv3RedistRegion contains the MemoryRegion, a backpointer allowing
14
14
the read/write callback to get hold of the GICv3State, and an index
15
Fixes: 636540e9c40b
15
which allows us to calculate which CPU's redistributor is being
16
Cc: qemu-stable@nongnu.org
16
accessed.
17
Reported-by: Quentin Perret <qperret@google.com>
17
18
Signed-off-by: Marc Zyngier <maz@kernel.org>
18
Note that arm_gicv3_kvm always passes in NULL as the ops argument
19
Message-id: 20191122135833.28953-1-maz@kernel.org
19
to gicv3_init_irqs_and_mmio(), so the only MemoryRegion read/write
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
callbacks we need to update to handle this new scheme are the
21
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
21
gicv3_redist_read/write functions used by the emulated GICv3.
22
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
---
25
---
24
target/arm/helper.c | 7 +++++--
26
include/hw/intc/arm_gicv3_common.h | 12 ++++++++-
25
1 file changed, 5 insertions(+), 2 deletions(-)
27
hw/intc/arm_gicv3.c | 6 -----
26
28
hw/intc/arm_gicv3_common.c | 15 ++++++++---
27
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
hw/intc/arm_gicv3_kvm.c | 4 +--
28
index XXXXXXX..XXXXXXX 100644
30
hw/intc/arm_gicv3_redist.c | 40 ++++++++++++++++--------------
29
--- a/target/arm/helper.c
31
5 files changed, 46 insertions(+), 31 deletions(-)
30
+++ b/target/arm/helper.c
32
31
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
33
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
32
CPUState *cs = env_cpu(env);
34
index XXXXXXX..XXXXXXX 100644
33
uint64_t hcr_el2 = arm_hcr_el2_eff(env);
35
--- a/include/hw/intc/arm_gicv3_common.h
34
uint64_t ret = 0;
36
+++ b/include/hw/intc/arm_gicv3_common.h
35
+ bool allow_virt = (arm_current_el(env) == 1 &&
37
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
36
+ (!arm_is_secure_below_el3(env) ||
38
bool seenbetter;
37
+ (env->cp15.scr_el3 & SCR_EEL2)));
39
};
38
40
39
- if (hcr_el2 & HCR_IMO) {
41
+/*
40
+ if (allow_virt && (hcr_el2 & HCR_IMO)) {
42
+ * The redistributor pages might be split into more than one region
41
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
43
+ * on some machine types if there are many CPUs.
42
ret |= CPSR_I;
44
+ */
43
}
45
+typedef struct GICv3RedistRegion {
44
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
46
+ GICv3State *gic;
45
}
47
+ MemoryRegion iomem;
48
+ uint32_t cpuidx; /* index of first CPU this region covers */
49
+} GICv3RedistRegion;
50
+
51
struct GICv3State {
52
/*< private >*/
53
SysBusDevice parent_obj;
54
/*< public >*/
55
56
MemoryRegion iomem_dist; /* Distributor */
57
- MemoryRegion *iomem_redist; /* Redistributor Regions */
58
+ GICv3RedistRegion *redist_regions; /* Redistributor Regions */
59
uint32_t *redist_region_count; /* redistributor count within each region */
60
uint32_t nb_redist_regions; /* number of redist regions */
61
62
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/intc/arm_gicv3.c
65
+++ b/hw/intc/arm_gicv3.c
66
@@ -XXX,XX +XXX,XX @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
67
return;
46
}
68
}
47
69
48
- if (hcr_el2 & HCR_FMO) {
70
- if (s->nb_redist_regions != 1) {
49
+ if (allow_virt && (hcr_el2 & HCR_FMO)) {
71
- error_setg(errp, "VGICv3 redist region number(%d) not equal to 1",
50
if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
72
- s->nb_redist_regions);
51
ret |= CPSR_F;
73
- return;
52
}
74
- }
75
-
76
gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
77
78
gicv3_init_cpuif(s);
79
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/intc/arm_gicv3_common.c
82
+++ b/hw/intc/arm_gicv3_common.c
83
@@ -XXX,XX +XXX,XX @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
84
{
85
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
86
int i;
87
+ int cpuidx;
88
89
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
90
* GPIO array layout is thus:
91
@@ -XXX,XX +XXX,XX @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
92
"gicv3_dist", 0x10000);
93
sysbus_init_mmio(sbd, &s->iomem_dist);
94
95
- s->iomem_redist = g_new0(MemoryRegion, s->nb_redist_regions);
96
+ s->redist_regions = g_new0(GICv3RedistRegion, s->nb_redist_regions);
97
+ cpuidx = 0;
98
for (i = 0; i < s->nb_redist_regions; i++) {
99
char *name = g_strdup_printf("gicv3_redist_region[%d]", i);
100
+ GICv3RedistRegion *region = &s->redist_regions[i];
101
102
- memory_region_init_io(&s->iomem_redist[i], OBJECT(s),
103
- ops ? &ops[1] : NULL, s, name,
104
+ region->gic = s;
105
+ region->cpuidx = cpuidx;
106
+ cpuidx += s->redist_region_count[i];
107
+
108
+ memory_region_init_io(&region->iomem, OBJECT(s),
109
+ ops ? &ops[1] : NULL, region, name,
110
s->redist_region_count[i] * GICV3_REDIST_SIZE);
111
- sysbus_init_mmio(sbd, &s->iomem_redist[i]);
112
+ sysbus_init_mmio(sbd, &region->iomem);
113
g_free(name);
114
}
115
}
116
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/intc/arm_gicv3_kvm.c
119
+++ b/hw/intc/arm_gicv3_kvm.c
120
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
121
KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd, 0);
122
123
if (!multiple_redist_region_allowed) {
124
- kvm_arm_register_device(&s->iomem_redist[0], -1,
125
+ kvm_arm_register_device(&s->redist_regions[0].iomem, -1,
126
KVM_DEV_ARM_VGIC_GRP_ADDR,
127
KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd, 0);
128
} else {
129
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
130
uint64_t addr_ormask =
131
i | ((uint64_t)s->redist_region_count[i] << 52);
132
133
- kvm_arm_register_device(&s->iomem_redist[i], -1,
134
+ kvm_arm_register_device(&s->redist_regions[i].iomem, -1,
135
KVM_DEV_ARM_VGIC_GRP_ADDR,
136
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION,
137
s->dev_fd, addr_ormask);
138
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/hw/intc/arm_gicv3_redist.c
141
+++ b/hw/intc/arm_gicv3_redist.c
142
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writell(GICv3CPUState *cs, hwaddr offset,
143
MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
144
unsigned size, MemTxAttrs attrs)
145
{
146
- GICv3State *s = opaque;
147
+ GICv3RedistRegion *region = opaque;
148
+ GICv3State *s = region->gic;
149
GICv3CPUState *cs;
150
MemTxResult r;
151
int cpuidx;
152
153
assert((offset & (size - 1)) == 0);
154
155
- /* This region covers all the redistributor pages; there are
156
- * (for GICv3) two 64K pages per CPU. At the moment they are
157
- * all contiguous (ie in this one region), though we might later
158
- * want to allow splitting of redistributor pages into several
159
- * blocks so we can support more CPUs.
160
+ /*
161
+ * There are (for GICv3) two 64K redistributor pages per CPU.
162
+ * In some cases the redistributor pages for all CPUs are not
163
+ * contiguous (eg on the virt board they are split into two
164
+ * parts if there are too many CPUs to all fit in the same place
165
+ * in the memory map); if so then the GIC has multiple MemoryRegions
166
+ * for the redistributors.
167
*/
168
- cpuidx = offset / 0x20000;
169
- offset %= 0x20000;
170
- assert(cpuidx < s->num_cpu);
171
+ cpuidx = region->cpuidx + offset / GICV3_REDIST_SIZE;
172
+ offset %= GICV3_REDIST_SIZE;
173
174
cs = &s->cpu[cpuidx];
175
176
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
177
MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
178
unsigned size, MemTxAttrs attrs)
179
{
180
- GICv3State *s = opaque;
181
+ GICv3RedistRegion *region = opaque;
182
+ GICv3State *s = region->gic;
183
GICv3CPUState *cs;
184
MemTxResult r;
185
int cpuidx;
186
187
assert((offset & (size - 1)) == 0);
188
189
- /* This region covers all the redistributor pages; there are
190
- * (for GICv3) two 64K pages per CPU. At the moment they are
191
- * all contiguous (ie in this one region), though we might later
192
- * want to allow splitting of redistributor pages into several
193
- * blocks so we can support more CPUs.
194
+ /*
195
+ * There are (for GICv3) two 64K redistributor pages per CPU.
196
+ * In some cases the redistributor pages for all CPUs are not
197
+ * contiguous (eg on the virt board they are split into two
198
+ * parts if there are too many CPUs to all fit in the same place
199
+ * in the memory map); if so then the GIC has multiple MemoryRegions
200
+ * for the redistributors.
201
*/
202
- cpuidx = offset / 0x20000;
203
- offset %= 0x20000;
204
- assert(cpuidx < s->num_cpu);
205
+ cpuidx = region->cpuidx + offset / GICV3_REDIST_SIZE;
206
+ offset %= GICV3_REDIST_SIZE;
207
208
cs = &s->cpu[cpuidx];
209
53
--
210
--
54
2.20.1
211
2.25.1
55
212
56
213
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
Add the CRP as unimplemented thus avoiding bus errors when
3
The PL031 currently is not able to report guest RTC change to the QMP
4
guests access these registers.
4
monitor as opposed to mc146818 or spapr RTCs. This patch adds the call
5
to qapi_event_send_rtc_change() when the Load Register is written. The
6
value which is reported corresponds to the difference between the guest
7
reference time and the reference time kept in softmmu/rtc.c.
5
8
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
For instance adding 20s to the guest RTC value will report 20. Adding
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
an extra 20s to the guest RTC value will report 20 + 20 = 40.
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
9
Message-id: 20191115154734.26449-2-edgar.iglesias@gmail.com
12
The inclusion of qapi/qapi-types-misc-target.h in hw/rtl/pl031.c
13
require to compile the PL031 with specific_ss.add() to avoid
14
./qapi/qapi-types-misc-target.h:18:13: error: attempt to use poisoned
15
"TARGET_<ARCH>".
16
17
Signed-off-by: Eric Auger <eric.auger@redhat.com>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Message-id: 20210920122535.269988-1-eric.auger@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
21
---
12
include/hw/arm/xlnx-versal.h | 3 +++
22
hw/rtc/pl031.c | 10 +++++++++-
13
hw/arm/xlnx-versal.c | 2 ++
23
hw/rtc/meson.build | 2 +-
14
2 files changed, 5 insertions(+)
24
2 files changed, 10 insertions(+), 2 deletions(-)
15
25
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
26
diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c
17
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
28
--- a/hw/rtc/pl031.c
19
+++ b/include/hw/arm/xlnx-versal.h
29
+++ b/hw/rtc/pl031.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
@@ -XXX,XX +XXX,XX @@
21
#define MM_IOU_SCNTRS_SIZE 0x10000
31
#include "qemu/log.h"
22
#define MM_FPD_CRF 0xfd1a0000U
32
#include "qemu/module.h"
23
#define MM_FPD_CRF_SIZE 0x140000
33
#include "trace.h"
34
+#include "qapi/qapi-events-misc-target.h"
35
36
#define RTC_DR 0x00 /* Data read register */
37
#define RTC_MR 0x04 /* Match register */
38
@@ -XXX,XX +XXX,XX @@ static void pl031_write(void * opaque, hwaddr offset,
39
trace_pl031_write(offset, value);
40
41
switch (offset) {
42
- case RTC_LR:
43
+ case RTC_LR: {
44
+ struct tm tm;
24
+
45
+
25
+#define MM_PMC_CRP 0xf1260000U
46
s->tick_offset += value - pl031_get_count(s);
26
+#define MM_PMC_CRP_SIZE 0x10000
47
+
27
#endif
48
+ qemu_get_timedate(&tm, s->tick_offset);
28
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
49
+ qapi_event_send_rtc_change(qemu_timedate_diff(&tm));
50
+
51
pl031_set_alarm(s);
52
break;
53
+ }
54
case RTC_MR:
55
s->mr = value;
56
pl031_set_alarm(s);
57
diff --git a/hw/rtc/meson.build b/hw/rtc/meson.build
29
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/xlnx-versal.c
59
--- a/hw/rtc/meson.build
31
+++ b/hw/arm/xlnx-versal.c
60
+++ b/hw/rtc/meson.build
32
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
61
@@ -XXX,XX +XXX,XX @@
33
MM_CRL, MM_CRL_SIZE);
62
softmmu_ss.add(when: 'CONFIG_DS1338', if_true: files('ds1338.c'))
34
versal_unimp_area(s, "crf", &s->mr_ps,
63
softmmu_ss.add(when: 'CONFIG_M41T80', if_true: files('m41t80.c'))
35
MM_FPD_CRF, MM_FPD_CRF_SIZE);
64
softmmu_ss.add(when: 'CONFIG_M48T59', if_true: files('m48t59.c'))
36
+ versal_unimp_area(s, "crp", &s->mr_ps,
65
-softmmu_ss.add(when: 'CONFIG_PL031', if_true: files('pl031.c'))
37
+ MM_PMC_CRP, MM_PMC_CRP_SIZE);
66
+specific_ss.add(when: 'CONFIG_PL031', if_true: files('pl031.c'))
38
versal_unimp_area(s, "iou-scntr", &s->mr_ps,
67
softmmu_ss.add(when: 'CONFIG_TWL92230', if_true: files('twl92230.c'))
39
MM_IOU_SCNTR, MM_IOU_SCNTR_SIZE);
68
softmmu_ss.add(when: ['CONFIG_ISA_BUS', 'CONFIG_M48T59'], if_true: files('m48t59-isa.c'))
40
versal_unimp_area(s, "iou-scntr-seucre", &s->mr_ps,
69
softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-rtc.c'))
41
--
70
--
42
2.20.1
71
2.25.1
43
72
44
73
diff view generated by jsdifflib