VirtualBox

Changeset 61916 in vbox for trunk


Ignore:
Timestamp:
Jun 28, 2016 1:34:00 PM (8 years ago)
Author:
vboxsync
Message:

IOAPIC: Fix flip-flop handling.

File:
1 edited

Legend:

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

    r61874 r61916  
    617617PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
    618618{
     619#define IOAPIC_ASSERT_IRQ(a_idxRte, a_PinMask)       do { \
     620        pThis->au32TagSrc[(a_idxRte)] = !pThis->au32TagSrc[(a_idxRte)] ? uTagSrc : RT_BIT_32(31); \
     621        pThis->uIrr |= a_PinMask; \
     622        ioapicSignalIntrForRte(pThis, (a_idxRte)); \
     623    } while (0)
     624
    619625    PIOAPIC pThis = PDMINS_2_DATA(pDevIns, PIOAPIC);
    620626    LogFlow(("IOAPIC: ioapicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
     
    646652        }
    647653
    648         /*
    649          * If the device is flip-flopping the interrupt line, there's no need to
    650          * set and unset the IRR.
    651          */
    652654        bool const     fFlipFlop = ((iLevel & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP);
    653655        uint32_t const uPrevIrr  = pThis->uIrr & uPinMask;
    654         if (u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_EDGE)
     656        if (!fFlipFlop)
    655657        {
    656             /*
    657              * For edge-triggered interrupts, we need to act only on an edge transition.
    658              * See ICH9 spec. 13.5.7 "REDIR_TBL: Redirection Table (LPC I/F-D31:F0)"
    659              */
    660             if (!uPrevIrr)
     658            if (u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_EDGE)
    661659            {
    662                 if (!fFlipFlop)
    663                     pThis->uIrr |= uPinMask;
    664 
    665                 if (!pThis->au32TagSrc[idxRte])
    666                     pThis->au32TagSrc[idxRte] = uTagSrc;
     660                /*
     661                 * For edge-triggered interrupts, we need to act only on a low to high edge transition.
     662                 * See ICH9 spec. 13.5.7 "REDIR_TBL: Redirection Table (LPC I/F-D31:F0)".
     663                 */
     664                if (!uPrevIrr)
     665                    IOAPIC_ASSERT_IRQ(idxRte, uPinMask);
    667666                else
    668                     pThis->au32TagSrc[idxRte] = RT_BIT_32(31);
    669 
    670                 ioapicSignalIntrForRte(pThis, idxRte);
     667                {
     668                    STAM_COUNTER_INC(&pThis->StatRedundantEdgeIntr);
     669                    Log2(("IOAPIC: Redundant edge-triggered interrupt %#x (%u)\n", idxRte, idxRte));
     670                }
    671671            }
    672672            else
    673673            {
    674                 STAM_COUNTER_INC(&pThis->StatRedundantEdgeIntr);
    675                 Log2(("IOAPIC: Redundant edge-triggered interrupt %#x (%u)\n", idxRte, idxRte));
     674                Assert(u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL);
     675
     676                /*
     677                 * For level-triggered interrupts, redundant interrupts are not a problem
     678                 * and will eventually be delivered anyway after an EOI, but our PDM devices
     679                 * should not typically call us with no change to the level.
     680                 */
     681                if (!uPrevIrr)
     682                { /* likely */ }
     683                else
     684                {
     685                    STAM_COUNTER_INC(&pThis->StatRedundantLevelIntr);
     686                    Log2(("IOAPIC: Redundant level-triggered interrupt %#x (%u)\n", idxRte, idxRte));
     687                }
     688
     689                IOAPIC_ASSERT_IRQ(idxRte, uPinMask);
    676690            }
    677691        }
    678692        else
    679693        {
    680             Assert(u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL);
    681 
    682694            /*
    683              * For level-triggered interrupts, redundant interrupts are not a problem
    684              * and will eventually be delivered anyway after an EOI, but our PDM devices
    685              * should not typically call us with no change to the level.
     695             * The device is flip-flopping the interrupt line, which implies we should de-assert
     696             * and assert the interrupt line. The interrupt line is left in the asserted state
     697             * after a flip-flop request.
    686698             */
    687             if (!uPrevIrr)
    688             { /* likely */ }
    689             else
    690             {
    691                 STAM_COUNTER_INC(&pThis->StatRedundantLevelIntr);
    692                 Log2(("IOAPIC: Redundant level-triggered interrupt %#x (%u)\n", idxRte, idxRte));
    693             }
    694 
    695             if (!fFlipFlop)
    696                 pThis->uIrr |= uPinMask;
    697 
    698             if (!pThis->au32TagSrc[idxRte])
    699                 pThis->au32TagSrc[idxRte] = uTagSrc;
    700             else
    701                 pThis->au32TagSrc[idxRte] = RT_BIT_32(31);
    702 
    703             ioapicSignalIntrForRte(pThis, idxRte);
     699            IOAPIC_ASSERT_IRQ(idxRte, uPinMask);
    704700        }
    705701
    706702        PDMCritSectLeave(&pThis->CritSect);
    707703    }
     704#undef IOAPIC_ASSERT_IRQ
    708705}
    709706
Note: See TracChangeset for help on using the changeset viewer.

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