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 --- |