641c641
< updateAndInformCPUInterfaces();
---
> update();
665a666
> clearIrqCpuInterface(int_id);
669c670
< updateAndInformCPUInterfaces();
---
> update();
950c951
< updateAndInformCPUInterfaces();
---
> update();
959c960,962
< updateAndInformCPUInterfaces();
---
> clearIrqCpuInterface(int_id);
>
> update();
962,963c965,966
< void
< Gicv3Distributor::updateAndInformCPUInterfaces()
---
> Gicv3CPUInterface*
> Gicv3Distributor::route(uint32_t int_id)
965c968,969
< update();
---
> IROUTER affinity_routing = irqAffinityRouting[int_id];
> Gicv3Redistributor * target_redistributor = nullptr;
967,968c971,991
< for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
< gic->getCPUInterface(i)->update();
---
> const Gicv3::GroupId int_group = getIntGroup(int_id);
>
> if (affinity_routing.IRM) {
> // Interrupts routed to any PE defined as a participating node
> for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
> Gicv3Redistributor * redistributor_i =
> gic->getRedistributor(i);
>
> if (redistributor_i->
> canBeSelectedFor1toNInterrupt(int_group)) {
> target_redistributor = redistributor_i;
> break;
> }
> }
> } else {
> uint32_t affinity = (affinity_routing.Aff3 << 24) |
> (affinity_routing.Aff2 << 16) |
> (affinity_routing.Aff1 << 8) |
> (affinity_routing.Aff0 << 0);
> target_redistributor =
> gic->getRedistributorByAffinity(affinity);
969a993,999
>
> if (!target_redistributor) {
> // Interrrupts targeting not present cpus must remain pending
> return nullptr;
> } else {
> return target_redistributor->getCPUInterface();
> }
973c1003
< Gicv3Distributor::fullUpdate()
---
> Gicv3Distributor::clearIrqCpuInterface(uint32_t int_id)
975,985c1005,1007
< for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
< Gicv3CPUInterface * cpu_interface_i = gic->getCPUInterface(i);
< cpu_interface_i->hppi.prio = 0xff;
< }
<
< update();
<
< for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
< Gicv3Redistributor * redistributor_i = gic->getRedistributor(i);
< redistributor_i->update();
< }
---
> auto cpu_interface = route(int_id);
> if (cpu_interface)
> cpu_interface->hppi.prio = 0xff;
991,992d1012
< std::vector<bool> new_hppi(gic->getSystem()->numContexts(), false);
<
1001,1002d1020
< IROUTER affinity_routing = irqAffinityRouting[int_id];
< Gicv3Redistributor * target_redistributor = nullptr;
1004,1008c1022,1023
< if (affinity_routing.IRM) {
< // Interrupts routed to any PE defined as a participating node
< for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
< Gicv3Redistributor * redistributor_i =
< gic->getRedistributor(i);
---
> // Find the cpu interface where to route the interrupt
> Gicv3CPUInterface *target_cpu_interface = route(int_id);
1010,1023c1025,1026
< if (redistributor_i->
< canBeSelectedFor1toNInterrupt(int_group)) {
< target_redistributor = redistributor_i;
< break;
< }
< }
< } else {
< uint32_t affinity = (affinity_routing.Aff3 << 24) |
< (affinity_routing.Aff3 << 16) |
< (affinity_routing.Aff1 << 8) |
< (affinity_routing.Aff0 << 0);
< target_redistributor =
< gic->getRedistributorByAffinity(affinity);
< }
---
> // Invalid routing
> if (!target_cpu_interface) continue;
1025,1033d1027
< if (!target_redistributor) {
< // Interrrupts targeting not present cpus must remain pending
< return;
< }
<
< Gicv3CPUInterface * target_cpu_interface =
< target_redistributor->getCPUInterface();
< uint32_t target_cpu = target_redistributor->cpuId;
<
1035,1039d1028
< /*
< * Multiple pending ints with same priority.
< * Implementation choice which one to signal.
< * Our implementation selects the one with the lower id.
< */
1041a1031
>
1045d1034
< new_hppi[target_cpu] = true;
1049a1039
> // Update all redistributors
1051,1059c1041
< Gicv3Redistributor * redistributor_i = gic->getRedistributor(i);
< Gicv3CPUInterface * cpu_interface_i =
< redistributor_i->getCPUInterface();
<
< if (!new_hppi[i] && cpu_interface_i->hppi.prio != 0xff &&
< cpu_interface_i->hppi.intid >= (Gicv3::SGI_MAX + Gicv3::PPI_MAX) &&
< cpu_interface_i->hppi.intid < Gicv3::INTID_SECURE) {
< fullUpdate();
< }
---
> gic->getRedistributor(i)->update();