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