- Timestamp:
- Jun 28, 2016 1:34:00 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevIOAPIC_New.cpp
r61874 r61916 617 617 PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc) 618 618 { 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 619 625 PIOAPIC pThis = PDMINS_2_DATA(pDevIns, PIOAPIC); 620 626 LogFlow(("IOAPIC: ioapicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc)); … … 646 652 } 647 653 648 /*649 * If the device is flip-flopping the interrupt line, there's no need to650 * set and unset the IRR.651 */652 654 bool const fFlipFlop = ((iLevel & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP); 653 655 uint32_t const uPrevIrr = pThis->uIrr & uPinMask; 654 if ( u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_EDGE)656 if (!fFlipFlop) 655 657 { 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) 661 659 { 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); 667 666 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 } 671 671 } 672 672 else 673 673 { 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); 676 690 } 677 691 } 678 692 else 679 693 { 680 Assert(u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL);681 682 694 /* 683 * For level-triggered interrupts, redundant interrupts are not a problem684 * and will eventually be delivered anyway after an EOI, but our PDM devices685 * 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. 686 698 */ 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); 704 700 } 705 701 706 702 PDMCritSectLeave(&pThis->CritSect); 707 703 } 704 #undef IOAPIC_ASSERT_IRQ 708 705 } 709 706
Note:
See TracChangeset
for help on using the changeset viewer.