gic_v3_cpu_interface.cc (14236:5d24c3de4262) gic_v3_cpu_interface.cc (14237:fa3f5209a8e8)
1/*
2 * Copyright (c) 2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2018 Metempsy Technology Consulting
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Jairo Balart
41 */
42
43#include "dev/arm/gic_v3_cpu_interface.hh"
44
45#include "arch/arm/isa.hh"
46#include "debug/GIC.hh"
47#include "dev/arm/gic_v3.hh"
48#include "dev/arm/gic_v3_distributor.hh"
49#include "dev/arm/gic_v3_redistributor.hh"
50
51const uint8_t Gicv3CPUInterface::GIC_MIN_BPR;
52const uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS;
53
54Gicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
55 : BaseISADevice(),
56 gic(gic),
57 redistributor(nullptr),
58 distributor(nullptr),
59 cpuId(cpu_id)
60{
61}
62
63void
64Gicv3CPUInterface::init()
65{
66 redistributor = gic->getRedistributor(cpuId);
67 distributor = gic->getDistributor();
68}
69
70void
71Gicv3CPUInterface::initState()
72{
73 reset();
74}
75
76void
77Gicv3CPUInterface::reset()
78{
79 hppi.prio = 0xff;
80}
81
82void
83Gicv3CPUInterface::setThreadContext(ThreadContext *tc)
84{
85 maintenanceInterrupt = gic->params()->maint_int->get(tc);
86}
87
88bool
89Gicv3CPUInterface::getHCREL2FMO() const
90{
91 HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
92
93 if (hcr.tge && hcr.e2h) {
94 return false;
95 } else if (hcr.tge) {
96 return true;
97 } else {
98 return hcr.fmo;
99 }
100}
101
102bool
103Gicv3CPUInterface::getHCREL2IMO() const
104{
105 HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
106
107 if (hcr.tge && hcr.e2h) {
108 return false;
109 } else if (hcr.tge) {
110 return true;
111 } else {
112 return hcr.imo;
113 }
114}
115
116RegVal
117Gicv3CPUInterface::readMiscReg(int misc_reg)
118{
119 RegVal value = isa->readMiscRegNoEffect(misc_reg);
120 bool hcr_fmo = getHCREL2FMO();
121 bool hcr_imo = getHCREL2IMO();
122
123 switch (misc_reg) {
124 // Active Priorities Group 1 Registers
125 case MISCREG_ICC_AP1R0:
126 case MISCREG_ICC_AP1R0_EL1: {
127 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
128 return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1);
129 }
130
131 break;
132 }
133
134 case MISCREG_ICC_AP1R1:
135 case MISCREG_ICC_AP1R1_EL1:
136
137 // only implemented if supporting 6 or more bits of priority
138 case MISCREG_ICC_AP1R2:
139 case MISCREG_ICC_AP1R2_EL1:
140
141 // only implemented if supporting 7 or more bits of priority
142 case MISCREG_ICC_AP1R3:
143 case MISCREG_ICC_AP1R3_EL1:
144 // only implemented if supporting 7 or more bits of priority
145 return 0;
146
147 // Active Priorities Group 0 Registers
148 case MISCREG_ICC_AP0R0:
149 case MISCREG_ICC_AP0R0_EL1: {
150 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
151 return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1);
152 }
153
154 break;
155 }
156
157 case MISCREG_ICC_AP0R1:
158 case MISCREG_ICC_AP0R1_EL1:
159
160 // only implemented if supporting 6 or more bits of priority
161 case MISCREG_ICC_AP0R2:
162 case MISCREG_ICC_AP0R2_EL1:
163
164 // only implemented if supporting 7 or more bits of priority
165 case MISCREG_ICC_AP0R3:
166 case MISCREG_ICC_AP0R3_EL1:
167 // only implemented if supporting 7 or more bits of priority
168 return 0;
169
170 // Interrupt Group 0 Enable register EL1
171 case MISCREG_ICC_IGRPEN0:
172 case MISCREG_ICC_IGRPEN0_EL1: {
173 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
174 return readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
175 }
176
177 break;
178 }
179
180 case MISCREG_ICV_IGRPEN0_EL1: {
181 ICH_VMCR_EL2 ich_vmcr_el2 =
182 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
183 value = ich_vmcr_el2.VENG0;
184 break;
185 }
186
187 // Interrupt Group 1 Enable register EL1
188 case MISCREG_ICC_IGRPEN1:
189 case MISCREG_ICC_IGRPEN1_EL1: {
190 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
191 return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
192 }
193
194 break;
195 }
196
197 case MISCREG_ICV_IGRPEN1_EL1: {
198 ICH_VMCR_EL2 ich_vmcr_el2 =
199 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
200 value = ich_vmcr_el2.VENG1;
201 break;
202 }
203
204 // Interrupt Group 1 Enable register EL3
205 case MISCREG_ICC_MGRPEN1:
206 case MISCREG_ICC_IGRPEN1_EL3:
207 break;
208
209 // Running Priority Register
210 case MISCREG_ICC_RPR:
211 case MISCREG_ICC_RPR_EL1: {
212 if ((currEL() == EL1) && !inSecureState() &&
213 (hcr_imo || hcr_fmo)) {
214 return readMiscReg(MISCREG_ICV_RPR_EL1);
215 }
216
217 uint8_t rprio = highestActivePriority();
218
219 if (haveEL(EL3) && !inSecureState() &&
220 (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
221 // Spec section 4.8.1
222 // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
223 if ((rprio & 0x80) == 0) {
224 // If the current priority mask value is in the range of
225 // 0x00-0x7F a read access returns the value 0x0
226 rprio = 0;
227 } else if (rprio != 0xff) {
228 // If the current priority mask value is in the range of
229 // 0x80-0xFF a read access returns the Non-secure read of
230 // the current value
231 rprio = (rprio << 1) & 0xff;
232 }
233 }
234
235 value = rprio;
236 break;
237 }
238
239 // Virtual Running Priority Register
240 case MISCREG_ICV_RPR_EL1: {
241 value = virtualHighestActivePriority();
242 break;
243 }
244
245 // Highest Priority Pending Interrupt Register 0
246 case MISCREG_ICC_HPPIR0:
247 case MISCREG_ICC_HPPIR0_EL1: {
248 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
249 return readMiscReg(MISCREG_ICV_HPPIR0_EL1);
250 }
251
252 value = getHPPIR0();
253 break;
254 }
255
256 // Virtual Highest Priority Pending Interrupt Register 0
257 case MISCREG_ICV_HPPIR0_EL1: {
258 value = Gicv3::INTID_SPURIOUS;
259 int lr_idx = getHPPVILR();
260
261 if (lr_idx >= 0) {
262 ICH_LR_EL2 ich_lr_el2 =
263 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
264 Gicv3::GroupId group =
265 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
266
267 if (group == Gicv3::G0S) {
268 value = ich_lr_el2.vINTID;
269 }
270 }
271
272 break;
273 }
274
275 // Highest Priority Pending Interrupt Register 1
276 case MISCREG_ICC_HPPIR1:
277 case MISCREG_ICC_HPPIR1_EL1: {
278 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
279 return readMiscReg(MISCREG_ICV_HPPIR1_EL1);
280 }
281
282 value = getHPPIR1();
283 break;
284 }
285
286 // Virtual Highest Priority Pending Interrupt Register 1
287 case MISCREG_ICV_HPPIR1_EL1: {
288 value = Gicv3::INTID_SPURIOUS;
289 int lr_idx = getHPPVILR();
290
291 if (lr_idx >= 0) {
292 ICH_LR_EL2 ich_lr_el2 =
293 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
294 Gicv3::GroupId group =
295 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
296
297 if (group == Gicv3::G1NS) {
298 value = ich_lr_el2.vINTID;
299 }
300 }
301
302 break;
303 }
304
305 // Binary Point Register 0
306 case MISCREG_ICC_BPR0:
1/*
2 * Copyright (c) 2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2018 Metempsy Technology Consulting
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Jairo Balart
41 */
42
43#include "dev/arm/gic_v3_cpu_interface.hh"
44
45#include "arch/arm/isa.hh"
46#include "debug/GIC.hh"
47#include "dev/arm/gic_v3.hh"
48#include "dev/arm/gic_v3_distributor.hh"
49#include "dev/arm/gic_v3_redistributor.hh"
50
51const uint8_t Gicv3CPUInterface::GIC_MIN_BPR;
52const uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS;
53
54Gicv3CPUInterface::Gicv3CPUInterface(Gicv3 * gic, uint32_t cpu_id)
55 : BaseISADevice(),
56 gic(gic),
57 redistributor(nullptr),
58 distributor(nullptr),
59 cpuId(cpu_id)
60{
61}
62
63void
64Gicv3CPUInterface::init()
65{
66 redistributor = gic->getRedistributor(cpuId);
67 distributor = gic->getDistributor();
68}
69
70void
71Gicv3CPUInterface::initState()
72{
73 reset();
74}
75
76void
77Gicv3CPUInterface::reset()
78{
79 hppi.prio = 0xff;
80}
81
82void
83Gicv3CPUInterface::setThreadContext(ThreadContext *tc)
84{
85 maintenanceInterrupt = gic->params()->maint_int->get(tc);
86}
87
88bool
89Gicv3CPUInterface::getHCREL2FMO() const
90{
91 HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
92
93 if (hcr.tge && hcr.e2h) {
94 return false;
95 } else if (hcr.tge) {
96 return true;
97 } else {
98 return hcr.fmo;
99 }
100}
101
102bool
103Gicv3CPUInterface::getHCREL2IMO() const
104{
105 HCR hcr = isa->readMiscRegNoEffect(MISCREG_HCR_EL2);
106
107 if (hcr.tge && hcr.e2h) {
108 return false;
109 } else if (hcr.tge) {
110 return true;
111 } else {
112 return hcr.imo;
113 }
114}
115
116RegVal
117Gicv3CPUInterface::readMiscReg(int misc_reg)
118{
119 RegVal value = isa->readMiscRegNoEffect(misc_reg);
120 bool hcr_fmo = getHCREL2FMO();
121 bool hcr_imo = getHCREL2IMO();
122
123 switch (misc_reg) {
124 // Active Priorities Group 1 Registers
125 case MISCREG_ICC_AP1R0:
126 case MISCREG_ICC_AP1R0_EL1: {
127 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
128 return isa->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1);
129 }
130
131 break;
132 }
133
134 case MISCREG_ICC_AP1R1:
135 case MISCREG_ICC_AP1R1_EL1:
136
137 // only implemented if supporting 6 or more bits of priority
138 case MISCREG_ICC_AP1R2:
139 case MISCREG_ICC_AP1R2_EL1:
140
141 // only implemented if supporting 7 or more bits of priority
142 case MISCREG_ICC_AP1R3:
143 case MISCREG_ICC_AP1R3_EL1:
144 // only implemented if supporting 7 or more bits of priority
145 return 0;
146
147 // Active Priorities Group 0 Registers
148 case MISCREG_ICC_AP0R0:
149 case MISCREG_ICC_AP0R0_EL1: {
150 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
151 return isa->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1);
152 }
153
154 break;
155 }
156
157 case MISCREG_ICC_AP0R1:
158 case MISCREG_ICC_AP0R1_EL1:
159
160 // only implemented if supporting 6 or more bits of priority
161 case MISCREG_ICC_AP0R2:
162 case MISCREG_ICC_AP0R2_EL1:
163
164 // only implemented if supporting 7 or more bits of priority
165 case MISCREG_ICC_AP0R3:
166 case MISCREG_ICC_AP0R3_EL1:
167 // only implemented if supporting 7 or more bits of priority
168 return 0;
169
170 // Interrupt Group 0 Enable register EL1
171 case MISCREG_ICC_IGRPEN0:
172 case MISCREG_ICC_IGRPEN0_EL1: {
173 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
174 return readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
175 }
176
177 break;
178 }
179
180 case MISCREG_ICV_IGRPEN0_EL1: {
181 ICH_VMCR_EL2 ich_vmcr_el2 =
182 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
183 value = ich_vmcr_el2.VENG0;
184 break;
185 }
186
187 // Interrupt Group 1 Enable register EL1
188 case MISCREG_ICC_IGRPEN1:
189 case MISCREG_ICC_IGRPEN1_EL1: {
190 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
191 return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
192 }
193
194 break;
195 }
196
197 case MISCREG_ICV_IGRPEN1_EL1: {
198 ICH_VMCR_EL2 ich_vmcr_el2 =
199 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
200 value = ich_vmcr_el2.VENG1;
201 break;
202 }
203
204 // Interrupt Group 1 Enable register EL3
205 case MISCREG_ICC_MGRPEN1:
206 case MISCREG_ICC_IGRPEN1_EL3:
207 break;
208
209 // Running Priority Register
210 case MISCREG_ICC_RPR:
211 case MISCREG_ICC_RPR_EL1: {
212 if ((currEL() == EL1) && !inSecureState() &&
213 (hcr_imo || hcr_fmo)) {
214 return readMiscReg(MISCREG_ICV_RPR_EL1);
215 }
216
217 uint8_t rprio = highestActivePriority();
218
219 if (haveEL(EL3) && !inSecureState() &&
220 (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
221 // Spec section 4.8.1
222 // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
223 if ((rprio & 0x80) == 0) {
224 // If the current priority mask value is in the range of
225 // 0x00-0x7F a read access returns the value 0x0
226 rprio = 0;
227 } else if (rprio != 0xff) {
228 // If the current priority mask value is in the range of
229 // 0x80-0xFF a read access returns the Non-secure read of
230 // the current value
231 rprio = (rprio << 1) & 0xff;
232 }
233 }
234
235 value = rprio;
236 break;
237 }
238
239 // Virtual Running Priority Register
240 case MISCREG_ICV_RPR_EL1: {
241 value = virtualHighestActivePriority();
242 break;
243 }
244
245 // Highest Priority Pending Interrupt Register 0
246 case MISCREG_ICC_HPPIR0:
247 case MISCREG_ICC_HPPIR0_EL1: {
248 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
249 return readMiscReg(MISCREG_ICV_HPPIR0_EL1);
250 }
251
252 value = getHPPIR0();
253 break;
254 }
255
256 // Virtual Highest Priority Pending Interrupt Register 0
257 case MISCREG_ICV_HPPIR0_EL1: {
258 value = Gicv3::INTID_SPURIOUS;
259 int lr_idx = getHPPVILR();
260
261 if (lr_idx >= 0) {
262 ICH_LR_EL2 ich_lr_el2 =
263 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
264 Gicv3::GroupId group =
265 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
266
267 if (group == Gicv3::G0S) {
268 value = ich_lr_el2.vINTID;
269 }
270 }
271
272 break;
273 }
274
275 // Highest Priority Pending Interrupt Register 1
276 case MISCREG_ICC_HPPIR1:
277 case MISCREG_ICC_HPPIR1_EL1: {
278 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
279 return readMiscReg(MISCREG_ICV_HPPIR1_EL1);
280 }
281
282 value = getHPPIR1();
283 break;
284 }
285
286 // Virtual Highest Priority Pending Interrupt Register 1
287 case MISCREG_ICV_HPPIR1_EL1: {
288 value = Gicv3::INTID_SPURIOUS;
289 int lr_idx = getHPPVILR();
290
291 if (lr_idx >= 0) {
292 ICH_LR_EL2 ich_lr_el2 =
293 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
294 Gicv3::GroupId group =
295 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
296
297 if (group == Gicv3::G1NS) {
298 value = ich_lr_el2.vINTID;
299 }
300 }
301
302 break;
303 }
304
305 // Binary Point Register 0
306 case MISCREG_ICC_BPR0:
307 case MISCREG_ICC_BPR0_EL1:
307 case MISCREG_ICC_BPR0_EL1: {
308 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
309 return readMiscReg(MISCREG_ICV_BPR0_EL1);
310 }
311
308 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
309 return readMiscReg(MISCREG_ICV_BPR0_EL1);
310 }
311
312 M5_FALLTHROUGH;
312 value = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
313 break;
314 }
313
314 // Binary Point Register 1
315 case MISCREG_ICC_BPR1:
316 case MISCREG_ICC_BPR1_EL1: {
315
316 // Binary Point Register 1
317 case MISCREG_ICC_BPR1:
318 case MISCREG_ICC_BPR1_EL1: {
317 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
318 return readMiscReg(MISCREG_ICV_BPR1_EL1);
319 }
319 value = bpr1(isSecureBelowEL3() ? Gicv3::G1S : Gicv3::G1NS);
320 break;
321 }
320
322
321 Gicv3::GroupId group =
322 misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S;
323 // Virtual Binary Point Register 0
324 case MISCREG_ICV_BPR0_EL1: {
325 ICH_VMCR_EL2 ich_vmcr_el2 =
326 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
323
327
324 if (group == Gicv3::G1S && !inSecureState()) {
325 group = Gicv3::G1NS;
326 }
327
328 ICC_CTLR_EL1 icc_ctlr_el1_s =
329 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
330
331 if ((group == Gicv3::G1S) && !isEL3OrMon() &&
332 icc_ctlr_el1_s.CBPR) {
333 group = Gicv3::G0S;
334 }
335
336 bool sat_inc = false;
337
338 ICC_CTLR_EL1 icc_ctlr_el1_ns =
339 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
340
341 if ((group == Gicv3::G1NS) && (currEL() < EL3) &&
342 icc_ctlr_el1_ns.CBPR) {
343 // Reads return BPR0 + 1 saturated to 7, WI
344 group = Gicv3::G0S;
345 sat_inc = true;
346 }
347
348 uint8_t bpr;
349
350 if (group == Gicv3::G0S) {
351 bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
352 } else {
353 bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1);
354 bpr = std::max(bpr, group == Gicv3::G1S ?
355 GIC_MIN_BPR : GIC_MIN_BPR_NS);
356 }
357
358 if (sat_inc) {
359 bpr++;
360
361 if (bpr > 7) {
362 bpr = 7;
363 }
364 }
365
366 value = bpr;
367 break;
328 value = ich_vmcr_el2.VBPR0;
329 break;
368 }
369
370 // Virtual Binary Point Register 1
330 }
331
332 // Virtual Binary Point Register 1
371 case MISCREG_ICV_BPR0_EL1:
372 case MISCREG_ICV_BPR1_EL1: {
333 case MISCREG_ICV_BPR1_EL1: {
373 Gicv3::GroupId group =
374 misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
375 ICH_VMCR_EL2 ich_vmcr_el2 =
376 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
377 bool sat_inc = false;
334 ICH_VMCR_EL2 ich_vmcr_el2 =
335 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
378
336
379 if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
380 // bpr0 + 1 saturated to 7, WI
381 group = Gicv3::G0S;
382 sat_inc = true;
383 }
337 if (ich_vmcr_el2.VCBPR) {
338 // bpr0 + 1 saturated to 7, WI
339 value = ich_vmcr_el2.VBPR0 + 1;
340 value = value < 7 ? value : 7;
341 } else {
342 value = ich_vmcr_el2.VBPR1;
343 }
384
344
385 uint8_t vbpr;
386
387 if (group == Gicv3::G0S) {
388 vbpr = ich_vmcr_el2.VBPR0;
389 } else {
390 vbpr = ich_vmcr_el2.VBPR1;
391 }
392
393 if (sat_inc) {
394 vbpr++;
395
396 if (vbpr > 7) {
397 vbpr = 7;
398 }
399 }
400
401 value = vbpr;
402 break;
345 break;
403 }
404
405 // Interrupt Priority Mask Register
406 case MISCREG_ICC_PMR:
407 case MISCREG_ICC_PMR_EL1:
408 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
409 return readMiscReg(MISCREG_ICV_PMR_EL1);
410 }
411
412 if (haveEL(EL3) && !inSecureState() &&
413 (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
414 // Spec section 4.8.1
415 // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
416 if ((value & 0x80) == 0) {
417 // If the current priority mask value is in the range of
418 // 0x00-0x7F a read access returns the value 0x00.
419 value = 0;
420 } else if (value != 0xff) {
421 // If the current priority mask value is in the range of
422 // 0x80-0xFF a read access returns the Non-secure read of the
423 // current value.
424 value = (value << 1) & 0xff;
425 }
426 }
427
428 break;
429
430 case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
431 ICH_VMCR_EL2 ich_vmcr_el2 =
432 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
433
434 value = ich_vmcr_el2.VPMR;
435 break;
436 }
437
438 // Interrupt Acknowledge Register 0
439 case MISCREG_ICC_IAR0:
440 case MISCREG_ICC_IAR0_EL1: {
441 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
442 return readMiscReg(MISCREG_ICV_IAR0_EL1);
443 }
444
445 uint32_t int_id;
446
447 if (hppiCanPreempt()) {
448 int_id = getHPPIR0();
449
450 // avoid activation for special interrupts
451 if (int_id < Gicv3::INTID_SECURE ||
452 int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
453 activateIRQ(int_id, hppi.group);
454 }
455 } else {
456 int_id = Gicv3::INTID_SPURIOUS;
457 }
458
459 value = int_id;
460 break;
461 }
462
463 // Virtual Interrupt Acknowledge Register 0
464 case MISCREG_ICV_IAR0_EL1: {
465 int lr_idx = getHPPVILR();
466 uint32_t int_id = Gicv3::INTID_SPURIOUS;
467
468 if (lr_idx >= 0) {
469 ICH_LR_EL2 ich_lr_el2 =
470 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
471
472 if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
473 int_id = ich_lr_el2.vINTID;
474
475 if (int_id < Gicv3::INTID_SECURE ||
476 int_id > Gicv3::INTID_SPURIOUS) {
477 virtualActivateIRQ(lr_idx);
478 } else {
479 // Bogus... Pseudocode says:
480 // - Move from pending to invalid...
481 // - Return de bogus id...
482 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
483 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
484 ich_lr_el2);
485 }
486 }
487 }
488
489 value = int_id;
490 virtualUpdate();
491 break;
492 }
493
494 // Interrupt Acknowledge Register 1
495 case MISCREG_ICC_IAR1:
496 case MISCREG_ICC_IAR1_EL1: {
497 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
498 return readMiscReg(MISCREG_ICV_IAR1_EL1);
499 }
500
501 uint32_t int_id;
502
503 if (hppiCanPreempt()) {
504 int_id = getHPPIR1();
505
506 // avoid activation for special interrupts
507 if (int_id < Gicv3::INTID_SECURE ||
508 int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
509 activateIRQ(int_id, hppi.group);
510 }
511 } else {
512 int_id = Gicv3::INTID_SPURIOUS;
513 }
514
515 value = int_id;
516 break;
517 }
518
519 // Virtual Interrupt Acknowledge Register 1
520 case MISCREG_ICV_IAR1_EL1: {
521 int lr_idx = getHPPVILR();
522 uint32_t int_id = Gicv3::INTID_SPURIOUS;
523
524 if (lr_idx >= 0) {
525 ICH_LR_EL2 ich_lr_el2 =
526 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
527
528 if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
529 int_id = ich_lr_el2.vINTID;
530
531 if (int_id < Gicv3::INTID_SECURE ||
532 int_id > Gicv3::INTID_SPURIOUS) {
533 virtualActivateIRQ(lr_idx);
534 } else {
535 // Bogus... Pseudocode says:
536 // - Move from pending to invalid...
537 // - Return de bogus id...
538 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
539 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
540 ich_lr_el2);
541 }
542 }
543 }
544
545 value = int_id;
546 virtualUpdate();
547 break;
548 }
549
550 // System Register Enable Register EL1
551 case MISCREG_ICC_SRE:
552 case MISCREG_ICC_SRE_EL1: {
553 /*
554 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
555 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
556 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
557 */
558 ICC_SRE_EL1 icc_sre_el1 = 0;
559 icc_sre_el1.SRE = 1;
560 icc_sre_el1.DIB = 1;
561 icc_sre_el1.DFB = 1;
562 value = icc_sre_el1;
563 break;
564 }
565
566 // System Register Enable Register EL2
567 case MISCREG_ICC_HSRE:
568 case MISCREG_ICC_SRE_EL2: {
569 /*
570 * Enable [3] == 1
571 * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
572 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
573 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
574 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
575 */
576 ICC_SRE_EL2 icc_sre_el2 = 0;
577 icc_sre_el2.SRE = 1;
578 icc_sre_el2.DIB = 1;
579 icc_sre_el2.DFB = 1;
580 icc_sre_el2.Enable = 1;
581 value = icc_sre_el2;
582 break;
583 }
584
585 // System Register Enable Register EL3
586 case MISCREG_ICC_MSRE:
587 case MISCREG_ICC_SRE_EL3: {
588 /*
589 * Enable [3] == 1
590 * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
591 * EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
592 * RAO/WI)
593 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
594 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
595 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
596 */
597 ICC_SRE_EL3 icc_sre_el3 = 0;
598 icc_sre_el3.SRE = 1;
599 icc_sre_el3.DIB = 1;
600 icc_sre_el3.DFB = 1;
601 icc_sre_el3.Enable = 1;
602 value = icc_sre_el3;
603 break;
604 }
605
606 // Control Register
607 case MISCREG_ICC_CTLR:
608 case MISCREG_ICC_CTLR_EL1: {
609 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
610 return readMiscReg(MISCREG_ICV_CTLR_EL1);
611 }
612
613 // Enforce value for RO bits
614 // ExtRange [19], INTIDs in the range 1024..8191 not supported
615 // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
616 // A3V [15], supports non-zero values of the Aff3 field in SGI
617 // generation System registers
618 // SEIS [14], does not support generation of SEIs (deprecated)
619 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
620 // PRIbits [10:8], number of priority bits implemented, minus one
621 ICC_CTLR_EL1 icc_ctlr_el1 = value;
622 icc_ctlr_el1.ExtRange = 0;
623 icc_ctlr_el1.RSS = 1;
624 icc_ctlr_el1.A3V = 1;
625 icc_ctlr_el1.SEIS = 0;
626 icc_ctlr_el1.IDbits = 1;
627 icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
628 value = icc_ctlr_el1;
629 break;
630 }
631
632 // Virtual Control Register
633 case MISCREG_ICV_CTLR_EL1: {
634 ICV_CTLR_EL1 icv_ctlr_el1 = value;
635 icv_ctlr_el1.RSS = 0;
636 icv_ctlr_el1.A3V = 1;
637 icv_ctlr_el1.SEIS = 0;
638 icv_ctlr_el1.IDbits = 1;
639 icv_ctlr_el1.PRIbits = 7;
640 value = icv_ctlr_el1;
641 break;
642 }
643
644 // Control Register
645 case MISCREG_ICC_MCTLR:
646 case MISCREG_ICC_CTLR_EL3: {
647 // Enforce value for RO bits
648 // ExtRange [19], INTIDs in the range 1024..8191 not supported
649 // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
650 // nDS [17], supports disabling of security
651 // A3V [15], supports non-zero values of the Aff3 field in SGI
652 // generation System registers
653 // SEIS [14], does not support generation of SEIs (deprecated)
654 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
655 // PRIbits [10:8], number of priority bits implemented, minus one
656 ICC_CTLR_EL3 icc_ctlr_el3 = value;
657 icc_ctlr_el3.ExtRange = 0;
658 icc_ctlr_el3.RSS = 1;
659 icc_ctlr_el3.nDS = 0;
660 icc_ctlr_el3.A3V = 1;
661 icc_ctlr_el3.SEIS = 0;
662 icc_ctlr_el3.IDbits = 0;
663 icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
664 value = icc_ctlr_el3;
665 break;
666 }
667
668 // Hyp Control Register
669 case MISCREG_ICH_HCR:
670 case MISCREG_ICH_HCR_EL2:
671 break;
672
673 // Hyp Active Priorities Group 0 Registers
674 case MISCREG_ICH_AP0R0:
675 case MISCREG_ICH_AP0R0_EL2:
676 break;
677
678 // only implemented if supporting 6 or more bits of priority
679 case MISCREG_ICH_AP0R1:
680 case MISCREG_ICH_AP0R1_EL2:
681 // only implemented if supporting 7 or more bits of priority
682 case MISCREG_ICH_AP0R2:
683 case MISCREG_ICH_AP0R2_EL2:
684 // only implemented if supporting 7 or more bits of priority
685 case MISCREG_ICH_AP0R3:
686 case MISCREG_ICH_AP0R3_EL2:
687 // Unimplemented registers are RAZ/WI
688 return 0;
689
690 // Hyp Active Priorities Group 1 Registers
691 case MISCREG_ICH_AP1R0:
692 case MISCREG_ICH_AP1R0_EL2:
693 break;
694
695 // only implemented if supporting 6 or more bits of priority
696 case MISCREG_ICH_AP1R1:
697 case MISCREG_ICH_AP1R1_EL2:
698 // only implemented if supporting 7 or more bits of priority
699 case MISCREG_ICH_AP1R2:
700 case MISCREG_ICH_AP1R2_EL2:
701 // only implemented if supporting 7 or more bits of priority
702 case MISCREG_ICH_AP1R3:
703 case MISCREG_ICH_AP1R3_EL2:
704 // Unimplemented registers are RAZ/WI
705 return 0;
706
707 // Maintenance Interrupt State Register
708 case MISCREG_ICH_MISR:
709 case MISCREG_ICH_MISR_EL2:
710 value = maintenanceInterruptStatus();
711 break;
712
713 // VGIC Type Register
714 case MISCREG_ICH_VTR:
715 case MISCREG_ICH_VTR_EL2: {
716 ICH_VTR_EL2 ich_vtr_el2 = value;
717
718 ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1;
719 ich_vtr_el2.A3V = 1;
720 ich_vtr_el2.IDbits = 1;
721 ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1;
722 ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1;
723
724 value = ich_vtr_el2;
725 break;
726 }
727
728 // End of Interrupt Status Register
729 case MISCREG_ICH_EISR:
730 case MISCREG_ICH_EISR_EL2:
731 value = eoiMaintenanceInterruptStatus();
732 break;
733
734 // Empty List Register Status Register
735 case MISCREG_ICH_ELRSR:
736 case MISCREG_ICH_ELRSR_EL2:
737 value = 0;
738
739 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
740 ICH_LR_EL2 ich_lr_el2 =
741 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
742
743 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
744 (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
745 value |= (1 << lr_idx);
746 }
747 }
748
749 break;
750
751 // List Registers
752 case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
753 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
754 value = value >> 32;
755 break;
756
757 // List Registers
758 case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15:
759 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
760 value = value & 0xffffffff;
761 break;
762
763 // List Registers
764 case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2:
765 break;
766
767 // Virtual Machine Control Register
768 case MISCREG_ICH_VMCR:
769 case MISCREG_ICH_VMCR_EL2:
770 break;
771
772 default:
773 panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
774 misc_reg, miscRegName[misc_reg]);
775 }
776
777 DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
778 miscRegName[misc_reg], value);
779 return value;
780}
781
782void
783Gicv3CPUInterface::setMiscReg(int misc_reg, RegVal val)
784{
785 bool do_virtual_update = false;
786 DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
787 miscRegName[misc_reg], val);
788 bool hcr_fmo = getHCREL2FMO();
789 bool hcr_imo = getHCREL2IMO();
790
791 switch (misc_reg) {
792 // Active Priorities Group 1 Registers
793 case MISCREG_ICC_AP1R0:
794 case MISCREG_ICC_AP1R0_EL1:
795 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
796 return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val);
797 }
798
799 break;
800
801 case MISCREG_ICC_AP1R1:
802 case MISCREG_ICC_AP1R1_EL1:
803
804 // only implemented if supporting 6 or more bits of priority
805 case MISCREG_ICC_AP1R2:
806 case MISCREG_ICC_AP1R2_EL1:
807
808 // only implemented if supporting 7 or more bits of priority
809 case MISCREG_ICC_AP1R3:
810 case MISCREG_ICC_AP1R3_EL1:
811 // only implemented if supporting 7 or more bits of priority
812 break;
813
814 // Active Priorities Group 0 Registers
815 case MISCREG_ICC_AP0R0:
816 case MISCREG_ICC_AP0R0_EL1:
817 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
818 return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val);
819 }
820
821 break;
822
823 case MISCREG_ICC_AP0R1:
824 case MISCREG_ICC_AP0R1_EL1:
825
826 // only implemented if supporting 6 or more bits of priority
827 case MISCREG_ICC_AP0R2:
828 case MISCREG_ICC_AP0R2_EL1:
829
830 // only implemented if supporting 7 or more bits of priority
831 case MISCREG_ICC_AP0R3:
832 case MISCREG_ICC_AP0R3_EL1:
833 // only implemented if supporting 7 or more bits of priority
834 break;
835
836 // End Of Interrupt Register 0
837 case MISCREG_ICC_EOIR0:
838 case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0
839 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
840 return setMiscReg(MISCREG_ICV_EOIR0_EL1, val);
841 }
842
843 int int_id = val & 0xffffff;
844
845 // avoid activation for special interrupts
846 if (int_id >= Gicv3::INTID_SECURE &&
847 int_id <= Gicv3::INTID_SPURIOUS) {
848 return;
849 }
850
851 Gicv3::GroupId group = Gicv3::G0S;
852
853 if (highestActiveGroup() != group) {
854 return;
855 }
856
857 dropPriority(group);
858
859 if (!isEOISplitMode()) {
860 deactivateIRQ(int_id, group);
861 }
862
863 break;
864 }
865
866 // Virtual End Of Interrupt Register 0
867 case MISCREG_ICV_EOIR0_EL1: {
868 int int_id = val & 0xffffff;
869
870 // avoid deactivation for special interrupts
871 if (int_id >= Gicv3::INTID_SECURE &&
872 int_id <= Gicv3::INTID_SPURIOUS) {
873 return;
874 }
875
876 uint8_t drop_prio = virtualDropPriority();
877
878 if (drop_prio == 0xff) {
879 return;
880 }
881
882 int lr_idx = virtualFindActive(int_id);
883
884 if (lr_idx < 0) {
885 // No LR found matching
886 virtualIncrementEOICount();
887 } else {
888 ICH_LR_EL2 ich_lr_el2 =
889 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
890 Gicv3::GroupId lr_group =
891 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
892 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
893
894 if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) {
895 //if (!virtualIsEOISplitMode())
896 {
897 virtualDeactivateIRQ(lr_idx);
898 }
899 }
900 }
901
902 virtualUpdate();
903 break;
904 }
905
906 // End Of Interrupt Register 1
907 case MISCREG_ICC_EOIR1:
908 case MISCREG_ICC_EOIR1_EL1: {
909 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
910 return setMiscReg(MISCREG_ICV_EOIR1_EL1, val);
911 }
912
913 int int_id = val & 0xffffff;
914
915 // avoid deactivation for special interrupts
916 if (int_id >= Gicv3::INTID_SECURE &&
917 int_id <= Gicv3::INTID_SPURIOUS) {
918 return;
919 }
920
921 Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
922
923 if (highestActiveGroup() == Gicv3::G0S) {
924 return;
925 }
926
927 if (distributor->DS == 0) {
928 if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) {
929 return;
930 } else if (highestActiveGroup() == Gicv3::G1NS &&
931 !(!inSecureState() or (currEL() == EL3))) {
932 return;
933 }
934 }
935
936 dropPriority(group);
937
938 if (!isEOISplitMode()) {
939 deactivateIRQ(int_id, group);
940 }
941
942 break;
943 }
944
945 // Virtual End Of Interrupt Register 1
946 case MISCREG_ICV_EOIR1_EL1: {
947 int int_id = val & 0xffffff;
948
949 // avoid deactivation for special interrupts
950 if (int_id >= Gicv3::INTID_SECURE &&
951 int_id <= Gicv3::INTID_SPURIOUS) {
952 return;
953 }
954
955 uint8_t drop_prio = virtualDropPriority();
956
957 if (drop_prio == 0xff) {
958 return;
959 }
960
961 int lr_idx = virtualFindActive(int_id);
962
963 if (lr_idx < 0) {
964 // No matching LR found
965 virtualIncrementEOICount();
966 } else {
967 ICH_LR_EL2 ich_lr_el2 =
968 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
969 Gicv3::GroupId lr_group =
970 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
971 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
972
973 if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) {
974 if (!virtualIsEOISplitMode()) {
975 virtualDeactivateIRQ(lr_idx);
976 }
977 }
978 }
979
980 virtualUpdate();
981 break;
982 }
983
984 // Deactivate Interrupt Register
985 case MISCREG_ICC_DIR:
986 case MISCREG_ICC_DIR_EL1: {
987 if ((currEL() == EL1) && !inSecureState() &&
988 (hcr_imo || hcr_fmo)) {
989 return setMiscReg(MISCREG_ICV_DIR_EL1, val);
990 }
991
992 int int_id = val & 0xffffff;
993
994 // The following checks are as per spec pseudocode
995 // aarch64/support/ICC_DIR_EL1
996
997 // Check for spurious ID
998 if (int_id >= Gicv3::INTID_SECURE) {
999 return;
1000 }
1001
1002 // EOI mode is not set, so don't deactivate
1003 if (!isEOISplitMode()) {
1004 return;
1005 }
1006
1007 Gicv3::GroupId group =
1008 int_id >= 32 ? distributor->getIntGroup(int_id) :
1009 redistributor->getIntGroup(int_id);
1010 bool irq_is_grp0 = group == Gicv3::G0S;
1011 bool single_sec_state = distributor->DS;
1012 bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS);
1013 SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
1014 bool route_fiq_to_el3 = scr_el3.fiq;
1015 bool route_irq_to_el3 = scr_el3.irq;
1016 bool route_fiq_to_el2 = hcr_fmo;
1017 bool route_irq_to_el2 = hcr_imo;
1018
1019 switch (currEL()) {
1020 case EL3:
1021 break;
1022
1023 case EL2:
1024 if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
1025 break;
1026 }
1027
1028 if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
1029 break;
1030 }
1031
1032 return;
1033
1034 case EL1:
1035 if (!isSecureBelowEL3()) {
1036 if (single_sec_state && irq_is_grp0 &&
1037 !route_fiq_to_el3 && !route_fiq_to_el2) {
1038 break;
1039 }
1040
1041 if (!irq_is_secure && !irq_is_grp0 &&
1042 !route_irq_to_el3 && !route_irq_to_el2) {
1043 break;
1044 }
1045 } else {
1046 if (irq_is_grp0 && !route_fiq_to_el3) {
1047 break;
1048 }
1049
1050 if (!irq_is_grp0 &&
1051 (!irq_is_secure || !single_sec_state) &&
1052 !route_irq_to_el3) {
1053 break;
1054 }
1055 }
1056
1057 return;
1058
1059 default:
1060 break;
1061 }
1062
1063 deactivateIRQ(int_id, group);
1064 break;
1065 }
1066
1067 // Deactivate Virtual Interrupt Register
1068 case MISCREG_ICV_DIR_EL1: {
1069 int int_id = val & 0xffffff;
1070
1071 // avoid deactivation for special interrupts
1072 if (int_id >= Gicv3::INTID_SECURE &&
1073 int_id <= Gicv3::INTID_SPURIOUS) {
1074 return;
1075 }
1076
1077 if (!virtualIsEOISplitMode()) {
1078 return;
1079 }
1080
1081 int lr_idx = virtualFindActive(int_id);
1082
1083 if (lr_idx < 0) {
1084 // No matching LR found
1085 virtualIncrementEOICount();
1086 } else {
1087 virtualDeactivateIRQ(lr_idx);
1088 }
1089
1090 virtualUpdate();
1091 break;
1092 }
1093
1094 // Binary Point Register 0
1095 case MISCREG_ICC_BPR0:
346 }
347
348 // Interrupt Priority Mask Register
349 case MISCREG_ICC_PMR:
350 case MISCREG_ICC_PMR_EL1:
351 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
352 return readMiscReg(MISCREG_ICV_PMR_EL1);
353 }
354
355 if (haveEL(EL3) && !inSecureState() &&
356 (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
357 // Spec section 4.8.1
358 // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
359 if ((value & 0x80) == 0) {
360 // If the current priority mask value is in the range of
361 // 0x00-0x7F a read access returns the value 0x00.
362 value = 0;
363 } else if (value != 0xff) {
364 // If the current priority mask value is in the range of
365 // 0x80-0xFF a read access returns the Non-secure read of the
366 // current value.
367 value = (value << 1) & 0xff;
368 }
369 }
370
371 break;
372
373 case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
374 ICH_VMCR_EL2 ich_vmcr_el2 =
375 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
376
377 value = ich_vmcr_el2.VPMR;
378 break;
379 }
380
381 // Interrupt Acknowledge Register 0
382 case MISCREG_ICC_IAR0:
383 case MISCREG_ICC_IAR0_EL1: {
384 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
385 return readMiscReg(MISCREG_ICV_IAR0_EL1);
386 }
387
388 uint32_t int_id;
389
390 if (hppiCanPreempt()) {
391 int_id = getHPPIR0();
392
393 // avoid activation for special interrupts
394 if (int_id < Gicv3::INTID_SECURE ||
395 int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
396 activateIRQ(int_id, hppi.group);
397 }
398 } else {
399 int_id = Gicv3::INTID_SPURIOUS;
400 }
401
402 value = int_id;
403 break;
404 }
405
406 // Virtual Interrupt Acknowledge Register 0
407 case MISCREG_ICV_IAR0_EL1: {
408 int lr_idx = getHPPVILR();
409 uint32_t int_id = Gicv3::INTID_SPURIOUS;
410
411 if (lr_idx >= 0) {
412 ICH_LR_EL2 ich_lr_el2 =
413 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
414
415 if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
416 int_id = ich_lr_el2.vINTID;
417
418 if (int_id < Gicv3::INTID_SECURE ||
419 int_id > Gicv3::INTID_SPURIOUS) {
420 virtualActivateIRQ(lr_idx);
421 } else {
422 // Bogus... Pseudocode says:
423 // - Move from pending to invalid...
424 // - Return de bogus id...
425 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
426 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
427 ich_lr_el2);
428 }
429 }
430 }
431
432 value = int_id;
433 virtualUpdate();
434 break;
435 }
436
437 // Interrupt Acknowledge Register 1
438 case MISCREG_ICC_IAR1:
439 case MISCREG_ICC_IAR1_EL1: {
440 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
441 return readMiscReg(MISCREG_ICV_IAR1_EL1);
442 }
443
444 uint32_t int_id;
445
446 if (hppiCanPreempt()) {
447 int_id = getHPPIR1();
448
449 // avoid activation for special interrupts
450 if (int_id < Gicv3::INTID_SECURE ||
451 int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
452 activateIRQ(int_id, hppi.group);
453 }
454 } else {
455 int_id = Gicv3::INTID_SPURIOUS;
456 }
457
458 value = int_id;
459 break;
460 }
461
462 // Virtual Interrupt Acknowledge Register 1
463 case MISCREG_ICV_IAR1_EL1: {
464 int lr_idx = getHPPVILR();
465 uint32_t int_id = Gicv3::INTID_SPURIOUS;
466
467 if (lr_idx >= 0) {
468 ICH_LR_EL2 ich_lr_el2 =
469 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
470
471 if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
472 int_id = ich_lr_el2.vINTID;
473
474 if (int_id < Gicv3::INTID_SECURE ||
475 int_id > Gicv3::INTID_SPURIOUS) {
476 virtualActivateIRQ(lr_idx);
477 } else {
478 // Bogus... Pseudocode says:
479 // - Move from pending to invalid...
480 // - Return de bogus id...
481 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
482 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx,
483 ich_lr_el2);
484 }
485 }
486 }
487
488 value = int_id;
489 virtualUpdate();
490 break;
491 }
492
493 // System Register Enable Register EL1
494 case MISCREG_ICC_SRE:
495 case MISCREG_ICC_SRE_EL1: {
496 /*
497 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
498 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
499 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
500 */
501 ICC_SRE_EL1 icc_sre_el1 = 0;
502 icc_sre_el1.SRE = 1;
503 icc_sre_el1.DIB = 1;
504 icc_sre_el1.DFB = 1;
505 value = icc_sre_el1;
506 break;
507 }
508
509 // System Register Enable Register EL2
510 case MISCREG_ICC_HSRE:
511 case MISCREG_ICC_SRE_EL2: {
512 /*
513 * Enable [3] == 1
514 * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
515 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
516 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
517 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
518 */
519 ICC_SRE_EL2 icc_sre_el2 = 0;
520 icc_sre_el2.SRE = 1;
521 icc_sre_el2.DIB = 1;
522 icc_sre_el2.DFB = 1;
523 icc_sre_el2.Enable = 1;
524 value = icc_sre_el2;
525 break;
526 }
527
528 // System Register Enable Register EL3
529 case MISCREG_ICC_MSRE:
530 case MISCREG_ICC_SRE_EL3: {
531 /*
532 * Enable [3] == 1
533 * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
534 * EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
535 * RAO/WI)
536 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
537 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
538 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
539 */
540 ICC_SRE_EL3 icc_sre_el3 = 0;
541 icc_sre_el3.SRE = 1;
542 icc_sre_el3.DIB = 1;
543 icc_sre_el3.DFB = 1;
544 icc_sre_el3.Enable = 1;
545 value = icc_sre_el3;
546 break;
547 }
548
549 // Control Register
550 case MISCREG_ICC_CTLR:
551 case MISCREG_ICC_CTLR_EL1: {
552 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
553 return readMiscReg(MISCREG_ICV_CTLR_EL1);
554 }
555
556 // Enforce value for RO bits
557 // ExtRange [19], INTIDs in the range 1024..8191 not supported
558 // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
559 // A3V [15], supports non-zero values of the Aff3 field in SGI
560 // generation System registers
561 // SEIS [14], does not support generation of SEIs (deprecated)
562 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
563 // PRIbits [10:8], number of priority bits implemented, minus one
564 ICC_CTLR_EL1 icc_ctlr_el1 = value;
565 icc_ctlr_el1.ExtRange = 0;
566 icc_ctlr_el1.RSS = 1;
567 icc_ctlr_el1.A3V = 1;
568 icc_ctlr_el1.SEIS = 0;
569 icc_ctlr_el1.IDbits = 1;
570 icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
571 value = icc_ctlr_el1;
572 break;
573 }
574
575 // Virtual Control Register
576 case MISCREG_ICV_CTLR_EL1: {
577 ICV_CTLR_EL1 icv_ctlr_el1 = value;
578 icv_ctlr_el1.RSS = 0;
579 icv_ctlr_el1.A3V = 1;
580 icv_ctlr_el1.SEIS = 0;
581 icv_ctlr_el1.IDbits = 1;
582 icv_ctlr_el1.PRIbits = 7;
583 value = icv_ctlr_el1;
584 break;
585 }
586
587 // Control Register
588 case MISCREG_ICC_MCTLR:
589 case MISCREG_ICC_CTLR_EL3: {
590 // Enforce value for RO bits
591 // ExtRange [19], INTIDs in the range 1024..8191 not supported
592 // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
593 // nDS [17], supports disabling of security
594 // A3V [15], supports non-zero values of the Aff3 field in SGI
595 // generation System registers
596 // SEIS [14], does not support generation of SEIs (deprecated)
597 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
598 // PRIbits [10:8], number of priority bits implemented, minus one
599 ICC_CTLR_EL3 icc_ctlr_el3 = value;
600 icc_ctlr_el3.ExtRange = 0;
601 icc_ctlr_el3.RSS = 1;
602 icc_ctlr_el3.nDS = 0;
603 icc_ctlr_el3.A3V = 1;
604 icc_ctlr_el3.SEIS = 0;
605 icc_ctlr_el3.IDbits = 0;
606 icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
607 value = icc_ctlr_el3;
608 break;
609 }
610
611 // Hyp Control Register
612 case MISCREG_ICH_HCR:
613 case MISCREG_ICH_HCR_EL2:
614 break;
615
616 // Hyp Active Priorities Group 0 Registers
617 case MISCREG_ICH_AP0R0:
618 case MISCREG_ICH_AP0R0_EL2:
619 break;
620
621 // only implemented if supporting 6 or more bits of priority
622 case MISCREG_ICH_AP0R1:
623 case MISCREG_ICH_AP0R1_EL2:
624 // only implemented if supporting 7 or more bits of priority
625 case MISCREG_ICH_AP0R2:
626 case MISCREG_ICH_AP0R2_EL2:
627 // only implemented if supporting 7 or more bits of priority
628 case MISCREG_ICH_AP0R3:
629 case MISCREG_ICH_AP0R3_EL2:
630 // Unimplemented registers are RAZ/WI
631 return 0;
632
633 // Hyp Active Priorities Group 1 Registers
634 case MISCREG_ICH_AP1R0:
635 case MISCREG_ICH_AP1R0_EL2:
636 break;
637
638 // only implemented if supporting 6 or more bits of priority
639 case MISCREG_ICH_AP1R1:
640 case MISCREG_ICH_AP1R1_EL2:
641 // only implemented if supporting 7 or more bits of priority
642 case MISCREG_ICH_AP1R2:
643 case MISCREG_ICH_AP1R2_EL2:
644 // only implemented if supporting 7 or more bits of priority
645 case MISCREG_ICH_AP1R3:
646 case MISCREG_ICH_AP1R3_EL2:
647 // Unimplemented registers are RAZ/WI
648 return 0;
649
650 // Maintenance Interrupt State Register
651 case MISCREG_ICH_MISR:
652 case MISCREG_ICH_MISR_EL2:
653 value = maintenanceInterruptStatus();
654 break;
655
656 // VGIC Type Register
657 case MISCREG_ICH_VTR:
658 case MISCREG_ICH_VTR_EL2: {
659 ICH_VTR_EL2 ich_vtr_el2 = value;
660
661 ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1;
662 ich_vtr_el2.A3V = 1;
663 ich_vtr_el2.IDbits = 1;
664 ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1;
665 ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1;
666
667 value = ich_vtr_el2;
668 break;
669 }
670
671 // End of Interrupt Status Register
672 case MISCREG_ICH_EISR:
673 case MISCREG_ICH_EISR_EL2:
674 value = eoiMaintenanceInterruptStatus();
675 break;
676
677 // Empty List Register Status Register
678 case MISCREG_ICH_ELRSR:
679 case MISCREG_ICH_ELRSR_EL2:
680 value = 0;
681
682 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
683 ICH_LR_EL2 ich_lr_el2 =
684 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
685
686 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
687 (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
688 value |= (1 << lr_idx);
689 }
690 }
691
692 break;
693
694 // List Registers
695 case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
696 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
697 value = value >> 32;
698 break;
699
700 // List Registers
701 case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15:
702 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
703 value = value & 0xffffffff;
704 break;
705
706 // List Registers
707 case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2:
708 break;
709
710 // Virtual Machine Control Register
711 case MISCREG_ICH_VMCR:
712 case MISCREG_ICH_VMCR_EL2:
713 break;
714
715 default:
716 panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
717 misc_reg, miscRegName[misc_reg]);
718 }
719
720 DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
721 miscRegName[misc_reg], value);
722 return value;
723}
724
725void
726Gicv3CPUInterface::setMiscReg(int misc_reg, RegVal val)
727{
728 bool do_virtual_update = false;
729 DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
730 miscRegName[misc_reg], val);
731 bool hcr_fmo = getHCREL2FMO();
732 bool hcr_imo = getHCREL2IMO();
733
734 switch (misc_reg) {
735 // Active Priorities Group 1 Registers
736 case MISCREG_ICC_AP1R0:
737 case MISCREG_ICC_AP1R0_EL1:
738 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
739 return isa->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1, val);
740 }
741
742 break;
743
744 case MISCREG_ICC_AP1R1:
745 case MISCREG_ICC_AP1R1_EL1:
746
747 // only implemented if supporting 6 or more bits of priority
748 case MISCREG_ICC_AP1R2:
749 case MISCREG_ICC_AP1R2_EL1:
750
751 // only implemented if supporting 7 or more bits of priority
752 case MISCREG_ICC_AP1R3:
753 case MISCREG_ICC_AP1R3_EL1:
754 // only implemented if supporting 7 or more bits of priority
755 break;
756
757 // Active Priorities Group 0 Registers
758 case MISCREG_ICC_AP0R0:
759 case MISCREG_ICC_AP0R0_EL1:
760 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
761 return isa->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1, val);
762 }
763
764 break;
765
766 case MISCREG_ICC_AP0R1:
767 case MISCREG_ICC_AP0R1_EL1:
768
769 // only implemented if supporting 6 or more bits of priority
770 case MISCREG_ICC_AP0R2:
771 case MISCREG_ICC_AP0R2_EL1:
772
773 // only implemented if supporting 7 or more bits of priority
774 case MISCREG_ICC_AP0R3:
775 case MISCREG_ICC_AP0R3_EL1:
776 // only implemented if supporting 7 or more bits of priority
777 break;
778
779 // End Of Interrupt Register 0
780 case MISCREG_ICC_EOIR0:
781 case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0
782 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
783 return setMiscReg(MISCREG_ICV_EOIR0_EL1, val);
784 }
785
786 int int_id = val & 0xffffff;
787
788 // avoid activation for special interrupts
789 if (int_id >= Gicv3::INTID_SECURE &&
790 int_id <= Gicv3::INTID_SPURIOUS) {
791 return;
792 }
793
794 Gicv3::GroupId group = Gicv3::G0S;
795
796 if (highestActiveGroup() != group) {
797 return;
798 }
799
800 dropPriority(group);
801
802 if (!isEOISplitMode()) {
803 deactivateIRQ(int_id, group);
804 }
805
806 break;
807 }
808
809 // Virtual End Of Interrupt Register 0
810 case MISCREG_ICV_EOIR0_EL1: {
811 int int_id = val & 0xffffff;
812
813 // avoid deactivation for special interrupts
814 if (int_id >= Gicv3::INTID_SECURE &&
815 int_id <= Gicv3::INTID_SPURIOUS) {
816 return;
817 }
818
819 uint8_t drop_prio = virtualDropPriority();
820
821 if (drop_prio == 0xff) {
822 return;
823 }
824
825 int lr_idx = virtualFindActive(int_id);
826
827 if (lr_idx < 0) {
828 // No LR found matching
829 virtualIncrementEOICount();
830 } else {
831 ICH_LR_EL2 ich_lr_el2 =
832 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
833 Gicv3::GroupId lr_group =
834 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
835 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
836
837 if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) {
838 //if (!virtualIsEOISplitMode())
839 {
840 virtualDeactivateIRQ(lr_idx);
841 }
842 }
843 }
844
845 virtualUpdate();
846 break;
847 }
848
849 // End Of Interrupt Register 1
850 case MISCREG_ICC_EOIR1:
851 case MISCREG_ICC_EOIR1_EL1: {
852 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
853 return setMiscReg(MISCREG_ICV_EOIR1_EL1, val);
854 }
855
856 int int_id = val & 0xffffff;
857
858 // avoid deactivation for special interrupts
859 if (int_id >= Gicv3::INTID_SECURE &&
860 int_id <= Gicv3::INTID_SPURIOUS) {
861 return;
862 }
863
864 Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
865
866 if (highestActiveGroup() == Gicv3::G0S) {
867 return;
868 }
869
870 if (distributor->DS == 0) {
871 if (highestActiveGroup() == Gicv3::G1S && !inSecureState()) {
872 return;
873 } else if (highestActiveGroup() == Gicv3::G1NS &&
874 !(!inSecureState() or (currEL() == EL3))) {
875 return;
876 }
877 }
878
879 dropPriority(group);
880
881 if (!isEOISplitMode()) {
882 deactivateIRQ(int_id, group);
883 }
884
885 break;
886 }
887
888 // Virtual End Of Interrupt Register 1
889 case MISCREG_ICV_EOIR1_EL1: {
890 int int_id = val & 0xffffff;
891
892 // avoid deactivation for special interrupts
893 if (int_id >= Gicv3::INTID_SECURE &&
894 int_id <= Gicv3::INTID_SPURIOUS) {
895 return;
896 }
897
898 uint8_t drop_prio = virtualDropPriority();
899
900 if (drop_prio == 0xff) {
901 return;
902 }
903
904 int lr_idx = virtualFindActive(int_id);
905
906 if (lr_idx < 0) {
907 // No matching LR found
908 virtualIncrementEOICount();
909 } else {
910 ICH_LR_EL2 ich_lr_el2 =
911 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
912 Gicv3::GroupId lr_group =
913 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
914 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
915
916 if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) {
917 if (!virtualIsEOISplitMode()) {
918 virtualDeactivateIRQ(lr_idx);
919 }
920 }
921 }
922
923 virtualUpdate();
924 break;
925 }
926
927 // Deactivate Interrupt Register
928 case MISCREG_ICC_DIR:
929 case MISCREG_ICC_DIR_EL1: {
930 if ((currEL() == EL1) && !inSecureState() &&
931 (hcr_imo || hcr_fmo)) {
932 return setMiscReg(MISCREG_ICV_DIR_EL1, val);
933 }
934
935 int int_id = val & 0xffffff;
936
937 // The following checks are as per spec pseudocode
938 // aarch64/support/ICC_DIR_EL1
939
940 // Check for spurious ID
941 if (int_id >= Gicv3::INTID_SECURE) {
942 return;
943 }
944
945 // EOI mode is not set, so don't deactivate
946 if (!isEOISplitMode()) {
947 return;
948 }
949
950 Gicv3::GroupId group =
951 int_id >= 32 ? distributor->getIntGroup(int_id) :
952 redistributor->getIntGroup(int_id);
953 bool irq_is_grp0 = group == Gicv3::G0S;
954 bool single_sec_state = distributor->DS;
955 bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS);
956 SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
957 bool route_fiq_to_el3 = scr_el3.fiq;
958 bool route_irq_to_el3 = scr_el3.irq;
959 bool route_fiq_to_el2 = hcr_fmo;
960 bool route_irq_to_el2 = hcr_imo;
961
962 switch (currEL()) {
963 case EL3:
964 break;
965
966 case EL2:
967 if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
968 break;
969 }
970
971 if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
972 break;
973 }
974
975 return;
976
977 case EL1:
978 if (!isSecureBelowEL3()) {
979 if (single_sec_state && irq_is_grp0 &&
980 !route_fiq_to_el3 && !route_fiq_to_el2) {
981 break;
982 }
983
984 if (!irq_is_secure && !irq_is_grp0 &&
985 !route_irq_to_el3 && !route_irq_to_el2) {
986 break;
987 }
988 } else {
989 if (irq_is_grp0 && !route_fiq_to_el3) {
990 break;
991 }
992
993 if (!irq_is_grp0 &&
994 (!irq_is_secure || !single_sec_state) &&
995 !route_irq_to_el3) {
996 break;
997 }
998 }
999
1000 return;
1001
1002 default:
1003 break;
1004 }
1005
1006 deactivateIRQ(int_id, group);
1007 break;
1008 }
1009
1010 // Deactivate Virtual Interrupt Register
1011 case MISCREG_ICV_DIR_EL1: {
1012 int int_id = val & 0xffffff;
1013
1014 // avoid deactivation for special interrupts
1015 if (int_id >= Gicv3::INTID_SECURE &&
1016 int_id <= Gicv3::INTID_SPURIOUS) {
1017 return;
1018 }
1019
1020 if (!virtualIsEOISplitMode()) {
1021 return;
1022 }
1023
1024 int lr_idx = virtualFindActive(int_id);
1025
1026 if (lr_idx < 0) {
1027 // No matching LR found
1028 virtualIncrementEOICount();
1029 } else {
1030 virtualDeactivateIRQ(lr_idx);
1031 }
1032
1033 virtualUpdate();
1034 break;
1035 }
1036
1037 // Binary Point Register 0
1038 case MISCREG_ICC_BPR0:
1096 case MISCREG_ICC_BPR0_EL1:
1039 case MISCREG_ICC_BPR0_EL1: {
1040 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
1041 return setMiscReg(MISCREG_ICV_BPR0_EL1, val);
1042 }
1043 break;
1044 }
1097 // Binary Point Register 1
1098 case MISCREG_ICC_BPR1:
1099 case MISCREG_ICC_BPR1_EL1: {
1045 // Binary Point Register 1
1046 case MISCREG_ICC_BPR1:
1047 case MISCREG_ICC_BPR1_EL1: {
1100 if ((currEL() == EL1) && !inSecureState()) {
1101 if (misc_reg == MISCREG_ICC_BPR0_EL1 && hcr_fmo) {
1102 return setMiscReg(MISCREG_ICV_BPR0_EL1, val);
1103 } else if (misc_reg == MISCREG_ICC_BPR1_EL1 && hcr_imo) {
1104 return setMiscReg(MISCREG_ICV_BPR1_EL1, val);
1105 }
1106 }
1048 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
1049 return setMiscReg(MISCREG_ICV_BPR1_EL1, val);
1050 }
1107
1051
1108 Gicv3::GroupId group =
1109 misc_reg == MISCREG_ICC_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1S;
1052 val &= 0x7;
1110
1053
1111 if (group == Gicv3::G1S && !inSecureState()) {
1112 group = Gicv3::G1NS;
1113 }
1054 if (isSecureBelowEL3()) {
1055 // group == Gicv3::G1S
1056 ICC_CTLR_EL1 icc_ctlr_el1_s =
1057 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
1114
1058
1115 ICC_CTLR_EL1 icc_ctlr_el1_s =
1116 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
1059 val = val > GIC_MIN_BPR ? val : GIC_MIN_BPR;
1060 if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
1061 isa->setMiscRegNoEffect(MISCREG_ICC_BPR0_EL1, val);
1062 } else {
1063 isa->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S, val);
1064 }
1065 return;
1066 } else {
1067 // group == Gicv3::G1NS
1068 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1069 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1117
1070
1118 if ((group == Gicv3::G1S) && !isEL3OrMon() &&
1119 icc_ctlr_el1_s.CBPR) {
1120 group = Gicv3::G0S;
1121 }
1071 val = val > GIC_MIN_BPR_NS ? val : GIC_MIN_BPR_NS;
1072 if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
1073 // Non secure writes from EL1 and EL2 are ignored
1074 } else {
1075 isa->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS, val);
1076 }
1077 return;
1078 }
1122
1079
1123 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1124 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1125
1126 if ((group == Gicv3::G1NS) && (currEL() < EL3) &&
1127 icc_ctlr_el1_ns.CBPR) {
1128 // BPR0 + 1 saturated to 7, WI
1129 return;
1130 }
1131
1132 uint8_t min_val = (group == Gicv3::G1NS) ?
1133 GIC_MIN_BPR_NS : GIC_MIN_BPR;
1134 val &= 0x7;
1135
1136 if (val < min_val) {
1137 val = min_val;
1138 }
1139
1140 break;
1080 break;
1141 }
1142
1143 // Virtual Binary Point Register 0
1144 case MISCREG_ICV_BPR0_EL1:
1145 // Virtual Binary Point Register 1
1146 case MISCREG_ICV_BPR1_EL1: {
1147 Gicv3::GroupId group =
1148 misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
1149 ICH_VMCR_EL2 ich_vmcr_el2 =
1150 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1151
1152 if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1153 // BPR0 + 1 saturated to 7, WI
1154 return;
1155 }
1156
1157 uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS;
1158
1159 if (group != Gicv3::G0S) {
1160 min_VPBR++;
1161 }
1162
1163 if (val < min_VPBR) {
1164 val = min_VPBR;
1165 }
1166
1167 if (group == Gicv3::G0S) {
1168 ich_vmcr_el2.VBPR0 = val;
1169 } else {
1170 ich_vmcr_el2.VBPR1 = val;
1171 }
1172
1173 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1174 do_virtual_update = true;
1175 break;
1176 }
1177
1178 // Control Register EL1
1179 case MISCREG_ICC_CTLR:
1180 case MISCREG_ICC_CTLR_EL1: {
1181 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
1182 return setMiscReg(MISCREG_ICV_CTLR_EL1, val);
1183 }
1184
1185 /*
1186 * ExtRange is RO.
1187 * RSS is RO.
1188 * A3V is RO.
1189 * SEIS is RO.
1190 * IDbits is RO.
1191 * PRIbits is RO.
1192 */
1193 ICC_CTLR_EL1 requested_icc_ctlr_el1 = val;
1194 ICC_CTLR_EL1 icc_ctlr_el1 =
1195 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
1196
1197 ICC_CTLR_EL3 icc_ctlr_el3 =
1198 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1199
1200 // The following could be refactored but it is following
1201 // spec description section 9.2.6 point by point.
1202
1203 // PMHE
1204 if (haveEL(EL3)) {
1205 // PMHE is alias of ICC_CTLR_EL3.PMHE
1206
1207 if (distributor->DS == 0) {
1208 // PMHE is RO
1209 } else if (distributor->DS == 1) {
1210 // PMHE is RW
1211 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1212 icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
1213 }
1214 } else {
1215 // PMHE is RW (by implementation choice)
1216 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1217 }
1218
1219 // EOImode
1220 icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
1221
1222 if (inSecureState()) {
1223 // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
1224 icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
1225 } else {
1226 // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
1227 icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
1228 }
1229
1230 // CBPR
1231 if (haveEL(EL3)) {
1232 // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}
1233
1234 if (distributor->DS == 0) {
1235 // CBPR is RO
1236 } else {
1237 // CBPR is RW
1238 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1239
1240 if (inSecureState()) {
1241 icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
1242 } else {
1243 icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
1244 }
1245 }
1246 } else {
1247 // CBPR is RW
1248 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1249 }
1250
1251 isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3);
1252
1253 val = icc_ctlr_el1;
1254 break;
1255 }
1256
1257 // Virtual Control Register
1258 case MISCREG_ICV_CTLR_EL1: {
1259 ICV_CTLR_EL1 requested_icv_ctlr_el1 = val;
1260 ICV_CTLR_EL1 icv_ctlr_el1 =
1261 isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1);
1262 icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
1263 icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
1264 val = icv_ctlr_el1;
1265
1266 // Aliases
1267 // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
1268 // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
1269 ICH_VMCR_EL2 ich_vmcr_el2 =
1270 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1271 ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
1272 ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
1273 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1274 break;
1275 }
1276
1277 // Control Register EL3
1278 case MISCREG_ICC_MCTLR:
1279 case MISCREG_ICC_CTLR_EL3: {
1280 /*
1281 * ExtRange is RO.
1282 * RSS is RO.
1283 * nDS is RO.
1284 * A3V is RO.
1285 * SEIS is RO.
1286 * IDbits is RO.
1287 * PRIbits is RO.
1288 * PMHE is RAO/WI, priority-based routing is always used.
1289 */
1290 ICC_CTLR_EL3 requested_icc_ctlr_el3 = val;
1291
1292 // Aliases
1293 if (haveEL(EL3))
1294 {
1295 ICC_CTLR_EL1 icc_ctlr_el1_s =
1296 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
1297 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1298 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1299
1300 // ICC_CTLR_EL1(NS).EOImode is an alias of
1301 // ICC_CTLR_EL3.EOImode_EL1NS
1302 icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
1303 // ICC_CTLR_EL1(S).EOImode is an alias of
1304 // ICC_CTLR_EL3.EOImode_EL1S
1305 icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
1306 // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
1307 icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
1308 // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
1309 icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
1310
1311 isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
1312 isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS,
1313 icc_ctlr_el1_ns);
1314 }
1315
1316 ICC_CTLR_EL3 icc_ctlr_el3 =
1317 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1318
1319 icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
1320 icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
1321 icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
1322 icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
1323 icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
1324 icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
1325
1326 val = icc_ctlr_el3;
1327 break;
1328 }
1329
1330 // Priority Mask Register
1331 case MISCREG_ICC_PMR:
1332 case MISCREG_ICC_PMR_EL1: {
1333 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
1334 return setMiscReg(MISCREG_ICV_PMR_EL1, val);
1335 }
1336
1337 val &= 0xff;
1338 SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
1339
1340 if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
1341 // Spec section 4.8.1
1342 // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
1343 RegVal old_icc_pmr_el1 =
1344 isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1);
1345
1346 if (!(old_icc_pmr_el1 & 0x80)) {
1347 // If the current priority mask value is in the range of
1348 // 0x00-0x7F then WI
1349 return;
1350 }
1351
1352 // If the current priority mask value is in the range of
1353 // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
1354 // based on the Non-secure read of the priority mask value
1355 // written to the register.
1356
1357 val = (val >> 1) | 0x80;
1358 }
1359
1360 val &= ~0U << (8 - PRIORITY_BITS);
1361 break;
1362 }
1363
1364 case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
1365 ICH_VMCR_EL2 ich_vmcr_el2 =
1366 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1367 ich_vmcr_el2.VPMR = val & 0xff;
1368
1369 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1370 virtualUpdate();
1371 return;
1372 }
1373
1374 // Interrupt Group 0 Enable Register EL1
1375 case MISCREG_ICC_IGRPEN0:
1376 case MISCREG_ICC_IGRPEN0_EL1: {
1377 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
1378 return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val);
1379 }
1380
1381 break;
1382 }
1383
1384 // Virtual Interrupt Group 0 Enable register
1385 case MISCREG_ICV_IGRPEN0_EL1: {
1386 bool enable = val & 0x1;
1387 ICH_VMCR_EL2 ich_vmcr_el2 =
1388 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1389 ich_vmcr_el2.VENG0 = enable;
1390 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1391 virtualUpdate();
1392 return;
1393 }
1394
1395 // Interrupt Group 1 Enable register EL1
1396 case MISCREG_ICC_IGRPEN1:
1397 case MISCREG_ICC_IGRPEN1_EL1: {
1398 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
1399 return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val);
1400 }
1401
1402 if (haveEL(EL3)) {
1403 ICC_IGRPEN1_EL1 icc_igrpen1_el1 = val;
1404 ICC_IGRPEN1_EL3 icc_igrpen1_el3 =
1405 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3);
1406
1407 if (inSecureState()) {
1408 // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1S
1409 icc_igrpen1_el3.EnableGrp1S = icc_igrpen1_el1.Enable;
1410 } else {
1411 // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1NS
1412 icc_igrpen1_el3.EnableGrp1NS = icc_igrpen1_el1.Enable;
1413 }
1414
1415 isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3,
1416 icc_igrpen1_el3);
1417 }
1418
1419 break;
1420 }
1421
1422 // Virtual Interrupt Group 1 Enable register
1423 case MISCREG_ICV_IGRPEN1_EL1: {
1424 bool enable = val & 0x1;
1425 ICH_VMCR_EL2 ich_vmcr_el2 =
1426 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1427 ich_vmcr_el2.VENG1 = enable;
1428 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1429 virtualUpdate();
1430 return;
1431 }
1432
1433 // Interrupt Group 1 Enable register
1434 case MISCREG_ICC_MGRPEN1:
1435 case MISCREG_ICC_IGRPEN1_EL3: {
1436 ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val;
1437 ICC_IGRPEN1_EL1 icc_igrpen1_el1 =
1438 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1);
1439
1440 if (inSecureState()) {
1441 // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1S
1442 icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1S;
1443 } else {
1444 // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1NS
1445 icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1NS;
1446 }
1447
1448 isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1, icc_igrpen1_el1);
1449 break;
1450 }
1451
1452 // Software Generated Interrupt Group 0 Register
1453 case MISCREG_ICC_SGI0R:
1454 case MISCREG_ICC_SGI0R_EL1:
1455 generateSGI(val, Gicv3::G0S);
1456 break;
1457
1458 // Software Generated Interrupt Group 1 Register
1459 case MISCREG_ICC_SGI1R:
1460 case MISCREG_ICC_SGI1R_EL1: {
1461 Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
1462
1463 generateSGI(val, group);
1464 break;
1465 }
1466
1467 // Alias Software Generated Interrupt Group 1 Register
1468 case MISCREG_ICC_ASGI1R:
1469 case MISCREG_ICC_ASGI1R_EL1: {
1470 Gicv3::GroupId group = inSecureState() ? Gicv3::G1NS : Gicv3::G1S;
1471
1472 generateSGI(val, group);
1473 break;
1474 }
1475
1476 // System Register Enable Register EL1
1477 case MISCREG_ICC_SRE:
1478 case MISCREG_ICC_SRE_EL1:
1479 // System Register Enable Register EL2
1480 case MISCREG_ICC_HSRE:
1481 case MISCREG_ICC_SRE_EL2:
1482 // System Register Enable Register EL3
1483 case MISCREG_ICC_MSRE:
1484 case MISCREG_ICC_SRE_EL3:
1485 // All bits are RAO/WI
1486 return;
1487
1488 // Hyp Control Register
1489 case MISCREG_ICH_HCR:
1490 case MISCREG_ICH_HCR_EL2: {
1491 ICH_HCR_EL2 requested_ich_hcr_el2 = val;
1492 ICH_HCR_EL2 ich_hcr_el2 =
1493 isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
1494
1495 if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
1496 {
1497 // EOIcount - Permitted behaviors are:
1498 // - Increment EOIcount.
1499 // - Leave EOIcount unchanged.
1500 ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
1501 }
1502
1503 ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
1504 ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
1505 ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
1506 ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
1507 ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
1508 ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
1509 ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
1510 ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
1511 ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
1512 ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
1513 ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
1514 ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
1515 ich_hcr_el2.En = requested_ich_hcr_el2.En;
1516 val = ich_hcr_el2;
1517 do_virtual_update = true;
1518 break;
1519 }
1520
1521 // List Registers
1522 case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: {
1523 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
1524 ICH_LRC requested_ich_lrc = val;
1525 ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg);
1526
1527 ich_lrc.State = requested_ich_lrc.State;
1528 ich_lrc.HW = requested_ich_lrc.HW;
1529 ich_lrc.Group = requested_ich_lrc.Group;
1530
1531 // Priority, bits [23:16]
1532 // At least five bits must be implemented.
1533 // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
1534 // We implement 5 bits.
1535 ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
1536 (ich_lrc.Priority & 0x07);
1537
1538 // pINTID, bits [12:0]
1539 // When ICH_LR<n>.HW is 0 this field has the following meaning:
1540 // - Bits[12:10] : RES0.
1541 // - Bit[9] : EOI.
1542 // - Bits[8:0] : RES0.
1543 // When ICH_LR<n>.HW is 1:
1544 // - This field is only required to implement enough bits to hold a
1545 // valid value for the implemented INTID size. Any unused higher
1546 // order bits are RES0.
1547 if (requested_ich_lrc.HW == 0) {
1548 ich_lrc.EOI = requested_ich_lrc.EOI;
1549 } else {
1550 ich_lrc.pINTID = requested_ich_lrc.pINTID;
1551 }
1552
1553 val = ich_lrc;
1554 do_virtual_update = true;
1555 break;
1556 }
1557
1558 // List Registers
1559 case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: {
1560 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
1561 RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
1562 val = (old_val & 0xffffffff00000000) | (val & 0xffffffff);
1563 do_virtual_update = true;
1564 break;
1565 }
1566
1567 // List Registers
1568 case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
1569 ICH_LR_EL2 requested_ich_lr_el2 = val;
1570 ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg);
1571
1572 ich_lr_el2.State = requested_ich_lr_el2.State;
1573 ich_lr_el2.HW = requested_ich_lr_el2.HW;
1574 ich_lr_el2.Group = requested_ich_lr_el2.Group;
1575
1576 // Priority, bits [55:48]
1577 // At least five bits must be implemented.
1578 // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
1579 // We implement 5 bits.
1580 ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
1581 (ich_lr_el2.Priority & 0x07);
1582
1583 // pINTID, bits [44:32]
1584 // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
1585 // - Bits[44:42] : RES0.
1586 // - Bit[41] : EOI.
1587 // - Bits[40:32] : RES0.
1588 // When ICH_LR<n>_EL2.HW is 1:
1589 // - This field is only required to implement enough bits to hold a
1590 // valid value for the implemented INTID size. Any unused higher
1591 // order bits are RES0.
1592 if (requested_ich_lr_el2.HW == 0) {
1593 ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
1594 } else {
1595 ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
1596 }
1597
1598 // vINTID, bits [31:0]
1599 // It is IMPLEMENTATION DEFINED how many bits are implemented,
1600 // though at least 16 bits must be implemented.
1601 // Unimplemented bits are RES0.
1602 ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
1603
1604 val = ich_lr_el2;
1605 do_virtual_update = true;
1606 break;
1607 }
1608
1609 // Virtual Machine Control Register
1610 case MISCREG_ICH_VMCR:
1611 case MISCREG_ICH_VMCR_EL2: {
1612 ICH_VMCR_EL2 requested_ich_vmcr_el2 = val;
1613 ICH_VMCR_EL2 ich_vmcr_el2 =
1614 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1615 ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
1616 uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;
1617
1618 if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
1619 ich_vmcr_el2.VBPR0 = min_vpr0;
1620 } else {
1621 ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
1622 }
1623
1624 uint8_t min_vpr1 = min_vpr0 + 1;
1625
1626 if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
1627 ich_vmcr_el2.VBPR1 = min_vpr1;
1628 } else {
1629 ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
1630 }
1631
1632 ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
1633 ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
1634 ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
1635 ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
1636 val = ich_vmcr_el2;
1637 break;
1638 }
1639
1640 // Hyp Active Priorities Group 0 Registers
1641 case MISCREG_ICH_AP0R0:
1642 case MISCREG_ICH_AP0R0_EL2:
1643 break;
1644
1645 // only implemented if supporting 6 or more bits of priority
1646 case MISCREG_ICH_AP0R1:
1647 case MISCREG_ICH_AP0R1_EL2:
1648 // only implemented if supporting 7 or more bits of priority
1649 case MISCREG_ICH_AP0R2:
1650 case MISCREG_ICH_AP0R2_EL2:
1651 // only implemented if supporting 7 or more bits of priority
1652 case MISCREG_ICH_AP0R3:
1653 case MISCREG_ICH_AP0R3_EL2:
1654 // Unimplemented registers are RAZ/WI
1655 return;
1656
1657 // Hyp Active Priorities Group 1 Registers
1658 case MISCREG_ICH_AP1R0:
1659 case MISCREG_ICH_AP1R0_EL2:
1660 break;
1661
1662 // only implemented if supporting 6 or more bits of priority
1663 case MISCREG_ICH_AP1R1:
1664 case MISCREG_ICH_AP1R1_EL2:
1665 // only implemented if supporting 7 or more bits of priority
1666 case MISCREG_ICH_AP1R2:
1667 case MISCREG_ICH_AP1R2_EL2:
1668 // only implemented if supporting 7 or more bits of priority
1669 case MISCREG_ICH_AP1R3:
1670 case MISCREG_ICH_AP1R3_EL2:
1671 // Unimplemented registers are RAZ/WI
1672 return;
1673
1674 default:
1675 panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
1676 misc_reg, miscRegName[misc_reg]);
1677 }
1678
1679 isa->setMiscRegNoEffect(misc_reg, val);
1680
1681 if (do_virtual_update) {
1682 virtualUpdate();
1683 }
1684}
1685
1686int
1687Gicv3CPUInterface::virtualFindActive(uint32_t int_id) const
1688{
1689 for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
1690 ICH_LR_EL2 ich_lr_el2 =
1691 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
1692
1693 if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) ||
1694 (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) &&
1695 (ich_lr_el2.vINTID == int_id)) {
1696 return lr_idx;
1697 }
1698 }
1699
1700 return -1;
1701}
1702
1703uint32_t
1704Gicv3CPUInterface::getHPPIR0() const
1705{
1706 if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
1707 return Gicv3::INTID_SPURIOUS;
1708 }
1709
1710 bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS;
1711
1712 if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
1713 // interrupt for the other state pending
1714 return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE;
1715 }
1716
1717 if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon())
1718 return Gicv3::INTID_SPURIOUS;
1719 }
1720
1721 if (irq_is_secure && !inSecureState()) {
1722 // Secure interrupts not visible in Non-secure
1723 return Gicv3::INTID_SPURIOUS;
1724 }
1725
1726 return hppi.intid;
1727}
1728
1729uint32_t
1730Gicv3CPUInterface::getHPPIR1() const
1731{
1732 if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
1733 return Gicv3::INTID_SPURIOUS;
1734 }
1735
1736 ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1737 if ((currEL() == EL3) && icc_ctlr_el3.RM) {
1738 if (hppi.group == Gicv3::G0S) {
1739 return Gicv3::INTID_SECURE;
1740 } else if (hppi.group == Gicv3::G1NS) {
1741 return Gicv3::INTID_NONSECURE;
1742 }
1743 }
1744
1745 if (hppi.group == Gicv3::G0S) {
1746 return Gicv3::INTID_SPURIOUS;
1747 }
1748
1749 bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS);
1750
1751 if (irq_is_secure) {
1752 if (!inSecureState()) {
1753 // Secure interrupts not visible in Non-secure
1754 return Gicv3::INTID_SPURIOUS;
1755 }
1756 } else if (!isEL3OrMon() && inSecureState()) {
1757 // Group 1 non-secure interrupts not visible in Secure EL1
1758 return Gicv3::INTID_SPURIOUS;
1759 }
1760
1761 return hppi.intid;
1762}
1763
1764void
1765Gicv3CPUInterface::dropPriority(Gicv3::GroupId group)
1766{
1767 int apr_misc_reg;
1768 RegVal apr;
1769 apr_misc_reg = group == Gicv3::G0S ?
1770 MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
1771 apr = isa->readMiscRegNoEffect(apr_misc_reg);
1772
1773 if (apr) {
1774 apr &= apr - 1;
1775 isa->setMiscRegNoEffect(apr_misc_reg, apr);
1776 }
1777
1778 update();
1779}
1780
1781uint8_t
1782Gicv3CPUInterface::virtualDropPriority()
1783{
1784 int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);
1785
1786 for (int i = 0; i < apr_max; i++) {
1787 RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i);
1788 RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
1789
1790 if (!vapr0 && !vapr1) {
1791 continue;
1792 }
1793
1794 int vapr0_count = ctz32(vapr0);
1795 int vapr1_count = ctz32(vapr1);
1796
1797 if (vapr0_count <= vapr1_count) {
1798 vapr0 &= vapr0 - 1;
1799 isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0);
1800 return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
1801 } else {
1802 vapr1 &= vapr1 - 1;
1803 isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1);
1804 return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
1805 }
1806 }
1807
1808 return 0xff;
1809}
1810
1811void
1812Gicv3CPUInterface::generateSGI(RegVal val, Gicv3::GroupId group)
1813{
1814 uint8_t aff3 = bits(val, 55, 48);
1815 uint8_t aff2 = bits(val, 39, 32);
1816 uint8_t aff1 = bits(val, 23, 16);;
1817 uint16_t target_list = bits(val, 15, 0);
1818 uint32_t int_id = bits(val, 27, 24);
1819 bool irm = bits(val, 40, 40);
1820 uint8_t rs = bits(val, 47, 44);
1821
1822 bool ns = !inSecureState();
1823
1824 for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
1825 Gicv3Redistributor * redistributor_i =
1826 gic->getRedistributor(i);
1827 uint32_t affinity_i = redistributor_i->getAffinity();
1828
1829 if (irm) {
1830 // Interrupts routed to all PEs in the system,
1831 // excluding "self"
1832 if (affinity_i == redistributor->getAffinity()) {
1833 continue;
1834 }
1835 } else {
1836 // Interrupts routed to the PEs specified by
1837 // Aff3.Aff2.Aff1.<target list>
1838 if ((affinity_i >> 8) !=
1839 ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
1840 continue;
1841 }
1842
1843 uint8_t aff0_i = bits(affinity_i, 7, 0);
1844
1845 if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
1846 ((0x1 << (aff0_i - rs * 16)) & target_list))) {
1847 continue;
1848 }
1849 }
1850
1851 redistributor_i->sendSGI(int_id, group, ns);
1852 }
1853}
1854
1855void
1856Gicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
1857{
1858 // Update active priority registers.
1859 uint32_t prio = hppi.prio & 0xf8;
1860 int apr_bit = prio >> (8 - PRIORITY_BITS);
1861 int reg_bit = apr_bit % 32;
1862 int apr_idx = group == Gicv3::G0S ?
1863 MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
1864 RegVal apr = isa->readMiscRegNoEffect(apr_idx);
1865 apr |= (1 << reg_bit);
1866 isa->setMiscRegNoEffect(apr_idx, apr);
1867
1868 // Move interrupt state from pending to active.
1869 if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
1870 // SGI or PPI, redistributor
1871 redistributor->activateIRQ(int_id);
1872 } else if (int_id < Gicv3::INTID_SECURE) {
1873 // SPI, distributor
1874 distributor->activateIRQ(int_id);
1875 } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
1876 // LPI, Redistributor
1877 redistributor->setClrLPI(int_id, false);
1878 }
1879
1880 // By setting the priority to 0xff we are effectively
1881 // making the int_id not pending anymore at the cpu
1882 // interface.
1883 hppi.prio = 0xff;
1884 updateDistributor();
1885}
1886
1887void
1888Gicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx)
1889{
1890 // Update active priority registers.
1891 ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
1892 lr_idx);
1893 Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S;
1894 uint8_t prio = ich_lr_el.Priority & 0xf8;
1895 int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS);
1896 int reg_no = apr_bit / 32;
1897 int reg_bit = apr_bit % 32;
1898 int apr_idx = group == Gicv3::G0S ?
1899 MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no;
1900 RegVal apr = isa->readMiscRegNoEffect(apr_idx);
1901 apr |= (1 << reg_bit);
1902 isa->setMiscRegNoEffect(apr_idx, apr);
1903 // Move interrupt state from pending to active.
1904 ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE;
1905 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el);
1906}
1907
1908void
1909Gicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group)
1910{
1911 if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
1912 // SGI or PPI, redistributor
1913 redistributor->deactivateIRQ(int_id);
1914 } else if (int_id < Gicv3::INTID_SECURE) {
1915 // SPI, distributor
1916 distributor->deactivateIRQ(int_id);
1917 }
1918
1919 updateDistributor();
1920}
1921
1922void
1923Gicv3CPUInterface::virtualDeactivateIRQ(int lr_idx)
1924{
1925 ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
1926 lr_idx);
1927
1928 if (ich_lr_el2.HW) {
1929 // Deactivate the associated physical interrupt
1930 if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) {
1931 Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ?
1932 distributor->getIntGroup(ich_lr_el2.pINTID) :
1933 redistributor->getIntGroup(ich_lr_el2.pINTID);
1934 deactivateIRQ(ich_lr_el2.pINTID, group);
1935 }
1936 }
1937
1938 // Remove the active bit
1939 ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE;
1940 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2);
1941}
1942
1943/*
1944 * Returns the priority group field for the current BPR value for the group.
1945 * GroupBits() Pseudocode from spec.
1946 */
1947uint32_t
1948Gicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
1949{
1950 ICC_CTLR_EL1 icc_ctlr_el1_s =
1951 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
1952 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1953 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1954
1955 if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
1956 (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) {
1957 group = Gicv3::G0S;
1958 }
1959
1960 int bpr;
1961
1962 if (group == Gicv3::G0S) {
1963 bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7;
1081 }
1082
1083 // Virtual Binary Point Register 0
1084 case MISCREG_ICV_BPR0_EL1:
1085 // Virtual Binary Point Register 1
1086 case MISCREG_ICV_BPR1_EL1: {
1087 Gicv3::GroupId group =
1088 misc_reg == MISCREG_ICV_BPR0_EL1 ? Gicv3::G0S : Gicv3::G1NS;
1089 ICH_VMCR_EL2 ich_vmcr_el2 =
1090 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1091
1092 if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1093 // BPR0 + 1 saturated to 7, WI
1094 return;
1095 }
1096
1097 uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS;
1098
1099 if (group != Gicv3::G0S) {
1100 min_VPBR++;
1101 }
1102
1103 if (val < min_VPBR) {
1104 val = min_VPBR;
1105 }
1106
1107 if (group == Gicv3::G0S) {
1108 ich_vmcr_el2.VBPR0 = val;
1109 } else {
1110 ich_vmcr_el2.VBPR1 = val;
1111 }
1112
1113 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1114 do_virtual_update = true;
1115 break;
1116 }
1117
1118 // Control Register EL1
1119 case MISCREG_ICC_CTLR:
1120 case MISCREG_ICC_CTLR_EL1: {
1121 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
1122 return setMiscReg(MISCREG_ICV_CTLR_EL1, val);
1123 }
1124
1125 /*
1126 * ExtRange is RO.
1127 * RSS is RO.
1128 * A3V is RO.
1129 * SEIS is RO.
1130 * IDbits is RO.
1131 * PRIbits is RO.
1132 */
1133 ICC_CTLR_EL1 requested_icc_ctlr_el1 = val;
1134 ICC_CTLR_EL1 icc_ctlr_el1 =
1135 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
1136
1137 ICC_CTLR_EL3 icc_ctlr_el3 =
1138 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1139
1140 // The following could be refactored but it is following
1141 // spec description section 9.2.6 point by point.
1142
1143 // PMHE
1144 if (haveEL(EL3)) {
1145 // PMHE is alias of ICC_CTLR_EL3.PMHE
1146
1147 if (distributor->DS == 0) {
1148 // PMHE is RO
1149 } else if (distributor->DS == 1) {
1150 // PMHE is RW
1151 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1152 icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
1153 }
1154 } else {
1155 // PMHE is RW (by implementation choice)
1156 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1157 }
1158
1159 // EOImode
1160 icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
1161
1162 if (inSecureState()) {
1163 // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
1164 icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
1165 } else {
1166 // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
1167 icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
1168 }
1169
1170 // CBPR
1171 if (haveEL(EL3)) {
1172 // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}
1173
1174 if (distributor->DS == 0) {
1175 // CBPR is RO
1176 } else {
1177 // CBPR is RW
1178 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1179
1180 if (inSecureState()) {
1181 icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
1182 } else {
1183 icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
1184 }
1185 }
1186 } else {
1187 // CBPR is RW
1188 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1189 }
1190
1191 isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3);
1192
1193 val = icc_ctlr_el1;
1194 break;
1195 }
1196
1197 // Virtual Control Register
1198 case MISCREG_ICV_CTLR_EL1: {
1199 ICV_CTLR_EL1 requested_icv_ctlr_el1 = val;
1200 ICV_CTLR_EL1 icv_ctlr_el1 =
1201 isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1);
1202 icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
1203 icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
1204 val = icv_ctlr_el1;
1205
1206 // Aliases
1207 // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
1208 // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
1209 ICH_VMCR_EL2 ich_vmcr_el2 =
1210 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1211 ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
1212 ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
1213 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1214 break;
1215 }
1216
1217 // Control Register EL3
1218 case MISCREG_ICC_MCTLR:
1219 case MISCREG_ICC_CTLR_EL3: {
1220 /*
1221 * ExtRange is RO.
1222 * RSS is RO.
1223 * nDS is RO.
1224 * A3V is RO.
1225 * SEIS is RO.
1226 * IDbits is RO.
1227 * PRIbits is RO.
1228 * PMHE is RAO/WI, priority-based routing is always used.
1229 */
1230 ICC_CTLR_EL3 requested_icc_ctlr_el3 = val;
1231
1232 // Aliases
1233 if (haveEL(EL3))
1234 {
1235 ICC_CTLR_EL1 icc_ctlr_el1_s =
1236 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
1237 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1238 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1239
1240 // ICC_CTLR_EL1(NS).EOImode is an alias of
1241 // ICC_CTLR_EL3.EOImode_EL1NS
1242 icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
1243 // ICC_CTLR_EL1(S).EOImode is an alias of
1244 // ICC_CTLR_EL3.EOImode_EL1S
1245 icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
1246 // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
1247 icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
1248 // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
1249 icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
1250
1251 isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
1252 isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS,
1253 icc_ctlr_el1_ns);
1254 }
1255
1256 ICC_CTLR_EL3 icc_ctlr_el3 =
1257 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1258
1259 icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
1260 icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
1261 icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
1262 icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
1263 icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
1264 icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
1265
1266 val = icc_ctlr_el3;
1267 break;
1268 }
1269
1270 // Priority Mask Register
1271 case MISCREG_ICC_PMR:
1272 case MISCREG_ICC_PMR_EL1: {
1273 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
1274 return setMiscReg(MISCREG_ICV_PMR_EL1, val);
1275 }
1276
1277 val &= 0xff;
1278 SCR scr_el3 = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
1279
1280 if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
1281 // Spec section 4.8.1
1282 // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
1283 RegVal old_icc_pmr_el1 =
1284 isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1);
1285
1286 if (!(old_icc_pmr_el1 & 0x80)) {
1287 // If the current priority mask value is in the range of
1288 // 0x00-0x7F then WI
1289 return;
1290 }
1291
1292 // If the current priority mask value is in the range of
1293 // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
1294 // based on the Non-secure read of the priority mask value
1295 // written to the register.
1296
1297 val = (val >> 1) | 0x80;
1298 }
1299
1300 val &= ~0U << (8 - PRIORITY_BITS);
1301 break;
1302 }
1303
1304 case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
1305 ICH_VMCR_EL2 ich_vmcr_el2 =
1306 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1307 ich_vmcr_el2.VPMR = val & 0xff;
1308
1309 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1310 virtualUpdate();
1311 return;
1312 }
1313
1314 // Interrupt Group 0 Enable Register EL1
1315 case MISCREG_ICC_IGRPEN0:
1316 case MISCREG_ICC_IGRPEN0_EL1: {
1317 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
1318 return setMiscReg(MISCREG_ICV_IGRPEN0_EL1, val);
1319 }
1320
1321 break;
1322 }
1323
1324 // Virtual Interrupt Group 0 Enable register
1325 case MISCREG_ICV_IGRPEN0_EL1: {
1326 bool enable = val & 0x1;
1327 ICH_VMCR_EL2 ich_vmcr_el2 =
1328 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1329 ich_vmcr_el2.VENG0 = enable;
1330 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1331 virtualUpdate();
1332 return;
1333 }
1334
1335 // Interrupt Group 1 Enable register EL1
1336 case MISCREG_ICC_IGRPEN1:
1337 case MISCREG_ICC_IGRPEN1_EL1: {
1338 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
1339 return setMiscReg(MISCREG_ICV_IGRPEN1_EL1, val);
1340 }
1341
1342 if (haveEL(EL3)) {
1343 ICC_IGRPEN1_EL1 icc_igrpen1_el1 = val;
1344 ICC_IGRPEN1_EL3 icc_igrpen1_el3 =
1345 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3);
1346
1347 if (inSecureState()) {
1348 // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1S
1349 icc_igrpen1_el3.EnableGrp1S = icc_igrpen1_el1.Enable;
1350 } else {
1351 // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1NS
1352 icc_igrpen1_el3.EnableGrp1NS = icc_igrpen1_el1.Enable;
1353 }
1354
1355 isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3,
1356 icc_igrpen1_el3);
1357 }
1358
1359 break;
1360 }
1361
1362 // Virtual Interrupt Group 1 Enable register
1363 case MISCREG_ICV_IGRPEN1_EL1: {
1364 bool enable = val & 0x1;
1365 ICH_VMCR_EL2 ich_vmcr_el2 =
1366 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1367 ich_vmcr_el2.VENG1 = enable;
1368 isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
1369 virtualUpdate();
1370 return;
1371 }
1372
1373 // Interrupt Group 1 Enable register
1374 case MISCREG_ICC_MGRPEN1:
1375 case MISCREG_ICC_IGRPEN1_EL3: {
1376 ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val;
1377 ICC_IGRPEN1_EL1 icc_igrpen1_el1 =
1378 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1);
1379
1380 if (inSecureState()) {
1381 // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1S
1382 icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1S;
1383 } else {
1384 // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1NS
1385 icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1NS;
1386 }
1387
1388 isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1, icc_igrpen1_el1);
1389 break;
1390 }
1391
1392 // Software Generated Interrupt Group 0 Register
1393 case MISCREG_ICC_SGI0R:
1394 case MISCREG_ICC_SGI0R_EL1:
1395 generateSGI(val, Gicv3::G0S);
1396 break;
1397
1398 // Software Generated Interrupt Group 1 Register
1399 case MISCREG_ICC_SGI1R:
1400 case MISCREG_ICC_SGI1R_EL1: {
1401 Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
1402
1403 generateSGI(val, group);
1404 break;
1405 }
1406
1407 // Alias Software Generated Interrupt Group 1 Register
1408 case MISCREG_ICC_ASGI1R:
1409 case MISCREG_ICC_ASGI1R_EL1: {
1410 Gicv3::GroupId group = inSecureState() ? Gicv3::G1NS : Gicv3::G1S;
1411
1412 generateSGI(val, group);
1413 break;
1414 }
1415
1416 // System Register Enable Register EL1
1417 case MISCREG_ICC_SRE:
1418 case MISCREG_ICC_SRE_EL1:
1419 // System Register Enable Register EL2
1420 case MISCREG_ICC_HSRE:
1421 case MISCREG_ICC_SRE_EL2:
1422 // System Register Enable Register EL3
1423 case MISCREG_ICC_MSRE:
1424 case MISCREG_ICC_SRE_EL3:
1425 // All bits are RAO/WI
1426 return;
1427
1428 // Hyp Control Register
1429 case MISCREG_ICH_HCR:
1430 case MISCREG_ICH_HCR_EL2: {
1431 ICH_HCR_EL2 requested_ich_hcr_el2 = val;
1432 ICH_HCR_EL2 ich_hcr_el2 =
1433 isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
1434
1435 if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
1436 {
1437 // EOIcount - Permitted behaviors are:
1438 // - Increment EOIcount.
1439 // - Leave EOIcount unchanged.
1440 ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
1441 }
1442
1443 ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
1444 ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
1445 ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
1446 ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
1447 ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
1448 ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
1449 ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
1450 ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
1451 ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
1452 ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
1453 ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
1454 ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
1455 ich_hcr_el2.En = requested_ich_hcr_el2.En;
1456 val = ich_hcr_el2;
1457 do_virtual_update = true;
1458 break;
1459 }
1460
1461 // List Registers
1462 case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: {
1463 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
1464 ICH_LRC requested_ich_lrc = val;
1465 ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg);
1466
1467 ich_lrc.State = requested_ich_lrc.State;
1468 ich_lrc.HW = requested_ich_lrc.HW;
1469 ich_lrc.Group = requested_ich_lrc.Group;
1470
1471 // Priority, bits [23:16]
1472 // At least five bits must be implemented.
1473 // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
1474 // We implement 5 bits.
1475 ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
1476 (ich_lrc.Priority & 0x07);
1477
1478 // pINTID, bits [12:0]
1479 // When ICH_LR<n>.HW is 0 this field has the following meaning:
1480 // - Bits[12:10] : RES0.
1481 // - Bit[9] : EOI.
1482 // - Bits[8:0] : RES0.
1483 // When ICH_LR<n>.HW is 1:
1484 // - This field is only required to implement enough bits to hold a
1485 // valid value for the implemented INTID size. Any unused higher
1486 // order bits are RES0.
1487 if (requested_ich_lrc.HW == 0) {
1488 ich_lrc.EOI = requested_ich_lrc.EOI;
1489 } else {
1490 ich_lrc.pINTID = requested_ich_lrc.pINTID;
1491 }
1492
1493 val = ich_lrc;
1494 do_virtual_update = true;
1495 break;
1496 }
1497
1498 // List Registers
1499 case MISCREG_ICH_LR0 ... MISCREG_ICH_LR15: {
1500 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
1501 RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
1502 val = (old_val & 0xffffffff00000000) | (val & 0xffffffff);
1503 do_virtual_update = true;
1504 break;
1505 }
1506
1507 // List Registers
1508 case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
1509 ICH_LR_EL2 requested_ich_lr_el2 = val;
1510 ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg);
1511
1512 ich_lr_el2.State = requested_ich_lr_el2.State;
1513 ich_lr_el2.HW = requested_ich_lr_el2.HW;
1514 ich_lr_el2.Group = requested_ich_lr_el2.Group;
1515
1516 // Priority, bits [55:48]
1517 // At least five bits must be implemented.
1518 // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
1519 // We implement 5 bits.
1520 ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
1521 (ich_lr_el2.Priority & 0x07);
1522
1523 // pINTID, bits [44:32]
1524 // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
1525 // - Bits[44:42] : RES0.
1526 // - Bit[41] : EOI.
1527 // - Bits[40:32] : RES0.
1528 // When ICH_LR<n>_EL2.HW is 1:
1529 // - This field is only required to implement enough bits to hold a
1530 // valid value for the implemented INTID size. Any unused higher
1531 // order bits are RES0.
1532 if (requested_ich_lr_el2.HW == 0) {
1533 ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
1534 } else {
1535 ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
1536 }
1537
1538 // vINTID, bits [31:0]
1539 // It is IMPLEMENTATION DEFINED how many bits are implemented,
1540 // though at least 16 bits must be implemented.
1541 // Unimplemented bits are RES0.
1542 ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
1543
1544 val = ich_lr_el2;
1545 do_virtual_update = true;
1546 break;
1547 }
1548
1549 // Virtual Machine Control Register
1550 case MISCREG_ICH_VMCR:
1551 case MISCREG_ICH_VMCR_EL2: {
1552 ICH_VMCR_EL2 requested_ich_vmcr_el2 = val;
1553 ICH_VMCR_EL2 ich_vmcr_el2 =
1554 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1555 ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
1556 uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;
1557
1558 if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
1559 ich_vmcr_el2.VBPR0 = min_vpr0;
1560 } else {
1561 ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
1562 }
1563
1564 uint8_t min_vpr1 = min_vpr0 + 1;
1565
1566 if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
1567 ich_vmcr_el2.VBPR1 = min_vpr1;
1568 } else {
1569 ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
1570 }
1571
1572 ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
1573 ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
1574 ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
1575 ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
1576 val = ich_vmcr_el2;
1577 break;
1578 }
1579
1580 // Hyp Active Priorities Group 0 Registers
1581 case MISCREG_ICH_AP0R0:
1582 case MISCREG_ICH_AP0R0_EL2:
1583 break;
1584
1585 // only implemented if supporting 6 or more bits of priority
1586 case MISCREG_ICH_AP0R1:
1587 case MISCREG_ICH_AP0R1_EL2:
1588 // only implemented if supporting 7 or more bits of priority
1589 case MISCREG_ICH_AP0R2:
1590 case MISCREG_ICH_AP0R2_EL2:
1591 // only implemented if supporting 7 or more bits of priority
1592 case MISCREG_ICH_AP0R3:
1593 case MISCREG_ICH_AP0R3_EL2:
1594 // Unimplemented registers are RAZ/WI
1595 return;
1596
1597 // Hyp Active Priorities Group 1 Registers
1598 case MISCREG_ICH_AP1R0:
1599 case MISCREG_ICH_AP1R0_EL2:
1600 break;
1601
1602 // only implemented if supporting 6 or more bits of priority
1603 case MISCREG_ICH_AP1R1:
1604 case MISCREG_ICH_AP1R1_EL2:
1605 // only implemented if supporting 7 or more bits of priority
1606 case MISCREG_ICH_AP1R2:
1607 case MISCREG_ICH_AP1R2_EL2:
1608 // only implemented if supporting 7 or more bits of priority
1609 case MISCREG_ICH_AP1R3:
1610 case MISCREG_ICH_AP1R3_EL2:
1611 // Unimplemented registers are RAZ/WI
1612 return;
1613
1614 default:
1615 panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
1616 misc_reg, miscRegName[misc_reg]);
1617 }
1618
1619 isa->setMiscRegNoEffect(misc_reg, val);
1620
1621 if (do_virtual_update) {
1622 virtualUpdate();
1623 }
1624}
1625
1626int
1627Gicv3CPUInterface::virtualFindActive(uint32_t int_id) const
1628{
1629 for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
1630 ICH_LR_EL2 ich_lr_el2 =
1631 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
1632
1633 if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) ||
1634 (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) &&
1635 (ich_lr_el2.vINTID == int_id)) {
1636 return lr_idx;
1637 }
1638 }
1639
1640 return -1;
1641}
1642
1643uint32_t
1644Gicv3CPUInterface::getHPPIR0() const
1645{
1646 if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
1647 return Gicv3::INTID_SPURIOUS;
1648 }
1649
1650 bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS;
1651
1652 if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
1653 // interrupt for the other state pending
1654 return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE;
1655 }
1656
1657 if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon())
1658 return Gicv3::INTID_SPURIOUS;
1659 }
1660
1661 if (irq_is_secure && !inSecureState()) {
1662 // Secure interrupts not visible in Non-secure
1663 return Gicv3::INTID_SPURIOUS;
1664 }
1665
1666 return hppi.intid;
1667}
1668
1669uint32_t
1670Gicv3CPUInterface::getHPPIR1() const
1671{
1672 if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
1673 return Gicv3::INTID_SPURIOUS;
1674 }
1675
1676 ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1677 if ((currEL() == EL3) && icc_ctlr_el3.RM) {
1678 if (hppi.group == Gicv3::G0S) {
1679 return Gicv3::INTID_SECURE;
1680 } else if (hppi.group == Gicv3::G1NS) {
1681 return Gicv3::INTID_NONSECURE;
1682 }
1683 }
1684
1685 if (hppi.group == Gicv3::G0S) {
1686 return Gicv3::INTID_SPURIOUS;
1687 }
1688
1689 bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS);
1690
1691 if (irq_is_secure) {
1692 if (!inSecureState()) {
1693 // Secure interrupts not visible in Non-secure
1694 return Gicv3::INTID_SPURIOUS;
1695 }
1696 } else if (!isEL3OrMon() && inSecureState()) {
1697 // Group 1 non-secure interrupts not visible in Secure EL1
1698 return Gicv3::INTID_SPURIOUS;
1699 }
1700
1701 return hppi.intid;
1702}
1703
1704void
1705Gicv3CPUInterface::dropPriority(Gicv3::GroupId group)
1706{
1707 int apr_misc_reg;
1708 RegVal apr;
1709 apr_misc_reg = group == Gicv3::G0S ?
1710 MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
1711 apr = isa->readMiscRegNoEffect(apr_misc_reg);
1712
1713 if (apr) {
1714 apr &= apr - 1;
1715 isa->setMiscRegNoEffect(apr_misc_reg, apr);
1716 }
1717
1718 update();
1719}
1720
1721uint8_t
1722Gicv3CPUInterface::virtualDropPriority()
1723{
1724 int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);
1725
1726 for (int i = 0; i < apr_max; i++) {
1727 RegVal vapr0 = isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i);
1728 RegVal vapr1 = isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
1729
1730 if (!vapr0 && !vapr1) {
1731 continue;
1732 }
1733
1734 int vapr0_count = ctz32(vapr0);
1735 int vapr1_count = ctz32(vapr1);
1736
1737 if (vapr0_count <= vapr1_count) {
1738 vapr0 &= vapr0 - 1;
1739 isa->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i, vapr0);
1740 return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
1741 } else {
1742 vapr1 &= vapr1 - 1;
1743 isa->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i, vapr1);
1744 return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
1745 }
1746 }
1747
1748 return 0xff;
1749}
1750
1751void
1752Gicv3CPUInterface::generateSGI(RegVal val, Gicv3::GroupId group)
1753{
1754 uint8_t aff3 = bits(val, 55, 48);
1755 uint8_t aff2 = bits(val, 39, 32);
1756 uint8_t aff1 = bits(val, 23, 16);;
1757 uint16_t target_list = bits(val, 15, 0);
1758 uint32_t int_id = bits(val, 27, 24);
1759 bool irm = bits(val, 40, 40);
1760 uint8_t rs = bits(val, 47, 44);
1761
1762 bool ns = !inSecureState();
1763
1764 for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
1765 Gicv3Redistributor * redistributor_i =
1766 gic->getRedistributor(i);
1767 uint32_t affinity_i = redistributor_i->getAffinity();
1768
1769 if (irm) {
1770 // Interrupts routed to all PEs in the system,
1771 // excluding "self"
1772 if (affinity_i == redistributor->getAffinity()) {
1773 continue;
1774 }
1775 } else {
1776 // Interrupts routed to the PEs specified by
1777 // Aff3.Aff2.Aff1.<target list>
1778 if ((affinity_i >> 8) !=
1779 ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
1780 continue;
1781 }
1782
1783 uint8_t aff0_i = bits(affinity_i, 7, 0);
1784
1785 if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
1786 ((0x1 << (aff0_i - rs * 16)) & target_list))) {
1787 continue;
1788 }
1789 }
1790
1791 redistributor_i->sendSGI(int_id, group, ns);
1792 }
1793}
1794
1795void
1796Gicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
1797{
1798 // Update active priority registers.
1799 uint32_t prio = hppi.prio & 0xf8;
1800 int apr_bit = prio >> (8 - PRIORITY_BITS);
1801 int reg_bit = apr_bit % 32;
1802 int apr_idx = group == Gicv3::G0S ?
1803 MISCREG_ICC_AP0R0_EL1 : MISCREG_ICC_AP1R0_EL1;
1804 RegVal apr = isa->readMiscRegNoEffect(apr_idx);
1805 apr |= (1 << reg_bit);
1806 isa->setMiscRegNoEffect(apr_idx, apr);
1807
1808 // Move interrupt state from pending to active.
1809 if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
1810 // SGI or PPI, redistributor
1811 redistributor->activateIRQ(int_id);
1812 } else if (int_id < Gicv3::INTID_SECURE) {
1813 // SPI, distributor
1814 distributor->activateIRQ(int_id);
1815 } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
1816 // LPI, Redistributor
1817 redistributor->setClrLPI(int_id, false);
1818 }
1819
1820 // By setting the priority to 0xff we are effectively
1821 // making the int_id not pending anymore at the cpu
1822 // interface.
1823 hppi.prio = 0xff;
1824 updateDistributor();
1825}
1826
1827void
1828Gicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx)
1829{
1830 // Update active priority registers.
1831 ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
1832 lr_idx);
1833 Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S;
1834 uint8_t prio = ich_lr_el.Priority & 0xf8;
1835 int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS);
1836 int reg_no = apr_bit / 32;
1837 int reg_bit = apr_bit % 32;
1838 int apr_idx = group == Gicv3::G0S ?
1839 MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no;
1840 RegVal apr = isa->readMiscRegNoEffect(apr_idx);
1841 apr |= (1 << reg_bit);
1842 isa->setMiscRegNoEffect(apr_idx, apr);
1843 // Move interrupt state from pending to active.
1844 ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE;
1845 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el);
1846}
1847
1848void
1849Gicv3CPUInterface::deactivateIRQ(uint32_t int_id, Gicv3::GroupId group)
1850{
1851 if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
1852 // SGI or PPI, redistributor
1853 redistributor->deactivateIRQ(int_id);
1854 } else if (int_id < Gicv3::INTID_SECURE) {
1855 // SPI, distributor
1856 distributor->deactivateIRQ(int_id);
1857 }
1858
1859 updateDistributor();
1860}
1861
1862void
1863Gicv3CPUInterface::virtualDeactivateIRQ(int lr_idx)
1864{
1865 ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
1866 lr_idx);
1867
1868 if (ich_lr_el2.HW) {
1869 // Deactivate the associated physical interrupt
1870 if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) {
1871 Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ?
1872 distributor->getIntGroup(ich_lr_el2.pINTID) :
1873 redistributor->getIntGroup(ich_lr_el2.pINTID);
1874 deactivateIRQ(ich_lr_el2.pINTID, group);
1875 }
1876 }
1877
1878 // Remove the active bit
1879 ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE;
1880 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2);
1881}
1882
1883/*
1884 * Returns the priority group field for the current BPR value for the group.
1885 * GroupBits() Pseudocode from spec.
1886 */
1887uint32_t
1888Gicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
1889{
1890 ICC_CTLR_EL1 icc_ctlr_el1_s =
1891 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
1892 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1893 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1894
1895 if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
1896 (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) {
1897 group = Gicv3::G0S;
1898 }
1899
1900 int bpr;
1901
1902 if (group == Gicv3::G0S) {
1903 bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7;
1904 } else if (group == Gicv3::G1S) {
1905 bpr = bpr1(Gicv3::G1S) & 0x7;
1964 } else {
1906 } else {
1965 bpr = readMiscReg(MISCREG_ICC_BPR1_EL1) & 0x7;
1907 bpr = bpr1(Gicv3::G1NS) & 0x7;
1966 }
1967
1968 if (group == Gicv3::G1NS) {
1969 assert(bpr > 0);
1970 bpr--;
1971 }
1972
1973 return ~0U << (bpr + 1);
1974}
1975
1976uint32_t
1977Gicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const
1978{
1979 ICH_VMCR_EL2 ich_vmcr_el2 =
1980 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1981
1982 if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1983 group = Gicv3::G0S;
1984 }
1985
1986 int bpr;
1987
1988 if (group == Gicv3::G0S) {
1989 bpr = ich_vmcr_el2.VBPR0;
1990 } else {
1991 bpr = ich_vmcr_el2.VBPR1;
1992 }
1993
1994 if (group == Gicv3::G1NS) {
1995 assert(bpr > 0);
1996 bpr--;
1997 }
1998
1999 return ~0U << (bpr + 1);
2000}
2001
2002bool
2003Gicv3CPUInterface::isEOISplitMode() const
2004{
2005 if (isEL3OrMon()) {
2006 ICC_CTLR_EL3 icc_ctlr_el3 =
2007 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
2008 return icc_ctlr_el3.EOImode_EL3;
2009 } else {
2010 ICC_CTLR_EL1 icc_ctlr_el1 =
2011 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
2012 return icc_ctlr_el1.EOImode;
2013 }
2014}
2015
2016bool
2017Gicv3CPUInterface::virtualIsEOISplitMode() const
2018{
2019 ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
2020 return ich_vmcr_el2.VEOIM;
2021}
2022
2023int
2024Gicv3CPUInterface::highestActiveGroup() const
2025{
2026 int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1));
2027 int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S));
2028 int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS));
2029
2030 if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
2031 return Gicv3::G1NS;
2032 }
2033
2034 if (gq_ctz < g0_ctz) {
2035 return Gicv3::G1S;
2036 }
2037
2038 if (g0_ctz < 32) {
2039 return Gicv3::G0S;
2040 }
2041
2042 return -1;
2043}
2044
2045void
2046Gicv3CPUInterface::updateDistributor()
2047{
2048 distributor->update();
2049}
2050
2051void
2052Gicv3CPUInterface::update()
2053{
2054 bool signal_IRQ = false;
2055 bool signal_FIQ = false;
2056
2057 if (hppi.group == Gicv3::G1S && !haveEL(EL3)) {
2058 /*
2059 * Secure enabled GIC sending a G1S IRQ to a secure disabled
2060 * CPU -> send G0 IRQ
2061 */
2062 hppi.group = Gicv3::G0S;
2063 }
2064
2065 if (hppiCanPreempt()) {
2066 ArmISA::InterruptTypes int_type = intSignalType(hppi.group);
2067 DPRINTF(GIC, "Gicv3CPUInterface::update(): "
2068 "posting int as %d!\n", int_type);
2069 int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
2070 }
2071
2072 if (signal_IRQ) {
2073 gic->postInt(cpuId, ArmISA::INT_IRQ);
2074 } else {
2075 gic->deassertInt(cpuId, ArmISA::INT_IRQ);
2076 }
2077
2078 if (signal_FIQ) {
2079 gic->postInt(cpuId, ArmISA::INT_FIQ);
2080 } else {
2081 gic->deassertInt(cpuId, ArmISA::INT_FIQ);
2082 }
2083}
2084
2085void
2086Gicv3CPUInterface::virtualUpdate()
2087{
2088 bool signal_IRQ = false;
2089 bool signal_FIQ = false;
2090 int lr_idx = getHPPVILR();
2091
2092 if (lr_idx >= 0) {
2093 ICH_LR_EL2 ich_lr_el2 =
2094 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2095
2096 if (hppviCanPreempt(lr_idx)) {
2097 if (ich_lr_el2.Group) {
2098 signal_IRQ = true;
2099 } else {
2100 signal_FIQ = true;
2101 }
2102 }
2103 }
2104
2105 ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2106
2107 if (ich_hcr_el2.En) {
2108 if (maintenanceInterruptStatus()) {
2109 maintenanceInterrupt->raise();
2110 }
2111 }
2112
2113 if (signal_IRQ) {
2114 DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
2115 "posting int as %d!\n", ArmISA::INT_VIRT_IRQ);
2116 gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ);
2117 } else {
2118 gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ);
2119 }
2120
2121 if (signal_FIQ) {
2122 DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
2123 "posting int as %d!\n", ArmISA::INT_VIRT_FIQ);
2124 gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ);
2125 } else {
2126 gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ);
2127 }
2128}
2129
2130// Returns the index of the LR with the HPPI
2131int
2132Gicv3CPUInterface::getHPPVILR() const
2133{
2134 int idx = -1;
2135 ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
2136
2137 if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
2138 // VG0 and VG1 disabled...
2139 return idx;
2140 }
2141
2142 uint8_t highest_prio = 0xff;
2143
2144 for (int i = 0; i < 16; i++) {
2145 ICH_LR_EL2 ich_lr_el2 =
2146 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i);
2147
2148 if (ich_lr_el2.State != Gicv3::INT_PENDING) {
2149 continue;
2150 }
2151
2152 if (ich_lr_el2.Group) {
2153 // VG1
2154 if (!ich_vmcr_el2.VENG1) {
2155 continue;
2156 }
2157 } else {
2158 // VG0
2159 if (!ich_vmcr_el2.VENG0) {
2160 continue;
2161 }
2162 }
2163
2164 uint8_t prio = ich_lr_el2.Priority;
2165
2166 if (prio < highest_prio) {
2167 highest_prio = prio;
2168 idx = i;
2169 }
2170 }
2171
2172 return idx;
2173}
2174
2175bool
2176Gicv3CPUInterface::hppviCanPreempt(int lr_idx) const
2177{
2178 ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2179 if (!ich_hcr_el2.En) {
2180 // virtual interface is disabled
2181 return false;
2182 }
2183
2184 ICH_LR_EL2 ich_lr_el2 =
2185 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2186 uint8_t prio = ich_lr_el2.Priority;
2187 uint8_t vpmr =
2188 bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24);
2189
2190 if (prio >= vpmr) {
2191 // prioriry masked
2192 return false;
2193 }
2194
2195 uint8_t rprio = virtualHighestActivePriority();
2196
2197 if (rprio == 0xff) {
2198 return true;
2199 }
2200
2201 Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
2202 uint32_t prio_mask = virtualGroupPriorityMask(group);
2203
2204 if ((prio & prio_mask) < (rprio & prio_mask)) {
2205 return true;
2206 }
2207
2208 return false;
2209}
2210
2211uint8_t
2212Gicv3CPUInterface::virtualHighestActivePriority() const
2213{
2214 uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);
2215
2216 for (int i = 0; i < num_aprs; i++) {
2217 RegVal vapr =
2218 isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) |
2219 isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
2220
2221 if (!vapr) {
2222 continue;
2223 }
2224
2225 return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1);
2226 }
2227
2228 // no active interrups, return idle priority
2229 return 0xff;
2230}
2231
2232void
2233Gicv3CPUInterface::virtualIncrementEOICount()
2234{
2235 // Increment the EOICOUNT field in ICH_HCR_EL2
2236 RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2237 uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27);
2238 EOI_cout++;
2239 ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout);
2240 isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2);
2241}
2242
2243// spec section 4.6.2
2244ArmISA::InterruptTypes
2245Gicv3CPUInterface::intSignalType(Gicv3::GroupId group) const
2246{
2247 bool is_fiq = false;
2248
2249 switch (group) {
2250 case Gicv3::G0S:
2251 is_fiq = true;
2252 break;
2253
2254 case Gicv3::G1S:
2255 is_fiq = (distributor->DS == 0) &&
2256 (!inSecureState() || ((currEL() == EL3) && isAA64()));
2257 break;
2258
2259 case Gicv3::G1NS:
2260 is_fiq = (distributor->DS == 0) && inSecureState();
2261 break;
2262
2263 default:
2264 panic("Gicv3CPUInterface::intSignalType(): invalid group!");
2265 }
2266
2267 if (is_fiq) {
2268 return ArmISA::INT_FIQ;
2269 } else {
2270 return ArmISA::INT_IRQ;
2271 }
2272}
2273
2274bool
2275Gicv3CPUInterface::hppiCanPreempt()
2276{
2277 if (hppi.prio == 0xff) {
2278 // there is no pending interrupt
2279 return false;
2280 }
2281
2282 if (!groupEnabled(hppi.group)) {
2283 // group disabled at CPU interface
2284 return false;
2285 }
2286
2287 if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) {
2288 // priority masked
2289 return false;
2290 }
2291
2292 uint8_t rprio = highestActivePriority();
2293
2294 if (rprio == 0xff) {
2295 return true;
2296 }
2297
2298 uint32_t prio_mask = groupPriorityMask(hppi.group);
2299
2300 if ((hppi.prio & prio_mask) < (rprio & prio_mask)) {
2301 return true;
2302 }
2303
2304 return false;
2305}
2306
2307uint8_t
2308Gicv3CPUInterface::highestActivePriority() const
2309{
2310 uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) |
2311 isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) |
2312 isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S);
2313
2314 if (apr) {
2315 return ctz32(apr) << (GIC_MIN_BPR + 1);
2316 }
2317
2318 // no active interrups, return idle priority
2319 return 0xff;
2320}
2321
2322bool
2323Gicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const
2324{
2325 switch (group) {
2326 case Gicv3::G0S: {
2327 ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
2328 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1);
2329 return icc_igrpen0_el1.Enable && distributor->EnableGrp0;
2330 }
2331
2332 case Gicv3::G1S: {
2333 ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
2334 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S);
2335 return icc_igrpen1_el1_s.Enable && distributor->EnableGrp1S;
2336 }
2337
2338 case Gicv3::G1NS: {
2339 ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
2340 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS);
2341 return icc_igrpen1_el1_ns.Enable && distributor->EnableGrp1NS;
2342 }
2343
2344 default:
2345 panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
2346 }
2347}
2348
2349bool
2350Gicv3CPUInterface::inSecureState() const
2351{
2352 if (!gic->getSystem()->haveSecurity()) {
2353 return false;
2354 }
2355
2356 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2357 SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR);
2358 return ArmISA::inSecureState(scr, cpsr);
2359}
2360
2361int
2362Gicv3CPUInterface::currEL() const
2363{
2364 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2365 bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2366
2367 if (is_64) {
2368 return (ExceptionLevel)(uint8_t) cpsr.el;
2369 } else {
2370 switch (cpsr.mode) {
2371 case MODE_USER:
2372 return 0;
2373
2374 case MODE_HYP:
2375 return 2;
2376
2377 case MODE_MON:
2378 return 3;
2379
2380 default:
2381 return 1;
2382 }
2383 }
2384}
2385
2386bool
2387Gicv3CPUInterface::haveEL(ExceptionLevel el) const
2388{
2389 switch (el) {
2390 case EL0:
2391 case EL1:
2392 return true;
2393
2394 case EL2:
2395 return gic->getSystem()->haveVirtualization();
2396
2397 case EL3:
2398 return gic->getSystem()->haveSecurity();
2399
2400 default:
2401 warn("Unimplemented Exception Level\n");
2402 return false;
2403 }
2404}
2405
2406bool
2407Gicv3CPUInterface::isSecureBelowEL3() const
2408{
2409 SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
2410 return haveEL(EL3) && scr.ns == 0;
2411}
2412
2413bool
2414Gicv3CPUInterface::isAA64() const
2415{
2416 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2417 return opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2418}
2419
2420bool
2421Gicv3CPUInterface::isEL3OrMon() const
2422{
2423 if (haveEL(EL3)) {
2424 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2425 bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2426
2427 if (is_64 && (cpsr.el == EL3)) {
2428 return true;
2429 } else if (!is_64 && (cpsr.mode == MODE_MON)) {
2430 return true;
2431 }
2432 }
2433
2434 return false;
2435}
2436
2437// Computes ICH_EISR_EL2
2438uint64_t
2439Gicv3CPUInterface::eoiMaintenanceInterruptStatus() const
2440{
2441 // ICH_EISR_EL2
2442 // Bits [63:16] - RES0
2443 // Status<n>, bit [n], for n = 0 to 15
2444 // EOI maintenance interrupt status bit for List register <n>:
2445 // 0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
2446 // maintenance interrupt.
2447 // 1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
2448 // interrupt that has not been handled.
2449 //
2450 // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
2451 // of the following are true:
2452 // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
2453 // - ICH_LR<n>_EL2.HW is 0.
2454 // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.
2455
2456 uint64_t value = 0;
2457
2458 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
2459 ICH_LR_EL2 ich_lr_el2 =
2460 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2461
2462 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
2463 !ich_lr_el2.HW && ich_lr_el2.EOI) {
2464 value |= (1 << lr_idx);
2465 }
2466 }
2467
2468 return value;
2469}
2470
2471Gicv3CPUInterface::ICH_MISR_EL2
2472Gicv3CPUInterface::maintenanceInterruptStatus() const
2473{
2474 // Comments are copied from SPEC section 9.4.7 (ID012119)
2475 ICH_MISR_EL2 ich_misr_el2 = 0;
2476 ICH_HCR_EL2 ich_hcr_el2 =
2477 isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2478 ICH_VMCR_EL2 ich_vmcr_el2 =
2479 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
2480
2481 // End Of Interrupt. [bit 0]
2482 // This maintenance interrupt is asserted when at least one bit in
2483 // ICH_EISR_EL2 is 1.
2484
2485 if (eoiMaintenanceInterruptStatus()) {
2486 ich_misr_el2.EOI = 1;
2487 }
2488
2489 // Underflow. [bit 1]
2490 // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
2491 // zero or one of the List register entries are marked as a valid
2492 // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
2493 // do not equal 0x0.
2494 uint32_t num_valid_interrupts = 0;
2495 uint32_t num_pending_interrupts = 0;
2496
2497 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
2498 ICH_LR_EL2 ich_lr_el2 =
2499 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2500
2501 if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
2502 num_valid_interrupts++;
2503 }
2504
2505 if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) {
2506 num_pending_interrupts++;
2507 }
2508 }
2509
2510 if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
2511 ich_misr_el2.U = 1;
2512 }
2513
2514 // List Register Entry Not Present. [bit 2]
2515 // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
2516 // and ICH_HCR_EL2.EOIcount is non-zero.
2517 if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
2518 ich_misr_el2.LRENP = 1;
2519 }
2520
2521 // No Pending. [bit 3]
2522 // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
2523 // no List register is in pending state.
2524 if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
2525 ich_misr_el2.NP = 1;
2526 }
2527
2528 // vPE Group 0 Enabled. [bit 4]
2529 // This maintenance interrupt is asserted when
2530 // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
2531 if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
2532 ich_misr_el2.VGrp0E = 1;
2533 }
2534
2535 // vPE Group 0 Disabled. [bit 5]
2536 // This maintenance interrupt is asserted when
2537 // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
2538 if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
2539 ich_misr_el2.VGrp0D = 1;
2540 }
2541
2542 // vPE Group 1 Enabled. [bit 6]
2543 // This maintenance interrupt is asserted when
2544 // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
2545 if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
2546 ich_misr_el2.VGrp1E = 1;
2547 }
2548
2549 // vPE Group 1 Disabled. [bit 7]
2550 // This maintenance interrupt is asserted when
2551 // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
2552 if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
2553 ich_misr_el2.VGrp1D = 1;
2554 }
2555
2556 return ich_misr_el2;
2557}
2558
1908 }
1909
1910 if (group == Gicv3::G1NS) {
1911 assert(bpr > 0);
1912 bpr--;
1913 }
1914
1915 return ~0U << (bpr + 1);
1916}
1917
1918uint32_t
1919Gicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const
1920{
1921 ICH_VMCR_EL2 ich_vmcr_el2 =
1922 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1923
1924 if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1925 group = Gicv3::G0S;
1926 }
1927
1928 int bpr;
1929
1930 if (group == Gicv3::G0S) {
1931 bpr = ich_vmcr_el2.VBPR0;
1932 } else {
1933 bpr = ich_vmcr_el2.VBPR1;
1934 }
1935
1936 if (group == Gicv3::G1NS) {
1937 assert(bpr > 0);
1938 bpr--;
1939 }
1940
1941 return ~0U << (bpr + 1);
1942}
1943
1944bool
1945Gicv3CPUInterface::isEOISplitMode() const
1946{
1947 if (isEL3OrMon()) {
1948 ICC_CTLR_EL3 icc_ctlr_el3 =
1949 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1950 return icc_ctlr_el3.EOImode_EL3;
1951 } else {
1952 ICC_CTLR_EL1 icc_ctlr_el1 =
1953 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
1954 return icc_ctlr_el1.EOImode;
1955 }
1956}
1957
1958bool
1959Gicv3CPUInterface::virtualIsEOISplitMode() const
1960{
1961 ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1962 return ich_vmcr_el2.VEOIM;
1963}
1964
1965int
1966Gicv3CPUInterface::highestActiveGroup() const
1967{
1968 int g0_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1));
1969 int gq_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S));
1970 int g1nz_ctz = ctz32(isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS));
1971
1972 if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
1973 return Gicv3::G1NS;
1974 }
1975
1976 if (gq_ctz < g0_ctz) {
1977 return Gicv3::G1S;
1978 }
1979
1980 if (g0_ctz < 32) {
1981 return Gicv3::G0S;
1982 }
1983
1984 return -1;
1985}
1986
1987void
1988Gicv3CPUInterface::updateDistributor()
1989{
1990 distributor->update();
1991}
1992
1993void
1994Gicv3CPUInterface::update()
1995{
1996 bool signal_IRQ = false;
1997 bool signal_FIQ = false;
1998
1999 if (hppi.group == Gicv3::G1S && !haveEL(EL3)) {
2000 /*
2001 * Secure enabled GIC sending a G1S IRQ to a secure disabled
2002 * CPU -> send G0 IRQ
2003 */
2004 hppi.group = Gicv3::G0S;
2005 }
2006
2007 if (hppiCanPreempt()) {
2008 ArmISA::InterruptTypes int_type = intSignalType(hppi.group);
2009 DPRINTF(GIC, "Gicv3CPUInterface::update(): "
2010 "posting int as %d!\n", int_type);
2011 int_type == ArmISA::INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
2012 }
2013
2014 if (signal_IRQ) {
2015 gic->postInt(cpuId, ArmISA::INT_IRQ);
2016 } else {
2017 gic->deassertInt(cpuId, ArmISA::INT_IRQ);
2018 }
2019
2020 if (signal_FIQ) {
2021 gic->postInt(cpuId, ArmISA::INT_FIQ);
2022 } else {
2023 gic->deassertInt(cpuId, ArmISA::INT_FIQ);
2024 }
2025}
2026
2027void
2028Gicv3CPUInterface::virtualUpdate()
2029{
2030 bool signal_IRQ = false;
2031 bool signal_FIQ = false;
2032 int lr_idx = getHPPVILR();
2033
2034 if (lr_idx >= 0) {
2035 ICH_LR_EL2 ich_lr_el2 =
2036 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2037
2038 if (hppviCanPreempt(lr_idx)) {
2039 if (ich_lr_el2.Group) {
2040 signal_IRQ = true;
2041 } else {
2042 signal_FIQ = true;
2043 }
2044 }
2045 }
2046
2047 ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2048
2049 if (ich_hcr_el2.En) {
2050 if (maintenanceInterruptStatus()) {
2051 maintenanceInterrupt->raise();
2052 }
2053 }
2054
2055 if (signal_IRQ) {
2056 DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
2057 "posting int as %d!\n", ArmISA::INT_VIRT_IRQ);
2058 gic->postInt(cpuId, ArmISA::INT_VIRT_IRQ);
2059 } else {
2060 gic->deassertInt(cpuId, ArmISA::INT_VIRT_IRQ);
2061 }
2062
2063 if (signal_FIQ) {
2064 DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
2065 "posting int as %d!\n", ArmISA::INT_VIRT_FIQ);
2066 gic->postInt(cpuId, ArmISA::INT_VIRT_FIQ);
2067 } else {
2068 gic->deassertInt(cpuId, ArmISA::INT_VIRT_FIQ);
2069 }
2070}
2071
2072// Returns the index of the LR with the HPPI
2073int
2074Gicv3CPUInterface::getHPPVILR() const
2075{
2076 int idx = -1;
2077 ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
2078
2079 if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
2080 // VG0 and VG1 disabled...
2081 return idx;
2082 }
2083
2084 uint8_t highest_prio = 0xff;
2085
2086 for (int i = 0; i < 16; i++) {
2087 ICH_LR_EL2 ich_lr_el2 =
2088 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + i);
2089
2090 if (ich_lr_el2.State != Gicv3::INT_PENDING) {
2091 continue;
2092 }
2093
2094 if (ich_lr_el2.Group) {
2095 // VG1
2096 if (!ich_vmcr_el2.VENG1) {
2097 continue;
2098 }
2099 } else {
2100 // VG0
2101 if (!ich_vmcr_el2.VENG0) {
2102 continue;
2103 }
2104 }
2105
2106 uint8_t prio = ich_lr_el2.Priority;
2107
2108 if (prio < highest_prio) {
2109 highest_prio = prio;
2110 idx = i;
2111 }
2112 }
2113
2114 return idx;
2115}
2116
2117bool
2118Gicv3CPUInterface::hppviCanPreempt(int lr_idx) const
2119{
2120 ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2121 if (!ich_hcr_el2.En) {
2122 // virtual interface is disabled
2123 return false;
2124 }
2125
2126 ICH_LR_EL2 ich_lr_el2 =
2127 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2128 uint8_t prio = ich_lr_el2.Priority;
2129 uint8_t vpmr =
2130 bits(isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2), 31, 24);
2131
2132 if (prio >= vpmr) {
2133 // prioriry masked
2134 return false;
2135 }
2136
2137 uint8_t rprio = virtualHighestActivePriority();
2138
2139 if (rprio == 0xff) {
2140 return true;
2141 }
2142
2143 Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
2144 uint32_t prio_mask = virtualGroupPriorityMask(group);
2145
2146 if ((prio & prio_mask) < (rprio & prio_mask)) {
2147 return true;
2148 }
2149
2150 return false;
2151}
2152
2153uint8_t
2154Gicv3CPUInterface::virtualHighestActivePriority() const
2155{
2156 uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);
2157
2158 for (int i = 0; i < num_aprs; i++) {
2159 RegVal vapr =
2160 isa->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2 + i) |
2161 isa->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2 + i);
2162
2163 if (!vapr) {
2164 continue;
2165 }
2166
2167 return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1);
2168 }
2169
2170 // no active interrups, return idle priority
2171 return 0xff;
2172}
2173
2174void
2175Gicv3CPUInterface::virtualIncrementEOICount()
2176{
2177 // Increment the EOICOUNT field in ICH_HCR_EL2
2178 RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2179 uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27);
2180 EOI_cout++;
2181 ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout);
2182 isa->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2, ich_hcr_el2);
2183}
2184
2185// spec section 4.6.2
2186ArmISA::InterruptTypes
2187Gicv3CPUInterface::intSignalType(Gicv3::GroupId group) const
2188{
2189 bool is_fiq = false;
2190
2191 switch (group) {
2192 case Gicv3::G0S:
2193 is_fiq = true;
2194 break;
2195
2196 case Gicv3::G1S:
2197 is_fiq = (distributor->DS == 0) &&
2198 (!inSecureState() || ((currEL() == EL3) && isAA64()));
2199 break;
2200
2201 case Gicv3::G1NS:
2202 is_fiq = (distributor->DS == 0) && inSecureState();
2203 break;
2204
2205 default:
2206 panic("Gicv3CPUInterface::intSignalType(): invalid group!");
2207 }
2208
2209 if (is_fiq) {
2210 return ArmISA::INT_FIQ;
2211 } else {
2212 return ArmISA::INT_IRQ;
2213 }
2214}
2215
2216bool
2217Gicv3CPUInterface::hppiCanPreempt()
2218{
2219 if (hppi.prio == 0xff) {
2220 // there is no pending interrupt
2221 return false;
2222 }
2223
2224 if (!groupEnabled(hppi.group)) {
2225 // group disabled at CPU interface
2226 return false;
2227 }
2228
2229 if (hppi.prio >= isa->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1)) {
2230 // priority masked
2231 return false;
2232 }
2233
2234 uint8_t rprio = highestActivePriority();
2235
2236 if (rprio == 0xff) {
2237 return true;
2238 }
2239
2240 uint32_t prio_mask = groupPriorityMask(hppi.group);
2241
2242 if ((hppi.prio & prio_mask) < (rprio & prio_mask)) {
2243 return true;
2244 }
2245
2246 return false;
2247}
2248
2249uint8_t
2250Gicv3CPUInterface::highestActivePriority() const
2251{
2252 uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) |
2253 isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS) |
2254 isa->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S);
2255
2256 if (apr) {
2257 return ctz32(apr) << (GIC_MIN_BPR + 1);
2258 }
2259
2260 // no active interrups, return idle priority
2261 return 0xff;
2262}
2263
2264bool
2265Gicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const
2266{
2267 switch (group) {
2268 case Gicv3::G0S: {
2269 ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
2270 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1);
2271 return icc_igrpen0_el1.Enable && distributor->EnableGrp0;
2272 }
2273
2274 case Gicv3::G1S: {
2275 ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
2276 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S);
2277 return icc_igrpen1_el1_s.Enable && distributor->EnableGrp1S;
2278 }
2279
2280 case Gicv3::G1NS: {
2281 ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
2282 isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS);
2283 return icc_igrpen1_el1_ns.Enable && distributor->EnableGrp1NS;
2284 }
2285
2286 default:
2287 panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
2288 }
2289}
2290
2291bool
2292Gicv3CPUInterface::inSecureState() const
2293{
2294 if (!gic->getSystem()->haveSecurity()) {
2295 return false;
2296 }
2297
2298 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2299 SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR);
2300 return ArmISA::inSecureState(scr, cpsr);
2301}
2302
2303int
2304Gicv3CPUInterface::currEL() const
2305{
2306 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2307 bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2308
2309 if (is_64) {
2310 return (ExceptionLevel)(uint8_t) cpsr.el;
2311 } else {
2312 switch (cpsr.mode) {
2313 case MODE_USER:
2314 return 0;
2315
2316 case MODE_HYP:
2317 return 2;
2318
2319 case MODE_MON:
2320 return 3;
2321
2322 default:
2323 return 1;
2324 }
2325 }
2326}
2327
2328bool
2329Gicv3CPUInterface::haveEL(ExceptionLevel el) const
2330{
2331 switch (el) {
2332 case EL0:
2333 case EL1:
2334 return true;
2335
2336 case EL2:
2337 return gic->getSystem()->haveVirtualization();
2338
2339 case EL3:
2340 return gic->getSystem()->haveSecurity();
2341
2342 default:
2343 warn("Unimplemented Exception Level\n");
2344 return false;
2345 }
2346}
2347
2348bool
2349Gicv3CPUInterface::isSecureBelowEL3() const
2350{
2351 SCR scr = isa->readMiscRegNoEffect(MISCREG_SCR_EL3);
2352 return haveEL(EL3) && scr.ns == 0;
2353}
2354
2355bool
2356Gicv3CPUInterface::isAA64() const
2357{
2358 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2359 return opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2360}
2361
2362bool
2363Gicv3CPUInterface::isEL3OrMon() const
2364{
2365 if (haveEL(EL3)) {
2366 CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2367 bool is_64 = opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2368
2369 if (is_64 && (cpsr.el == EL3)) {
2370 return true;
2371 } else if (!is_64 && (cpsr.mode == MODE_MON)) {
2372 return true;
2373 }
2374 }
2375
2376 return false;
2377}
2378
2379// Computes ICH_EISR_EL2
2380uint64_t
2381Gicv3CPUInterface::eoiMaintenanceInterruptStatus() const
2382{
2383 // ICH_EISR_EL2
2384 // Bits [63:16] - RES0
2385 // Status<n>, bit [n], for n = 0 to 15
2386 // EOI maintenance interrupt status bit for List register <n>:
2387 // 0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
2388 // maintenance interrupt.
2389 // 1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
2390 // interrupt that has not been handled.
2391 //
2392 // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
2393 // of the following are true:
2394 // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
2395 // - ICH_LR<n>_EL2.HW is 0.
2396 // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.
2397
2398 uint64_t value = 0;
2399
2400 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
2401 ICH_LR_EL2 ich_lr_el2 =
2402 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2403
2404 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
2405 !ich_lr_el2.HW && ich_lr_el2.EOI) {
2406 value |= (1 << lr_idx);
2407 }
2408 }
2409
2410 return value;
2411}
2412
2413Gicv3CPUInterface::ICH_MISR_EL2
2414Gicv3CPUInterface::maintenanceInterruptStatus() const
2415{
2416 // Comments are copied from SPEC section 9.4.7 (ID012119)
2417 ICH_MISR_EL2 ich_misr_el2 = 0;
2418 ICH_HCR_EL2 ich_hcr_el2 =
2419 isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2420 ICH_VMCR_EL2 ich_vmcr_el2 =
2421 isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
2422
2423 // End Of Interrupt. [bit 0]
2424 // This maintenance interrupt is asserted when at least one bit in
2425 // ICH_EISR_EL2 is 1.
2426
2427 if (eoiMaintenanceInterruptStatus()) {
2428 ich_misr_el2.EOI = 1;
2429 }
2430
2431 // Underflow. [bit 1]
2432 // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
2433 // zero or one of the List register entries are marked as a valid
2434 // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
2435 // do not equal 0x0.
2436 uint32_t num_valid_interrupts = 0;
2437 uint32_t num_pending_interrupts = 0;
2438
2439 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
2440 ICH_LR_EL2 ich_lr_el2 =
2441 isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2442
2443 if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
2444 num_valid_interrupts++;
2445 }
2446
2447 if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) {
2448 num_pending_interrupts++;
2449 }
2450 }
2451
2452 if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
2453 ich_misr_el2.U = 1;
2454 }
2455
2456 // List Register Entry Not Present. [bit 2]
2457 // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
2458 // and ICH_HCR_EL2.EOIcount is non-zero.
2459 if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
2460 ich_misr_el2.LRENP = 1;
2461 }
2462
2463 // No Pending. [bit 3]
2464 // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
2465 // no List register is in pending state.
2466 if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
2467 ich_misr_el2.NP = 1;
2468 }
2469
2470 // vPE Group 0 Enabled. [bit 4]
2471 // This maintenance interrupt is asserted when
2472 // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
2473 if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
2474 ich_misr_el2.VGrp0E = 1;
2475 }
2476
2477 // vPE Group 0 Disabled. [bit 5]
2478 // This maintenance interrupt is asserted when
2479 // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
2480 if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
2481 ich_misr_el2.VGrp0D = 1;
2482 }
2483
2484 // vPE Group 1 Enabled. [bit 6]
2485 // This maintenance interrupt is asserted when
2486 // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
2487 if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
2488 ich_misr_el2.VGrp1E = 1;
2489 }
2490
2491 // vPE Group 1 Disabled. [bit 7]
2492 // This maintenance interrupt is asserted when
2493 // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
2494 if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
2495 ich_misr_el2.VGrp1D = 1;
2496 }
2497
2498 return ich_misr_el2;
2499}
2500
2501RegVal
2502Gicv3CPUInterface::bpr1(Gicv3::GroupId group)
2503{
2504 bool hcr_imo = getHCREL2IMO();
2505 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
2506 return readMiscReg(MISCREG_ICV_BPR1_EL1);
2507 }
2508
2509 RegVal bpr = 0;
2510
2511 if (group == Gicv3::G1S) {
2512 ICC_CTLR_EL1 icc_ctlr_el1_s =
2513 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
2514
2515 if (!isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
2516 bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1);
2517 } else {
2518 bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S);
2519 bpr = bpr > GIC_MIN_BPR ? bpr : GIC_MIN_BPR;
2520 }
2521 } else if (group == Gicv3::G1NS) {
2522 ICC_CTLR_EL1 icc_ctlr_el1_ns =
2523 isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
2524
2525 // Check if EL3 is implemented and this is a non secure accesses at
2526 // EL1 and EL2
2527 if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
2528 // Reads return BPR0 + 1 saturated to 7, WI
2529 bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1) + 1;
2530 bpr = bpr < 7 ? bpr : 7;
2531 } else {
2532 bpr = isa->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS);
2533 bpr = bpr > GIC_MIN_BPR_NS ? bpr : GIC_MIN_BPR_NS;
2534 }
2535 } else {
2536 panic("Should be used with G1S and G1NS only\n");
2537 }
2538
2539 return bpr;
2540}
2541
2559void
2560Gicv3CPUInterface::serialize(CheckpointOut & cp) const
2561{
2562 SERIALIZE_SCALAR(hppi.intid);
2563 SERIALIZE_SCALAR(hppi.prio);
2564 SERIALIZE_ENUM(hppi.group);
2565}
2566
2567void
2568Gicv3CPUInterface::unserialize(CheckpointIn & cp)
2569{
2570 UNSERIALIZE_SCALAR(hppi.intid);
2571 UNSERIALIZE_SCALAR(hppi.prio);
2572 UNSERIALIZE_ENUM(hppi.group);
2573}
2542void
2543Gicv3CPUInterface::serialize(CheckpointOut & cp) const
2544{
2545 SERIALIZE_SCALAR(hppi.intid);
2546 SERIALIZE_SCALAR(hppi.prio);
2547 SERIALIZE_ENUM(hppi.group);
2548}
2549
2550void
2551Gicv3CPUInterface::unserialize(CheckpointIn & cp)
2552{
2553 UNSERIALIZE_SCALAR(hppi.intid);
2554 UNSERIALIZE_SCALAR(hppi.prio);
2555 UNSERIALIZE_ENUM(hppi.group);
2556}