VirtualBox

Changeset 90308 in vbox


Ignore:
Timestamp:
Jul 23, 2021 1:59:25 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
145864
Message:

DevIoApic: PDM_IRQ_LEVEL_FLIP_FLOP fix (HPET). Needs state saving. bugref:10073 oem2tickeref:43

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevIoApic.cpp

    r90307 r90308  
    260260    /** The IRQ tags and source IDs for each pin (tracing purposes). */
    261261    uint32_t                au32TagSrc[IOAPIC_NUM_INTR_PINS];
     262    /** Bitmap keeping the flip-flop-ness of pending interrupts. */
     263    uint64_t                bmFlipFlop[(IOAPIC_NUM_INTR_PINS + 63) / 64];
    262264
    263265    /** The internal IRR reflecting state of the interrupt lines. */
     
    664666#endif
    665667
    666     /*
    667      * For level-triggered interrupts, we set the remote IRR bit to indicate
    668      * the local APIC has accepted the interrupt.
    669      *
    670      * For edge-triggered interrupts, we should not clear the IRR bit as it
    671      * should remain intact to reflect the state of the interrupt line.
    672      * The device will explicitly transition to inactive state via the
    673      * ioapicSetIrq() callback.
    674      */
    675     if (   u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL
    676         && rc == VINF_SUCCESS)
    677     {
    678         Assert(u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL);
    679         pThis->au64RedirTable[idxRte] |= IOAPIC_RTE_REMOTE_IRR;
    680         STAM_COUNTER_INC(&pThis->StatLevelIrqSent);
    681         STAM_PROFILE_ADV_START(&pThis->aStatLevelAct[idxRte], a);
     668    if (rc == VINF_SUCCESS)
     669    {
     670        /*
     671         * For level-triggered interrupts, we set the remote IRR bit to indicate
     672         * the local APIC has accepted the interrupt.
     673         *
     674         * For edge-triggered interrupts, we should not clear the IRR bit as it
     675         * should remain intact to reflect the state of the interrupt line.
     676         * The device will explicitly transition to inactive state via the
     677         * ioapicSetIrq() callback.
     678         */
     679        if (u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL)
     680        {
     681            Assert(u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL);
     682            pThis->au64RedirTable[idxRte] |= IOAPIC_RTE_REMOTE_IRR;
     683            STAM_COUNTER_INC(&pThis->StatLevelIrqSent);
     684            STAM_PROFILE_ADV_START(&pThis->aStatLevelAct[idxRte], a);
     685        }
     686        /*
     687         * Edge-triggered flip-flops gets cleaned up here as the device code will
     688         * not do any explicit ioapicSetIrq and we won't receive any EOI either.
     689         */
     690        else if (ASMBitTest(pThis->bmFlipFlop, idxRte))
     691        {
     692            Log2(("IOAPIC: Clearing IRR for edge flip-flop %#x uTagSrc=%#x\n", idxRte, pThis->au32TagSrc[idxRte]));
     693            pThis->au32TagSrc[idxRte] = 0;
     694            pThis->uIrr &= ~RT_BIT_32(idxRte);
     695        }
    682696    }
    683697}
     
    942956        if (!fFlipFlop)
    943957        {
     958            ASMBitClear(pThis->bmFlipFlop, idxRte);
     959
    944960            uint32_t const uPrevIrr = pThis->uIrr & uPinMask;
    945961            if (u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_EDGE)
     
    9851001             * hence just the assert is done.
    9861002             */
     1003            ASMBitSet(pThis->bmFlipFlop, idxRte);
    9871004            IOAPIC_ASSERT_IRQ(uBusDevFn, idxRte, uPinMask, true);
    9881005        }
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