Changeset 40907 in vbox for trunk/src/VBox/VMM/VMMRC
- Timestamp:
- Apr 13, 2012 8:50:14 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp
r37410 r40907 34 34 #include <iprt/assert.h> 35 35 #include <iprt/string.h> 36 37 #include "dtrace/VBoxVMM.h" 38 #include "PDMInline.h" 36 39 37 40 … … 54 57 * Internal Functions * 55 58 *******************************************************************************/ 56 static void pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel); 57 static void pdmRCIoApicSetIrq(PVM pVM, int iIrq, int iLevel); 58 static void pdmRCIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue); 59 static bool pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel, uint32_t uTagSrc); 60 59 61 60 62 /** @name Raw-Mode Context Device Helpers … … 71 73 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceRC; 72 74 PPDMPCIBUS pPciBus = pDevIns->Internal.s.pPciBusRC; 75 76 pdmLock(pVM); 77 uint32_t uTagSrc; 78 if (iLevel & PDM_IRQ_LEVEL_HIGH) 79 { 80 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing); 81 if (iLevel == PDM_IRQ_LEVEL_HIGH) 82 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 83 else 84 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 85 } 86 else 87 uTagSrc = pDevIns->Internal.s.uLastIrqTag; 88 73 89 if ( pPciDev 74 90 && pPciBus 75 91 && pPciBus->pDevInsRC) 76 92 { 77 p dmLock(pVM);78 pPciBus->pfnSetIrqRC(pPciBus->pDevInsRC, pPciDev, iIrq, iLevel); 93 pPciBus->pfnSetIrqRC(pPciBus->pDevInsRC, pPciDev, iIrq, iLevel, uTagSrc); 94 79 95 pdmUnlock(pVM); 96 97 if (iLevel == PDM_IRQ_LEVEL_LOW) 98 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 80 99 } 81 100 else 82 101 { 102 pdmUnlock(pVM); 103 83 104 /* queue for ring-3 execution. */ 84 105 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC); 85 if (pTask) 86 { 87 pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ; 88 pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns); 89 pTask->u.SetIRQ.iIrq = iIrq; 90 pTask->u.SetIRQ.iLevel = iLevel; 91 92 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0); 93 } 94 else 95 AssertMsgFailed(("We're out of devhlp queue items!!!\n")); 96 } 97 98 LogFlow(("pdmRCDevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance)); 106 AssertReturnVoid(pTask); 107 108 pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ; 109 pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns); 110 pTask->u.SetIRQ.iIrq = iIrq; 111 pTask->u.SetIRQ.iLevel = iLevel; 112 pTask->u.SetIRQ.uTagSrc = uTagSrc; 113 114 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0); 115 } 116 117 LogFlow(("pdmRCDevHlp_PCISetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc)); 99 118 } 100 119 … … 105 124 PDMDEV_ASSERT_DEVINS(pDevIns); 106 125 LogFlow(("pdmRCDevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel)); 107 108 pdmRCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel); 109 110 LogFlow(("pdmRCDevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance)); 126 PVM pVM = pDevIns->Internal.s.pVMRC; 127 128 pdmLock(pVM); 129 uint32_t uTagSrc; 130 if (iLevel & PDM_IRQ_LEVEL_HIGH) 131 { 132 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing); 133 if (iLevel == PDM_IRQ_LEVEL_HIGH) 134 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 135 else 136 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 137 } 138 else 139 uTagSrc = pDevIns->Internal.s.uLastIrqTag; 140 141 bool fRc = pdmRCIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); 142 143 if (iLevel == PDM_IRQ_LEVEL_LOW && fRc) 144 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc)); 145 pdmUnlock(pVM); 146 LogFlow(("pdmRCDevHlp_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc)); 111 147 } 112 148 … … 531 567 /** @interface_method_impl{PDMIOAPICHLPRC,pfnApicBusDeliver} */ 532 568 static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode, 533 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode )569 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc) 534 570 { 535 571 PDMDEV_ASSERT_DEVINS(pDevIns); 536 572 PVM pVM = pDevIns->Internal.s.pVMRC; 537 LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n", 538 pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode)); 573 LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n", 574 pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc)); 575 Assert(pVM->pdm.s.Apic.pDevInsRC); 539 576 if (pVM->pdm.s.Apic.pfnBusDeliverRC) 540 return pVM->pdm.s.Apic.pfnBusDeliverRC(pVM->pdm.s.Apic.pDevInsRC, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode); 577 return pVM->pdm.s.Apic.pfnBusDeliverRC(pVM->pdm.s.Apic.pDevInsRC, u8Dest, u8DestMode, u8DeliveryMode, iVector, 578 u8Polarity, u8TriggerMode, uTagSrc); 541 579 return VINF_SUCCESS; 542 580 } … … 581 619 582 620 /** @interface_method_impl{PDMPCIHLPRC,pfnIsaSetIrq} */ 583 static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 584 { 585 PDMDEV_ASSERT_DEVINS(pDevIns); 586 Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel)); 587 pdmRCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel); 621 static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc) 622 { 623 PDMDEV_ASSERT_DEVINS(pDevIns); 624 Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc)); 625 PVM pVM = pDevIns->Internal.s.pVMRC; 626 627 pdmLock(pVM); 628 pdmRCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel, uTagSrc); 629 pdmUnlock(pVM); 588 630 } 589 631 590 632 591 633 /** @interface_method_impl{PDMPCIHLPRC,pfnIoApicSetIrq} */ 592 static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel) 593 { 594 PDMDEV_ASSERT_DEVINS(pDevIns); 595 Log4(("pdmRCPciHlp_IoApicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel)); 596 pdmRCIoApicSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel); 597 } 634 static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc) 635 { 636 PDMDEV_ASSERT_DEVINS(pDevIns); 637 Log4(("pdmRCPciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc)); 638 PVM pVM = pDevIns->Internal.s.pVMRC; 639 640 if (pVM->pdm.s.IoApic.pDevInsRC) 641 { 642 pdmLock(pVM); 643 pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel, uTagSrc); 644 pdmUnlock(pVM); 645 } 646 else if (pVM->pdm.s.IoApic.pDevInsR3) 647 { 648 /* queue for ring-3 execution. */ 649 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC); 650 if (pTask) 651 { 652 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ; 653 pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */ 654 pTask->u.SetIRQ.iIrq = iIrq; 655 pTask->u.SetIRQ.iLevel = iLevel; 656 pTask->u.SetIRQ.uTagSrc = uTagSrc; 657 658 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0); 659 } 660 else 661 AssertMsgFailed(("We're out of devhlp queue items!!!\n")); 662 } 663 } 664 598 665 599 666 /** @interface_method_impl{PDMPCIHLPRC,pfnIoApicSendMsi} */ 600 static DECLCALLBACK(void) pdmRCPciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue) 601 { 602 PDMDEV_ASSERT_DEVINS(pDevIns); 603 Log4(("pdmRCPciHlp_IoApicSendMsi: Address=%p Value=%d\n", GCAddr, uValue)); 604 pdmRCIoApicSendMsi(pDevIns->Internal.s.pVMRC, GCAddr, uValue); 667 static DECLCALLBACK(void) pdmRCPciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc) 668 { 669 PDMDEV_ASSERT_DEVINS(pDevIns); 670 Log4(("pdmRCPciHlp_IoApicSendMsi: GCPhys=%p uValue=%d uTagSrc=%#x\n", GCPhys, uValue, uTagSrc)); 671 PVM pVM = pDevIns->Internal.s.pVMRC; 672 673 if (pVM->pdm.s.IoApic.pDevInsRC) 674 { 675 pdmLock(pVM); 676 pVM->pdm.s.IoApic.pfnSendMsiRC(pVM->pdm.s.IoApic.pDevInsRC, GCPhys, uValue, uTagSrc); 677 pdmUnlock(pVM); 678 } 679 else 680 { 681 AssertFatalMsgFailed(("Lazy bastarts!")); 682 } 605 683 } 606 684 … … 764 842 765 843 /** 766 * Sets an irq on the I/O APIC.844 * Sets an irq on the PIC and I/O APIC. 767 845 * 768 * @param pVM The VM handle. 769 * @param iIrq The irq. 770 * @param iLevel The new level. 771 */ 772 static void pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel) 773 { 774 if ( ( pVM->pdm.s.IoApic.pDevInsRC 775 || !pVM->pdm.s.IoApic.pDevInsR3) 776 && ( pVM->pdm.s.Pic.pDevInsRC 777 || !pVM->pdm.s.Pic.pDevInsR3)) 778 { 779 pdmLock(pVM); 846 * @returns true if delivered, false if postponed. 847 * @param pVM The VM handle. 848 * @param iIrq The irq. 849 * @param iLevel The new level. 850 * @param uTagSrc The IRQ tag and source. 851 * 852 * @remarks The caller holds the PDM lock. 853 */ 854 static bool pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel, uint32_t uTagSrc) 855 { 856 if (RT_LIKELY( ( pVM->pdm.s.IoApic.pDevInsRC 857 || !pVM->pdm.s.IoApic.pDevInsR3) 858 && ( pVM->pdm.s.Pic.pDevInsRC 859 || !pVM->pdm.s.Pic.pDevInsR3))) 860 { 780 861 if (pVM->pdm.s.Pic.pDevInsRC) 781 pVM->pdm.s.Pic.pfnSetIrqRC(pVM->pdm.s.Pic.pDevInsRC, iIrq, iLevel );862 pVM->pdm.s.Pic.pfnSetIrqRC(pVM->pdm.s.Pic.pDevInsRC, iIrq, iLevel, uTagSrc); 782 863 if (pVM->pdm.s.IoApic.pDevInsRC) 783 pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel); 784 pdmUnlock(pVM); 785 } 786 else 787 { 788 /* queue for ring-3 execution. */ 789 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC); 790 if (pTask) 791 { 792 pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ; 793 pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */ 794 pTask->u.SetIRQ.iIrq = iIrq; 795 pTask->u.SetIRQ.iLevel = iLevel; 796 797 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0); 798 } 799 else 800 AssertMsgFailed(("We're out of devhlp queue items!!!\n")); 801 } 802 } 803 804 805 /** 806 * Sets an irq on the I/O APIC. 807 * 808 * @param pVM The VM handle. 809 * @param iIrq The irq. 810 * @param iLevel The new level. 811 */ 812 static void pdmRCIoApicSetIrq(PVM pVM, int iIrq, int iLevel) 813 { 814 if (pVM->pdm.s.IoApic.pDevInsRC) 815 { 816 pdmLock(pVM); 817 pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel); 818 pdmUnlock(pVM); 819 } 820 else if (pVM->pdm.s.IoApic.pDevInsR3) 821 { 822 /* queue for ring-3 execution. */ 823 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC); 824 if (pTask) 825 { 826 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ; 827 pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */ 828 pTask->u.SetIRQ.iIrq = iIrq; 829 pTask->u.SetIRQ.iLevel = iLevel; 830 831 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0); 832 } 833 else 834 AssertMsgFailed(("We're out of devhlp queue items!!!\n")); 835 } 836 } 837 838 839 /** 840 * Sends an MSI to I/O APIC. 841 * 842 * @param pVM The VM handle. 843 * @param GCAddr Address of the message. 844 * @param uValue Value of the message. 845 */ 846 static void pdmRCIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue) 847 { 848 if (pVM->pdm.s.IoApic.pDevInsRC) 849 { 850 pdmLock(pVM); 851 pVM->pdm.s.IoApic.pfnSendMsiRC(pVM->pdm.s.IoApic.pDevInsRC, GCAddr, uValue); 852 pdmUnlock(pVM); 853 } 854 } 864 pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel, uTagSrc); 865 return true; 866 } 867 868 /* queue for ring-3 execution. */ 869 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC); 870 AssertReturn(pTask, false); 871 872 pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ; 873 pTask->pDevInsR3 = NIL_RTR3PTR; /* not required */ 874 pTask->u.SetIRQ.iIrq = iIrq; 875 pTask->u.SetIRQ.iLevel = iLevel; 876 pTask->u.SetIRQ.uTagSrc = uTagSrc; 877 878 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0); 879 return false; 880 } 881
Note:
See TracChangeset
for help on using the changeset viewer.