VirtualBox

Ignore:
Timestamp:
Mar 7, 2025 12:10:21 PM (6 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167860
Message:

VMM/GIC: bugref:10404 Implement active priority registers (not thoroughly tested).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/GICAll.cpp

    r108472 r108473  
    14211421    else
    14221422    {
    1423         /* SGIs are always edge-triggered ignore writes, verify value on strict builds (arm64 Win11 guests writes this). */
     1423        /* SGIs are always edge-triggered ignore writes. Windows 11 (24H2) arm64 guests writes these. */
    14241424        Assert(uValue == 0xaaaaaaaa);
    14251425        Assert(pGicCpu->bmIntrConfig[0] == uValue);
     
    20382038            ASMBitSet(&pGicCpu->bmIntrActive[0], idxIntr);
    20392039
     2040            /** @todo Duplicate block Id=E5ED12D2-088D-4525-9609-8325C02846C3 (start). */
     2041            /* Update the active priorities bitmap. */
     2042            AssertCompile(sizeof(pGicCpu->bmActivePriorityGroup0) * 8 >= 128);
     2043            AssertCompile(sizeof(pGicCpu->bmActivePriorityGroup1) * 8 >= 128);
     2044            uint8_t const idxPreemptionLevel = bIntrPriority >> 1;
     2045            if (fGroup0)
     2046                ASMBitSet(&pGicCpu->bmActivePriorityGroup0, idxPreemptionLevel);
     2047            if (fGroup1)
     2048                ASMBitSet(&pGicCpu->bmActivePriorityGroup1, idxPreemptionLevel);
     2049
     2050            /* Drop priority. */
     2051            if (RT_LIKELY(pGicCpu->idxRunningPriority < RT_ELEMENTS(pGicCpu->abRunningPriorities) - 1))
     2052            {
     2053                LogFlowFunc(("Dropping interrupt priority from %u -> %u (idxRunningPriority: %u -> %u)\n",
     2054                             pGicCpu->abRunningPriorities[pGicCpu->idxRunningPriority],
     2055                             bIntrPriority,
     2056                             pGicCpu->idxRunningPriority, pGicCpu->idxRunningPriority + 1));
     2057                pGicCpu->abRunningPriorities[++pGicCpu->idxRunningPriority] = bIntrPriority;
     2058            }
     2059            else
     2060                AssertReleaseMsgFailed(("Index of running interrupt priority out-of-bounds %u\n", pGicCpu->idxRunningPriority));
     2061            /** @todo Duplicate block Id=E5ED12D2-088D-4525-9609-8325C02846C3 (end). */
     2062
     2063            /* If it is an edge-triggered interrupt, mark it as no longer pending. */
     2064            AssertRelease(2 * idxIntr + 1 < sizeof(pGicCpu->bmIntrConfig) * 8);
     2065            bool const fEdgeTriggered = ASMBitTest(&pGicCpu->bmIntrConfig[0], 2 * idxIntr + 1);
     2066            if (fEdgeTriggered)
     2067                ASMBitClear(&pGicCpu->bmIntrPending[0], idxIntr);
     2068
     2069            /* Update the redistributor IRQ state to reflect change to the active interrupt. */
     2070            gicReDistUpdateIrqState(pGicDev, pVCpu);
     2071        }
     2072        else
     2073        {
     2074            /* Sanity check if the interrupt ID belongs to the distributor. */
     2075            Assert(GIC_IS_INTR_SPI(uIntId) || GIC_IS_INTR_EXT_SPI(uIntId));
     2076
     2077            /* Mark the interrupt as active. */
     2078            Assert(idxIntr < sizeof(pGicDev->bmIntrActive) * 8);
     2079            ASMBitSet(&pGicDev->bmIntrActive[0], idxIntr);
     2080
     2081            /** @todo Duplicate block Id=E5ED12D2-088D-4525-9609-8325C02846C3 (start). */
     2082            /* Update the active priorities bitmap. */
     2083            AssertCompile(sizeof(pGicCpu->bmActivePriorityGroup0) * 8 >= 128);
     2084            AssertCompile(sizeof(pGicCpu->bmActivePriorityGroup1) * 8 >= 128);
     2085            uint8_t const idxPreemptionLevel = bIntrPriority >> 1;
     2086            if (fGroup0)
     2087                ASMBitSet(&pGicCpu->bmActivePriorityGroup0, idxPreemptionLevel);
     2088            if (fGroup1)
     2089                ASMBitSet(&pGicCpu->bmActivePriorityGroup1, idxPreemptionLevel);
     2090
    20402091            /* Drop priority. */
    20412092            Assert(pGicCpu->idxRunningPriority < RT_ELEMENTS(pGicCpu->abRunningPriorities) - 1);
     
    20462097                         pGicCpu->idxRunningPriority, pGicCpu->idxRunningPriority + 1));
    20472098            pGicCpu->abRunningPriorities[++pGicCpu->idxRunningPriority] = bIntrPriority;
    2048 
    2049             /* If it is an edge-triggered interrupt, mark it as no longer pending. */
    2050             AssertRelease(2 * idxIntr + 1 < sizeof(pGicCpu->bmIntrConfig) * 8);
    2051             bool const fEdgeTriggered = ASMBitTest(&pGicCpu->bmIntrConfig[0], 2 * idxIntr + 1);
    2052             if (fEdgeTriggered)
    2053                 ASMBitClear(&pGicCpu->bmIntrPending[0], idxIntr);
    2054 
    2055             /* Update the redistributor IRQ state to reflect change to the active interrupt. */
    2056             gicReDistUpdateIrqState(pGicDev, pVCpu);
    2057         }
    2058         else
    2059         {
    2060             /* Sanity check if the interrupt ID belongs to the distirbutor. */
    2061             Assert(GIC_IS_INTR_SPI(uIntId) || GIC_IS_INTR_EXT_SPI(uIntId));
    2062 
    2063             /* Mark the interrupt as active. */
    2064             Assert(idxIntr < sizeof(pGicDev->bmIntrActive) * 8);
    2065             ASMBitSet(&pGicDev->bmIntrActive[0], idxIntr);
    2066 
    2067             /* Drop priority. */
    2068             Assert(pGicCpu->idxRunningPriority < RT_ELEMENTS(pGicCpu->abRunningPriorities) - 1);
    2069 
    2070             LogFlowFunc(("Dropping interrupt priority from %u -> %u (idxRunningPriority: %u -> %u)\n",
    2071                          pGicCpu->abRunningPriorities[pGicCpu->idxRunningPriority],
    2072                          bIntrPriority,
    2073                          pGicCpu->idxRunningPriority, pGicCpu->idxRunningPriority + 1));
    2074             pGicCpu->abRunningPriorities[++pGicCpu->idxRunningPriority] = bIntrPriority;
     2099            /** @todo Duplicate block Id=E5ED12D2-088D-4525-9609-8325C02846C3 (end). */
    20752100
    20762101            /* If it is an edge-triggered interrupt, mark it as no longer pending. */
     
    27172742            break;
    27182743        default:
    2719             //AssertReleaseFailed();
    2720             break;
     2744        {
     2745            /* Windows 11 arm64 (24H2) writes zeroes into these reserved registers. We ignore them. */
     2746            if (offReg >= 0x7fe0 && offReg <= 0x7ffc)
     2747                LogFlowFunc(("Bad guest writing to reserved GIC distributor register space [0x7fe0..0x7ffc] -- ignoring!"));
     2748            else
     2749                AssertReleaseMsgFailed(("offReg=%#x uValue=%#RX32\n", offReg, uValue));
     2750            break;
     2751        }
    27212752    }
    27222753
     
    36003631            break;
    36013632        case ARMV8_AARCH64_SYSREG_ICC_AP0R0_EL1:
    3602             /** @todo */
     3633            AssertReleaseFailed();
    36033634            break;
    36043635        case ARMV8_AARCH64_SYSREG_ICC_AP0R1_EL1:
     
    36123643            break;
    36133644        case ARMV8_AARCH64_SYSREG_ICC_AP1R0_EL1:
    3614             /** @todo */
     3645            AssertReleaseFailed();
    36153646            break;
    36163647        case ARMV8_AARCH64_SYSREG_ICC_AP1R1_EL1:
     
    37633794
    37643795            /*
    3765              * Restore previous interrupt priority.
     3796             * Drop priority by restoring previous interrupt.
    37663797             */
    37673798            Assert(pGicCpu->idxRunningPriority > 0);
    3768             if (RT_LIKELY(pGicCpu->idxRunningPriority))
     3799            if (RT_LIKELY(pGicCpu->idxRunningPriority > 0))
    37693800            {
    37703801                LogFlowFunc(("Restoring interrupt priority from %u -> %u (idxRunningPriority: %u -> %u)\n",
     
    37723803                             pGicCpu->abRunningPriorities[pGicCpu->idxRunningPriority - 1],
    37733804                             pGicCpu->idxRunningPriority, pGicCpu->idxRunningPriority - 1));
     3805
     3806                /* Update the active priorities bitmap. */
     3807                /** @todo Double check if this is doing the right thing :/ */
     3808                uint8_t const idxPreemptionLevel = pGicCpu->abRunningPriorities[pGicCpu->idxRunningPriority] >> 1;
     3809                AssertCompile(sizeof(pGicCpu->bmActivePriorityGroup1) * 8 >= 128);
     3810                ASMBitClear(&pGicCpu->bmActivePriorityGroup1, idxPreemptionLevel);
     3811
    37743812                pGicCpu->idxRunningPriority--;
    37753813            }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette