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