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