Changeset 108428 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Mar 4, 2025 8:25:38 AM (2 months ago)
- svn:sync-xref-src-repo-rev:
- 167802
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/GICAll.cpp
r108427 r108428 1648 1648 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC)) 1649 1649 apicSignalNextPendingIntr(pVCpu); 1650 }1651 #endif1652 1653 1654 #if 01655 static uint16_t gicGetHighestPrioPendingIntrFrom(const void *pvIntrPending, uint32_t cIntrs, uint8_t *pabIntrPriority,1656 uint32_t cIntrPriority, uint8_t *pbPriority)1657 {1658 uint16_t uIntIdHighest = 0;1659 uint8_t bPriority = UINT8_MAX;1660 1661 /* Find the INTID and priority of the pending interrupt with the highest priority. */1662 int32_t idxIntr = ASMBitFirstSet(pvIntrPending, cIntrs);1663 AssertCompile(!(cIntrs % 32));1664 if (idxIntr >= 0)1665 {1666 do1667 {1668 uint16_t const uIntId = gicGetIntIdFromIndex((uint16_t)idxIntr);1669 AssertRelease(uIntId < cIntrPriority);1670 if (pabIntrPriority[uIntId] < bPriority)1671 {1672 bPriority = pabIntrPriority[uIntId];1673 uIntIdHighest = uIntId;1674 }1675 idxIntr = ASMBitNextSet(pvIntrPending, cIntrs, idxIntr);1676 } while (idxIntr != -1);1677 }1678 else1679 {1680 bPriority = UINT8_MAX;1681 uIntIdHighest = GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT;1682 }1683 1684 *pbPriority = bPriority;1685 return uIntIdHighest;1686 }1687 1688 1689 static uint16_t gicDistGetHighestPrioPendingIntr(PCGICDEV pGicDev, uint8_t *pbPriority)1690 {1691 uint16_t uIntIdHighest = 0;1692 uint8_t bPriority = UINT8_MAX;1693 uint32_t const cIntrs = sizeof(pGicDev->bmIntrPending) * 8;1694 void const *pvIntrPending = &pGicDev->bmIntrPending[0];1695 1696 /* Find the INTID and priority of the pending interrupt with the highest priority. */1697 int32_t idxIntr = ASMBitFirstSet(pvIntrPending, cIntrs);1698 AssertCompile(!(cIntrs % 32));1699 if (idxIntr >= 0)1700 {1701 Assert(!pGicDev->fAffRoutingEnabled || idxIntr >= GIC_INTID_RANGE_SPI_START);1702 do1703 {1704 uint16_t const uIntId = gicGetIntIdFromIndex((uint16_t)idxIntr);1705 Assert(uIntId < RT_ELEMENTS(pGicDev->abIntrPriority));1706 if (pGicDev->abIntrPriority[uIntId] < bPriority)1707 {1708 bPriority = pGicDev->abIntrPriority[idxIntr];1709 uIntIdHighest = uIntId;1710 }1711 idxIntr = ASMBitNextSet(pvIntrPending, cIntrs, idxIntr);1712 } while (idxIntr != -1);1713 }1714 else1715 {1716 bPriority = UINT8_MAX;1717 uIntIdHighest = GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT;1718 }1719 1720 /* Sanity check if the interrupt ID is plausible. */1721 Assert( GIC_IS_INTR_SGI_OR_PPI(uIntIdHighest)1722 || GIC_IS_INTR_SPI(uIntIdHighest)1723 || GIC_IS_INTR_EXT_PPI(uIntIdHighest)1724 || GIC_IS_INTR_EXT_SPI(uIntIdHighest)1725 || uIntIdHighest == GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT);1726 /* Ensure if no interrupt is pending, priority is appropriate. */1727 Assert(uIntIdHighest != GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT || bPriority == UINT8_MAX);1728 1729 *pbPriority = bPriority;1730 return uIntIdHighest;1731 }1732 1733 1734 static uint16_t gicDistGetHighestPrioPendingGroupIntr(PCGICDEV pGicDev, uint8_t *pbPriority, bool fGroup0)1735 {1736 uint32_t bmIntrPending[64];1737 for (uint8_t i = 0; i < RT_ELEMENTS(bmIntrs); i++)1738 {1739 bmIntrPending[i] = (pGicDev->bmIntrPending[i] & pGicDev->bmIntrEnabled[i]) & ~pGicDev->bmIntrActive[i];1740 if (fGroup0)1741 bmIntrPending[i] &= ~pGicDev->bmIntrGroup[i];1742 else1743 bmIntrPending[i] &= pGicDev->bmIntrGroup[i];1744 }1745 1746 void const *pvIntrPending = &bmIntrPending[0];1747 uint32_t const cIntrs = sizeof(bmIntrPending) * 8;1748 uint16_t const uIntId = gicGetHighestPrioPendingIntrFrom(pvIntrPending, cIntrs, pGicDev->abIntrPriority,1749 RT_ELEMENTS(pGicDev->abIntrPriority), pbPriority);1750 1751 /* Sanity check if the interrupt ID is plausible. */1752 Assert( GIC_IS_INTR_SGI_OR_PPI(uIntIdHighest)1753 || GIC_IS_INTR_SPI(uIntIdHighest)1754 || GIC_IS_INTR_EXT_PPI(uIntIdHighest)1755 || GIC_IS_INTR_EXT_SPI(uIntIdHighest)1756 || uIntIdHighest == GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT);1757 /* Ensure if no interrupt is pending, priority is appropriate. */1758 Assert(uIntIdHighest != GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT || bPriority == UINT8_MAX);1759 1760 return uIntId;1761 }1762 1763 1764 static uint16_t gicReDistGetHighestPrioPendingGroupIntr(PCGICCPU pGicCpu, uint8_t *pbPriority, bool fGroup0)1765 {1766 uint32_t bmIntrPending[3];1767 for (uint8_t i = 0; i < RT_ELEMENTS(bmIntrs); i++)1768 {1769 bmIntrPending[i] = (pGicCpu->bmIntrPending[i] & pGicCpu->bmIntrEnabled[i]) & ~pGicCpu->bmIntrActive[i];1770 if (fGroup0)1771 bmIntrPending[i] &= ~pGicCpu->bmIntrGroup[i];1772 else1773 bmIntrPending[i] &= pGicCpu->bmIntrGroup[i];1774 }1775 1776 void const *pvIntrPending = &bmIntrPending[0];1777 uint32_t const cIntrs = sizeof(bmIntrPending) * 8;1778 uint16_t const uIntId = gicGetHighestPrioPendingIntrFrom(pvIntrPending, cIntrs, pGicCpu->abIntrPriority,1779 RT_ELEMENTS(pGicCpu->abIntrPriority), pbPriority);1780 1781 /* Sanity check if the interrupt ID is plausible. */1782 Assert( GIC_IS_INTR_SGI_OR_PPI(uIntId)1783 || GIC_IS_INTR_EXT_PPI(uIntId)1784 || uIntId == GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT);1785 /* Ensure if no interrupt is pending, priority is appropriate. */1786 Assert(uIntId != GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT || *pbPriority == UINT8_MAX);1787 return uIntId;1788 }1789 1790 static uint16_t gicReDistGetHighestPrioPendingIntr(PCGICCPU pGicCpu, uint8_t *pbPriority)1791 {1792 uint16_t uIntIdHighest = 0;1793 uint8_t bPriority = UINT8_MAX;1794 uint32_t const cIntrs = sizeof(pGicCpu->bmIntrPending) * 8;1795 void const *pvIntrPending = &pGicCpu->bmIntrPending[0];1796 1797 /* Find the INTID and priority of the pending interrupt with the highest priority. */1798 int32_t idxIntr = ASMBitFirstSet(pvIntrPending, cIntrs);1799 AssertCompile(!(cIntrs % 32));1800 if (idxIntr >= 0)1801 {1802 do1803 {1804 uint16_t const uIntId = gicGetIntIdFromIndex((uint16_t)idxIntr);1805 Assert(uIntId < RT_ELEMENTS(pGicCpu->abIntrPriority));1806 if (pGicCpu->abIntrPriority[uIntId] < bPriority)1807 {1808 bPriority = pGicCpu->abIntrPriority[idxIntr];1809 uIntIdHighest = uIntId;1810 }1811 idxIntr = ASMBitNextSet(pvIntrPending, cIntrs, idxIntr);1812 } while (idxIntr != -1);1813 }1814 else1815 {1816 bPriority = UINT8_MAX;1817 uIntIdHighest = GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT;1818 }1819 1820 /* Sanity check if the interrupt ID is plausible. */1821 Assert( GIC_IS_INTR_SGI_OR_PPI(uIntIdHighest)1822 || GIC_IS_INTR_EXT_PPI(uIntIdHighest)1823 || uIntIdHighest == GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT);1824 /* Ensure if no interrupt is pending, priority is appropriate. */1825 Assert(uIntIdHighest != GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT || bPriority == UINT8_MAX);1826 1827 *pbPriority = bPriority;1828 return uIntIdHighest;1829 }1830 1831 1832 static uint16_t gicGetHighestPrioPendingIntr(PCVMCC pVM, PGICDEV pGicDev)1833 {1834 /* Get highest priority pending interrupt from the distributor. */1835 uint8_t bPriority;1836 uint16_t uIntIdHighest = gicDistGetHighestPrioPendingIntr(pGicDev, &bPriority);1837 1838 /* Compare with the highest priority pending interrupt from each redistributor. */1839 uint32_t const cCpus = pVM->cCpus;1840 for (VMCPUID idCpu = 0; idCpu < cCpus; idCpu++)1841 {1842 PCVMCPUCC pVCpu = pVM->CTX_SUFF(apCpus)[idCpu];1843 PCGICCPU pGicCpu = VMCPU_TO_GICCPU(pVCpu);1844 1845 uint8_t bReDistPriority;1846 uint16_t const uIntId = gicReDistGetHighestPrioPendingIntr(pGicCpu, &bReDistPriority);1847 if ( uIntId != GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT1848 && bReDistPriority < bPriority)1849 {1850 bReDistPriority = bPriority;1851 uIntIdHighest = uIntId;1852 }1853 }1854 1855 /* Sanity check if the interrupt ID is plausible. */1856 Assert( GIC_IS_INTR_SGI_OR_PPI(uIntIdHighest)1857 || GIC_IS_INTR_SPI(uIntIdHighest)1858 || GIC_IS_INTR_EXT_PPI(uIntIdHighest)1859 || GIC_IS_INTR_EXT_SPI(uIntIdHighest)1860 || uIntIdHighest == GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT);1861 /* Ensure if no interrupt is pending, priority is appropriate. */1862 Assert(uIntIdHighest != GIC_INTID_RANGE_SPECIAL_NO_INTERRUPT || bPriority == UINT8_MAX);1863 1864 return uIntIdHighest;1865 1650 } 1866 1651 #endif
Note:
See TracChangeset
for help on using the changeset viewer.