gic_v3_redistributor.cc (14227:af80b8fab43b) gic_v3_redistributor.cc (14231:222f6512335e)
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

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

531 if (pending) {
532 DPRINTF(GIC, "Gicv3Redistributor::write() "
533 "(GICR_ISPENDR0): int_id %d (PPI) "
534 "pending bit set\n", int_id);
535 irqPending[int_id] = true;
536 }
537 }
538
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

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

531 if (pending) {
532 DPRINTF(GIC, "Gicv3Redistributor::write() "
533 "(GICR_ISPENDR0): int_id %d (PPI) "
534 "pending bit set\n", int_id);
535 irqPending[int_id] = true;
536 }
537 }
538
539 updateAndInformCPUInterface();
539 updateDistributor();
540 break;
541
542 case GICR_ICPENDR0:// Interrupt Clear-Pending Register 0
543 for (int int_id = 0; int_id < 8 * size; int_id++) {
544 if (!distributor->DS && !is_secure_access) {
545 // RAZ/WI for non-secure accesses for secure interrupts
546 if (getIntGroup(int_id) != Gicv3::G1NS) {
547 continue;

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

728void
729Gicv3Redistributor::sendPPInt(uint32_t int_id)
730{
731 assert((int_id >= Gicv3::SGI_MAX) &&
732 (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX));
733 irqPending[int_id] = true;
734 DPRINTF(GIC, "Gicv3Redistributor::sendPPInt(): "
735 "int_id %d (PPI) pending bit set\n", int_id);
540 break;
541
542 case GICR_ICPENDR0:// Interrupt Clear-Pending Register 0
543 for (int int_id = 0; int_id < 8 * size; int_id++) {
544 if (!distributor->DS && !is_secure_access) {
545 // RAZ/WI for non-secure accesses for secure interrupts
546 if (getIntGroup(int_id) != Gicv3::G1NS) {
547 continue;

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

728void
729Gicv3Redistributor::sendPPInt(uint32_t int_id)
730{
731 assert((int_id >= Gicv3::SGI_MAX) &&
732 (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX));
733 irqPending[int_id] = true;
734 DPRINTF(GIC, "Gicv3Redistributor::sendPPInt(): "
735 "int_id %d (PPI) pending bit set\n", int_id);
736 updateAndInformCPUInterface();
736 updateDistributor();
737}
738
739void
740Gicv3Redistributor::sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns)
741{
742 assert(int_id < Gicv3::SGI_MAX);
743 Gicv3::GroupId int_group = getIntGroup(int_id);
744

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

765 distributor->DS);
766 }
767
768 if (!forward) return;
769
770 irqPending[int_id] = true;
771 DPRINTF(GIC, "Gicv3ReDistributor::sendSGI(): "
772 "int_id %d (SGI) pending bit set\n", int_id);
737}
738
739void
740Gicv3Redistributor::sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns)
741{
742 assert(int_id < Gicv3::SGI_MAX);
743 Gicv3::GroupId int_group = getIntGroup(int_id);
744

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

765 distributor->DS);
766 }
767
768 if (!forward) return;
769
770 irqPending[int_id] = true;
771 DPRINTF(GIC, "Gicv3ReDistributor::sendSGI(): "
772 "int_id %d (SGI) pending bit set\n", int_id);
773 updateAndInformCPUInterface();
773 updateDistributor();
774}
775
776Gicv3::IntStatus
777Gicv3Redistributor::intStatus(uint32_t int_id) const
778{
779 assert(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX);
780
781 if (irqPending[int_id]) {

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

786 return Gicv3::INT_PENDING;
787 } else if (irqActive[int_id]) {
788 return Gicv3::INT_ACTIVE;
789 } else {
790 return Gicv3::INT_INACTIVE;
791 }
792}
793
774}
775
776Gicv3::IntStatus
777Gicv3Redistributor::intStatus(uint32_t int_id) const
778{
779 assert(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX);
780
781 if (irqPending[int_id]) {

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

786 return Gicv3::INT_PENDING;
787 } else if (irqActive[int_id]) {
788 return Gicv3::INT_ACTIVE;
789 } else {
790 return Gicv3::INT_INACTIVE;
791 }
792}
793
794void
795Gicv3Redistributor::updateDistributor()
796{
797 distributor->update();
798}
799
794/*
795 * Recalculate the highest priority pending interrupt after a
796 * change to redistributor state.
797 */
798void
799Gicv3Redistributor::update()
800{
800/*
801 * Recalculate the highest priority pending interrupt after a
802 * change to redistributor state.
803 */
804void
805Gicv3Redistributor::update()
806{
801 bool new_hppi = false;
802
803 for (int int_id = 0; int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX; int_id++) {
804 Gicv3::GroupId int_group = getIntGroup(int_id);
805 bool group_enabled = distributor->groupEnabled(int_group);
806
807 if (irqPending[int_id] && irqEnabled[int_id] &&
808 !irqActive[int_id] && group_enabled) {
809 if ((irqPriority[int_id] < cpuInterface->hppi.prio) ||
810 /*
811 * Multiple pending ints with same priority.
812 * Implementation choice which one to signal.
813 * Our implementation selects the one with the lower id.
814 */
815 (irqPriority[int_id] == cpuInterface->hppi.prio &&
816 int_id < cpuInterface->hppi.intid)) {
817 cpuInterface->hppi.intid = int_id;
818 cpuInterface->hppi.prio = irqPriority[int_id];
819 cpuInterface->hppi.group = int_group;
807 for (int int_id = 0; int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX; int_id++) {
808 Gicv3::GroupId int_group = getIntGroup(int_id);
809 bool group_enabled = distributor->groupEnabled(int_group);
810
811 if (irqPending[int_id] && irqEnabled[int_id] &&
812 !irqActive[int_id] && group_enabled) {
813 if ((irqPriority[int_id] < cpuInterface->hppi.prio) ||
814 /*
815 * Multiple pending ints with same priority.
816 * Implementation choice which one to signal.
817 * Our implementation selects the one with the lower id.
818 */
819 (irqPriority[int_id] == cpuInterface->hppi.prio &&
820 int_id < cpuInterface->hppi.intid)) {
821 cpuInterface->hppi.intid = int_id;
822 cpuInterface->hppi.prio = irqPriority[int_id];
823 cpuInterface->hppi.group = int_group;
820 new_hppi = true;
821 }
822 }
823 }
824
825 // Check LPIs
826 if (EnableLPIs) {
827
828 const uint32_t largest_lpi_id = 1 << (lpiIDBits + 1);

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

861 uint8_t lpi_priority = config_entry.priority << 2;
862
863 if ((lpi_priority < cpuInterface->hppi.prio) ||
864 (lpi_priority == cpuInterface->hppi.prio &&
865 lpi_id < cpuInterface->hppi.intid)) {
866 cpuInterface->hppi.intid = lpi_id;
867 cpuInterface->hppi.prio = lpi_priority;
868 cpuInterface->hppi.group = lpi_group;
824 }
825 }
826 }
827
828 // Check LPIs
829 if (EnableLPIs) {
830
831 const uint32_t largest_lpi_id = 1 << (lpiIDBits + 1);

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

864 uint8_t lpi_priority = config_entry.priority << 2;
865
866 if ((lpi_priority < cpuInterface->hppi.prio) ||
867 (lpi_priority == cpuInterface->hppi.prio &&
868 lpi_id < cpuInterface->hppi.intid)) {
869 cpuInterface->hppi.intid = lpi_id;
870 cpuInterface->hppi.prio = lpi_priority;
871 cpuInterface->hppi.group = lpi_group;
869 new_hppi = true;
870 }
871 }
872 }
873 }
874
872 }
873 }
874 }
875 }
876
875 if (!new_hppi && cpuInterface->hppi.prio != 0xff &&
876 (cpuInterface->hppi.intid < Gicv3::SGI_MAX + Gicv3::PPI_MAX ||
877 cpuInterface->hppi.intid > SMALLEST_LPI_ID)) {
878 distributor->fullUpdate();
879 }
877 cpuInterface->update();
880}
881
882uint8_t
883Gicv3Redistributor::readEntryLPI(uint32_t lpi_id)
884{
885 Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8);
886
887 uint8_t lpi_pending_entry;

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

953 return;
954 }
955
956 lpi_pending_entry &= ~(1 << (lpi_pending_entry_bit_position));
957 }
958
959 writeEntryLPI(lpi_id, lpi_pending_entry);
960
878}
879
880uint8_t
881Gicv3Redistributor::readEntryLPI(uint32_t lpi_id)
882{
883 Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8);
884
885 uint8_t lpi_pending_entry;

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

951 return;
952 }
953
954 lpi_pending_entry &= ~(1 << (lpi_pending_entry_bit_position));
955 }
956
957 writeEntryLPI(lpi_id, lpi_pending_entry);
958
961 updateAndInformCPUInterface();
959 updateDistributor();
962}
963
960}
961
964void
965Gicv3Redistributor::updateAndInformCPUInterface()
966{
967 update();
968 cpuInterface->update();
969}
970
971Gicv3::GroupId
972Gicv3Redistributor::getIntGroup(int int_id) const
973{
974 assert(int_id < (Gicv3::SGI_MAX + Gicv3::PPI_MAX));
975
976 if (distributor->DS) {
977 if (irqGroup[int_id] == 0) {
978 return Gicv3::G0S;

--- 115 unchanged lines hidden ---
962Gicv3::GroupId
963Gicv3Redistributor::getIntGroup(int int_id) const
964{
965 assert(int_id < (Gicv3::SGI_MAX + Gicv3::PPI_MAX));
966
967 if (distributor->DS) {
968 if (irqGroup[int_id] == 0) {
969 return Gicv3::G0S;

--- 115 unchanged lines hidden ---