Deleted Added
sdiff udiff text old ( 14230:94c9f25c59ae ) new ( 14231:222f6512335e )
full compact
1/*
2 * Copyright (c) 2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 624 unchanged lines hidden (view full) ---

633
634 if (pending) {
635 DPRINTF(GIC, "Gicv3Distributor::write() (GICD_ISPENDR): "
636 "int_id %d (SPI) pending bit set\n", int_id);
637 irqPending[int_id] = true;
638 }
639 }
640
641 update();
642 return;
643 } else if (GICD_ICPENDR.contains(addr)) {
644 // Interrupt Clear-Pending Registers
645 int first_intid = (addr - GICD_ICPENDR.start()) * 8;
646
647 if (isNotSPI(first_intid)) {
648 return;
649 }

--- 8 unchanged lines hidden (view full) ---

658 continue;
659 }
660 }
661
662 bool clear = data & (1 << i) ? 1 : 0;
663
664 if (clear) {
665 irqPending[int_id] = false;
666 clearIrqCpuInterface(int_id);
667 }
668 }
669
670 update();
671 return;
672 } else if (GICD_ISACTIVER.contains(addr)) {
673 // Interrupt Set-Active Registers
674 int first_intid = (addr - GICD_ISACTIVER.start()) * 8;
675
676 if (isNotSPI(first_intid)) {
677 return;
678 }

--- 264 unchanged lines hidden (view full) ---

943void
944Gicv3Distributor::sendInt(uint32_t int_id)
945{
946 panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
947 panic_if(int_id > itLines, "Invalid SPI!");
948 irqPending[int_id] = true;
949 DPRINTF(GIC, "Gicv3Distributor::sendInt(): "
950 "int_id %d (SPI) pending bit set\n", int_id);
951 update();
952}
953
954void
955Gicv3Distributor::deassertSPI(uint32_t int_id)
956{
957 panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
958 panic_if(int_id > itLines, "Invalid SPI!");
959 irqPending[int_id] = false;
960 clearIrqCpuInterface(int_id);
961
962 update();
963}
964
965Gicv3CPUInterface*
966Gicv3Distributor::route(uint32_t int_id)
967{
968 IROUTER affinity_routing = irqAffinityRouting[int_id];
969 Gicv3Redistributor * target_redistributor = nullptr;
970
971 const Gicv3::GroupId int_group = getIntGroup(int_id);
972
973 if (affinity_routing.IRM) {
974 // Interrupts routed to any PE defined as a participating node
975 for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
976 Gicv3Redistributor * redistributor_i =
977 gic->getRedistributor(i);
978
979 if (redistributor_i->
980 canBeSelectedFor1toNInterrupt(int_group)) {
981 target_redistributor = redistributor_i;
982 break;
983 }
984 }
985 } else {
986 uint32_t affinity = (affinity_routing.Aff3 << 24) |
987 (affinity_routing.Aff2 << 16) |
988 (affinity_routing.Aff1 << 8) |
989 (affinity_routing.Aff0 << 0);
990 target_redistributor =
991 gic->getRedistributorByAffinity(affinity);
992 }
993
994 if (!target_redistributor) {
995 // Interrrupts targeting not present cpus must remain pending
996 return nullptr;
997 } else {
998 return target_redistributor->getCPUInterface();
999 }
1000}
1001
1002void
1003Gicv3Distributor::clearIrqCpuInterface(uint32_t int_id)
1004{
1005 auto cpu_interface = route(int_id);
1006 if (cpu_interface)
1007 cpu_interface->hppi.prio = 0xff;
1008}
1009
1010void
1011Gicv3Distributor::update()
1012{
1013 // Find the highest priority pending SPI
1014 for (int int_id = Gicv3::SGI_MAX + Gicv3::PPI_MAX; int_id < itLines;
1015 int_id++) {
1016 Gicv3::GroupId int_group = getIntGroup(int_id);
1017 bool group_enabled = groupEnabled(int_group);
1018
1019 if (irqPending[int_id] && irqEnabled[int_id] &&
1020 !irqActive[int_id] && group_enabled) {
1021
1022 // Find the cpu interface where to route the interrupt
1023 Gicv3CPUInterface *target_cpu_interface = route(int_id);
1024
1025 // Invalid routing
1026 if (!target_cpu_interface) continue;
1027
1028 if ((irqPriority[int_id] < target_cpu_interface->hppi.prio) ||
1029 (irqPriority[int_id] == target_cpu_interface->hppi.prio &&
1030 int_id < target_cpu_interface->hppi.intid)) {
1031
1032 target_cpu_interface->hppi.intid = int_id;
1033 target_cpu_interface->hppi.prio = irqPriority[int_id];
1034 target_cpu_interface->hppi.group = int_group;
1035 }
1036 }
1037 }
1038
1039 // Update all redistributors
1040 for (int i = 0; i < gic->getSystem()->numContexts(); i++) {
1041 gic->getRedistributor(i)->update();
1042 }
1043}
1044
1045Gicv3::IntStatus
1046Gicv3Distributor::intStatus(uint32_t int_id) const
1047{
1048 panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
1049 panic_if(int_id > itLines, "Invalid SPI!");

--- 91 unchanged lines hidden ---